mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 22:08:41 +00:00
cleanup pass over elf parsing; base addr calculation?
This commit is contained in:
+81
-103
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user