Skip to content

ElfOpen

Description

Open and parse an ELF file from disk.

Parameters

Name Direction Description
out out Populated on success.
path in Filesystem path. Prefer Str *; const char * accepted.
alloc in Allocator for the read-in byte buffer and the section / symbol vectors. Must outlive the Elf.

Success

Returns true; out owns the read-in buffer and will free it on ElfDeinit.

Failure

Returns false; logs the failing step (open / read / magic / class / decoding). out is left zeroed.

Usage example (Cross-references)

Usage examples (Cross-references)
        // (2) Open the stripped sibling.
        Elf stripped;
        if (!ElfOpen(&stripped, stripped_path_arg, base)) {
            LOG_ERROR("stripped binary not openable: {}", stripped_path_arg);
            DefaultAllocatorDeinit(&alloc);
    
        Elf elf;
        if (!ElfOpen(&elf, "/proc/self/exe", ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
    
        Elf elf;
        if (!ElfOpen(&elf, r.module_path, base)) {
            SymbolResolverDeinit(&res);
            DefaultAllocatorDeinit(&alloc);
    
        Elf elf;
        if (!ElfOpen(&elf, r.module_path, base)) {
            SymbolResolverDeinit(&res);
            DefaultAllocatorDeinit(&alloc);
    
        Elf elf;
        if (!ElfOpen(&elf, r.module_path, base)) {
            SymbolResolverDeinit(&res);
            DefaultAllocatorDeinit(&alloc);
        Elf              elf;
    
        bool opened = ElfOpen(&elf, "/proc/self/exe", ALLOCATOR_OF(&alloc));
        if (!opened) {
            DefaultAllocatorDeinit(&alloc);
        Elf              elf;
    
        if (!ElfOpen(&elf, "/proc/self/exe", ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        DefaultAllocator alloc = DefaultAllocatorInit();
        Elf              elf;
        if (!ElfOpen(&elf, "/proc/self/exe", ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
        Elf              elf;
    
        if (!ElfOpen(&elf, "/proc/self/exe", ALLOCATOR_OF(&alloc))) {
            DefaultAllocatorDeinit(&alloc);
            return false;
            append_build_id_path(&path, main->build_id, main->build_id_size);
            StrPushBackZstr(&path, ".debug");
            if (path_exists(path.data) && ElfOpen(out, path.data, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ true)) {
                    StrDeinit(&path);
            StrPushBack(&path, '/');
            StrPushBackZstr(&path, main->debuglink_name);
            if (path_exists(path.data) && ElfOpen(out, path.data, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
                    StrDeinit(&path);
            StrPushBackZstr(&path, "/.debug/");
            StrPushBackZstr(&path, main->debuglink_name);
            if (path_exists(path.data) && ElfOpen(out, path.data, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
                    StrDeinit(&path);
            StrPushBack(&path, '/');
            StrPushBackZstr(&path, main->debuglink_name);
            if (path_exists(path.data) && ElfOpen(out, path.data, alloc)) {
                if (sidecar_matches(main, out, /*by_build_id*/ false)) {
                    StrDeinit(&path);
        entry.path      = path;
        entry.load_base = load_base;
        if (!ElfOpen(&entry.elf, path, self->allocator)) {
            return NULL;
        }
    bool elf_open(Elf *out, Zstr path, Allocator *alloc) {
        if (!out || !path || !alloc) {
            LOG_FATAL("ElfOpen: NULL argument (contract violation)");
        }
        Buf data = BufInit(alloc);
        if (FileReadAndClose(path, &data) < 0) {
            BufDeinit(&data);
            LOG_ERROR("ElfOpen: failed to read {}", path);
            return false;
        }
Last updated on