^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) }