/* SPDX-License-Identifier: GPL-2.0-only */ /* * recordmcount.h * * This code was taken out of recordmcount.c written by * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved. * * The original code had the same algorithms for both 32bit * and 64bit ELF files, but the code was duplicated to support * the difference in structures that were used. This * file creates a macro of everything that is different between * the 64 and 32 bit code, such that by including this header * twice we can create both sets of functions by including this * header once with RECORD_MCOUNT_64 undefined, and again with * it defined. * * This conversion to macros was done by: * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
*/ #undef append_func #undef is_fake_mcount #undef fn_is_fake_mcount #undef MIPS_is_fake_mcount #undef mcount_adjust #undef sift_rel_mcount #undef nop_mcount #undef find_secsym_ndx #undef __has_rel_mcount #undef has_rel_mcount #undef tot_relsize #undef get_mcountsym #undef find_symtab #undef get_shnum #undef set_shnum #undef get_shstrndx #undef get_symindex #undef get_sym_str_and_relp #undef do_func #undef Elf_Addr #undef Elf_Ehdr #undef Elf_Shdr #undef Elf_Rel #undef Elf_Rela #undef Elf_Sym #undef ELF_R_SYM #undef Elf_r_sym #undef ELF_R_INFO #undef Elf_r_info #undef ELF_ST_BIND #undef ELF_ST_TYPE #undef fn_ELF_R_SYM #undef fn_ELF_R_INFO #undef uint_t #undef _w #undef _align #undef _size
/* Functions and pointers that do_file() may override for specific e_machine. */ staticint fn_is_fake_mcount(Elf_Rel const *rp)
{ return0;
} staticint (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
/* * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st * _mcount symbol is needed for dynamic function tracer, with it, to disable * tracing(ftrace_make_nop), the instruction in the position is replaced with * the "b label" instruction, to enable tracing(ftrace_make_call), replace the * instruction back. So, here, we set the 2nd one as fake and filter it. * * c: 3c030000 lui v1,0x0 <--> b label * c: R_MIPS_HI16 _mcount * c: R_MIPS_NONE *ABS* * c: R_MIPS_NONE *ABS* * 10: 64630000 daddiu v1,v1,0 * 10: R_MIPS_LO16 _mcount * 10: R_MIPS_NONE *ABS* * 10: R_MIPS_NONE *ABS* * 14: 03e0082d move at,ra * 18: 0060f809 jalr v1 * label:
*/ #define MIPS_FAKEMCOUNT_OFFSET 4
/* * Read the relocation table again, but this time its called on sections * that are not going to be traced. The mcount calls here will be converted * into nops.
*/ staticint nop_mcount(Elf_Shdr const *const relhdr,
Elf_Ehdr const *const ehdr, constchar *const txtname)
{
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
+ (void *)ehdr);
Elf_Sym const *sym0; charconst *str0;
Elf_Rel const *relp;
Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)]; unsigned rel_entsize = _w(relhdr->sh_entsize); unsignedconst nrel = _w(relhdr->sh_size) / rel_entsize; unsigned mcountsym = 0; unsigned t; int once = 0;
if (!mcountsym)
mcountsym = get_mcountsym(sym0, relp, str0);
if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { if (make_nop)
ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset)); if (warn_on_notrace_sect && !once) {
printf("Section %s has mcount callers being ignored\n",
txtname);
once = 1; /* just warn? */ if (!make_nop) return0;
}
}
/* * If we successfully removed the mcount, mark the relocation * as a nop (don't do anything with it).
*/ if (!ret) {
Elf_Rel rel;
rel = *(Elf_Rel *)relp;
Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop); if (ulseek((void *)relp - (void *)ehdr, SEEK_SET) < 0) return -1; if (uwrite(&rel, sizeof(rel)) < 0) return -1;
}
relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
} return0;
}
/* * Find a symbol in the given section, to be used as the base for relocating * the table of offsets of calls to mcount. A local or global symbol suffices, * but avoid a Weak symbol because it may be overridden; the change in value * would invalidate the relocations of the offsets of the calls to mcount. * Often the found symbol will be the unnamed local symbol generated by * GNU 'as' for the start of each section. For example: * Num: Value Size Type Bind Vis Ndx Name * 2: 00000000 0 SECTION LOCAL DEFAULT 1
*/ staticint find_secsym_ndx(unsignedconst txtndx, charconst *const txtname,
uint_t *const recvalp, unsignedint *sym_index,
Elf_Shdr const *const symhdr,
Elf32_Word const *symtab,
Elf32_Word const *symtab_shndx,
Elf_Ehdr const *const ehdr)
{
Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
+ (void *)ehdr); unsignedconst nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize);
Elf_Sym const *symp; unsigned t;
for (symp = sym0, t = nsym; t; --t, ++symp) { unsignedintconst st_bind = ELF_ST_BIND(symp->st_info);
if (txtndx == get_symindex(symp, symtab, symtab_shndx) /* avoid STB_WEAK */
&& (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { /* function symbols on ARM have quirks, avoid them */ if (w2(ehdr->e_machine) == EM_ARM
&& ELF_ST_TYPE(symp->st_info) == STT_FUNC) continue;
for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { charconst *const txtname = has_rel_mcount(relhdr, shdr0,
shstrtab, fname); if (txtname == already_has_rel_mcount) {
result = 0;
file_updated = 0; goto out; /* Nothing to be done; don't append! */
} if (txtname && is_mcounted_section_name(txtname)) { unsignedint recsym;
uint_t recval = 0;
symsec_sh_link = w(relhdr->sh_link);
result = find_secsym_ndx(w(relhdr->sh_info), txtname,
&recval, &recsym,
&shdr0[symsec_sh_link],
symtab, symtab_shndx,
ehdr); if (result) goto out;
rel_entsize = _w(relhdr->sh_entsize);
mlocp = sift_rel_mcount(mlocp,
(void *)mlocp - (void *)mloc0, &mrelp,
relhdr, ehdr, recsym, recval, reltype);
} elseif (txtname && (warn_on_notrace_sect || make_nop)) { /* * This section is ignored by ftrace, but still * has mcount calls. Convert them to nops now.
*/ if (nop_mcount(relhdr, ehdr, txtname) < 0) {
result = -1; goto out;
}
}
} if (!result && mloc0 != mlocp)
result = append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
rel_entsize, symsec_sh_link);
out:
free(mrel0);
free(mloc0); return result;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet am 2026-06-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.