From 48f5df252354296b688c3ae2df22a25d2e9097c3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Jul 2025 16:13:45 -0700 Subject: [PATCH] cleanup pass over elf parsing; base addr calculation? --- project.4coder | 2 +- src/dwarf/dwarf_elf.c | 184 ++++++++++------------ src/dwarf/dwarf_elf.h | 4 +- src/elf/elf.h | 4 +- src/elf/elf_parse.c | 233 +++++++++++++++------------- src/elf/elf_parse.h | 50 ++++-- src/radbin/radbin.c | 19 +-- src/radcon/radcon.c | 12 +- src/raddump/raddump.c | 4 +- src/rdi_from_dwarf/rdi_from_dwarf.c | 35 +---- 10 files changed, 273 insertions(+), 274 deletions(-) diff --git a/project.4coder b/project.4coder index 8f0e3d02..ff65fba6 100644 --- a/project.4coder +++ b/project.4coder @@ -53,7 +53,7 @@ commands = .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [scratch] - .f2 = { .win = "raddbg_stable --ipc kill_all && build radbin && pushd build && radbin.exe mule_main.rdi --out:a.dump && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f2 = { .win = "build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c index 9154741b..220223b1 100644 --- a/src/dwarf/dwarf_elf.c +++ b/src/dwarf/dwarf_elf.c @@ -2,34 +2,25 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) internal B32 -dw_is_dwarf_present_elf_section_table(String8 raw_image, ELF_BinInfo *bin) +dw_is_dwarf_present_from_elf_bin(String8 data, ELF_Bin *bin) { - Temp scratch = scratch_begin(0,0); - B32 is_dwarf_present = 0; - - ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); - - for (U64 i = 0; i < sections.count; ++i) { - ELF_Shdr64 *shdr = §ions.v[i]; - String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr); - - if (shdr->sh_type != ELF_SectionCode_ProgBits) { - continue; - } - + for EachIndex(idx, bin->shdrs.count) + { + ELF_Shdr64 *shdr = &bin->shdrs.v[idx]; + if(shdr->sh_type != ELF_SectionCode_ProgBits) { continue; } + String8 name = elf_name_from_shdr64(data, bin, shdr); DW_SectionKind s = dw_section_kind_from_string(name); - if (s == DW_Section_Null) { + if(s == DW_Section_Null) + { s = dw_section_dwo_kind_from_string(name); } - - is_dwarf_present = s != DW_Section_Null; - if (is_dwarf_present) { + is_dwarf_present = (s != DW_Section_Null); + if(is_dwarf_present) + { break; } } - - scratch_end(scratch); return is_dwarf_present; } @@ -37,99 +28,86 @@ dw_is_dwarf_present_elf_section_table(String8 raw_image, ELF_BinInfo *bin) #include "third_party/sinfl/sinfl.h" internal DW_Input -dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin) +dw_input_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin) { + DW_Input result = {0}; + B32 is_section_present[ArrayCount(result.sec)] = {0}; Temp scratch = scratch_begin(&arena, 1); - - DW_Input result = {0}; - B32 sect_status[ArrayCount(result.sec)] = {0}; - - ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); - - for (U64 sect_idx = 1; sect_idx < sections.count; ++sect_idx) { - ELF_Shdr64 *shdr = §ions.v[sect_idx]; + for(U64 section_idx = 1; section_idx < bin->shdrs.count; section_idx += 1) + { + ELF_Shdr64 *shdr = &bin->shdrs.v[section_idx]; + if(shdr->sh_type != ELF_SectionCode_ProgBits) { continue; } // skip BSS sections - // skip BSS sections - if (shdr->sh_type != ELF_SectionCode_ProgBits) { - continue; - } - - String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr); - - DW_SectionKind s = dw_section_kind_from_string(name); - B32 is_dwo = 0; - if (s == DW_Section_Null) { - s = dw_section_dwo_kind_from_string(name); + //- rjf: unpack section + String8 section_name = elf_name_from_shdr64(data, bin, shdr); + DW_SectionKind section_kind = dw_section_kind_from_string(section_name); + String8 section_data__maybe_compressed = str8_substr(data, r1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size)); + B32 is_dwo = 0; + if(section_kind == DW_Section_Null) + { + section_kind = dw_section_dwo_kind_from_string(section_name); is_dwo = 1; } - if (s != DW_Section_Null) { - if (sect_status[s]) { - Assert(!"too many debug sections with identical name, picking first"); - } else { - Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size); - String8 data = str8_substr(raw_image, raw_data_range); - - // ELF was compiled with compressed debug info - if (shdr->sh_flags & ELF_Shf_Compressed) { - String8 comp_data_with_header = data; - - // read header - ELF_Chdr64 chdr64 = {0}; - U64 chdr_size = 0; - if (ELF_HdrIs64Bit(bin->hdr.e_ident)) { - chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr64); - if (chdr_size != sizeof(chdr64)) { - Assert(!"not enough bytes to read header"); - } - } else if (ELF_HdrIs32Bit(bin->hdr.e_ident)) { - ELF_Chdr32 chdr32 = {0}; - chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr32); - if (chdr_size == sizeof(chdr32)) { - chdr64 = elf_chdr64_from_chdr32(chdr32); - } - } - - AssertAlways(IsPow2(chdr64.ch_addr_align)); - - // skip header - String8 comp_data = str8_skip(comp_data_with_header, chdr_size); - - // push buffer for the decompressor - U8 *decomp_buffer = push_array_no_zero_aligned(arena, U8, chdr64.ch_size, chdr64.ch_addr_align); - U64 actual_decomp_size = 0; - - // decompress - switch (chdr64.ch_type) { - case ELF_CompressType_None: { - AssertAlways(!"unexpected compression type"); - } break; - case ELF_CompressType_ZLib: { - actual_decomp_size = zsinflate(decomp_buffer, chdr64.ch_size, comp_data.str, comp_data.size); - } break; - case ELF_CompressType_ZStd: { - // TODO: zstd lib - NotImplemented; - } break; - default: InvalidPath; break; - } - - // TODO: error handling - AssertAlways(actual_decomp_size == chdr64.ch_size); - - // set decompressed section data - data = str8(decomp_buffer, actual_decomp_size); + //- rjf: decompress section data if needed + String8 section_data__uncompressed = {0}; + if(!(shdr->sh_flags & ELF_Shf_Compressed)) + { + section_data__uncompressed = section_data__maybe_compressed; + } + else + { + // rjf: read compressed-section header + ELF_Chdr64 chdr64 = {0}; + U64 chdr_size = 0; + if(ELF_HdrIs64Bit(bin->hdr.e_ident)) + { + chdr_size = str8_deserial_read_struct(section_data__maybe_compressed, 0, &chdr64); + } + else if(ELF_HdrIs32Bit(bin->hdr.e_ident)) + { + ELF_Chdr32 chdr32 = {0}; + chdr_size = str8_deserial_read_struct(section_data__maybe_compressed, 0, &chdr32); + if(chdr_size == sizeof(chdr32)) + { + chdr64 = elf_chdr64_from_chdr32(chdr32); + } + } + + // rjf: decompress + { + String8 section_data__compressed_contents = str8_skip(section_data__maybe_compressed, chdr_size); + switch(chdr64.ch_type) + { + default: + case ELF_CompressType_None: + { + section_data__uncompressed = section_data__compressed_contents; + }break; + case ELF_CompressType_ZLib: + { + U8 *section_data_uncompressed_buffer = push_array_no_zero_aligned(arena, U8, chdr64.ch_size, chdr64.ch_addr_align); + U64 section_data_uncompressed_size = 0; + section_data_uncompressed_size = zsinflate(section_data_uncompressed_buffer, chdr64.ch_size, section_data__compressed_contents.str, section_data__compressed_contents.size); + section_data__uncompressed = str8(section_data_uncompressed_buffer, section_data_uncompressed_size); + }break; + case ELF_CompressType_ZStd: + { + NotImplemented; + }break; } - - sect_status[s] = 1; - DW_Section *d = &result.sec[s]; - d->name = push_str8_copy(arena, name); - d->data = data; - d->is_dwo = is_dwo; } } + + //- rjf: store + { + is_section_present[section_kind] = 1; + DW_Section *d = &result.sec[section_kind]; + d->name = push_str8_copy(arena, section_name); + d->data = section_data__uncompressed; + d->is_dwo = is_dwo; + } } - scratch_end(scratch); return result; } diff --git a/src/dwarf/dwarf_elf.h b/src/dwarf/dwarf_elf.h index a54c1487..f4ec79ce 100644 --- a/src/dwarf/dwarf_elf.h +++ b/src/dwarf/dwarf_elf.h @@ -4,7 +4,7 @@ #ifndef DWARF_ELF_H #define DWARF_ELF_H -internal B32 dw_is_dwarf_present_elf_section_table(String8 raw_image, ELF_BinInfo *bin); -internal DW_Input dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin); +internal B32 dw_is_dwarf_present_from_elf_bin(String8 raw_image, ELF_Bin *bin); +internal DW_Input dw_input_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin); #endif // DWARF_ELF_H diff --git a/src/elf/elf.h b/src/elf/elf.h index d5c648b6..5e1291a2 100644 --- a/src/elf/elf.h +++ b/src/elf/elf.h @@ -671,6 +671,9 @@ typedef enum ELF_Identifier ELF_Identifier_Max = 16, } ELF_Identifier; +read_only global U8 elf_magic[] = {0x7f, 'E', 'L', 'F'}; +read_only global String8 elf_magic_string = {elf_magic, sizeof(elf_magic)}; + typedef U16 ELF_Type; typedef enum ELF_TypeEnum { @@ -993,4 +996,3 @@ internal String8 elf_string_from_class(Arena *arena, ELF_Class v); internal Arch arch_from_elf_machine(ELF_MachineKind machine); #endif // ELF_H - diff --git a/src/elf/elf_parse.c b/src/elf/elf_parse.c index ebd58bfd..3b804c0f 100644 --- a/src/elf/elf_parse.c +++ b/src/elf/elf_parse.c @@ -1,143 +1,166 @@ // Copyright (c) 2025 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal B32 -elf_check_magic(String8 data) -{ - U8 sig[ELF_Identifier_Max] = {0}; - str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1); - B32 is_magic_valid = (sig[ELF_Identifier_Mag0] == 0x7f && sig[ELF_Identifier_Mag1] == 'E' && sig[ELF_Identifier_Mag2] == 'L' && sig[ELF_Identifier_Mag3] == 'F'); - return is_magic_valid; -} +//- rjf: top-level binary parsing -internal ELF_BinInfo -elf_bin_from_data(String8 data) +internal ELF_Bin +elf_bin_from_data(Arena *arena, String8 data) { - ELF_Hdr64 hdr64 = {0}; - Rng1U64 sh_name_range = rng_1u64(0,0); - - if (elf_check_magic(data)) { + ELF_Bin bin = {0}; + if(str8_match(str8_prefix(data, elf_magic_string.size), elf_magic_string, 0) && + data.size >= ELF_Identifier_Max) + { + //- rjf: parse sig/header U8 sig[ELF_Identifier_Max] = {0}; str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1); - - switch (sig[ELF_Identifier_Class]) { - case ELF_Class_None: break; - case ELF_Class_32: { - ELF_Hdr32 hdr32 = {0}; - U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr32); - if (hdr_size == sizeof(hdr32)) { - hdr64 = elf_hdr64_from_hdr32(hdr32); - - U64 shstr_off = hdr32.e_shoff + hdr32.e_shentsize*hdr32.e_shstrndx; - ELF_Shdr32 shdr = {0}; - U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); - - if (shdr_size == sizeof(shdr)) { - sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + switch(sig[ELF_Identifier_Class]) + { + default: + case ELF_Class_None:{}break; + case ELF_Class_32: + { + ELF_Hdr32 hdr32 = {0}; + U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr32); + if(hdr_size == sizeof(hdr32)) + { + bin.hdr = elf_hdr64_from_hdr32(hdr32); + U64 shstr_off = hdr32.e_shoff + hdr32.e_shentsize*hdr32.e_shstrndx; + ELF_Shdr32 shdr = {0}; + U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); + if(shdr_size == sizeof(shdr)) + { + bin.sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + } + } + }break; + case ELF_Class_64: + { + ELF_Hdr64 hdr64 = {0}; + U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr64); + if(hdr_size == sizeof(hdr64)) + { + bin.hdr = hdr64; + U64 shstr_off = hdr64.e_shoff + hdr64.e_shentsize*hdr64.e_shstrndx; + ELF_Shdr64 shdr = {0}; + U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); + if(shdr_size == sizeof(shdr)) + { + bin.sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + } + } + }break; + } + + //- rjf: gather all shdrs + { + ELF_Hdr64 *hdr = &bin.hdr; + bin.shdrs.count = hdr->e_shnum; + bin.shdrs.v = push_array(arena, ELF_Shdr64, hdr->e_shnum); + Rng1U64 shdr_range = rng_1u64(hdr->e_shoff, hdr->e_shoff + hdr->e_shentsize*hdr->e_shnum); + String8 shdr_data = str8_substr(data, shdr_range); + for EachIndex(shdr_idx, hdr->e_shnum) + { + switch(hdr->e_ident[ELF_Identifier_Class]) + { + default: + case ELF_Class_None: + {}break; + case ELF_Class_32: + { + ELF_Shdr32 shdr32 = {0}; + str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr32), &shdr32); + bin.shdrs.v[shdr_idx] = elf_shdr64_from_shdr32(shdr32); + }break; + case ELF_Class_64: + { + str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr64), &bin.shdrs.v[shdr_idx]); + }break; } } - } break; - case ELF_Class_64: { - U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr64); - if (hdr_size == sizeof(hdr64)) { - U64 shstr_off = hdr64.e_shoff + hdr64.e_shentsize*hdr64.e_shstrndx; - ELF_Shdr64 shdr = {0}; - U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); - - if (shdr_size == sizeof(shdr)) { - sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + } + + //- rjf: gather all phdrs + { + ELF_Hdr64 *hdr = &bin.hdr; + bin.phdrs.count = hdr->e_phnum; + bin.phdrs.v = push_array(arena, ELF_Phdr64, hdr->e_phnum); + Rng1U64 phdr_range = rng_1u64(hdr->e_phoff, hdr->e_phoff + hdr->e_phentsize*hdr->e_phnum); + String8 phdr_data = str8_substr(data, phdr_range); + for EachIndex(phdr_idx, hdr->e_phnum) + { + switch(hdr->e_ident[ELF_Identifier_Class]) + { + default: + case ELF_Class_None: + {}break; + case ELF_Class_32: + { + ELF_Phdr32 phdr32 = {0}; + str8_deserial_read_struct(phdr_data, phdr_idx * sizeof(ELF_Phdr32), &phdr32); + bin.phdrs.v[phdr_idx] = elf_phdr64_from_phdr32(phdr32); + }break; + case ELF_Class_64: + { + str8_deserial_read_struct(phdr_data, phdr_idx * sizeof(ELF_Phdr64), &bin.phdrs.v[phdr_idx]); + }break; } } - } break; - default: Assert(!"invalid elf header"); break; - } - } - - ELF_BinInfo info = {0}; - info.hdr = hdr64; - info.sh_name_range = sh_name_range; - - return info; -} - -internal ELF_Shdr64Array -elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr) -{ - Rng1U64 shdr_range = rng_1u64(hdr->e_shoff, hdr->e_shoff + hdr->e_shentsize*hdr->e_shnum); - String8 shdr_data = str8_substr(raw_data, shdr_range); - - ELF_Shdr64Array result = {0}; - result.count = hdr->e_shnum; - result.v = push_array(arena, ELF_Shdr64, hdr->e_shnum); - - for(U64 shdr_idx = 0; shdr_idx < hdr->e_shnum; ++shdr_idx) { - switch (hdr->e_ident[ELF_Identifier_Class]) { - case ELF_Class_None: break; - case ELF_Class_32: { - ELF_Shdr32 shdr32 = {0}; - str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr32), &shdr32); - result.v[shdr_idx] = elf_shdr64_from_shdr32(shdr32); - } break; - case ELF_Class_64: { - str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr64), &result.v[shdr_idx]); - } break; - default: InvalidPath; break; } } - - return result; + return bin; } +//- rjf: extra bin info extraction + internal String8 -elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr) +elf_name_from_shdr64(String8 data, ELF_Bin *bin, ELF_Shdr64 *shdr) { - String8 sh_names = str8_substr(raw_data, sh_name_range); + String8 sh_names = str8_substr(data, bin->sh_name_range); String8 name = {0}; str8_deserial_read_cstr(sh_names, shdr->sh_name, &name); return name; } internal U64 -elf_base_addr_from_bin(ELF_Hdr64 *hdr) +elf_base_addr_from_bin(ELF_Bin *bin) { - NotImplemented; - return 0; + U64 base_vaddr = 0; + for EachIndex(phdr_idx, bin->phdrs.count) + { + ELF_Phdr64 *phdr = &bin->phdrs.v[phdr_idx]; + if(phdr->p_type == ELF_PType_Load && + (base_vaddr == 0 || phdr->p_vaddr < base_vaddr)) + { + base_vaddr = phdr->p_vaddr; + } + } + return base_vaddr; } -internal B32 -elf_parse_debug_link(String8 raw_data, ELF_BinInfo *elf, ELF_GnuDebugLink *debug_link_out) +internal ELF_GnuDebugLink +elf_gnu_debug_link_from_bin(String8 raw_data, ELF_Bin *bin) { - Temp scratch = scratch_begin(0,0); - - B32 is_debug_link_present = 0; - ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_data, &elf->hdr); - for (U64 i = 0; i < sections.count; ++i) { - ELF_Shdr64 *shdr = §ions.v[i]; - String8 name = elf_name_from_shdr64(raw_data, &elf->hdr, elf->sh_name_range, shdr); - - if (str8_match(name, str8_lit(".gnu_debuglink"), 0)) { + ELF_GnuDebugLink result = {0}; + for EachIndex(idx, bin->shdrs.count) + { + ELF_Shdr64 *shdr = &bin->shdrs.v[idx]; + String8 name = elf_name_from_shdr64(raw_data, bin, shdr); + if(str8_match(name, str8_lit(".gnu_debuglink"), 0)) + { Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size); - String8 data = str8_substr(raw_data, raw_data_range); - - String8 path = {0}; - U32 checksum = 0; + String8 data = str8_substr(raw_data, raw_data_range); + String8 path = {0}; + U32 checksum = 0; { U64 cursor = 0; cursor += str8_deserial_read_cstr(data, cursor, &path); - cursor = AlignPow2(cursor, 4); cursor += str8_deserial_read_struct(data, cursor, &checksum); } - - debug_link_out->path = path; - debug_link_out->checksum = checksum; - - is_debug_link_present = 1; + result.path = path; + result.checksum = checksum; break; } } - - scratch_end(scratch); - return is_debug_link_present; + return result; } - diff --git a/src/elf/elf_parse.h b/src/elf/elf_parse.h index 1d1d1ba4..1eec7c09 100644 --- a/src/elf/elf_parse.h +++ b/src/elf/elf_parse.h @@ -5,32 +5,48 @@ #define ELF_PARSE_H //////////////////////////////// +//~ rjf: Parsed Structure Types -typedef struct ELF_BinInfo +typedef struct ELF_Shdr64Array ELF_Shdr64Array; +struct ELF_Shdr64Array +{ + ELF_Shdr64 *v; + U64 count; +}; + +typedef struct ELF_Phdr64Array ELF_Phdr64Array; +struct ELF_Phdr64Array +{ + ELF_Phdr64 *v; + U64 count; +}; + +typedef struct ELF_Bin ELF_Bin; +struct ELF_Bin { ELF_Hdr64 hdr; - Rng1U64 sh_name_range; -} ELF_BinInfo; + Rng1U64 sh_name_range; + ELF_Shdr64Array shdrs; + ELF_Phdr64Array phdrs; +}; -typedef struct ELF_Shdr64Array -{ - U64 count; - ELF_Shdr64 *v; -} ELF_Shdr64Array; - -typedef struct ELF_GnuDebugLink +typedef struct ELF_GnuDebugLink ELF_GnuDebugLink; +struct ELF_GnuDebugLink { String8 path; - U32 checksum; -} ELF_GnuDebugLink; + U32 checksum; +}; //////////////////////////////// +//~ rjf: Parsing Functions -internal B32 elf_check_magic(String8 data); -internal ELF_BinInfo elf_bin_from_data(String8 data); +//- rjf: top-level binary parsing +internal ELF_Bin elf_bin_from_data(Arena *arena, String8 data); -internal ELF_Shdr64Array elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr); -internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr); -internal U64 elf_base_addr_from_bin(ELF_Hdr64 *hdr); +//- rjf: extra bin info extraction +internal B32 elf_is_dwarf_present_from_bin(String8 data, ELF_Bin *bin); +internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Bin *bin, ELF_Shdr64 *shdr); +internal U64 elf_base_addr_from_bin(ELF_Bin *bin); +internal ELF_GnuDebugLink elf_gnu_debug_link_from_bin(String8 raw_data, ELF_Bin *bin); #endif // ELF_PARSE_H diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index 4a071a6f..63bb4d84 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -264,13 +264,14 @@ rb_entry_point(CmdLine *cmdline) if(file_format == RB_FileFormat_ELF32 || file_format == RB_FileFormat_ELF64) { - ELF_BinInfo elf = elf_bin_from_data(file_data); - ELF_GnuDebugLink debug_link = {0}; - if(elf_parse_debug_link(file_data, &elf, &debug_link) && - debug_link.path.size != 0) + Temp scratch = scratch_begin(&arena, 1); + ELF_Bin bin = elf_bin_from_data(scratch.arena, file_data); + ELF_GnuDebugLink debug_link = elf_gnu_debug_link_from_bin(file_data, &bin); + if(debug_link.path.size != 0) { str8_list_push(arena, &input_file_path_tasks, debug_link.path); } + scratch_end(scratch); } ////////////////////////// @@ -298,8 +299,8 @@ rb_entry_point(CmdLine *cmdline) file_format == RB_FileFormat_ELF64) { Temp scratch = scratch_begin(&arena, 1); - ELF_BinInfo elf_bin = elf_bin_from_data(file_data); - if(dw_is_dwarf_present_elf_section_table(file_data, &elf_bin)) + ELF_Bin elf_bin = elf_bin_from_data(scratch.arena, file_data); + if(dw_is_dwarf_present_from_elf_bin(file_data, &elf_bin)) { file_format_flags |= RB_FileFormatFlag_HasDWARF; } @@ -898,7 +899,7 @@ rb_entry_point(CmdLine *cmdline) //- rjf: unpack file parses Arch arch = Arch_Null; PE_BinInfo pe = {0}; - ELF_BinInfo elf = {0}; + ELF_Bin elf = {0}; DW_Input dw = {0}; { if(f->format == RB_FileFormat_PE) @@ -909,7 +910,7 @@ rb_entry_point(CmdLine *cmdline) if(f->format == RB_FileFormat_ELF32 || f->format == RB_FileFormat_ELF64) { - elf = elf_bin_from_data(f->data); + elf = elf_bin_from_data(arena, f->data); arch = arch_from_elf_machine(elf.hdr.e_machine); } if(f->format_flags & RB_FileFormatFlag_HasDWARF) @@ -925,7 +926,7 @@ rb_entry_point(CmdLine *cmdline) else if(f->format == RB_FileFormat_ELF32 || f->format == RB_FileFormat_ELF64) { - dw = dw_input_from_elf_section_table(arena, f->data, &elf); + dw = dw_input_from_elf_bin(arena, f->data, &elf); } } } diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index 55593b54..1cd0643b 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -110,8 +110,8 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) pe_name = input_n->string; is_pe_present = 1; } else if (elf_check_magic(input_data)) { - ELF_BinInfo elf = elf_bin_from_data(input_data); - B32 is_dwarf_present = dw_is_dwarf_present_elf_section_table(input_data, &elf); + ELF_Bin elf = elf_bin_from_data(input_data); + B32 is_dwarf_present = dw_is_dwarf_present_from_bin(input_data, &elf); if (is_dwarf_present) { if (is_elf_debug_present) { fprintf(stderr, "error: ambiguous input, both ELFs have DWARF debug sections, please use --elf: --elf_debug: to clarify inputs.\n"); @@ -234,8 +234,8 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) // // Load image ELF // - ELF_BinInfo elf = elf_bin_from_data(elf_data); - B32 has_elf_dwarf = dw_is_dwarf_present_elf_section_table(elf_data, &elf); + ELF_Bin elf = elf_bin_from_data(elf_data); + B32 has_elf_dwarf = dw_is_dwarf_present_from_elf_bin(elf_data, &elf); // // ELF doesn't have debug info and no .debug was specified on command line, @@ -252,8 +252,8 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) // // Load .debug ELF // - ELF_BinInfo elf_debug = elf_bin_from_data(elf_debug_data); - B32 has_elf_debug_dwarf = dw_is_dwarf_present_elf_section_table(elf_debug_data, &elf_debug); + ELF_Bin elf_debug = elf_bin_from_data(elf_debug_data); + B32 has_elf_debug_dwarf = dw_is_dwarf_present_from_elf_bin(elf_debug_data, &elf_debug); // // Input is image ELF and .debug ELF diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 9dad6e5c..edb6a2f4 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -4078,9 +4078,9 @@ elf_print_dwarf_expressions(Arena *arena, String8List *out, String8 indent, Stri { Temp scratch = scratch_begin(&arena, 1); - ELF_BinInfo bin = elf_bin_from_data(raw_data); + ELF_Bin bin = elf_bin_from_data(raw_data); Arch arch = arch_from_elf_machine(bin.hdr.e_machine); - DW_Input dwarf_input = dw_input_from_elf_section_table(scratch.arena, raw_data, &bin); + DW_Input dwarf_input = dw_input_from_elf_bin(scratch.arena, raw_data, &bin); ELF_Class elf_class = bin.hdr.e_ident[ELF_Identifier_Class]; ExecutableImageKind image_type = elf_class == ELF_Class_32 ? ExecutableImageKind_Elf32 : elf_class == ELF_Class_64 ? ExecutableImageKind_Elf64 : ELF_Class_None; B32 relaxed = 1; diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index a7c3703c..8853262a 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -1097,44 +1097,23 @@ d2r_convert(Arena *arena, ASYNC_Root *async_root, D2R_ConvertParams *params) case ExecutableImageKind_CoffPe: { PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, params->exe_data); - - // get image arch arch = pe.arch; - - // get image base image_base = pe.image_base; - - // get image sections - String8 raw_sections = str8_substr(params->exe_data, pe.section_table_range); - U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); + String8 raw_sections = str8_substr(params->exe_data, pe.section_table_range); + U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_sections.str; - - // convert sections String8 string_table = str8_substr(params->exe_data, pe.string_table_range); binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, params->exe_data, string_table, section_count, section_table); - - // make DWARF input input = dw_input_from_coff_section_table(scratch.arena, params->exe_data, string_table, section_count, section_table); }break; case ExecutableImageKind_Elf32: case ExecutableImageKind_Elf64: { - ELF_BinInfo elf = elf_bin_from_data(params->dbg_data); - - // get image arch - arch = arch_from_elf_machine(elf.hdr.e_machine); - - // get image base - image_base = elf_base_addr_from_bin(&elf.hdr); - - // get image sections - ELF_Shdr64Array shdrs = elf_shdr64_array_from_bin(scratch.arena, params->dbg_data, &elf.hdr); - - // convert sections - binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, shdrs); - - // make DWARF input - input = dw_input_from_elf_section_table(scratch.arena, params->dbg_data, &elf); + ELF_Bin bin = elf_bin_from_data(scratch.arena, params->dbg_data); + arch = arch_from_elf_machine(bin.hdr.e_machine); + image_base = elf_base_addr_from_bin(&bin); + binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, bin.shdrs); + input = dw_input_from_elf_bin(scratch.arena, params->dbg_data, &bin); }break; }