23 #undef fn_is_fake_mcount
24 #undef MIPS_is_fake_mcount
26 #undef sift_rel_mcount
28 #undef find_secsym_ndx
29 #undef __has_rel_mcount
33 #undef get_sym_str_and_relp
54 #ifdef RECORD_MCOUNT_64
55 # define append_func append64
56 # define sift_rel_mcount sift64_rel_mcount
57 # define nop_mcount nop_mcount_64
58 # define find_secsym_ndx find64_secsym_ndx
59 # define __has_rel_mcount __has64_rel_mcount
60 # define has_rel_mcount has64_rel_mcount
61 # define tot_relsize tot64_relsize
62 # define get_sym_str_and_relp get_sym_str_and_relp_64
64 # define get_mcountsym get_mcountsym_64
65 # define is_fake_mcount is_fake_mcount64
66 # define fn_is_fake_mcount fn_is_fake_mcount64
67 # define MIPS_is_fake_mcount MIPS64_is_fake_mcount
68 # define mcount_adjust mcount_adjust_64
69 # define Elf_Addr Elf64_Addr
70 # define Elf_Ehdr Elf64_Ehdr
71 # define Elf_Shdr Elf64_Shdr
72 # define Elf_Rel Elf64_Rel
73 # define Elf_Rela Elf64_Rela
74 # define Elf_Sym Elf64_Sym
75 # define ELF_R_SYM ELF64_R_SYM
76 # define Elf_r_sym Elf64_r_sym
77 # define ELF_R_INFO ELF64_R_INFO
78 # define Elf_r_info Elf64_r_info
79 # define ELF_ST_BIND ELF64_ST_BIND
80 # define ELF_ST_TYPE ELF64_ST_TYPE
81 # define fn_ELF_R_SYM fn_ELF64_R_SYM
82 # define fn_ELF_R_INFO fn_ELF64_R_INFO
83 # define uint_t uint64_t
88 # define append_func append32
89 # define sift_rel_mcount sift32_rel_mcount
90 # define nop_mcount nop_mcount_32
91 # define find_secsym_ndx find32_secsym_ndx
92 # define __has_rel_mcount __has32_rel_mcount
93 # define has_rel_mcount has32_rel_mcount
94 # define tot_relsize tot32_relsize
95 # define get_sym_str_and_relp get_sym_str_and_relp_32
97 # define get_mcountsym get_mcountsym_32
98 # define is_fake_mcount is_fake_mcount32
99 # define fn_is_fake_mcount fn_is_fake_mcount32
100 # define MIPS_is_fake_mcount MIPS32_is_fake_mcount
101 # define mcount_adjust mcount_adjust_32
102 # define Elf_Addr Elf32_Addr
103 # define Elf_Ehdr Elf32_Ehdr
104 # define Elf_Shdr Elf32_Shdr
105 # define Elf_Rel Elf32_Rel
106 # define Elf_Rela Elf32_Rela
107 # define Elf_Sym Elf32_Sym
108 # define ELF_R_SYM ELF32_R_SYM
109 # define Elf_r_sym Elf32_r_sym
110 # define ELF_R_INFO ELF32_R_INFO
111 # define Elf_r_info Elf32_r_info
112 # define ELF_ST_BIND ELF32_ST_BIND
113 # define ELF_ST_TYPE ELF32_ST_TYPE
114 # define fn_ELF_R_SYM fn_ELF32_R_SYM
115 # define fn_ELF_R_INFO fn_ELF32_R_INFO
116 # define uint_t uint32_t
162 #define MIPS_FAKEMCOUNT_OFFSET 4
170 is_fake = old_r_offset &&
172 old_r_offset = current_r_offset;
180 uint_t const *
const mloc0,
181 uint_t const *
const mlocp,
184 unsigned int const rel_entsize,
185 unsigned int const symsec_sh_link)
189 char const *mc_name = (
sizeof(
Elf_Rela) == rel_entsize)
190 ?
".rela__mcount_loc"
191 :
".rel__mcount_loc";
192 unsigned const old_shnum =
w2(ehdr->e_shnum);
193 uint_t const old_shoff =
_w(ehdr->e_shoff);
194 uint_t const old_shstr_sh_size =
_w(shstr->sh_size);
195 uint_t const old_shstr_sh_offset =
_w(shstr->sh_offset);
199 shstr->sh_size =
_w(t);
200 shstr->sh_offset =
_w(
sb.st_size);
207 uwrite(
fd_map, old_shstr_sh_offset + (
void *)ehdr, old_shstr_sh_size);
213 uwrite(
fd_map, old_shoff + (
void *)ehdr,
217 t += 2*
sizeof(mcsec);
219 + old_shstr_sh_size);
223 mcsec.sh_offset =
_w(t);
224 mcsec.sh_size =
_w((
void *)mlocp - (
void *)mloc0);
227 mcsec.sh_addralign =
_w(
_size);
229 uwrite(
fd_map, &mcsec,
sizeof(mcsec));
231 mcsec.sh_name =
w(old_shstr_sh_size);
232 mcsec.sh_type = (
sizeof(
Elf_Rela) == rel_entsize)
237 mcsec.sh_offset =
_w((
void *)mlocp - (
void *)mloc0 + t);
238 mcsec.sh_size =
_w((
void *)mrelp - (
void *)mrel0);
239 mcsec.sh_link =
w(symsec_sh_link);
240 mcsec.sh_info =
w(old_shnum);
241 mcsec.sh_addralign =
_w(
_size);
242 mcsec.sh_entsize =
_w(rel_entsize);
243 uwrite(
fd_map, &mcsec,
sizeof(mcsec));
245 uwrite(
fd_map, mloc0, (
void *)mlocp - (
void *)mloc0);
246 uwrite(
fd_map, mrel0, (
void *)mrelp - (
void *)mrel0);
248 ehdr->e_shoff =
_w(new_e_shoff);
249 ehdr->e_shnum =
w2(2 +
w2(ehdr->e_shnum));
251 uwrite(
fd_map, ehdr,
sizeof(*ehdr));
256 char const *
const str0)
258 unsigned mcountsym = 0;
262 char const *symname = &str0[
w(symp->st_name)];
263 char const *
mcount = gpfx ==
'_' ?
"_mcount" :
"mcount";
264 char const *fentry =
"__fentry__";
266 if (symname[0] ==
'.')
268 if (
strcmp(mcount, symname) == 0 ||
269 (altmcount &&
strcmp(altmcount, symname) == 0) ||
270 (
strcmp(fentry, symname) == 0))
284 unsigned const symsec_sh_link =
w(relhdr->sh_link);
285 Elf_Shdr const *
const symsec = &shdr0[symsec_sh_link];
286 Elf_Shdr const *
const strsec = &shdr0[
w(symsec->sh_link)];
290 *sym0 = (
Elf_Sym const *)(
_w(symsec->sh_offset)
293 *str0 = (
char const *)(
_w(strsec->sh_offset)
305 unsigned const offbase,
309 unsigned const recsym,
311 unsigned const reltype)
313 uint_t *
const mloc0 = mlocp;
318 unsigned rel_entsize =
_w(relhdr->sh_entsize);
319 unsigned const nrel =
_w(relhdr->sh_size) / rel_entsize;
320 unsigned mcountsym = 0;
325 for (t = nrel;
t; --
t) {
331 _w(
_w(relp->r_offset) - recval + mcount_adjust);
332 mrelp->r_offset =
_w(offbase
333 + ((
void *)mlocp - (
void *)mloc0));
335 if (rel_entsize ==
sizeof(
Elf_Rela)) {
336 ((
Elf_Rela *)mrelp)->r_addend = addend;
341 mrelp = (
Elf_Rel *)(rel_entsize + (
void *)mrelp);
343 relp = (
Elf_Rel const *)(rel_entsize + (
void *)relp);
356 const char *
const txtname)
363 Elf_Shdr const *
const shdr = &shdr0[
w(relhdr->sh_info)];
364 unsigned rel_entsize =
_w(relhdr->sh_entsize);
365 unsigned const nrel =
_w(relhdr->sh_size) / rel_entsize;
366 unsigned mcountsym = 0;
372 for (t = nrel;
t; --
t) {
380 ret = make_nop((
void *)ehdr, shdr->sh_offset + relp->r_offset);
381 if (warn_on_notrace_sect && !once) {
382 printf(
"Section %s has mcount callers being ignored\n",
400 uwrite(
fd_map, &rel,
sizeof(rel));
402 relp = (
Elf_Rel const *)(rel_entsize + (
void *)relp);
418 char const *
const txtname,
425 unsigned const nsym =
_w(symhdr->sh_size) /
_w(symhdr->sh_entsize);
429 for (symp = sym0, t = nsym;
t; --
t, ++symp) {
430 unsigned int const st_bind =
ELF_ST_BIND(symp->st_info);
432 if (txtndx ==
w2(symp->st_shndx)
440 *recvalp =
_w(symp->st_value);
444 fprintf(stderr,
"Cannot find symbol for section %d: %s.\n",
454 char const *
const shstrtab,
455 char const *
const fname)
458 Elf_Shdr const *
const txthdr = &shdr0[
w(relhdr->sh_info)];
459 char const *
const txtname = &shstrtab[
w(txthdr->sh_name)];
461 if (
strcmp(
"__mcount_loc", txtname) == 0) {
462 fprintf(stderr,
"warning: __mcount_loc already exists: %s\n",
474 char const *
const shstrtab,
475 char const *
const fname)
485 const char *
const shstrtab,
486 const char *
const fname)
488 unsigned totrelsz = 0;
492 for (; nhdr; --nhdr, ++shdrp) {
494 if (txtname && is_mcounted_section_name(txtname))
495 totrelsz +=
_w(shdrp->sh_size);
503 do_func(
Elf_Ehdr *
const ehdr,
char const *
const fname,
unsigned const reltype)
507 unsigned const nhdr =
w2(ehdr->e_shnum);
508 Elf_Shdr *
const shstr = &shdr0[
w2(ehdr->e_shstrndx)];
509 char const *
const shstrtab = (
char const *)(
_w(shstr->sh_offset)
516 unsigned const totrelsz =
tot_relsize(shdr0, nhdr, shstrtab, fname);
517 Elf_Rel *
const mrel0 = umalloc(totrelsz);
521 uint_t *
const mloc0 = umalloc(totrelsz>>1);
524 unsigned rel_entsize = 0;
525 unsigned symsec_sh_link = 0;
527 for (relhdr = shdr0, k = nhdr;
k; --
k, ++relhdr) {
530 if (txtname && is_mcounted_section_name(txtname)) {
533 w(relhdr->sh_info), txtname, &recval,
534 &shdr0[symsec_sh_link =
w(relhdr->sh_link)],
537 rel_entsize =
_w(relhdr->sh_entsize);
539 (
void *)mlocp - (
void *)mloc0, &mrelp,
540 relhdr, ehdr, recsym, recval, reltype);
541 }
else if (txtname && (warn_on_notrace_sect || make_nop)) {
549 if (mloc0 != mlocp) {
550 append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
551 rel_entsize, symsec_sh_link);