From a84028d67a5b645971f93ab361afd2db2486254e Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:29:22 -0700 Subject: [PATCH] helper for checking if ELF has DWARF debug sections --- src/dwarf/dwarf_coff.c | 65 +++++++++++++++++++++++++++++++++++++++-- src/dwarf/dwarf_coff.h | 42 +++----------------------- src/dwarf/dwarf_elf.c | 50 ++++++++++++++++++++++++------- src/dwarf/dwarf_parse.c | 23 +++++++++++++++ 4 files changed, 129 insertions(+), 51 deletions(-) diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c index d8158251..68caeb0a 100644 --- a/src/dwarf/dwarf_coff.c +++ b/src/dwarf/dwarf_coff.c @@ -1,7 +1,68 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#pragma once +internal B32 +dw_is_dwarf_present_coff_section_table(String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + B32 is_dwarf_present = 0; + + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = §ions[i]; + String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + + DW_SectionKind s = dw_section_kind_from_string(name); + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + } + + is_dwarf_present = s != DW_Section_Null; + if (is_dwarf_present) { + break; + } + } + + return is_dwarf_present; +} + +internal DW_Input +dw_input_from_coff_section_table(Arena *arena, + String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + DW_Input input = {0}; + B32 sect_status[ArrayCount(input.sec)] = {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_kind_from_string(name); + B32 is_dwo = 0; + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + is_dwo = 1; + } + + 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 = &input.sec[s]; + d->name = push_str8_copy(arena, name); + d->data = str8_substr(raw_image, raw_data_range); + d->is_dwo = is_dwo; + } + } + } + + return input; +} -internal DW_Input dw_input_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 index 3a772531..768863f2 100644 --- a/src/dwarf/dwarf_coff.h +++ b/src/dwarf/dwarf_coff.h @@ -1,44 +1,10 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal DW_Input -dw_input_from_coff_section_table(Arena *arena, - String8 raw_image, - U64 string_table_off, - U64 section_count, - COFF_SectionHeader *sections) -{ - DW_Input input = {0}; - B32 sect_status[ArrayCount(input.sec)] = {0}; +#ifndef DWARF_COFF_H +#define DWARF_COFF_H - 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 = &input.sec[s]; - d->name = push_str8_copy(arena, name); - d->data = str8_substr(raw_image, raw_data_range); - d->is_dwo = is_dwo; - } - } - } - - return input; -} +internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); +#endif // DWARF_COFF_H diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c index 55d6e4f7..99117b2e 100644 --- a/src/dwarf/dwarf_elf.c +++ b/src/dwarf/dwarf_elf.c @@ -1,6 +1,38 @@ // Copyright (c) 2025 Epic Games Tools // 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) +{ + 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; + } + + DW_SectionKind s = dw_section_kind_from_string(name); + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + } + + is_dwarf_present = s != DW_Section_Null; + if (is_dwarf_present) { + break; + } + } + + scratch_end(scratch); + return is_dwarf_present; +} + internal DW_Input dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin) { @@ -10,7 +42,6 @@ dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bi B32 sect_status[ArrayCount(result.sec)] = {0}; ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); - String8 sh_names = str8_substr(raw_image, bin->sh_name_range); for (U64 sect_idx = 1; sect_idx < sections.count; ++sect_idx) { ELF_Shdr64 *shdr = §ions.v[sect_idx]; @@ -20,17 +51,14 @@ dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bi continue; } - String8 name = {0}; - str8_deserial_read_cstr(sh_names, shdr->sh_name, &name); + String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr); - 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 + 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); + is_dwo = 1; + } if (s != DW_Section_Null) { if (sect_status[s]) { diff --git a/src/dwarf/dwarf_parse.c b/src/dwarf/dwarf_parse.c index 0e34a29a..a8722d0e 100644 --- a/src/dwarf/dwarf_parse.c +++ b/src/dwarf/dwarf_parse.c @@ -169,6 +169,29 @@ str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 coun return bytes_read; } +internal DW_SectionKind +dw_section_kind_from_string(String8 string) +{ + DW_SectionKind s = DW_Section_Null; +#define X(_K,_L,_M,_W) \ + if (str8_match_lit(_L, string, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_M, string, 0)) { s = DW_Section_##_K; } + DW_SectionKind_XList(X) +#undef X + return s; +} + +internal DW_SectionKind +dw_section_dwo_kind_from_string(String8 string) +{ + DW_SectionKind s = DW_Section_Null; +#define X(_K,_L,_M,_W) \ + if (str8_match_lit(_W, string, 0)) { s = DW_Section_##_K; } + DW_SectionKind_XList(X) +#undef X + return s; +} + internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data) {