Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * recordmcount.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This code was taken out of recordmcount.c written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * The original code had the same algorithms for both 32bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * and 64bit ELF files, but the code was duplicated to support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * the difference in structures that were used. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * file creates a macro of everything that is different between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * the 64 and 32 bit code, such that by including this header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * twice we can create both sets of functions by including this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * header once with RECORD_MCOUNT_64 undefined, and again with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * it defined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * This conversion to macros was done by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #undef append_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #undef is_fake_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #undef fn_is_fake_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #undef MIPS_is_fake_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #undef mcount_adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #undef sift_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #undef nop_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #undef find_secsym_ndx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #undef __has_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #undef has_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #undef tot_relsize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #undef get_mcountsym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #undef find_symtab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #undef get_shnum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #undef set_shnum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #undef get_shstrndx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #undef get_symindex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #undef get_sym_str_and_relp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #undef do_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #undef Elf_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #undef Elf_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #undef Elf_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #undef Elf_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #undef Elf_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #undef Elf_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #undef ELF_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #undef Elf_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #undef ELF_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #undef Elf_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #undef ELF_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #undef ELF_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #undef fn_ELF_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #undef fn_ELF_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #undef uint_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #undef _w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #undef _align
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #undef _size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #ifdef RECORD_MCOUNT_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) # define append_func		append64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) # define sift_rel_mcount	sift64_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) # define nop_mcount		nop_mcount_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) # define find_secsym_ndx	find64_secsym_ndx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) # define __has_rel_mcount	__has64_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) # define has_rel_mcount		has64_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) # define tot_relsize		tot64_relsize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) # define find_symtab		find_symtab64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) # define get_shnum		get_shnum64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) # define set_shnum		set_shnum64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) # define get_shstrndx		get_shstrndx64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) # define get_symindex		get_symindex64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) # define get_sym_str_and_relp	get_sym_str_and_relp_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) # define do_func		do64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) # define get_mcountsym		get_mcountsym_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) # define is_fake_mcount		is_fake_mcount64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) # define fn_is_fake_mcount	fn_is_fake_mcount64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) # define MIPS_is_fake_mcount	MIPS64_is_fake_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) # define mcount_adjust		mcount_adjust_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) # define Elf_Addr		Elf64_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) # define Elf_Ehdr		Elf64_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) # define Elf_Shdr		Elf64_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) # define Elf_Rel		Elf64_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) # define Elf_Rela		Elf64_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) # define Elf_Sym		Elf64_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) # define ELF_R_SYM		ELF64_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) # define Elf_r_sym		Elf64_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) # define ELF_R_INFO		ELF64_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) # define Elf_r_info		Elf64_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) # define ELF_ST_BIND		ELF64_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) # define ELF_ST_TYPE		ELF64_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) # define fn_ELF_R_SYM		fn_ELF64_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) # define fn_ELF_R_INFO		fn_ELF64_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) # define uint_t			uint64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) # define _w			w8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) # define _align			7u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) # define _size			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) # define append_func		append32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) # define sift_rel_mcount	sift32_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) # define nop_mcount		nop_mcount_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) # define find_secsym_ndx	find32_secsym_ndx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) # define __has_rel_mcount	__has32_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) # define has_rel_mcount		has32_rel_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) # define tot_relsize		tot32_relsize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) # define find_symtab		find_symtab32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) # define get_shnum		get_shnum32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) # define set_shnum		set_shnum32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) # define get_shstrndx		get_shstrndx32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) # define get_symindex		get_symindex32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) # define get_sym_str_and_relp	get_sym_str_and_relp_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) # define do_func		do32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) # define get_mcountsym		get_mcountsym_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) # define is_fake_mcount		is_fake_mcount32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) # define fn_is_fake_mcount	fn_is_fake_mcount32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) # define MIPS_is_fake_mcount	MIPS32_is_fake_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) # define mcount_adjust		mcount_adjust_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) # define Elf_Addr		Elf32_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) # define Elf_Ehdr		Elf32_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) # define Elf_Shdr		Elf32_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) # define Elf_Rel		Elf32_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) # define Elf_Rela		Elf32_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) # define Elf_Sym		Elf32_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) # define ELF_R_SYM		ELF32_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) # define Elf_r_sym		Elf32_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) # define ELF_R_INFO		ELF32_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) # define Elf_r_info		Elf32_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) # define ELF_ST_BIND		ELF32_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) # define ELF_ST_TYPE		ELF32_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) # define fn_ELF_R_SYM		fn_ELF32_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) # define fn_ELF_R_INFO		fn_ELF32_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) # define uint_t			uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) # define _w			w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) # define _align			3u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) # define _size			4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Functions and pointers that do_file() may override for specific e_machine. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int fn_is_fake_mcount(Elf_Rel const *rp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return ELF_R_SYM(_w(rp->r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	rp->r_info = _w(ELF_R_INFO(sym, type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int mcount_adjust = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * _mcount symbol is needed for dynamic function tracer, with it, to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * tracing(ftrace_make_nop), the instruction in the position is replaced with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * the "b label" instruction, to enable tracing(ftrace_make_call), replace the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * instruction back. So, here, we set the 2nd one as fake and filter it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  * c:	3c030000	lui	v1,0x0		<-->	b	label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  *		c: R_MIPS_HI16	_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  *		c: R_MIPS_NONE	*ABS*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  *		c: R_MIPS_NONE	*ABS*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * 10:	64630000	daddiu	v1,v1,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *		10: R_MIPS_LO16	_mcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *		10: R_MIPS_NONE	*ABS*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  *		10: R_MIPS_NONE	*ABS*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * 14:	03e0082d	move	at,ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * 18:	0060f809	jalr	v1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define MIPS_FAKEMCOUNT_OFFSET	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int MIPS_is_fake_mcount(Elf_Rel const *rp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	static Elf_Addr old_r_offset = ~(Elf_Addr)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	Elf_Addr current_r_offset = _w(rp->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	int is_fake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	is_fake = (old_r_offset != ~(Elf_Addr)0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		(current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	old_r_offset = current_r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return is_fake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static unsigned int get_symindex(Elf_Sym const *sym, Elf32_Word const *symtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				 Elf32_Word const *symtab_shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	unsigned short shndx = w2(sym->st_shndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (shndx > SHN_UNDEF && shndx < SHN_LORESERVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return shndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (shndx == SHN_XINDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		offset = (unsigned long)sym - (unsigned long)symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		index = offset / sizeof(*sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		return w(symtab_shndx[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static unsigned int get_shnum(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (shdr0 && !ehdr->e_shnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		return w(shdr0->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	return w2(ehdr->e_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void set_shnum(Elf_Ehdr *ehdr, Elf_Shdr *shdr0, unsigned int new_shnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (new_shnum >= SHN_LORESERVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		ehdr->e_shnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		shdr0->sh_size = w(new_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		ehdr->e_shnum = w2(new_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int get_shstrndx(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (ehdr->e_shstrndx != SHN_XINDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return w2(ehdr->e_shstrndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return w(shdr0->sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void find_symtab(Elf_Ehdr *const ehdr, Elf_Shdr const *shdr0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			unsigned const nhdr, Elf32_Word **symtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			Elf32_Word **symtab_shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	Elf_Shdr const *relhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	unsigned k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	*symtab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	*symtab_shndx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		if (relhdr->sh_type == SHT_SYMTAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			*symtab = (void *)ehdr + relhdr->sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		else if (relhdr->sh_type == SHT_SYMTAB_SHNDX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			*symtab_shndx = (void *)ehdr + relhdr->sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (*symtab && *symtab_shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int append_func(Elf_Ehdr *const ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			Elf_Shdr *const shstr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			uint_t const *const mloc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			uint_t const *const mlocp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			Elf_Rel const *const mrel0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			Elf_Rel const *const mrelp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			unsigned int const rel_entsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			unsigned int const symsec_sh_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	/* Begin constructing output file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	Elf_Shdr mcsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		? ".rela__mcount_loc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		:  ".rel__mcount_loc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	uint_t const old_shoff = _w(ehdr->e_shoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	uint_t const old_shstr_sh_size   = _w(shstr->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	Elf_Shdr *const shdr0 = (Elf_Shdr *)(old_shoff + (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	unsigned int const old_shnum = get_shnum(ehdr, shdr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	unsigned int const new_shnum = 2 + old_shnum; /* {.rel,}__mcount_loc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	uint_t new_e_shoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	shstr->sh_size = _w(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	shstr->sh_offset = _w(sb.st_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	t += sb.st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	t += (_align & -t);  /* word-byte align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	new_e_shoff = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	set_shnum(ehdr, shdr0, new_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/* body for new shstrtab */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	if (ulseek(sb.st_size, SEEK_SET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (uwrite(old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (uwrite(mc_name, 1 + strlen(mc_name)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	/* old(modified) Elf_Shdr table, word-byte aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (ulseek(t, SEEK_SET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	t += sizeof(Elf_Shdr) * old_shnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (uwrite(old_shoff + (void *)ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	       sizeof(Elf_Shdr) * old_shnum) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	/* new sections __mcount_loc and .rel__mcount_loc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	t += 2*sizeof(mcsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		+ old_shstr_sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	mcsec.sh_type = w(SHT_PROGBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	mcsec.sh_flags = _w(SHF_ALLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	mcsec.sh_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	mcsec.sh_offset = _w(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	mcsec.sh_size = _w((void *)mlocp - (void *)mloc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	mcsec.sh_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	mcsec.sh_info = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	mcsec.sh_addralign = _w(_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	mcsec.sh_entsize = _w(_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	if (uwrite(&mcsec, sizeof(mcsec)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	mcsec.sh_name = w(old_shstr_sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		? w(SHT_RELA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		: w(SHT_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	mcsec.sh_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	mcsec.sh_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	mcsec.sh_size   = _w((void *)mrelp - (void *)mrel0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	mcsec.sh_link = w(symsec_sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	mcsec.sh_info = w(old_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	mcsec.sh_addralign = _w(_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	mcsec.sh_entsize = _w(rel_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (uwrite(&mcsec, sizeof(mcsec)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (uwrite(mloc0, (void *)mlocp - (void *)mloc0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (uwrite(mrel0, (void *)mrelp - (void *)mrel0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	ehdr->e_shoff = _w(new_e_shoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (ulseek(0, SEEK_SET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (uwrite(ehdr, sizeof(*ehdr)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static unsigned get_mcountsym(Elf_Sym const *const sym0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			      Elf_Rel const *relp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			      char const *const str0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	unsigned mcountsym = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	Elf_Sym const *const symp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		&sym0[Elf_r_sym(relp)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	char const *symname = &str0[w(symp->st_name)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	char const *mcount = gpfx == '_' ? "_mcount" : "mcount";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	char const *fentry = "__fentry__";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (symname[0] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		++symname;  /* ppc64 hack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (strcmp(mcount, symname) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	    (altmcount && strcmp(altmcount, symname) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	    (strcmp(fentry, symname) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		mcountsym = Elf_r_sym(relp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	return mcountsym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void get_sym_str_and_relp(Elf_Shdr const *const relhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 				 Elf_Ehdr const *const ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				 Elf_Sym const **sym0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 				 char const **str0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 				 Elf_Rel const **relp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	unsigned const symsec_sh_link = w(relhdr->sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	*sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 				  + (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	*str0 = (char const *)(_w(strsec->sh_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			       + (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	*relp = rel0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * Look at the relocations in order to find the calls to mcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * Accumulate the section offsets that are found, and their relocation info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * onto the end of the existing arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static uint_t *sift_rel_mcount(uint_t *mlocp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			       unsigned const offbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			       Elf_Rel **const mrelpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			       Elf_Shdr const *const relhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			       Elf_Ehdr const *const ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			       unsigned const recsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			       uint_t const recval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			       unsigned const reltype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	uint_t *const mloc0 = mlocp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	Elf_Rel *mrelp = *mrelpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	Elf_Sym const *sym0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	char const *str0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	Elf_Rel const *relp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	unsigned rel_entsize = _w(relhdr->sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	unsigned mcountsym = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	unsigned t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	for (t = nrel; t; --t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		if (!mcountsym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			mcountsym = get_mcountsym(sym0, relp, str0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		if (mcountsym && mcountsym == Elf_r_sym(relp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 				!is_fake_mcount(relp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			uint_t const addend =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 				_w(_w(relp->r_offset) - recval + mcount_adjust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			mrelp->r_offset = _w(offbase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 				+ ((void *)mlocp - (void *)mloc0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			Elf_r_info(mrelp, recsym, reltype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			if (rel_entsize == sizeof(Elf_Rela)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				((Elf_Rela *)mrelp)->r_addend = addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 				*mlocp++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				*mlocp++ = addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	*mrelpp = mrelp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	return mlocp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  * Read the relocation table again, but this time its called on sections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  * that are not going to be traced. The mcount calls here will be converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  * into nops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int nop_mcount(Elf_Shdr const *const relhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		      Elf_Ehdr const *const ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		      const char *const txtname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	Elf_Sym const *sym0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	char const *str0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	Elf_Rel const *relp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	unsigned rel_entsize = _w(relhdr->sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	unsigned mcountsym = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	unsigned t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	int once = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	for (t = nrel; t; --t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		if (!mcountsym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 			mcountsym = get_mcountsym(sym0, relp, str0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			if (make_nop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 				ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			if (warn_on_notrace_sect && !once) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				printf("Section %s has mcount callers being ignored\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 				       txtname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				once = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 				/* just warn? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				if (!make_nop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		 * If we successfully removed the mcount, mark the relocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		 * as a nop (don't do anything with it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			Elf_Rel rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			rel = *(Elf_Rel *)relp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			if (ulseek((void *)relp - (void *)ehdr, SEEK_SET) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			if (uwrite(&rel, sizeof(rel)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)  * Find a symbol in the given section, to be used as the base for relocating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)  * the table of offsets of calls to mcount.  A local or global symbol suffices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)  * but avoid a Weak symbol because it may be overridden; the change in value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  * would invalidate the relocations of the offsets of the calls to mcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  * Often the found symbol will be the unnamed local symbol generated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  * GNU 'as' for the start of each section.  For example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  *    Num:    Value  Size Type    Bind   Vis      Ndx Name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)  *      2: 00000000     0 SECTION LOCAL  DEFAULT    1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int find_secsym_ndx(unsigned const txtndx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 				char const *const txtname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				uint_t *const recvalp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 				unsigned int *sym_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 				Elf_Shdr const *const symhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 				Elf32_Word const *symtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				Elf32_Word const *symtab_shndx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 				Elf_Ehdr const *const ehdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	unsigned const nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	Elf_Sym const *symp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	unsigned t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	for (symp = sym0, t = nsym; t; --t, ++symp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		unsigned int const st_bind = ELF_ST_BIND(symp->st_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (txtndx == get_symindex(symp, symtab, symtab_shndx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			/* avoid STB_WEAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		    && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			/* function symbols on ARM have quirks, avoid them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			if (w2(ehdr->e_machine) == EM_ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			    && ELF_ST_TYPE(symp->st_info) == STT_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			*recvalp = _w(symp->st_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			*sym_index = symp - sym0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	fprintf(stderr, "Cannot find symbol for section %u: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		txtndx, txtname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static char const * __has_rel_mcount(Elf_Shdr const *const relhdr, /* reltype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				     Elf_Shdr const *const shdr0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 				     char const *const shstrtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				     char const *const fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	/* .sh_info depends on .sh_type == SHT_REL[,A] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	char const *const txtname = &shstrtab[w(txthdr->sh_name)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	if (strcmp("__mcount_loc", txtname) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		return already_has_rel_mcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	if (w(txthdr->sh_type) != SHT_PROGBITS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	    !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	return txtname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static char const *has_rel_mcount(Elf_Shdr const *const relhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 				  Elf_Shdr const *const shdr0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 				  char const *const shstrtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 				  char const *const fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (w(relhdr->sh_type) != SHT_REL && w(relhdr->sh_type) != SHT_RELA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	return __has_rel_mcount(relhdr, shdr0, shstrtab, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static unsigned tot_relsize(Elf_Shdr const *const shdr0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			    unsigned nhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			    const char *const shstrtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 			    const char *const fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	unsigned totrelsz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	Elf_Shdr const *shdrp = shdr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	char const *txtname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	for (; nhdr; --nhdr, ++shdrp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		if (txtname == already_has_rel_mcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			totrelsz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		if (txtname && is_mcounted_section_name(txtname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			totrelsz += _w(shdrp->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return totrelsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Overall supervision for Elf32 ET_REL file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		   unsigned const reltype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	unsigned const nhdr = get_shnum(ehdr, shdr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	Elf_Shdr *const shstr = &shdr0[get_shstrndx(ehdr, shdr0)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	char const *const shstrtab = (char const *)(_w(shstr->sh_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		+ (void *)ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	Elf_Shdr const *relhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	unsigned k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	Elf32_Word *symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	Elf32_Word *symtab_shndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	/* Upper bound on space: assume all relevant relocs are for mcount. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	unsigned       totrelsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	Elf_Rel *      mrel0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	Elf_Rel *      mrelp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	uint_t *      mloc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	uint_t *      mlocp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	unsigned rel_entsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	unsigned symsec_sh_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (totrelsz == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	mrel0 = umalloc(totrelsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	mrelp = mrel0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (!mrel0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	/* 2*sizeof(address) <= sizeof(Elf_Rel) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	mloc0 = umalloc(totrelsz>>1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	mlocp = mloc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	if (!mloc0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		free(mrel0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	find_symtab(ehdr, shdr0, nhdr, &symtab, &symtab_shndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		char const *const txtname = has_rel_mcount(relhdr, shdr0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			shstrtab, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		if (txtname == already_has_rel_mcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			file_updated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			goto out; /* Nothing to be done; don't append! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		if (txtname && is_mcounted_section_name(txtname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			unsigned int recsym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			uint_t recval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			symsec_sh_link = w(relhdr->sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			result = find_secsym_ndx(w(relhdr->sh_info), txtname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 						&recval, &recsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 						&shdr0[symsec_sh_link],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 						symtab, symtab_shndx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 						ehdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			rel_entsize = _w(relhdr->sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 			mlocp = sift_rel_mcount(mlocp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 				(void *)mlocp - (void *)mloc0, &mrelp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 				relhdr, ehdr, recsym, recval, reltype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		} else if (txtname && (warn_on_notrace_sect || make_nop)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 			 * This section is ignored by ftrace, but still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 			 * has mcount calls. Convert them to nops now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			if (nop_mcount(relhdr, ehdr, txtname) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 				result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (!result && mloc0 != mlocp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		result = append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 				     rel_entsize, symsec_sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	free(mrel0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	free(mloc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }