tools/perf/util/symbol-elf.c
Source file repositories/reference/linux-study-clean/tools/perf/util/symbol-elf.c
File Facts
- System
- Linux kernel
- Corpus path
tools/perf/util/symbol-elf.c- Extension
.c- Size
- 68820 bytes
- Lines
- 2939
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
fcntl.hstdio.herrno.hstdlib.hstring.hunistd.hinttypes.hcompress.hdso.hlibbfd.hmap.hmaps.hsymbol.hsymsrc.hmachine.hvdso.hdebug.hutil/copyfile.hlinux/ctype.hlinux/kernel.hlinux/zalloc.hlinux/string.hsymbol/kallsyms.hinternal/lib.h
Detected Declarations
struct rel_infostruct rela_dynstruct rela_dyn_infostruct kcorestruct phdr_datastruct sym_datastruct kcore_copy_infofunction elf_getphdrnumfunction elf_getshdrstrndxfunction elf_sym__typefunction elf_sym__visibilityfunction elf_sym__is_functionfunction elf_sym__is_objectfunction elf_sym__is_labelfunction elf_sym__filterfunction elf_sec__is_textfunction elf_sec__is_datafunction elf_sec__filterfunction elf_addr_to_indexfunction filename__has_sectionfunction elf_read_program_headerfunction get_rel_symidxfunction get_rel_offsetfunction rel_cmpfunction sort_relfunction addend_may_be_ifuncfunction get_ifunc_namefunction exit_relfunction get_plt_sizesfunction machine_is_x86function exit_rela_dynfunction cmp_offsetfunction sort_rela_dynfunction get_rela_dyn_infofunction get_x86_64_plt_dispfunction get_plt_got_namefunction dso__synthesize_plt_got_symbolsfunction outfunction elf_section_by_namefunction elf_read_build_idfunction read_build_idfunction filename__read_build_idfunction sysfs__read_build_idfunction filename__read_debuglinkfunction symsrc__possibly_runtimefunction symsrc__has_symtabfunction symsrc__destroyfunction elf__needs_adjust_symbols
Annotated Snippet
struct rel_info {
u32 nr_entries;
u32 *sorted;
bool is_rela;
Elf_Data *reldata;
GElf_Rela rela;
GElf_Rel rel;
};
static u32 get_rel_symidx(struct rel_info *ri, u32 idx)
{
idx = ri->sorted ? ri->sorted[idx] : idx;
if (ri->is_rela) {
gelf_getrela(ri->reldata, idx, &ri->rela);
return GELF_R_SYM(ri->rela.r_info);
}
gelf_getrel(ri->reldata, idx, &ri->rel);
return GELF_R_SYM(ri->rel.r_info);
}
static u64 get_rel_offset(struct rel_info *ri, u32 x)
{
if (ri->is_rela) {
GElf_Rela rela;
gelf_getrela(ri->reldata, x, &rela);
return rela.r_offset;
} else {
GElf_Rel rel;
gelf_getrel(ri->reldata, x, &rel);
return rel.r_offset;
}
}
static int rel_cmp(const void *a, const void *b, void *r)
{
struct rel_info *ri = r;
u64 a_offset = get_rel_offset(ri, *(const u32 *)a);
u64 b_offset = get_rel_offset(ri, *(const u32 *)b);
return a_offset < b_offset ? -1 : (a_offset > b_offset ? 1 : 0);
}
static int sort_rel(struct rel_info *ri)
{
size_t sz = sizeof(ri->sorted[0]);
u32 i;
ri->sorted = calloc(ri->nr_entries, sz);
if (!ri->sorted)
return -1;
for (i = 0; i < ri->nr_entries; i++)
ri->sorted[i] = i;
qsort_r(ri->sorted, ri->nr_entries, sz, rel_cmp, ri);
return 0;
}
/*
* For x86_64, the GNU linker is putting IFUNC information in the relocation
* addend.
*/
static bool addend_may_be_ifunc(GElf_Ehdr *ehdr, struct rel_info *ri)
{
return ehdr->e_machine == EM_X86_64 && ri->is_rela &&
GELF_R_TYPE(ri->rela.r_info) == R_X86_64_IRELATIVE;
}
static bool get_ifunc_name(Elf *elf, struct dso *dso, GElf_Ehdr *ehdr,
struct rel_info *ri, char *buf, size_t buf_sz)
{
u64 addr = ri->rela.r_addend;
struct symbol *sym;
GElf_Phdr phdr;
if (!addend_may_be_ifunc(ehdr, ri))
return false;
if (elf_read_program_header(elf, addr, &phdr))
return false;
addr -= phdr.p_vaddr - phdr.p_offset;
sym = dso__find_symbol_nocache(dso, addr);
/* Expecting the address to be an IFUNC or IFUNC alias */
if (!sym || sym->start != addr || (sym->type != STT_GNU_IFUNC && !sym->ifunc_alias))
return false;
snprintf(buf, buf_sz, "%s@plt", sym->name);
Annotation
- Immediate include surface: `fcntl.h`, `stdio.h`, `errno.h`, `stdlib.h`, `string.h`, `unistd.h`, `inttypes.h`, `compress.h`.
- Detected declarations: `struct rel_info`, `struct rela_dyn`, `struct rela_dyn_info`, `struct kcore`, `struct phdr_data`, `struct sym_data`, `struct kcore_copy_info`, `function elf_getphdrnum`, `function elf_getshdrstrndx`, `function elf_sym__type`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.