From b596a6ed8a0479f881eae127a4228518e0f77fc9 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 23 Oct 2025 17:53:30 -0700 Subject: [PATCH] dumper for SHT_NOTE --- src/dwarf/dwarf_elf.c | 4 +- src/elf/elf.h | 237 +++++++++------------------------------ src/elf/elf_dump.c | 215 +++++++++++++++++++++++++++++++++++ src/elf/elf_dump.h | 30 +++++ src/gnu/gnu.c | 225 +++++++++++++++++++++++++++++++++++++ src/gnu/gnu.h | 146 ++++++++++++++++++++++++ src/radbin/radbin.c | 30 +++-- src/radbin/radbin_main.c | 4 + 8 files changed, 694 insertions(+), 197 deletions(-) create mode 100644 src/elf/elf_dump.c create mode 100644 src/elf/elf_dump.h diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c index 6ea144f8..39884286 100644 --- a/src/dwarf/dwarf_elf.c +++ b/src/dwarf/dwarf_elf.c @@ -8,7 +8,7 @@ dw_is_dwarf_present_from_elf_bin(String8 data, ELF_Bin *bin) for EachIndex(idx, bin->shdrs.count) { ELF_Shdr64 *shdr = &bin->shdrs.v[idx]; - if(shdr->sh_type != ELF_SectionCode_ProgBits) { continue; } + if(shdr->sh_type != ELF_ShType_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) @@ -35,7 +35,7 @@ dw_input_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin) 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 + if(shdr->sh_type != ELF_ShType_ProgBits) { continue; } // skip BSS sections //- rjf: unpack section String8 section_name = elf_name_from_shdr64(data, bin, shdr); diff --git a/src/elf/elf.h b/src/elf/elf.h index 648d46dd..ddc6950e 100644 --- a/src/elf/elf.h +++ b/src/elf/elf.h @@ -151,40 +151,42 @@ enum ELF_PFlag_Read = (1 << 2), }; -typedef U32 ELF_SectionCode; +typedef U32 ELF_ShType; enum { - ELF_SectionCode_Null = 0, - ELF_SectionCode_ProgBits = 1, - ELF_SectionCode_Symtab = 2, - ELF_SectionCode_Strtab = 3, - ELF_SectionCode_Rela = 4, - ELF_SectionCode_Hash = 5, - ELF_SectionCode_Dynamic = 6, - ELF_SectionCode_Note = 7, - ELF_SectionCode_NoBits = 8, - ELF_SectionCode_Rel = 9, - ELF_SectionCode_Shlib = 10, - ELF_SectionCode_Dynsym = 11, - ELF_SectionCode_InitArray = 14, - ELF_SectionCode_FiniArray = 15, // Array of ptrs to init functions - ELF_SectionCode_PreinitArray = 16, // Array of ptrs to finish functions - ELF_SectionCode_Group = 17, // Array of ptrs to pre-init funcs - ELF_SectionCode_SymtabShndx = 18, // Section contains a section group - ELF_SectionCode_GNU_IncrementalInputs = 0x6fff4700, // Indices for SHN_XINDEX entries - ELF_SectionCode_GNU_Attributes = 0x6ffffff5, // Incremental build data - ELF_SectionCode_GNU_Hash = 0x6ffffff6, // Object attributes - ELF_SectionCode_GNU_LibList = 0x6ffffff7, // GNU style symbol hash table - ELF_SectionCode_SUNW_verdef = 0x6ffffffd, - ELF_SectionCode_SUNW_verneed = 0x6ffffffe, // Versions defined by file - ELF_SectionCode_SUNW_versym = 0x6fffffff, // Versions needed by file + ELF_ShType_Null = 0, + ELF_ShType_ProgBits = 1, + ELF_ShType_Symtab = 2, + ELF_ShType_Strtab = 3, + ELF_ShType_Rela = 4, + ELF_ShType_Hash = 5, + ELF_ShType_Dynamic = 6, + ELF_ShType_Note = 7, + ELF_ShType_NoBits = 8, + ELF_ShType_Rel = 9, + ELF_ShType_Shlib = 10, + ELF_ShType_Dynsym = 11, + ELF_ShType_InitArray = 14, + ELF_ShType_FiniArray = 15, // Array of ptrs to init functions + ELF_ShType_PreinitArray = 16, // Array of ptrs to finish functions + ELF_ShType_Group = 17, // Array of ptrs to pre-init funcs + ELF_ShType_SymtabShndx = 18, // Section contains a section group + + ELF_ShType_GNU_IncrementalInputs = 0x6fff4700, // Indices for SHN_XINDEX entries + ELF_ShType_GNU_Attributes = 0x6ffffff5, // Incremental build data + ELF_ShType_GNU_Hash = 0x6ffffff6, // Object attributes + ELF_ShType_GNU_LibList = 0x6ffffff7, // GNU style symbol hash table + + ELF_ShType_SUNW_verdef = 0x6ffffffd, + ELF_ShType_SUNW_verneed = 0x6ffffffe, // Versions defined by file + ELF_ShType_SUNW_versym = 0x6fffffff, // Versions needed by file // Symbol versions - ELF_SectionCode_GNU_verdef = ELF_SectionCode_SUNW_verdef, - ELF_SectionCode_GNU_verneed = ELF_SectionCode_SUNW_verneed, - ELF_SectionCode_GNU_versym = ELF_SectionCode_SUNW_versym, - ELF_SectionCode_Proc, - ELF_SectionCode_User, + ELF_ShType_GNU_verdef = ELF_ShType_SUNW_verdef, + ELF_ShType_GNU_verneed = ELF_ShType_SUNW_verneed, + ELF_ShType_GNU_versym = ELF_ShType_SUNW_versym, + ELF_ShType_Proc, + ELF_ShType_User, }; typedef U32 ELF_SectionIndex; @@ -527,140 +529,7 @@ enum typedef U32 ELF_NoteType; enum { - ELF_NoteType_GNU_Abi = 1, - ELF_NoteType_GNU_HwCap = 2, - ELF_NoteType_GNU_BuildId = 3, - ELF_NoteType_GNU_GoldVersion = 4, - ELF_NoteType_GNU_PropertyType0 = 5, -}; - -typedef U32 ELF_GnuABITag; -enum -{ - ELF_GnuABITag_Linux = 0, - ELF_GnuABITag_Hurd = 1, - ELF_GnuABITag_Solaris = 2, - ELF_GnuABITag_FreeBsd = 3, - ELF_GnuABITag_NetBsd = 4, - ELF_GnuABITag_Syllable = 5, - ELF_GnuABITag_Nacl = 6, -}; - -typedef S32 ELF_GnuProperty; -enum -{ - ELF_GnuProperty_LoProc = 0xc0000000, - // processor-specific range - ELF_GnuProperty_HiProc = 0xdfffffff, - ELF_GnuProperty_LoUser = 0xe0000000, - // application-specific range - ELF_GnuProperty_HiUser = 0xffffffff, - ELF_GnuProperty_StackSize = 1, - ELF_GnuProperty_NoCopyOnProtected = 2, -}; - -typedef U32 ELF_GnuPropertyX86Isa1; -enum -{ - ELF_GnuPropertyX86Isa1_BaseLine = (1 << 0), - ELF_GnuPropertyX86Isa1_V2 = (1 << 1), - ELF_GnuPropertyX86Isa1_V3 = (1 << 2), - ELF_GnuPropertyX86Isa1_V4 = (1 << 3), -}; - -typedef U32 ELF_GnuPropertyX86Compat1Isa1; -enum -{ - ELF_GnuPropertyX86Compat1Isa1_486 = (1 << 0), - ELF_GnuPropertyX86Compat1Isa1_586 = (1 << 1), - ELF_GnuPropertyX86Compat1Isa1_686 = (1 << 2), - ELF_GnuPropertyX86Compat1Isa1_SSE = (1 << 3), - ELF_GnuPropertyX86Compat1Isa1_SSE2 = (1 << 4), - ELF_GnuPropertyX86Compat1Isa1_SSE3 = (1 << 5), - ELF_GnuPropertyX86Compat1Isa1_SSSE3 = (1 << 6), - ELF_GnuPropertyX86Compat1Isa1_SSE4_1 = (1 << 7), - ELF_GnuPropertyX86Compat1Isa1_SSE4_2 = (1 << 8), - ELF_GnuPropertyX86Compat1Isa1_AVX = (1 << 9), - ELF_GnuPropertyX86Compat1Isa1_AVX2 = (1 << 10), - ELF_GnuPropertyX86Compat1Isa1_AVX512F = (1 << 11), - ELF_GnuPropertyX86Compat1Isa1_AVX512ER = (1 << 12), - ELF_GnuPropertyX86Compat1Isa1_AVX512PF = (1 << 13), - ELF_GnuPropertyX86Compat1Isa1_AVX512VL = (1 << 14), - ELF_GnuPropertyX86Compat1Isa1_AVX512DQ = (1 << 15), - ELF_GnuPropertyX86Compat1Isa1_AVX512BW = (1 << 16), -}; - -typedef U32 ELF_GnuPropertyX86Compat2Isa1; -enum -{ - ELF_GnuPropertyX86Compat2Isa1_CMOVE = (1 << 0), - ELF_GnuPropertyX86Compat2Isa1_SSE = (1 << 1), - ELF_GnuPropertyX86Compat2Isa1_SSE2 = (1 << 2), - ELF_GnuPropertyX86Compat2Isa1_SSE3 = (1 << 3), - ELF_GnuPropertyX86Compat2Isa1_SSE4_1 = (1 << 4), - ELF_GnuPropertyX86Compat2Isa1_SSE4_2 = (1 << 5), - ELF_GnuPropertyX86Compat2Isa1_AVX = (1 << 6), - ELF_GnuPropertyX86Compat2Isa1_AVX2 = (1 << 7), - ELF_GnuPropertyX86Compat2Isa1_FMA = (1 << 8), - ELF_GnuPropertyX86Compat2Isa1_AVX512F = (1 << 9), - ELF_GnuPropertyX86Compat2Isa1_AVX512CD = (1 << 10), - ELF_GnuPropertyX86Compat2Isa1_AVX512ER = (1 << 11), - ELF_GnuPropertyX86Compat2Isa1_AVX512PF = (1 << 12), - ELF_GnuPropertyX86Compat2Isa1_AVX512VL = (1 << 13), - ELF_GnuPropertyX86Compat2Isa1_AVX512DQ = (1 << 14), - ELF_GnuPropertyX86Compat2Isa1_AVX512BW = (1 << 15), - ELF_GnuPropertyX86Compat2Isa1_AVX512_4FMAPS = (1 << 16), - ELF_GnuPropertyX86Compat2Isa1_AVX512_4VNNIW = (1 << 17), - ELF_GnuPropertyX86Compat2Isa1_AVX512_BITALG = (1 << 18), - ELF_GnuPropertyX86Compat2Isa1_AVX512_IFMA = (1 << 19), - ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI = (1 << 20), - ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI2 = (1 << 21), - ELF_GnuPropertyX86Compat2Isa1_AVX512_VNNI = (1 << 22), - ELF_GnuPropertyX86Compat2Isa1_AVX512_BF16 = (1 << 23), -}; - -typedef S32 ELF_GnuPropertyX86; -enum -{ - ELF_GnuPropertyX86_Feature1And = 0xc0000002, - ELF_GnuPropertyX86_Feature2Used = 0xc0010001, - ELF_GnuPropertyX86_Isa1needed = 0xc0008002, - ELF_GnuPropertyX86_Isa2Needed = 0xc0008001, - ELF_GnuPropertyX86_Isa1Used = 0xc0010002, - ELF_GnuPropertyX86_Compat_isa_1_used = 0xc0000000, - ELF_GnuPropertyX86_Compat_isa_1_needed = 0xc0000001, - ELF_GnuPropertyX86_UInt32AndLo = ELF_GnuPropertyX86_Feature1And, - ELF_GnuPropertyX86_UInt32AndHi = 0xc0007fff, - ELF_GnuPropertyX86_UInt32OrLo = 0xc0008000, - ELF_GnuPropertyX86_UInt32OrHi = 0xc000ffff, - ELF_GnuPropertyX86_UInt32OrAndLo = 0xc0010000, - ELF_GnuPropertyX86_UInt32OrAndHi = 0xc0017fff, -}; - -typedef U32 ELF_GnuPropertyX86Feature1; -enum -{ - ELF_GnuPropertyX86Feature1_Ibt = (1 << 0), - ELF_GnuPropertyX86Feature1_Shstk = (1 << 1), - ELF_GnuPropertyX86Feature1_LamU48 = (1 << 2), - ELF_GnuPropertyX86Feature1_LamU57 = (1 << 3), -}; - -typedef U32 ELF_GnuPropertyX86Feature2; -enum -{ - ELF_GnuPropertyX86Feature2_X86 = (1 << 0), - ELF_GnuPropertyX86Feature2_X87 = (1 << 1), - ELF_GnuPropertyX86Feature2_MMX = (1 << 2), - ELF_GnuPropertyX86Feature2_XMM = (1 << 3), - ELF_GnuPropertyX86Feature2_YMM = (1 << 4), - ELF_GnuPropertyX86Feature2_ZMM = (1 << 5), - ELF_GnuPropertyX86Feature2_FXSR = (1 << 6), - ELF_GnuPropertyX86Feature2_XSAVE = (1 << 7), - ELF_GnuPropertyX86Feature2_XSAVEOPT = (1 << 8), - ELF_GnuPropertyX86Feature2_XSAVEC = (1 << 9), - ELF_GnuPropertyX86Feature2_TMM = (1 << 10), - ELF_GnuPropertyX86Feature2_MASK = (1 << 11), + ELF_NoteType_STapSdt = 3, // System Tap probes }; #define ELF_HdrIs64Bit(e_ident) (e_ident[ELF_Identifier_Class] == ELF_Class_64) @@ -721,30 +590,30 @@ typedef struct ELF_Hdr32 typedef struct ELF_Shdr64 { - U32 sh_name; - U32 sh_type; - U64 sh_flags; - U64 sh_addr; - U64 sh_offset; - U64 sh_size; - U32 sh_link; - U32 sh_info; - U64 sh_addralign; - U64 sh_entsize; + U32 sh_name; + ELF_ShType sh_type; + U64 sh_flags; + U64 sh_addr; + U64 sh_offset; + U64 sh_size; + U32 sh_link; + U32 sh_info; + U64 sh_addralign; + U64 sh_entsize; } ELF_Shdr64; typedef struct ELF_Shdr32 { - U32 sh_name; - U32 sh_type; - U32 sh_flags; - U32 sh_addr; - U32 sh_offset; - U32 sh_size; - U32 sh_link; - U32 sh_info; - U32 sh_addralign; - U32 sh_entsize; + U32 sh_name; + ELF_ShType sh_type; + U32 sh_flags; + U32 sh_addr; + U32 sh_offset; + U32 sh_size; + U32 sh_link; + U32 sh_info; + U32 sh_addralign; + U32 sh_entsize; } ELF_Shdr32; typedef struct ELF_Phdr64 diff --git a/src/elf/elf_dump.c b/src/elf/elf_dump.c new file mode 100644 index 00000000..c948ed3c --- /dev/null +++ b/src/elf/elf_dump.c @@ -0,0 +1,215 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal String8List +elf_dump_note(Arena *arena, String8 raw_notes, ELF_Class elf_class, ELF_MachineKind e_machine) +{ + Temp scratch = scratch_begin(&arena, 1); + + B32 is_bad_parse = 1; + String8List strings = {0}; + U64 cursor = 0; + + for (;cursor < raw_notes.size;) { + U32 owner_size; + U64 owner_size_size = str8_deserial_read_struct(raw_notes, cursor, &owner_size); + if (owner_size_size == 0) { goto exit; } + cursor += owner_size_size; + + U32 desc_size; + U64 desc_size_size = str8_deserial_read_struct(raw_notes, cursor, &desc_size); + if (desc_size_size == 0) { goto exit; } + cursor += desc_size_size; + + ELF_NoteType note_type; + U64 type_size = str8_deserial_read_struct(raw_notes, cursor, ¬e_type); + if (type_size == 0) { goto exit; } + cursor += type_size; + + if (cursor + owner_size > raw_notes.size) { goto exit; } + String8 owner = str8_cstring_capped(raw_notes.str + cursor, raw_notes.str + cursor + owner_size); + cursor += owner_size; + + if (cursor + desc_size > raw_notes.size) { goto exit; } + String8 raw_desc = str8_substr(raw_notes, r1u64(cursor, cursor + desc_size)); + cursor += desc_size; + cursor = AlignPow2(cursor, 4); + + String8List desc_fmt = {0}; + String8 note_type_str = {0}; + if (str8_match(owner, str8_lit("GNU"), StringMatchFlag_CaseInsensitive)) { + // format description + switch (note_type) { + case GNU_NoteType_Abi: { + U64 desc_cursor = 0; + + GNU_AbiTag os = 0; + U64 os_size = str8_deserial_read_struct(raw_desc, desc_cursor, &os); + if (os_size == 0) { goto exit; } + cursor += os_size; + + U32 major = 0; + U64 major_size = str8_deserial_read_struct(raw_desc, desc_cursor, &major); + if (major_size == 0) { goto exit; } + cursor += major_size; + + U32 minor = 0; + U64 minor_size = str8_deserial_read_struct(raw_desc, desc_cursor, &minor); + if (minor_size == 0) { goto exit; } + cursor += minor_size; + + U32 sub_minor = 0; + U64 sub_minor_size = str8_deserial_read_struct(raw_desc, desc_cursor, &sub_minor); + if (sub_minor_size == 0) { goto exit; } + cursor += sub_minor_size; + + String8 os_str = gnu_string_from_abi_tag(os); + if (os_str.size == 0) os_str = str8f(scratch.arena, "0x%x", os); + + str8_list_pushf(scratch.arena, &desc_fmt, "OS: %S, ABI: %u.%u.%u", os_str, major, minor, sub_minor); + } break; + case GNU_NoteType_BuildId: { + String8List build_id = {0}; + for EachIndex(desc_cursor, desc_size) { + U8 v = 0; + U64 v_size = str8_deserial_read_struct(raw_desc, desc_cursor, &v); + if (v_size == 0) { goto exit; } + desc_cursor += v_size; + str8_list_pushf(scratch.arena, &build_id, "%02x", v); + } + String8 build_id_str = str8_list_join(scratch.arena, &build_id, 0); + str8_list_pushf(scratch.arena, &desc_fmt, "Build ID: %S", build_id_str); + } break; + case GNU_NoteType_PropertyType0: { + U64 align = elf_class == ELF_Class_64 ? 8 : 4; + for (U64 desc_cursor = 0; desc_cursor < raw_desc.size; ) { + GNU_Property type = 0; + U64 type_size = str8_deserial_read_struct(raw_desc, desc_cursor, &type); + if (type_size == 0) { goto exit; } + desc_cursor += type_size; + + U32 size = 0; + U64 size_size = str8_deserial_read_struct(raw_desc, desc_cursor, &size); + if (size_size == 0) { goto exit; } + desc_cursor += size_size; + + U32 flags = 0; + if (size == 4) { + U64 flags_size = str8_deserial_read_struct(raw_desc, desc_cursor, &flags); + if (flags_size == 0) { goto exit; } + desc_cursor += flags_size; + } + + switch (e_machine) { + case ELF_MachineKind_None: break; + case ELF_MachineKind_X86_64: { + String8 features = gnu_string_from_property_flags_x86(scratch.arena, type, flags); + str8_list_pushf(scratch.arena, &desc_fmt, "x86 features: %S", features); + } break; + default: NotImplemented; break; + } + + desc_cursor = AlignPow2(desc_cursor, align); + } + } break; + default: NotImplemented; break; + } + + note_type_str = gnu_string_from_note_type(note_type); + } else if (str8_match(owner, str8_lit("stapsdt"), StringMatchFlag_CaseInsensitive)) { + if (note_type == ELF_NoteType_STapSdt) { + U64 desc_cursor = 0; + U64 addr_size = elf_class == ELF_Class_64 ? 8 : 4; + + U64 pc = 0; + U64 pc_size = str8_deserial_read(raw_desc, desc_cursor, &pc, addr_size, addr_size); + if (pc_size == 0) { goto exit; } + desc_cursor += pc_size; + + U64 base_addr = 0; + U64 base_addr_size = str8_deserial_read(raw_desc, desc_cursor, &base_addr, addr_size, addr_size); + if (base_addr_size == 0) { goto exit; } + desc_cursor += base_addr_size; + + U64 semaphore = 0; + U64 semaphore_size = str8_deserial_read(raw_desc, desc_cursor, &semaphore, addr_size, addr_size); + if (semaphore_size == 0) { goto exit; } + desc_cursor += semaphore_size; + + String8 provider = str8_cstring_capped(raw_desc.str + desc_cursor, raw_desc.str + raw_desc.size); + desc_cursor += provider.size + 1; + if (desc_cursor > raw_desc.size) { goto exit; } + + String8 probe = str8_cstring_capped(raw_desc.str + desc_cursor, raw_desc.str + raw_desc.size); + desc_cursor += probe.size + 1; + if (desc_cursor > raw_desc.size) { goto exit; } + + String8 args = str8_cstring_capped(raw_desc.str + desc_cursor, raw_desc.str + raw_desc.size); + desc_cursor += args.size + 1; + if (desc_cursor > raw_desc.size) { goto exit; } + + str8_list_pushf(scratch.arena, &desc_fmt, "Provider: %S", provider); + str8_list_pushf(scratch.arena, &desc_fmt, "Probe: %S", probe); + str8_list_pushf(scratch.arena, &desc_fmt, "PC: 0x%I64x", pc); + str8_list_pushf(scratch.arena, &desc_fmt, "Base: 0x%I64x", base_addr); + str8_list_pushf(scratch.arena, &desc_fmt, "Semaphore: 0x%I64x", semaphore); + str8_list_pushf(scratch.arena, &desc_fmt, "Arguments: %S", args); + + note_type_str = str8_lit("NT_STAPSDT"); + } + } + + if (note_type_str.size == 0) note_type_str = str8f(scratch.arena, "0x%x", note_type); + + str8_list_pushf(arena, &strings, "{"); + str8_list_pushf(arena, &strings, " Owner: %S", owner); + str8_list_pushf(arena, &strings, " Data Size: 0x%x", desc_size); + str8_list_pushf(arena, &strings, " Type: %S", note_type_str); + if (desc_fmt.node_count) { + str8_list_pushf(arena, &strings, " Description:"); + str8_list_pushf(arena, &strings, " {"); + for EachNode(n, String8Node, desc_fmt.first) { str8_list_pushf(arena, &strings, " %S", n->string); } + str8_list_pushf(arena, &strings, " }"); + } + str8_list_pushf(arena, &strings, "}"); + } + + is_bad_parse = 0; +exit:; + if (is_bad_parse) { + str8_list_pushf(arena, &strings, "ERROR: unable to parse data @ 0x%Ix64", cursor); + } + scratch_end(scratch); + return strings; +} + +internal String8List +elf_dump(Arena *arena, String8 raw_elf, ELF_DumpSubsetFlags flags) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8List strings = {0}; + ELF_Bin elf = elf_bin_from_data(scratch.arena, raw_elf); + + if (flags & ELF_DumpSubsetFlag_Note) { + for EachIndex(sect_idx, elf.shdrs.count) { + ELF_Shdr64 *shdr = &elf.shdrs.v[sect_idx]; + if (shdr->sh_type == ELF_ShType_Note) { + String8 raw_notes = str8_substr(raw_elf, r1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size)); + String8 shdr_name = elf_name_from_shdr64(raw_elf, &elf, shdr); + str8_list_pushf(scratch.arena, &strings, "//"); + str8_list_pushf(scratch.arena, &strings, "// %S", shdr_name); + str8_list_pushf(scratch.arena, &strings, "//"); + String8List note_strings = elf_dump_note(scratch.arena, raw_notes, elf.hdr.e_ident[ELF_Identifier_Class], elf.hdr.e_machine); + str8_list_concat_in_place(&strings, ¬e_strings); + } + } + } + + String8 out = str8_list_join(arena, &strings, &(StringJoin){.sep=str8_lit("\n"), .post=str8_lit("\n")}); + String8List result = {0}; + str8_list_push(arena, &result, out); + + scratch_end(scratch); + return result; +} diff --git a/src/elf/elf_dump.h b/src/elf/elf_dump.h new file mode 100644 index 00000000..5b920ffc --- /dev/null +++ b/src/elf/elf_dump.h @@ -0,0 +1,30 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef ELF_DUMP_H +#define ELF_DUMP_H + +#define ELF_DumpSubset_XList \ + X(Note, note, "NOTE") + +typedef U32 ELF_DumpSubset; +enum +{ +#define X(name, name_lower, title) ELF_DumpSubset_##name, + ELF_DumpSubset_XList +#undef X +}; + +typedef U32 ELF_DumpSubsetFlags; +enum +{ +#define X(name, name_lower, title) ELF_DumpSubsetFlag_##name = (1 << ELF_DumpSubset_##name), + ELF_DumpSubset_XList +#undef X + ELF_DumpSubsetFlag_All = ~0, +}; + +internal String8List elf_dump(Arena *arena, String8 raw_elf, ELF_DumpSubsetFlags flags); + +#endif // ELF_DUMP_H + diff --git a/src/gnu/gnu.c b/src/gnu/gnu.c index c56091f9..814d786f 100644 --- a/src/gnu/gnu.c +++ b/src/gnu/gnu.c @@ -51,3 +51,228 @@ gnu_rdebug_info64_from_rdebug_info32(GNU_RDebugInfo32 rdebug32) return result; } +internal String8 +gnu_string_from_abi_tag(GNU_AbiTag abi_tag) +{ + switch (abi_tag) { + case GNU_AbiTag_Linux: return str8_lit("Linux"); + case GNU_AbiTag_Hurd: return str8_lit("Hurd"); + case GNU_AbiTag_Solaris: return str8_lit("Solaris"); + case GNU_AbiTag_FreeBsd: return str8_lit("FreeBsd"); + case GNU_AbiTag_NetBsd: return str8_lit("NetBsd"); + case GNU_AbiTag_Syllable: return str8_lit("Syllable"); + case GNU_AbiTag_Nacl: return str8_lit("Nacl"); + } + return str8_zero(); +} + +internal String8 +gnu_string_from_note_type(GNU_NoteType note_type) +{ + switch (note_type) { + case GNU_NoteType_Abi: return str8_lit("GNU_Abi"); + case GNU_NoteType_HwCap: return str8_lit("GNU_HwCap"); + case GNU_NoteType_BuildId: return str8_lit("GNU_BuildId"); + case GNU_NoteType_GoldVersion: return str8_lit("GNU_GoldVersion"); + case GNU_NoteType_PropertyType0: return str8_lit("GNU_PropertyType0"); + } + return str8_zero(); +} + +internal String8 +gnu_string_from_property_x86(GNU_PropertyX86 prop) +{ + switch (prop) { + case GNU_PropertyX86_Feature1And: return str8_lit("Feature1And"); + case GNU_PropertyX86_Feature2Used: return str8_lit("Feature2Used"); + case GNU_PropertyX86_Isa1needed: return str8_lit("Isa1needed"); + case GNU_PropertyX86_Isa2Needed: return str8_lit("Isa2Needed"); + case GNU_PropertyX86_Isa1Used: return str8_lit("Isa1Used"); + case GNU_PropertyX86_Compat_isa_1_used: return str8_lit("Compat_isa_1_used"); + case GNU_PropertyX86_Compat_isa_1_needed: return str8_lit("Compat_isa_1_needed"); + case GNU_PropertyX86_UInt32AndHi: return str8_lit("UInt32AndHi"); + case GNU_PropertyX86_UInt32OrLo: return str8_lit("UInt32OrLo"); + case GNU_PropertyX86_UInt32OrHi: return str8_lit("UInt32OrHi"); + case GNU_PropertyX86_UInt32OrAndLo: return str8_lit("UInt32OrAndLo"); + case GNU_PropertyX86_UInt32OrAndHi: return str8_lit("UInt32OrAndHi"); + } + return str8_zero(); +} + +internal String8 +gnu_string_from_property_flags_x86(Arena *arena, GNU_PropertyX86 prop, U32 flags) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List fmt = {0}; + if (flags == 0) { + str8_list_pushf(scratch.arena, &fmt, "None"); + } + switch (prop) { + case GNU_PropertyX86_Isa1needed: + case GNU_PropertyX86_Isa1Used: { + if (flags & GNU_PropertyX86Isa1_BaseLine) { + str8_list_pushf(scratch.arena, &fmt, "BaseLine"); + flags &= ~GNU_PropertyX86Isa1_BaseLine; + } + if (flags & GNU_PropertyX86Isa1_V2) { + str8_list_pushf(scratch.arena, &fmt, "V2"); + flags &= ~GNU_PropertyX86Isa1_V2; + } + if (flags & GNU_PropertyX86Isa1_V3) { + str8_list_pushf(scratch.arena, &fmt, "V3"); + flags &= ~GNU_PropertyX86Isa1_V3; + } + if (flags & GNU_PropertyX86Isa1_V4) { + str8_list_pushf(scratch.arena, &fmt, "V4"); + flags &= ~GNU_PropertyX86Isa1_V4; + } + } break; + case GNU_PropertyX86_Feature1And: { + if (flags & GNU_PropertyX86Feature1_Ibt) { + str8_list_pushf(scratch.arena, &fmt, "Ibt"); + flags &= ~GNU_PropertyX86Feature1_Ibt; + } + if (flags & GNU_PropertyX86Feature1_Shstk) { + str8_list_pushf(scratch.arena, &fmt, "Shstk"); + flags &= ~GNU_PropertyX86Feature1_Shstk; + } + if (flags & GNU_PropertyX86Feature1_LamU48) { + str8_list_pushf(scratch.arena, &fmt, "LamU48"); + flags &= ~GNU_PropertyX86Feature1_LamU48; + } + if (flags & GNU_PropertyX86Feature1_LamU57) { + str8_list_pushf(scratch.arena, &fmt, "LamU57"); + flags &= ~GNU_PropertyX86Feature1_LamU57; + } + } break; + case GNU_PropertyX86_Feature2Used: { + if (flags & GNU_PropertyX86Feature2_X86) { + str8_list_pushf(scratch.arena, &fmt, "X86"); + flags &= ~GNU_PropertyX86Feature2_X86; + } + if (flags & GNU_PropertyX86Feature2_X87) { + str8_list_pushf(scratch.arena, &fmt, "X87"); + flags &= ~GNU_PropertyX86Feature2_X87; + } + if (flags & GNU_PropertyX86Feature2_MMX) { + str8_list_pushf(scratch.arena, &fmt, "MMX"); + flags &= ~GNU_PropertyX86Feature2_MMX; + } + if (flags & GNU_PropertyX86Feature2_XMM) { + str8_list_pushf(scratch.arena, &fmt, "XMM"); + flags &= ~GNU_PropertyX86Feature2_XMM; + } + if (flags & GNU_PropertyX86Feature2_YMM) { + str8_list_pushf(scratch.arena, &fmt, "YMM"); + flags &= ~GNU_PropertyX86Feature2_YMM; + } + if (flags & GNU_PropertyX86Feature2_ZMM) { + str8_list_pushf(scratch.arena, &fmt, "ZMM"); + flags &= ~GNU_PropertyX86Feature2_ZMM; + } + if (flags & GNU_PropertyX86Feature2_FXSR) { + str8_list_pushf(scratch.arena, &fmt, "FXSR"); + flags &= ~GNU_PropertyX86Feature2_FXSR; + } + if (flags & GNU_PropertyX86Feature2_XSAVE) { + str8_list_pushf(scratch.arena, &fmt, "XSAVE"); + flags &= ~GNU_PropertyX86Feature2_XSAVE; + } + if (flags & GNU_PropertyX86Feature2_XSAVEOPT) { + str8_list_pushf(scratch.arena, &fmt, "XSAVEOPT"); + flags &= ~GNU_PropertyX86Feature2_XSAVEOPT; + } + if (flags & GNU_PropertyX86Feature2_XSAVEC) { + str8_list_pushf(scratch.arena, &fmt, "XSAVEC"); + flags &= ~GNU_PropertyX86Feature2_XSAVEC; + } + if (flags & GNU_PropertyX86Feature2_TMM) { + str8_list_pushf(scratch.arena, &fmt, "TMM"); + flags &= ~GNU_PropertyX86Feature2_TMM; + } + if (flags & GNU_PropertyX86Feature2_MASK) { + str8_list_pushf(scratch.arena, &fmt, "MASK"); + flags &= ~GNU_PropertyX86Feature2_MASK; + } + } break; + case GNU_PropertyX86_Compat_isa_1_used: + case GNU_PropertyX86_Compat_isa_1_needed: { + if (flags & GNU_PropertyX86Compat1Isa1_486) { + str8_list_pushf(scratch.arena, &fmt, "486"); + flags &= ~GNU_PropertyX86Compat1Isa1_486; + } + if (flags & GNU_PropertyX86Compat1Isa1_586) { + str8_list_pushf(scratch.arena, &fmt, "586"); + flags &= ~GNU_PropertyX86Compat1Isa1_586; + } + if (flags & GNU_PropertyX86Compat1Isa1_686) { + str8_list_pushf(scratch.arena, &fmt, "686"); + flags &= ~GNU_PropertyX86Compat1Isa1_686; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSE) { + str8_list_pushf(scratch.arena, &fmt, "SSE"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSE; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSE2) { + str8_list_pushf(scratch.arena, &fmt, "SSE2"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSE2; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSE3) { + str8_list_pushf(scratch.arena, &fmt, "SSE3"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSE3; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSSE3) { + str8_list_pushf(scratch.arena, &fmt, "SSSE3"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSSE3; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSE4_1) { + str8_list_pushf(scratch.arena, &fmt, "SSE4_1"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSE4_1; + } + if (flags & GNU_PropertyX86Compat1Isa1_SSE4_2) { + str8_list_pushf(scratch.arena, &fmt, "SSE4_2"); + flags &= ~GNU_PropertyX86Compat1Isa1_SSE4_2; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX) { + str8_list_pushf(scratch.arena, &fmt, "AVX"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX2) { + str8_list_pushf(scratch.arena, &fmt, "AVX2"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX2; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512F) { + str8_list_pushf(scratch.arena, &fmt, "AVX512F"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512F; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512ER) { + str8_list_pushf(scratch.arena, &fmt, "AVX512ER"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512ER; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512PF) { + str8_list_pushf(scratch.arena, &fmt, "AVX512PF"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512PF; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512VL) { + str8_list_pushf(scratch.arena, &fmt, "AVX512VL"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512VL; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512DQ) { + str8_list_pushf(scratch.arena, &fmt, "AVX512DQ"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512DQ; + } + if (flags & GNU_PropertyX86Compat1Isa1_AVX512BW) { + str8_list_pushf(scratch.arena, &fmt, "AVX512BW"); + flags &= ~GNU_PropertyX86Compat1Isa1_AVX512BW; + } + } break; + } + if (flags) { + str8_list_pushf(scratch.arena, &fmt, "Unknown: 0x%x", flags); + } + + String8 result = str8_list_join(arena, &fmt, &(StringJoin){.sep = str8_lit(", ")}); + scratch_end(scratch); + return result; +} + diff --git a/src/gnu/gnu.h b/src/gnu/gnu.h index 679f11c9..37f15007 100644 --- a/src/gnu/gnu.h +++ b/src/gnu/gnu.h @@ -4,6 +4,145 @@ #ifndef GNU_H #define GNU_H +typedef ELF_NoteType GNU_NoteType; +enum +{ + GNU_NoteType_Abi = 1, + GNU_NoteType_HwCap = 2, + GNU_NoteType_BuildId = 3, + GNU_NoteType_GoldVersion = 4, + GNU_NoteType_PropertyType0 = 5, +}; + +typedef U32 GNU_Property; +enum +{ + GNU_Property_LoProc = 0xc0000000, + // processor-specific range + GNU_Property_HiProc = 0xdfffffff, + GNU_Property_LoUser = 0xe0000000, + // application-specific range + GNU_Property_HiUser = 0xffffffff, + GNU_Property_StackSize = 1, + GNU_Property_NoCopyOnProtected = 2, +}; + +typedef U32 GNU_PropertyX86Isa1; +enum +{ + GNU_PropertyX86Isa1_BaseLine = (1 << 0), + GNU_PropertyX86Isa1_V2 = (1 << 1), + GNU_PropertyX86Isa1_V3 = (1 << 2), + GNU_PropertyX86Isa1_V4 = (1 << 3), +}; + +typedef U32 GNU_PropertyX86Compat1Isa1; +enum +{ + GNU_PropertyX86Compat1Isa1_486 = (1 << 0), + GNU_PropertyX86Compat1Isa1_586 = (1 << 1), + GNU_PropertyX86Compat1Isa1_686 = (1 << 2), + GNU_PropertyX86Compat1Isa1_SSE = (1 << 3), + GNU_PropertyX86Compat1Isa1_SSE2 = (1 << 4), + GNU_PropertyX86Compat1Isa1_SSE3 = (1 << 5), + GNU_PropertyX86Compat1Isa1_SSSE3 = (1 << 6), + GNU_PropertyX86Compat1Isa1_SSE4_1 = (1 << 7), + GNU_PropertyX86Compat1Isa1_SSE4_2 = (1 << 8), + GNU_PropertyX86Compat1Isa1_AVX = (1 << 9), + GNU_PropertyX86Compat1Isa1_AVX2 = (1 << 10), + GNU_PropertyX86Compat1Isa1_AVX512F = (1 << 11), + GNU_PropertyX86Compat1Isa1_AVX512ER = (1 << 12), + GNU_PropertyX86Compat1Isa1_AVX512PF = (1 << 13), + GNU_PropertyX86Compat1Isa1_AVX512VL = (1 << 14), + GNU_PropertyX86Compat1Isa1_AVX512DQ = (1 << 15), + GNU_PropertyX86Compat1Isa1_AVX512BW = (1 << 16), +}; + +typedef U32 GNU_PropertyX86Compat2Isa1; +enum +{ + GNU_PropertyX86Compat2Isa1_CMOVE = (1 << 0), + GNU_PropertyX86Compat2Isa1_SSE = (1 << 1), + GNU_PropertyX86Compat2Isa1_SSE2 = (1 << 2), + GNU_PropertyX86Compat2Isa1_SSE3 = (1 << 3), + GNU_PropertyX86Compat2Isa1_SSE4_1 = (1 << 4), + GNU_PropertyX86Compat2Isa1_SSE4_2 = (1 << 5), + GNU_PropertyX86Compat2Isa1_AVX = (1 << 6), + GNU_PropertyX86Compat2Isa1_AVX2 = (1 << 7), + GNU_PropertyX86Compat2Isa1_FMA = (1 << 8), + GNU_PropertyX86Compat2Isa1_AVX512F = (1 << 9), + GNU_PropertyX86Compat2Isa1_AVX512CD = (1 << 10), + GNU_PropertyX86Compat2Isa1_AVX512ER = (1 << 11), + GNU_PropertyX86Compat2Isa1_AVX512PF = (1 << 12), + GNU_PropertyX86Compat2Isa1_AVX512VL = (1 << 13), + GNU_PropertyX86Compat2Isa1_AVX512DQ = (1 << 14), + GNU_PropertyX86Compat2Isa1_AVX512BW = (1 << 15), + GNU_PropertyX86Compat2Isa1_AVX512_4FMAPS = (1 << 16), + GNU_PropertyX86Compat2Isa1_AVX512_4VNNIW = (1 << 17), + GNU_PropertyX86Compat2Isa1_AVX512_BITALG = (1 << 18), + GNU_PropertyX86Compat2Isa1_AVX512_IFMA = (1 << 19), + GNU_PropertyX86Compat2Isa1_AVX512_VBMI = (1 << 20), + GNU_PropertyX86Compat2Isa1_AVX512_VBMI2 = (1 << 21), + GNU_PropertyX86Compat2Isa1_AVX512_VNNI = (1 << 22), + GNU_PropertyX86Compat2Isa1_AVX512_BF16 = (1 << 23), +}; + +typedef GNU_Property GNU_PropertyX86; +enum +{ + GNU_PropertyX86_Feature1And = 0xc0000002, + GNU_PropertyX86_Feature2Used = 0xc0010001, + GNU_PropertyX86_Isa1needed = 0xc0008002, + GNU_PropertyX86_Isa2Needed = 0xc0008001, + GNU_PropertyX86_Isa1Used = 0xc0010002, + GNU_PropertyX86_Compat_isa_1_used = 0xc0000000, + GNU_PropertyX86_Compat_isa_1_needed = 0xc0000001, + GNU_PropertyX86_UInt32AndLo = GNU_PropertyX86_Feature1And, + GNU_PropertyX86_UInt32AndHi = 0xc0007fff, + GNU_PropertyX86_UInt32OrLo = 0xc0008000, + GNU_PropertyX86_UInt32OrHi = 0xc000ffff, + GNU_PropertyX86_UInt32OrAndLo = 0xc0010000, + GNU_PropertyX86_UInt32OrAndHi = 0xc0017fff, +}; + +typedef U32 GNU_PropertyX86Feature1; +enum +{ + GNU_PropertyX86Feature1_Ibt = (1 << 0), + GNU_PropertyX86Feature1_Shstk = (1 << 1), + GNU_PropertyX86Feature1_LamU48 = (1 << 2), + GNU_PropertyX86Feature1_LamU57 = (1 << 3), +}; + +typedef U32 GNU_PropertyX86Feature2; +enum +{ + GNU_PropertyX86Feature2_X86 = (1 << 0), + GNU_PropertyX86Feature2_X87 = (1 << 1), + GNU_PropertyX86Feature2_MMX = (1 << 2), + GNU_PropertyX86Feature2_XMM = (1 << 3), + GNU_PropertyX86Feature2_YMM = (1 << 4), + GNU_PropertyX86Feature2_ZMM = (1 << 5), + GNU_PropertyX86Feature2_FXSR = (1 << 6), + GNU_PropertyX86Feature2_XSAVE = (1 << 7), + GNU_PropertyX86Feature2_XSAVEOPT = (1 << 8), + GNU_PropertyX86Feature2_XSAVEC = (1 << 9), + GNU_PropertyX86Feature2_TMM = (1 << 10), + GNU_PropertyX86Feature2_MASK = (1 << 11), +}; + +typedef U32 GNU_AbiTag; +enum +{ + GNU_AbiTag_Linux = 0, + GNU_AbiTag_Hurd = 1, + GNU_AbiTag_Solaris = 2, + GNU_AbiTag_FreeBsd = 3, + GNU_AbiTag_NetBsd = 4, + GNU_AbiTag_Syllable = 5, + GNU_AbiTag_Nacl = 6, +}; + typedef struct GNU_LinkMap64 { U64 addr_vaddr; @@ -55,4 +194,11 @@ internal GNU_LinkMap64 elf_linkmap64_from_linkmap32(GNU_LinkMap32 linkmap32); internal U64 gnu_rdebug_info_size_from_arch(Arch arch); internal U64 gnu_r_brk_offset_from_arch(Arch arch); +//////////////////////////////// +//~ enum + +internal String8 gnu_string_from_abi_tag(GNU_AbiTag abi_tag); +internal String8 gnu_string_from_note_type(GNU_NoteType note_type); +internal String8 gnu_string_from_property_x86(GNU_PropertyX86 prop); + #endif // GNU_H diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index b692d61d..3811d462 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -1039,8 +1039,9 @@ rb_thread_entry_point(void *p) //- rjf: unpack dump subset flags RDI_DumpSubsetFlags rdi_dump_subset_flags = RDI_DumpSubsetFlag_All; - DW_DumpSubsetFlags dw_dump_subset_flags = DW_DumpSubsetFlag_All; - EH_DumpSubsetFlags eh_dump_subset_flags = EH_DumpSubsetFlag_All; + DW_DumpSubsetFlags dw_dump_subset_flags = DW_DumpSubsetFlag_All; + EH_DumpSubsetFlags eh_dump_subset_flags = EH_DumpSubsetFlag_All; + ELF_DumpSubsetFlags elf_dump_subset_flags = ELF_DumpSubsetFlag_All; { String8List only_names = cmd_line_strings(cmdline, str8_lit("only")); if(only_names.node_count != 0) @@ -1060,6 +1061,9 @@ rb_thread_entry_point(void *p) #undef X #define X(name, name_lower, title) else if(str8_match(n->string, str8_lit(#name_lower), 0)) { eh_dump_subset_flags |= EH_DumpSubsetFlag_##name; } EH_DumpSubset_XList +#undef X +#define X(name, name_lower, title) else if(str8_match(n->string, str8_lit(#name_lower), 0)) { elf_dump_subset_flags |= ELF_DumpSubsetFlag_##name; } + ELF_DumpSubset_XList #undef X } String8List omit_names = cmd_line_strings(cmdline, str8_lit("omit")); @@ -1074,6 +1078,9 @@ rb_thread_entry_point(void *p) #undef X #define X(name, name_lower, title) else if(str8_match(n->string, str8_lit(#name_lower), 0)) { eh_dump_subset_flags &= ~EH_DumpSubsetFlag_##name; } EH_DumpSubset_XList +#undef X +#define X(name, name_lower, title) else if(str8_match(n->string, str8_lit(#name_lower), 0)) { elf_dump_subset_flags &= ~ELF_DumpSubsetFlag_##name; } + ELF_DumpSubset_XList #undef X } } @@ -1089,14 +1096,14 @@ rb_thread_entry_point(void *p) lane_sync(); //- rjf: unpack file parses - Arch arch = Arch_Null; - PE_BinInfo pe = {0}; - ELF_Bin elf = {0}; - DW_Input dw = {0}; - U64 eh_frame_hdr_vaddr = 0; - U64 eh_frame_vaddr = 0; - String8 eh_frame_hdr = {0}; - String8 eh_frame = {0}; + Arch arch = Arch_Null; + PE_BinInfo pe = {0}; + ELF_Bin elf = {0}; + DW_Input dw = {0}; + U64 eh_frame_hdr_vaddr = 0; + U64 eh_frame_vaddr = 0; + String8 eh_frame_hdr = {0}; + String8 eh_frame = {0}; { if(f->format == RB_FileFormat_PE) { @@ -1184,7 +1191,8 @@ rb_thread_entry_point(void *p) case RB_FileFormat_ELF32: case RB_FileFormat_ELF64: { - // TODO(rjf) + String8List elf_strings = elf_dump(arena, f->data, elf_dump_subset_flags); + str8_list_concat_in_place(&output_blobs, &elf_strings); }break; //- rjf: RDI file diff --git a/src/radbin/radbin_main.c b/src/radbin/radbin_main.c index e1abc2fc..5b742c04 100644 --- a/src/radbin/radbin_main.c +++ b/src/radbin/radbin_main.c @@ -19,7 +19,9 @@ #include "coff/coff_inc.h" #include "pe/pe.h" #include "elf/elf.h" +#include "gnu/gnu.h" #include "elf/elf_parse.h" +#include "elf/elf_dump.h" #include "codeview/codeview.h" #include "codeview/codeview_parse.h" #include "dwarf/dwarf_inc.h" @@ -43,7 +45,9 @@ #include "coff/coff_inc.c" #include "pe/pe.c" #include "elf/elf.c" +#include "gnu/gnu.c" #include "elf/elf_parse.c" +#include "elf/elf_dump.c" #include "codeview/codeview.c" #include "codeview/codeview_parse.c" #include "dwarf/dwarf_inc.c"