From ea6a84ca578f155dcbaacade8a1e4357f0fa1a8c Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 31 Jan 2025 13:26:33 -0800 Subject: [PATCH] helper for extracting DWARF sections in COFF files --- src/dwarf/dwarf_coff.c | 7 ++++++ src/dwarf/dwarf_coff.h | 45 ++++++++++++++++++++++++++++++++++++++ src/raddump/raddump.c | 45 ++------------------------------------ src/raddump/raddump_main.c | 2 ++ 4 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 src/dwarf/dwarf_coff.c create mode 100644 src/dwarf/dwarf_coff.h diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c new file mode 100644 index 00000000..942ca306 --- /dev/null +++ b/src/dwarf/dwarf_coff.c @@ -0,0 +1,7 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#pragma once + +internal DW_SectionArray dw_sections_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); + diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h new file mode 100644 index 00000000..368bff78 --- /dev/null +++ b/src/dwarf/dwarf_coff.h @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal DW_SectionArray +dw_sections_from_coff_section_table(Arena *arena, + String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + DW_SectionArray result = {0}; + B32 sect_status[ArrayCount(result.v)] = {0}; + + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = §ions[i]; + Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); + String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + + DW_SectionKind s = DW_Section_Null; + B32 is_dwo = 0; + #define X(_K,_L,_M,_W) \ + if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } + DW_SectionKind_XList(X) + #undef X + + if (s != DW_Section_Null) { + if (sect_status[s]) { + Assert(!"too many debug sections with identical name, picking first"); + } else { + sect_status[s] = 1; + DW_Section *d = &result.v[s]; + d->name = push_str8_copy(arena, name); + d->data = str8_substr(raw_image, raw_data_range); + d->mode = dim_1u64(raw_data_range) > max_U32 ? DW_Mode_64Bit : DW_Mode_32Bit; + d->is_dwo = is_dwo; + } + } + } + + return result; +} + + diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 0af1b6e1..15566eed 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -474,47 +474,6 @@ rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 st return result; } -internal DW_SectionArray -rd_dw_sections_from_coff_section_table(Arena *arena, - String8 raw_image, - U64 string_table_off, - U64 section_count, - COFF_SectionHeader *sections) -{ - DW_SectionArray result = {0}; - B32 sect_status[ArrayCount(result.v)] = {0}; - - for (U64 i = 0; i < section_count; ++i) { - COFF_SectionHeader *header = §ions[i]; - Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); - String8 name = coff_name_from_section_header(raw_image, header, string_table_off); - - DW_SectionKind s = DW_Section_Null; - B32 is_dwo = 0; - #define X(_K,_L,_M,_W) \ - if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } - DW_SectionKind_XList(X) - #undef X - - if (s != DW_Section_Null) { - if (sect_status[s]) { - rd_warningf("file contains multiple %S sections, picking first", name); - } else { - sect_status[s] = 1; - DW_Section *d = &result.v[s]; - d->name = push_str8_copy(arena, name); - d->data = str8_substr(raw_image, raw_data_range); - d->mode = dim_1u64(raw_data_range) > max_U32 ? DW_Mode_64Bit : DW_Mode_32Bit; - d->is_dwo = is_dwo; - } - } - } - - return result; -} - internal RD_DisasmResult rd_disasm_next_instruction(Arena *arena, Arch arch, U64 addr, String8 raw_code) { @@ -6210,7 +6169,7 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); + DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); } @@ -7952,7 +7911,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); + DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); } diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index 48b48b1b..ef0a3b6a 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -44,6 +44,7 @@ #include "dwarf/dwarf_parse.h" #include "dwarf/dwarf_expr.h" #include "dwarf/dwarf_unwind.h" +#include "dwarf/dwarf_coff.h" #include "dwarf/dwarf_enum.h" #include "base/base_inc.c" @@ -70,6 +71,7 @@ #include "dwarf/dwarf_parse.c" #include "dwarf/dwarf_expr.c" #include "dwarf/dwarf_unwind.c" +#include "dwarf/dwarf_coff.c" #include "dwarf/dwarf_enum.c" #include "linker/base_ext/base_inc.h"