Skip to content
ElfFindSection

ElfFindSection

Description

Find a section by name (first match) within the parsed ELF.

Parameters

Name Direction Description
self in Parsed Elf object.
name in Section name to look up (case-sensitive).

Success

Returns a pointer to the first matching ElfSection in self->sections. The pointer is borrowed and valid until ElfDeinit(self).

Failure

Returns NULL when no section name matches. self is untouched.

Usage example (Cross-references)

Usage examples (Cross-references)
            LOG_FATAL("DwarfFunctionsBuildFromElf: NULL argument");
        }
        const ElfSection *info_sec   = ElfFindSection(elf, ".debug_info");
        const ElfSection *abbrev_sec = ElfFindSection(elf, ".debug_abbrev");
        const ElfSection *str_sec    = ElfFindSection(elf, ".debug_str");
        }
        const ElfSection *info_sec   = ElfFindSection(elf, ".debug_info");
        const ElfSection *abbrev_sec = ElfFindSection(elf, ".debug_abbrev");
        const ElfSection *str_sec    = ElfFindSection(elf, ".debug_str");
        const ElfSection *info_sec   = ElfFindSection(elf, ".debug_info");
        const ElfSection *abbrev_sec = ElfFindSection(elf, ".debug_abbrev");
        const ElfSection *str_sec    = ElfFindSection(elf, ".debug_str");
    
        const u8 *info_b   = info_sec ? BufData(ElfBuf(elf)) + info_sec->offset : NULL;
        // CFI only there and leaves .eh_frame empty (the project's unwinder and
        // Sys/Backtrace would otherwise find no frames on such binaries).
        const ElfSection *eh = ElfFindSection(elf, ".eh_frame");
        bool              ok;
        if (eh && eh->size > 0) {
            ok                 = cfi_parse_section(out, BufData(ElfBuf(elf)) + eh->offset, eh->addr, eh->size, false);
        } else {
            const ElfSection *df = ElfFindSection(elf, ".debug_frame");
            if (!df || df->size == 0) {
                return true; // No CFI in this binary — still success, just empty.
    
    static void elf_decode_debug_metadata(Elf *self) {
        const ElfSection *note = ElfFindSection(self, ".note.gnu.build-id");
        if (note) {
            elf_decode_build_id(self, note);
            elf_decode_build_id(self, note);
        }
        const ElfSection *dl = ElfFindSection(self, ".gnu_debuglink");
        if (dl) {
            elf_decode_debug_link(self, dl);
        out->string_pool = StrInit(alloc);
    
        const ElfSection *line_section = ElfFindSection(elf, ".debug_line");
        if (!line_section || line_section->size == 0) {
            // No debug info — empty result is still success.
        }
    
        const ElfSection *text = ElfFindSection(&elf, ".text");
        bool              ok   = text != NULL && text->size > 0 && (text->flags & 0x4); // SHF_EXECINSTR = 0x4
        // Sections decode in order with correct names.
        ok                     = ok && VecLen(&elf.sections) == N_SECTIONS;
        const ElfSection *text = ElfFindSection(&elf, ".text");
        ok = ok && text != NULL && text->addr == TEXT_VADDR && text->offset == TEXT_OFF && text->size == TEXT_SIZE &&
             text->type == ELF_SECTION_TYPE_PROGBITS;
            return false;
        }
        bool ok = ElfFindSection(&elf, ".nosuchsection") == NULL && ElfFindSection(&elf, ".text") != NULL;
        ElfDeinit(&elf);
        DefaultAllocatorDeinit(&alloc);
        }
    
        const ElfSection *t = ElfFindSection(&elf, ".text");
        bool ok = t != NULL && t->type == ELF_SECTION_TYPE_PROGBITS && t->addr == TEXT_VADDR && t->offset == TEXT_OFF &&
                  t->size == TEXT_SIZE && (t->flags & 0x4) != 0;
        }
    
        const ElfSection *sym = ElfFindSection(&elf, ".symtab");
        // .symtab carries the distinctive info; every other section's info is 0.
        const ElfSection *txt = ElfFindSection(&elf, ".text");
        const ElfSection *sym = ElfFindSection(&elf, ".symtab");
        // .symtab carries the distinctive info; every other section's info is 0.
        const ElfSection *txt = ElfFindSection(&elf, ".text");
        bool              ok  = sym != NULL && sym->info == SYMTAB_INFO && txt != NULL && txt->info == 0;
        if (ok) {
            // Names resolved through the in-range shstrtab.
            ok = ElfFindSection(&elf, ".shstrtab") != NULL && ElfFindSection(&elf, ".text") != NULL;
            ElfDeinit(&elf);
        }
        // ".strtab" lives at NAME_STRTAB (25) in the shstrtab, well past the
        // first string. It must decode exactly, not collapse to "" or ".shstrtab".
        const ElfSection *s   = ElfFindSection(&elf, ".strtab");
        const ElfSection *sym = ElfFindSection(&elf, ".symtab");
        bool              ok =
        // first string. It must decode exactly, not collapse to "" or ".shstrtab".
        const ElfSection *s   = ElfFindSection(&elf, ".strtab");
        const ElfSection *sym = ElfFindSection(&elf, ".symtab");
        bool              ok =
            s != NULL && ZstrCompare(s->name, ".strtab") == 0 && sym != NULL && ZstrCompare(sym->name, ".symtab") == 0;
    
        // .strtab is the final section in the table.
        const ElfSection *last     = ElfFindSection(&elf, ".strtab");
        const ElfSection *expected = VecPtrAt(&elf.sections, N_SECTIONS - 1);
        bool              ok       = last != NULL && last == expected;
    
        // Absent name -> NULL.
        ok = ok && ElfFindSection(&elf, ".no_such_section_xyz") == NULL;
    
        ElfDeinit(&elf);
Last updated on