From dfd6950ff3cd5be318b821e19d6487d6c0d79781 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:20:22 -0800 Subject: [PATCH] deleted obsolete DWARF parser files --- src/rdi_from_dwarf/rdi_dwarf.c | 1892 ---------------------- src/rdi_from_dwarf/rdi_dwarf.h | 1493 ----------------- src/rdi_from_dwarf/rdi_dwarf_stringize.c | 102 -- src/rdi_from_dwarf/rdi_dwarf_stringize.h | 28 - src/rdi_from_dwarf/rdi_elf.c | 557 ------- src/rdi_from_dwarf/rdi_elf.h | 517 ------ 6 files changed, 4589 deletions(-) delete mode 100644 src/rdi_from_dwarf/rdi_dwarf.c delete mode 100644 src/rdi_from_dwarf/rdi_dwarf.h delete mode 100644 src/rdi_from_dwarf/rdi_dwarf_stringize.c delete mode 100644 src/rdi_from_dwarf/rdi_dwarf_stringize.h delete mode 100644 src/rdi_from_dwarf/rdi_elf.c delete mode 100644 src/rdi_from_dwarf/rdi_elf.h diff --git a/src/rdi_from_dwarf/rdi_dwarf.c b/src/rdi_from_dwarf/rdi_dwarf.c deleted file mode 100644 index eb257f0f..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf.c +++ /dev/null @@ -1,1892 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ Dwarf Decode Helpers - -static U64 -dwarf_leb128_decode_U64(U8 *ptr, U8 *opl){ - U64 r = 0; - switch (opl - ptr){ - case 10: r |= ((U64)(ptr[9]&0x7F) << 63); - case 9: r |= ((U64)(ptr[8]&0x7F) << 56); - case 8: r |= ((U64)(ptr[7]&0x7F) << 49); - case 7: r |= ((U64)(ptr[6]&0x7F) << 42); - case 6: r |= ((U64)(ptr[5]&0x7F) << 35); - case 5: r |= ((U64)(ptr[4]&0x7F) << 28); - case 4: r |= ((U64)(ptr[3]&0x7F) << 21); - case 3: r |= ((U64)(ptr[2]&0x7F) << 14); - case 2: r |= ((U64)(ptr[1]&0x7F) << 7); - case 1: r |= ((U64)(ptr[0]&0x7F) ); - case 0: default: break; - } - return(r); -} - -static S64 -dwarf_leb128_decode_S64(U8 *ptr, U8 *opl){ - U64 u = dwarf_leb128_decode_U32(ptr, opl); - U64 s = (U64)(opl - ptr)*7; - B32 neg = ((u & (1llu << s)) != 0); - if (neg){ - switch (opl - ptr){ - case 9: u |= ~0x7FFFFFFFFFFFFFFFllu; break; - case 8: u |= ~0x00FFFFFFFFFFFFFFllu; break; - case 7: u |= ~ 0x01FFFFFFFFFFFFllu; break; - case 6: u |= ~ 0x03FFFFFFFFFFllu; break; - case 5: u |= ~ 0x07FFFFFFFFllu; break; - case 4: u |= ~ 0x0FFFFFFFllu; break; - case 3: u |= ~ 0x1FFFFFllu; break; - case 2: u |= ~ 0x3FFFllu; break; - case 1: u |= ~ 0x7Fllu; break; - } - } - S64 r = (S64)(u); - return(r); -} - -static U32 -dwarf_leb128_decode_U32(U8 *ptr, U8 *opl){ - U32 r = 0; - switch (opl - ptr){ - case 5: r |= ((U32)(ptr[4]&0x7F) << 28); - case 4: r |= ((U32)(ptr[3]&0x7F) << 21); - case 3: r |= ((U32)(ptr[2]&0x7F) << 14); - case 2: r |= ((U32)(ptr[1]&0x7F) << 7); - case 1: r |= ((U32)(ptr[0]&0x7F) ); - case 0: default: break; - } - return(r); -} - - -//////////////////////////////// -//~ Dwarf Parser Functions - -static DWARF_Parsed* -dwarf_parsed_from_elf(Arena *arena, ELF_Parsed *elf){ - DWARF_Parsed *result = 0; - - if (elf != 0){ - //- extract debug info - U32 debug_section_idx[DWARF_SectionCode_COUNT] = {0}; - String8 debug_section_name[DWARF_SectionCode_COUNT] = {0}; - String8 debug_data[DWARF_SectionCode_COUNT] = {0}; - for (U64 i = 1; i < DWARF_SectionCode_COUNT; i += 1){ - DWARF_SectionNameRow *row = dwarf_section_name_table + i; - U32 idx = 0; - for (U32 j = 0; idx == 0 && j < DWARF_SECTION_NAME_VARIANT_COUNT; j += 1){ - idx = elf_section_idx_from_name(elf, row->name[j]); - } - debug_section_idx[i] = idx; - debug_section_name[i] = elf_section_name_from_idx(elf, idx); - debug_data[i] = elf_section_data_from_idx(elf, idx); - } - - //- fill result - { - result = push_array(arena, DWARF_Parsed, 1); - result->elf = elf; - MemoryCopyArray(result->debug_section_idx, debug_section_idx); - MemoryCopyArray(result->debug_section_name, debug_section_name); - MemoryCopyArray(result->debug_data, debug_data); - } - } - - return(result); -} - -static DWARF_IndexParsed* -dwarf_index_from_data(Arena *arena, String8 data){ - DWARF_IndexParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_SupParsed* -dwarf_sup_from_data(Arena *arena, String8 data){ - DWARF_SupParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_InfoParsed* -dwarf_info_from_data(Arena *arena, String8 data){ - // supported version numbers: 4,5 - - - // empty unit list - DWARF_InfoUnit *first = 0; - DWARF_InfoUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // rest of header depends on version - U64 abbrev_off = 0; - U8 address_size = 0; - U8 unit_type = 0; - U64 unit_dwo_id = 0; - U64 unit_type_signature = 0; - U64 unit_type_offset = 0; - switch (version){ - case 4: - { - // abbrev_off - if (is_64bit){ - abbrev_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_off = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - }break; - - case 5: - { - // unit_type - unit_type = (DWARF_UnitType)MemoryConsume(U8, ptr, unit_opl); - - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - - // abbrev_off - if (is_64bit){ - abbrev_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_off = MemoryConsume(U32, ptr, unit_opl); - } - - // rest of header depends on unit_type - switch (unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - unit_dwo_id = MemoryConsume(U64, ptr, unit_opl); - }break; - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - unit_type_signature = MemoryConsume(U64, ptr, unit_opl); - if (is_64bit){ - unit_type_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - unit_type_offset = MemoryConsume(U32, ptr, unit_opl); - } - }break; - } - }break; - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_InfoUnit *unit = push_array(arena, DWARF_InfoUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->version = version; - unit->unit_type = unit_type; - unit->address_size = address_size; - unit->abbrev_off = abbrev_off; - - switch (unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - unit->dwo_id = unit_dwo_id; - }break; - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - unit->type_signature = unit_type_signature; - unit->type_offset = unit_type_offset; - }break; - } - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_InfoParsed *result = push_array(arena, DWARF_InfoParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_PubNamesParsed* -dwarf_pubnames_from_data(Arena *arena, String8 data){ - // supported version numbers: 2 - - - // empty unit list - DWARF_PubNamesUnit *first = 0; - DWARF_PubNamesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // info_off - U64 info_off = 0; - if (is_64bit){ - info_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_off = MemoryConsume(U32, ptr, unit_opl); - } - - // info_length - U64 info_length = 0; - if (is_64bit){ - info_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_length = MemoryConsume(U32, ptr, unit_opl); - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_PubNamesUnit *unit = push_array(arena, DWARF_PubNamesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->version = version; - unit->info_off = info_off; - unit->info_length = info_length; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_PubNamesParsed *result = push_array(arena, DWARF_PubNamesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_NamesParsed* -dwarf_names_from_data(Arena *arena, String8 data){ - // supported version numbers: 5 - - - // empty unit list - DWARF_NamesUnit *first = 0; - DWARF_NamesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // *padding* - MemoryConsume(U16, ptr, unit_opl); - - // comp_unit_count - U32 comp_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // local_type_unit_count - U32 local_type_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // foreign_type_unit_count - U32 foreign_type_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // bucket_count - U32 bucket_count = MemoryConsume(U32, ptr, unit_opl); - - // name_count - U32 name_count = MemoryConsume(U32, ptr, unit_opl); - - // abbrev_table_size - U32 abbrev_table_size = MemoryConsume(U32, ptr, unit_opl); - - // augmentation_string_size - U32 augmentation_string_size = MemoryConsume(U32, ptr, unit_opl); - - // augmentation_string - U8 *augmentation_string = ptr; - { - U8 *ptr_raw = ptr + augmentation_string_size; - ptr = ClampTop(ptr_raw, unit_opl); - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_NamesUnit *unit = push_array(arena, DWARF_NamesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - unit->comp_unit_count = comp_unit_count; - unit->local_type_unit_count = local_type_unit_count; - unit->foreign_type_unit_count = foreign_type_unit_count; - unit->bucket_count = bucket_count; - unit->name_count = name_count; - unit->abbrev_table_size = abbrev_table_size; - unit->augmentation_string = str8_cstring_capped(augmentation_string, unit_opl); - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_NamesParsed *result = push_array(arena, DWARF_NamesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_ArangesParsed* -dwarf_aranges_from_data(Arena *arena, String8 data){ - // supported version numbers: 2 - - - // empty unit list - DWARF_ArangesUnit *first = 0; - DWARF_ArangesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // info_off - U64 info_off = 0; - if (is_64bit){ - info_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_off = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size - U8 address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment_selector_size - U8 segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_ArangesUnit *unit = push_array(arena, DWARF_ArangesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - unit->address_size = address_size; - unit->segment_selector_size = segment_selector_size; - unit->offset_size = offset_size; - unit->info_off = info_off; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_ArangesParsed *result = push_array(arena, DWARF_ArangesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_LineParsed* -dwarf_line_from_data(Arena *arena, String8 data){ - // supported version numbers: 4, 5 - - - // empty unit list - DWARF_LineUnit *first = 0; - DWARF_LineUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // offset size - U8 offset_size = is_64bit?8:4; - - // rest of header depends on version - U8 minimum_instruction_length = 0; - U8 maximum_operations_per_instruction = 0; - U8 default_is_stmt = 0; - S8 line_base = 0; - U8 line_range = 0; - U8 opcode_base = 0; - U8 *standard_opcode_lengths = 0; - // v4 - String8List include_directories = {0}; - DWARF_V4LineFileNamesList file_names = {0}; - // v5 - U8 address_size = 0; - U8 segment_selector_size = 0; - U8 directory_entry_format_count = 0; - DWARF_V5LinePathEntryFormat *directory_entry_format = 0; - U64 directories_count = 0; - U8 file_name_entry_format_count = 0; - DWARF_V5LinePathEntryFormat *file_name_entry_format = 0; - U64 file_names_count = 0; - - switch (version){ - case 4: - { - // header_length - U64 header_length = 0; - if (is_64bit){ - header_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - header_length = MemoryConsume(U32, ptr, unit_opl); - } - - // header opl - U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = ClampTop(header_opl_raw, unit_opl); - - // minimum_instruction_length - minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); - - // maximum_operations_per_instruction - maximum_operations_per_instruction = MemoryConsume(U8, ptr, header_opl); - - // default_is_stmt - default_is_stmt = MemoryConsume(U8, ptr, header_opl); - - // line_base - line_base = MemoryConsume(S8, ptr, header_opl); - - // line_range - line_range = MemoryConsume(U8, ptr, header_opl); - - // opcode_base - opcode_base = MemoryConsume(U8, ptr, header_opl); - - // standard_opcode_lengths - if (opcode_base > 1){ - standard_opcode_lengths = ptr; - ptr += opcode_base - 1; - } - - // include_directories - for (;ptr < header_opl;){ - // null byte ends entries - if (*ptr == 0){ - ptr += 1; - break; - } - - // extract dir range - U8 *dir_first = ptr; - for (;ptr < header_opl && *ptr != 0;) ptr += 1; - U8 *dir_opl = ptr; - if (ptr < header_opl){ - ptr += 1; - } - - // attach dir to list - String8 dir = str8_range(dir_first, dir_opl); - str8_list_push(arena, &include_directories, dir); - } - - // file_names - for (;ptr < header_opl;){ - // null byte ends entries - if (*ptr == 0){ - ptr += 1; - break; - } - - // extract file_name range - U8 *file_name_first = ptr; - for (;ptr < header_opl && *ptr != 0;) ptr += 1; - U8 *file_name_opl = ptr; - if (ptr < header_opl){ - ptr += 1; - } - - // extract include directory index - U64 include_directory_idx = 0; - DWARF_LEB128_DECODE_ADV(U64, include_directory_idx, ptr, header_opl); - - // extract last modified time - U64 last_modified_time = 0; - DWARF_LEB128_DECODE_ADV(U64, last_modified_time, ptr, header_opl); - - // extract file size - U64 file_size = 0; - DWARF_LEB128_DECODE_ADV(U64, file_size, ptr, header_opl); - - // emit file name entry - DWARF_V4LineFileNamesEntry *entry = push_array(arena, DWARF_V4LineFileNamesEntry, 1); - SLLQueuePush(file_names.first, file_names.last, entry); - file_names.count += 1; - entry->file_name = str8_range(file_name_first, file_name_opl); - entry->include_directory_idx = include_directory_idx; - entry->last_modified_time = last_modified_time; - entry->file_size = file_size; - } - - ptr = header_opl; - }break; - - case 5: - { - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment_selector_size - segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // header_length - U64 header_length = 0; - if (is_64bit){ - header_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - header_length = MemoryConsume(U32, ptr, unit_opl); - } - - // header opl - U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = ClampTop(header_opl_raw, unit_opl); - - // minimum_instruction_length - minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); - - // maximum_operations_per_instruction - maximum_operations_per_instruction = MemoryConsume(U8, ptr, header_opl); - - // default_is_stmt - default_is_stmt = MemoryConsume(U8, ptr, header_opl); - - // line_base - line_base = MemoryConsume(S8, ptr, header_opl); - - // line_range - line_range = MemoryConsume(U8, ptr, header_opl); - - // opcode_base - opcode_base = MemoryConsume(U8, ptr, header_opl); - - // standard_opcode_lengths - if (opcode_base > 1){ - standard_opcode_lengths = ptr; - ptr += opcode_base - 1; - } - - // directory_entry_format_count - directory_entry_format_count = MemoryConsume(U8, ptr, header_opl); - - // directory_entry_format - { - directory_entry_format = push_array(arena, DWARF_V5LinePathEntryFormat, - directory_entry_format_count); - DWARF_V5LinePathEntryFormat *entry = directory_entry_format; - DWARF_V5LinePathEntryFormat *entry_opl = - directory_entry_format + directory_entry_format_count; - for (;entry < entry_opl && ptr < header_opl; entry += 1){ - DWARF_LEB128_DECODE_ADV(U64, entry->content_type, ptr, header_opl); - DWARF_LEB128_DECODE_ADV(U64, entry->form, ptr, header_opl); - } - } - - // directories_count - DWARF_LEB128_DECODE_ADV(U64, directories_count, ptr, header_opl); - - // directories - DWARF_V5Directory *directories = push_array(arena, DWARF_V5Directory, directories_count); - dwarf__line_v5_directories(address_size, offset_size, - directory_entry_format, directory_entry_format_count, - directories, directories_count, - &ptr, header_opl); - - // file_name_entry_format_count - file_name_entry_format_count = MemoryConsume(U8, ptr, header_opl); - - // file_name_entry_format - { - file_name_entry_format = push_array(arena, DWARF_V5LinePathEntryFormat, - file_name_entry_format_count); - DWARF_V5LinePathEntryFormat *entry = file_name_entry_format; - for (;ptr < header_opl; entry += 1){ - DWARF_LEB128_DECODE_ADV(U64, entry->content_type, ptr, header_opl); - DWARF_LEB128_DECODE_ADV(U64, entry->form, ptr, header_opl); - } - } - - // file_names_count - DWARF_LEB128_DECODE_ADV(U64, file_names_count, ptr, header_opl); - - // file_names - DWARF_V5Directory *file_names = push_array(arena, DWARF_V5Directory, file_names_count); - dwarf__line_v5_directories(address_size, offset_size, - directory_entry_format, directory_entry_format_count, - file_names, file_names_count, - &ptr, header_opl); - }break; - } - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_LineUnit *unit = push_array(arena, DWARF_LineUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_LineParsed *result = push_array(arena, DWARF_LineParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_MacInfoParsed* -dwarf_mac_info_from_data(Arena *arena, String8 data){ - DWARF_MacInfoParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_MacroParsed* -dwarf_macro_from_data(Arena *arena, String8 data){ - DWARF_MacroParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_FrameParsed* -dwarf_frame_from_data(Arena *arena, String8 data){ - DWARF_FrameParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_RangesParsed* -dwarf_ranges_from_data(Arena *arena, String8 data){ - DWARF_RangesParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_StrOffsetsParsed* -dwarf_str_offsets_from_data(Arena *arena, String8 data){ - DWARF_StrOffsetsParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_AddrParsed* -dwarf_addr_from_data(Arena *arena, String8 data){ - // supported version numbers: 5 - - - // addr unit list - DWARF_AddrUnit *first = 0; - DWARF_AddrUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // address size - U8 address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment selector size - U8 segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // offset size - U32 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit addr unit - DWARF_AddrUnit *unit = push_array(arena, DWARF_AddrUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->dwarf_version = version; - unit->address_size = address_size; - unit->segment_selector_size = segment_selector_size; - - // advance to next unit - ptr = unit_opl; - } - - // fill result - DWARF_AddrParsed *result = push_array(arena, DWARF_AddrParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_RngListsParsed* -dwarf_rng_lists_from_data(Arena *arena, String8 data){ - DWARF_RngListsParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_LocListsParsed* -dwarf_loc_lists_from_data(Arena *arena, String8 data){ - DWARF_LocListsParsed *result = 0; - // TODO(allen): - return(result); -} - - -// parse helpers - -static void -dwarf__initial_length(String8 data, U8 **ptr_inout, U8 **unit_opl_out, B32 *is_64bit_out){ - U8 *unit_opl = 0; - B32 is_64bit = 0; - - U8 *opl = data.str + data.size; - U8 *ptr = *ptr_inout; - { - U64 length = 0; - U32 m = MemoryConsume(U32, ptr, opl); - if (m == 0xFFFFFFFF){ - is_64bit = 1; - length = MemoryConsume(U64, ptr, opl); - } - else{ - length = ClampTop(m, 0xFFFFFFF0); - } - if (length > 0){ - U64 unit_opl_off_raw = (ptr - data.str) + length; - U64 unit_opl_off = ClampTop(unit_opl_off_raw, data.size); - unit_opl = data.str + unit_opl_off; - } - else{ - unit_opl = ptr; - } - } - - *ptr_inout = ptr; - *unit_opl_out = unit_opl; - *is_64bit_out = is_64bit; -} - -static void -dwarf__line_v5_directories(U64 address_size, U64 offset_size, - DWARF_V5LinePathEntryFormat *format, U64 format_count, - DWARF_V5Directory *directories_out, U64 dir_count, - U8 **ptr_io, U8 *opl){ - - U8 *ptr = *ptr_io; - - DWARF_V5Directory *directory_ptr = directories_out; - for (U32 i = 0; i < dir_count; i += 1, directory_ptr += 1){ - DWARF_V5LinePathEntryFormat *fmt = format; - for (U32 j = 0; j < format_count; j += 1){ - - // form decode - DWARF_FormDecodeRules rules = - dwarf_form_decode_rule(fmt->form, address_size, offset_size); - - // execute decoding - DWARF_FormDecoded decoded = dwarf_form_decode(&rules, &ptr, opl, 0, 0); - - // store to correct field - U64 *target = 0; - switch (fmt->content_type){ - case DWARF_LineEntryFormat_path: - { - if (decoded.dataptr != 0){ - directory_ptr->path_str = str8(decoded.dataptr, decoded.val); - } - else{ - directory_ptr->path_off = decoded.val; - directory_ptr->path_sec_form = fmt->form; - } - }break; - - case DWARF_LineEntryFormat_directory_index: - { - target = &directory_ptr->directory_index; - }goto v5_directory_u64; - - case DWARF_LineEntryFormat_timestamp: - { - target = &directory_ptr->timestamp; - }goto v5_directory_u64; - - case DWARF_LineEntryFormat_size: - { - target = &directory_ptr->size; - }goto v5_directory_u64; - - v5_directory_u64: - { - if (decoded.dataptr != 0){ - U64 size = ClampTop(decoded.val, 8); - MemoryCopy(target, decoded.dataptr, size); - } - else{ - *target = decoded.val; - } - }break; - - case DWARF_LineEntryFormat_MD5: - { - if (decoded.dataptr != 0){ - U64 size = ClampTop(decoded.val, 16); - MemoryCopy(directory_ptr->md5_checksum, decoded.dataptr, size); - } - }break; - } - } - } - - *ptr_io = ptr; -} - - -// debug sections - -static String8 -dwarf_name_from_debug_section(DWARF_Parsed *dwarf, DWARF_SectionCode sec_code){ - String8 result = str8_lit("invalid_debug_section"); - if (sec_code < DWARF_SectionCode_COUNT){ - if (dwarf->debug_section_idx[sec_code] != 0){ - result = dwarf->debug_section_name[sec_code]; - } - } - return(result); -} - - -// abbrev functions - -static DWARF_AbbrevUnit* -dwarf_abbrev_unit_from_offset(DWARF_AbbrevParsed *abbrev, U64 offset){ - DWARF_AbbrevUnit *result = 0; - for (DWARF_AbbrevUnit *unit = abbrev->unit_first; - unit != 0; - unit = unit->next){ - if (unit->offset == offset){ - result = unit; - break; - } - } - return(result); -} - -static DWARF_AbbrevDecl* -dwarf_abbrev_decl_from_code(DWARF_AbbrevUnit *unit, U32 abbrev_code){ - DWARF_AbbrevDecl *result = 0; - for (DWARF_AbbrevDecl *decl = unit->first; - decl != 0; - decl = decl->next){ - if (decl->abbrev_code == abbrev_code){ - result = decl; - break; - } - } - return(result); -} - -// attribute decoding functions - -static DWARF_AttributeClassFlags -dwarf_attribute_class_from_form(DWARF_AttributeForm form){ - DWARF_AttributeClassFlags result = 0; - switch (form){ -#define X(N,C,f) case C: result = DWARF_AttributeClassFlag_##f; break; - DWARF_AttributeFormXList(X) -#undef X - } - return(result); -} - -static DWARF_AttributeClassFlags -dwarf_attribute_class_from_name(DWARF_AttributeName name){ - DWARF_AttributeClassFlags result = 0; - switch (name){ -#define X(N,C,f1,f2,f3,f4) case C: result = 0\ -|DWARF_AttributeClassFlag_##f1\ -|DWARF_AttributeClassFlag_##f2\ -|DWARF_AttributeClassFlag_##f3\ -|DWARF_AttributeClassFlag_##f4\ -;break; - DWARF_AttributeNameXList(X) -#undef X - } - return(result); -} - -// form decoding functions - -static DWARF_FormDecodeRules -dwarf_form_decode_rule(DWARF_AttributeForm form, U64 address_size, U64 offset_size){ - DWARF_FormDecodeRules result = {0}; - switch (form){ - case DWARF_AttributeForm_null: - case DWARF_AttributeForm_indirect:{}break; - - case DWARF_AttributeForm_addr: result.size = address_size; break; - case DWARF_AttributeForm_addrx: result.uleb128 = 1; break; - case DWARF_AttributeForm_addrx1: result.size = 1; break; - case DWARF_AttributeForm_addrx2: result.size = 2; break; - case DWARF_AttributeForm_addrx3: result.size = 3; break; - case DWARF_AttributeForm_addrx4: result.size = 4; break; - - case DWARF_AttributeForm_sec_offset: result.size = offset_size; break; - - case DWARF_AttributeForm_block1: result.size = 1; result.block = 1; break; - case DWARF_AttributeForm_block2: result.size = 2; result.block = 1; break; - case DWARF_AttributeForm_block4: result.size = 4; result.block = 1; break; - case DWARF_AttributeForm_block: result.uleb128 = 1; result.block = 1; break; - - case DWARF_AttributeForm_data1: result.size = 1; break; - case DWARF_AttributeForm_data2: result.size = 2; break; - case DWARF_AttributeForm_data4: result.size = 4; break; - case DWARF_AttributeForm_data8: result.size = 8; break; - case DWARF_AttributeForm_data16: result.size = 16; break; - - case DWARF_AttributeForm_sdata: result.sleb128 = 1; break; - case DWARF_AttributeForm_udata: result.uleb128 = 1; break; - - case DWARF_AttributeForm_implicit_const: result.in_abbrev = 1; break; - - case DWARF_AttributeForm_exprloc: result.uleb128 = 1; result.block = 1; break; - - case DWARF_AttributeForm_flag: result.size = 1; break; - case DWARF_AttributeForm_flag_present: result.auto_1 = 1; break; - - case DWARF_AttributeForm_loclistx: result.uleb128 = 1; break; - case DWARF_AttributeForm_rnglistx: result.uleb128 = 1; break; - - case DWARF_AttributeForm_ref1: result.size = 1; break; - case DWARF_AttributeForm_ref2: result.size = 2; break; - case DWARF_AttributeForm_ref4: result.size = 4; break; - case DWARF_AttributeForm_ref8: result.size = 8; break; - case DWARF_AttributeForm_ref_udata: result.uleb128 = 1; break; - - case DWARF_AttributeForm_ref_addr: result.size = offset_size; break; - - case DWARF_AttributeForm_ref_sig8: result.size = 8; break; - - case DWARF_AttributeForm_ref_sup4: result.size = 4; break; - case DWARF_AttributeForm_ref_sup8: result.size = 8; break; - - case DWARF_AttributeForm_string: result.null_terminated = 1; break; - - case DWARF_AttributeForm_strp: result.size = offset_size; break; - case DWARF_AttributeForm_line_strp: result.size = offset_size; break; - case DWARF_AttributeForm_strp_sup: result.size = offset_size; break; - - case DWARF_AttributeForm_strx: result.uleb128 = 1; break; - case DWARF_AttributeForm_strx1: result.size = 1; break; - case DWARF_AttributeForm_strx2: result.size = 2; break; - case DWARF_AttributeForm_strx3: result.size = 3; break; - case DWARF_AttributeForm_strx4: result.size = 4; break; - } - - return(result); -} - -static DWARF_FormDecoded -dwarf_form_decode(DWARF_FormDecodeRules *rules, U8 **ptr_io, U8 *opl, - DWARF_AbbrevDecl *abbrev_decl, U32 attrib_i){ - - // local copy of ptr - U8 *ptr = *ptr_io; - - // apply rules - U64 val = 0; - U8 *dataptr = 0; - - B32 success = 1; - if (rules->size > 0){ - if (ptr + rules->size <= opl){ - MemoryCopy(&val, ptr, rules->size); - ptr += rules->size; - } - else{ - success = 0; - } - } - else if (rules->uleb128 || rules->sleb128){ - U8 *val_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - if (success){ - if (rules->uleb128){ - val = dwarf_leb128_decode_U64(val_ptr, ptr); - } - else{ - val = (U64)dwarf_leb128_decode_S64(val_ptr, ptr); - } - } - } - else if (rules->in_abbrev){ - if (abbrev_decl != 0){ - if (abbrev_decl->implicit_const != 0){ - val = (U64)abbrev_decl->implicit_const[attrib_i]; - } - } - else{ - success = 0; - } - } - else if (rules->auto_1){ - val = 1; - } - if (rules->block){ - dataptr = ptr; - ptr += val; - } - else if (rules->null_terminated){ - dataptr = ptr; - for (;ptr < opl && *ptr != 0;) ptr += 1; - val = (U64)(ptr - dataptr); - if (ptr < opl){ - ptr += 1; - } - } - - // store out ptr - *ptr_io = ptr; - - // fill result - DWARF_FormDecoded result = {0}; - result.val = val; - result.dataptr = dataptr; - result.error = !success; - return(result); -} - - -// string functions - -static String8 -dwarf_string_from_unit_type(DWARF_UnitType type){ - String8 result = str8_lit("unrecognized_type"); - switch (type){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_UnitTypeXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_tag(DWARF_Tag tag){ - String8 result = str8_lit("unrecognized_tag"); - switch (tag){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_TagXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_attribute_name(DWARF_AttributeName name){ - String8 result = str8_lit("unrecognized_attribute_name"); - switch (name){ -#define X(N,C,f1,f2,f3,f4) case C: result = str8_lit(#N); break; - DWARF_AttributeNameXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_attribute_form(DWARF_AttributeForm form){ - String8 result = str8_lit("unrecognized_attribute_form"); - switch (form){ -#define X(N,C,k) case C: result = str8_lit(#N); break; - DWARF_AttributeFormXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_std_op(DWARF_LineStdOp op){ - String8 result = str8_lit("unrecognized_line_std_op"); - switch (op){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineStdOpXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_ext_op(DWARF_LineExtOp op){ - String8 result = str8_lit("unrecognized_line_ext_op"); - switch (op){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineExtOpXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_entry_format(DWARF_LineEntryFormat format){ - String8 result = str8_lit("unrecognized_line_entry_format"); - switch (format){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineEntryFormatXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_section_code(DWARF_SectionCode sec_code){ - String8 result = str8_lit("unrecognized_section_code"); - switch (sec_code){ - case DWARF_SectionCode_COUNT:{}break; -#define X(Nc,Vf,N0,N1,N2) case DWARF_SectionCode_##Nc: result = str8_lit(#Nc); break; - DWARF_SectionNameXList(X,0,0) -#undef X - } - return(result); -} - - - - - -#if 0 -static DWARF_InfoParsed* -dwarf_info_from_data(Arena *arena, String8 data, DWARF_InfoParams *params, - DWARF_AbbrevParsed *abbrev){ - - // unit index range to extract - U64 unit_idx_min = params->unit_idx_min; - U64 unit_idx_max = params->unit_idx_max; - - // empty unit list - DWARF_InfoUnit *unit_first = 0; - DWARF_InfoUnit *unit_last = 0; - U64 unit_count = 0; - B32 decoding_error = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // early escape on unit idx - if (unit_idx > unit_idx_max){ - break; - } - - // determine whether to full parse this unit - B32 full_parse = (unit_idx_min <= unit_idx); - - // header fields - U8 *unit_opl = 0; - B32 is_64bit = 0; - U16 version = 0; - U64 abbrev_offset = 0; - U32 address_size = 0; - DWARF_UnitType unit_type = DWARF_UnitType_null; - U64 unit_dwo_id = 0; - U64 unit_type_signature = 0; - U64 unit_type_offset = 0; - - // initial length - dwarf__initial_length(&ptr, opl, &unit_opl, &is_64bit); - - // if this is not a full parse we may use - // unit_opl to skip to the next unit now - if (full_parse){ - - // version (part of header) - version = MemoryConsume(U16, ptr, unit_opl); - - // rest of header depends on version - switch (version){ - case 4: - { - // abbrev_offset (part of header) - if (is_64bit){ - abbrev_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_offset = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size (part of header) - address_size = MemoryConsume(U8, ptr, unit_opl); - }break; - - case 5: - { - // unit_type (part of header) - unit_type = (DWARF_UnitType)MemoryConsume(U8, ptr, unit_opl); - - // address_size (part of header) - address_size = MemoryConsume(U8, ptr, unit_opl); - - // abbrev_offset (part of header) - if (is_64bit){ - abbrev_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_offset = MemoryConsume(U32, ptr, unit_opl); - } - - // rest of header depends on unit_type - switch (unit_type){ - case DWARF_UnitType_skeleton: - case DWARF_UnitType_split_compile: - { - unit_dwo_id = MemoryConsume(U64, ptr, unit_opl); - }break; - case DWARF_UnitType_type: - case DWARF_UnitType_split_type: - { - unit_type_signature = MemoryConsume(U64, ptr, unit_opl); - if (is_64bit){ - unit_type_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - unit_type_offset = MemoryConsume(U32, ptr, unit_opl); - } - }break; - } - }break; - } - - // offset size - U32 offset_size = is_64bit?8:4; - - // find matching abbrev unit - DWARF_AbbrevUnit *abbrev_unit = dwarf_abbrev_unit_from_offset(abbrev, abbrev_offset); - if (abbrev_unit == 0){ - // TODO: preserve error info - decoding_error = 1; - } - - // consume info entries - DWARF_InfoEntry *entry_root = 0; - U64 entry_count = 0; - - DWARF_InfoEntry *entry_consptr = 0; - if (abbrev_unit != 0){ - for (;ptr < unit_opl;){ - B32 success = 1; - - // mark beginning of entry - U8 *entry_start_ptr = ptr; - - // extract abbrev code - U8 *abbrev_code_ptr = ptr; - DWARF_LEB128_ADV(ptr, unit_opl, success); - if (!success){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - - U32 abbrev_code = dwarf_leb128_decode_U32(abbrev_code_ptr, ptr); - - // null abbrev code means pop - if (abbrev_code == 0){ - if (entry_consptr == 0){ - goto exit_unit_loop; - } - else{ - entry_consptr = entry_consptr->parent; - goto skip_entry; - } - } - - // get abbrev decl - DWARF_AbbrevDecl *abbrev_decl = dwarf_abbrev_decl_from_code(abbrev_unit, abbrev_code); - if (abbrev_decl == 0){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - - // allocate entry - U32 attrib_count = abbrev_decl->attrib_count; - DWARF_InfoEntry *entry = push_array(arena, DWARF_InfoEntry, 1); - DWARF_InfoAttribVal *attrib_vals = - push_array_no_zero(arena, DWARF_InfoAttribVal, attrib_count); - - // save entry offset - entry->info_offset = (U64)(entry_start_ptr - data.str); - - // set root at beginning - if (entry_root == 0){ - entry_root = entry; - } - - // attribute loop - DWARF_AbbrevAttribSpec *attrib_spec = abbrev_decl->attrib_specs; - DWARF_InfoAttribVal *attrib_val = attrib_vals; - for (U32 i = 0; i < attrib_count; i += 1, attrib_spec += 1, attrib_val += 1){ - - // determine decoding rules - U32 size = 0; - B8 uleb128 = 0; - B8 sleb128 = 0; - B8 in_abbrev = 0; - B8 auto_1 = 0; - B8 block = 0; - B8 null_terminated = 0; - { - DWARF_AttributeForm form = attrib_spec->form; - switch (form){ - case DWARF_AttributeForm_addr: size = address_size; break; - case DWARF_AttributeForm_addrx: uleb128 = 1; break; - case DWARF_AttributeForm_addrx1: size = 1; break; - case DWARF_AttributeForm_addrx2: size = 2; break; - case DWARF_AttributeForm_addrx3: size = 3; break; - case DWARF_AttributeForm_addrx4: size = 4; break; - - case DWARF_AttributeForm_sec_offset: size = offset_size; break; - - case DWARF_AttributeForm_block1: size = 1; block = 1; break; - case DWARF_AttributeForm_block2: size = 2; block = 1; break; - case DWARF_AttributeForm_block4: size = 4; block = 1; break; - case DWARF_AttributeForm_block: uleb128 = 1; block = 1; break; - - case DWARF_AttributeForm_data1: size = 1; break; - case DWARF_AttributeForm_data2: size = 2; break; - case DWARF_AttributeForm_data4: size = 4; break; - case DWARF_AttributeForm_data8: size = 8; break; - case DWARF_AttributeForm_data16: size = 16; break; - - case DWARF_AttributeForm_sdata: sleb128 = 1; break; - case DWARF_AttributeForm_udata: uleb128 = 1; break; - - case DWARF_AttributeForm_implicit_const: in_abbrev = 1; break; - - case DWARF_AttributeForm_exprloc: uleb128 = 1; block = 1; break; - - case DWARF_AttributeForm_flag: size = 1; break; - case DWARF_AttributeForm_flag_present: auto_1 = 1; break; - - case DWARF_AttributeForm_loclistx: uleb128 = 1; break; - case DWARF_AttributeForm_rnglistx: uleb128 = 1; break; - - case DWARF_AttributeForm_ref1: size = 1; break; - case DWARF_AttributeForm_ref2: size = 2; break; - case DWARF_AttributeForm_ref4: size = 4; break; - case DWARF_AttributeForm_ref8: size = 8; break; - case DWARF_AttributeForm_ref_udata: uleb128 = 1; break; - - case DWARF_AttributeForm_ref_addr: size = offset_size; break; - - case DWARF_AttributeForm_ref_sig8: size = 8; break; - - case DWARF_AttributeForm_ref_sup4: size = 4; break; - case DWARF_AttributeForm_ref_sup8: size = 8; break; - - case DWARF_AttributeForm_string: null_terminated = 1; break; - - case DWARF_AttributeForm_strp: size = offset_size; break; - case DWARF_AttributeForm_line_strp: size = offset_size; break; - case DWARF_AttributeForm_strp_sup: size = offset_size; break; - - case DWARF_AttributeForm_strx: uleb128 = 1; break; - case DWARF_AttributeForm_strx1: size = 1; break; - case DWARF_AttributeForm_strx2: size = 2; break; - case DWARF_AttributeForm_strx3: size = 3; break; - case DWARF_AttributeForm_strx4: size = 4; break; - } - } - - // execute decoding rules - U64 val = 0; - U8 *dataptr = 0; - { - if (size > 0){ - if (ptr + size <= unit_opl){ - MemoryCopy(&val, ptr, size); - ptr += size; - } - else{ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - } - else if (uleb128 || sleb128){ - U8 *val_ptr = ptr; - DWARF_LEB128_ADV(ptr, unit_opl, success); - if (!success){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - else{ - if (uleb128){ - val = dwarf_leb128_decode_U64(val_ptr, ptr); - } - else{ - val = (U64)dwarf_leb128_decode_S64(val_ptr, ptr); - } - } - } - else if (in_abbrev){ - if (abbrev_decl->implicit_const != 0){ - val = (U64)abbrev_decl->implicit_const[i]; - } - } - else if (auto_1){ - val = 1; - } - if (block){ - dataptr = ptr; - ptr += val; - } - else if (null_terminated){ - dataptr = ptr; - for (;ptr < unit_opl && *ptr != 0;) ptr += 1; - val = (U64)(ptr - dataptr); - } - } - - // save attribute - attrib_val->val = val; - attrib_val->dataptr = dataptr; - } - - // emit entry - if (entry_consptr != 0){ - SLLQueuePush_N(entry_consptr->first_child, entry_consptr->last_child, - entry, next_sibling); - entry_consptr->child_count += 1; - entry->parent = entry_consptr; - } - entry_count += 1; - entry->abbrev_decl = abbrev_decl; - entry->attrib_vals = attrib_vals; - - // move consptr down if has children - if (abbrev_decl->has_children){ - entry_consptr = entry; - } - - skip_entry:; - } - } - exit_unit_loop:; - - // TODO: notice errors, emit them, and exit loop here - if (decoding_error){ - break; - } - - // extract root attributes - U64 language = 0; - U64 str_offsets_base = 0; - U64 line_info_offset = 0; - U64 vbase = 0; - U64 addr_base = 0; - U64 rnglists_base = 0; - U64 loclists_base = 0; - if (entry_root != 0){ - - // pull out attributes - DWARF_AbbrevDecl *root_abbrev_decl = entry_root->abbrev_decl; - DWARF_AbbrevAttribSpec *attrib_specs = root_abbrev_decl->attrib_specs; - DWARF_InfoAttribVal *attrib_vals = entry_root->attrib_vals; - U32 attrib_count = root_abbrev_decl->attrib_count; - - // examine each attribute - DWARF_AbbrevAttribSpec *attrib_spec = attrib_specs; - DWARF_InfoAttribVal *attrib_val = attrib_vals; - for (U32 i = 0; i < attrib_count; i += 1, attrib_spec += 1, attrib_val += 1){ - - // determine if there is a root attribute to extract here - U64 *target_u64 = 0; - switch (attrib_spec->name){ - case DWARF_AttributeName_language: target_u64 = &language; break; - case DWARF_AttributeName_str_offsets_base: target_u64 = &str_offsets_base; break; - case DWARF_AttributeName_stmt_list: target_u64 = &line_info_offset; break; - case DWARF_AttributeName_low_pc: target_u64 = &vbase; break; - case DWARF_AttributeName_addr_base: target_u64 = &addr_base; break; - case DWARF_AttributeName_rnglists_base: target_u64 = &rnglists_base; break; - case DWARF_AttributeName_loclists_base: target_u64 = &loclists_base; break; - } - - // set target from attrib value - if (target_u64 != 0){ - *target_u64 = attrib_val->val; - } - } - } - - // allocate unit - DWARF_InfoUnit *unit = push_array(arena, DWARF_InfoUnit, 1); - - // fill & emit unit - SLLQueuePush(unit_first, unit_last, unit); - unit_count += 1; - // [header] - unit->dwarf_version = version; - unit->offset_size = offset_size; - unit->address_size = address_size; - // [root attributes] - unit->language = (DWARF_Language)language; - unit->str_offsets_base = str_offsets_base; - unit->line_info_offset = line_info_offset; - unit->vbase = vbase; - unit->addr_base = addr_base; - unit->rnglists_base = rnglists_base; - unit->loclists_base = loclists_base; - // [entries] - unit->entry_root = entry_root; - unit->entry_count = entry_count; - - } - - // set ptr to end of this unit - ptr = unit_opl; - } - - // fill result - DWARF_InfoParsed *result = push_array(arena, DWARF_InfoParsed, 1); - result->unit_first = unit_first; - result->unit_last = unit_last; - result->unit_count = unit_count; - result->decoding_error = decoding_error; - return(result); -} - -static DWARF_AbbrevParsed* -dwarf_abbrev_from_data(Arena *arena, String8 data, DWARF_AbbrevParams *params){ - /* .debug_abbrev - ** Layout - ** List(Tag) - ** Tag = { id:ULEB128, tag:ULEB128, has_children:B8, ListNullTerminated(Attribute) } - ** Attribute = { name:ULEB128, form:ULEB128, (val:SLEB128)? } - */ - - // unit index range to extract - U64 unit_idx_min = params->unit_idx_min; - U64 unit_idx_max = params->unit_idx_max; - - // empty unit list - DWARF_AbbrevUnit *unit_first = 0; - DWARF_AbbrevUnit *unit_last = 0; - U64 unit_count = 0; - B32 decoding_error = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // early escape on unit idx - if (unit_idx > unit_idx_max){ - break; - } - - // determine whether to full parse this unit - B32 full_parse = (unit_idx_min <= unit_idx); - - // save unit offset - U64 abbrev_unit_offset = (U64)(ptr - data.str); - - // allocate unit - DWARF_AbbrevUnit *unit = push_array(arena, DWARF_AbbrevUnit, 1); - - // empty abbrev list - DWARF_AbbrevDecl *abbrev_first = 0; - DWARF_AbbrevDecl *abbrev_last = 0; - U64 abbrev_count = 0; - - // abbrev decl loop - for (;ptr < opl;){ - B32 success = 1; - - // mark abbrev_code field - U8 *abbrev_code_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - - // null abbrev code means end of unit - if (success && *abbrev_code_ptr == 0){ - break; - } - - // mark tag - U8 *tag_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - U8 *end_tag_ptr = ptr; - - // extract has_children - B8 has_children = 0; - if (ptr < opl){ - has_children = *ptr; - ptr += 1; - } - else{ - success = 0; - } - - // count attributes - U8 *attrib_start_ptr = ptr; - U32 attrib_count = 0; - B32 has_implicit_const = 0; - if (success){ - for (;;){ - // decode normal attribute layout - U8 *attrib_name = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - U8 *attrib_form = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - - // handle special case implicit_const - if (success && *attrib_form == (U8)DWARF_AttributeForm_implicit_const){ - DWARF_LEB128_ADV(ptr, opl, success); - has_implicit_const = 1; - } - - // termination conditions - if (ptr == opl || - (*attrib_name == 0 && *attrib_form == 0)){ - break; - } - - // increment - attrib_count += 1; - } - } - - // build the abbreviation declaration - if (full_parse && success){ - - // allocate abbrev - DWARF_AbbrevDecl *abbrev = push_array(arena, DWARF_AbbrevDecl, 1); - DWARF_AbbrevAttribSpec *attribs = - push_array_no_zero(arena, DWARF_AbbrevAttribSpec, attrib_count); - U64 *implicit_const = 0; - if (has_implicit_const){ - implicit_const = push_array(arena, U64, attrib_count); - } - - // extract abbrev fields - U32 abbrev_code = dwarf_leb128_decode_U32(abbrev_code_ptr, tag_ptr); - U32 tag = dwarf_leb128_decode_U32(tag_ptr, end_tag_ptr); - - U8 *attrib_ptr = attrib_start_ptr; - DWARF_AbbrevAttribSpec *attrib = attribs; - for (U32 i = 0; i < attrib_count; i += 1, attrib += 1){ - // mark attribute fields - U8 *attrib_name = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - U8 *attrib_form = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - - // extract attribute fields - U32 name = dwarf_leb128_decode_U32(attrib_name, attrib_form); - U32 form = dwarf_leb128_decode_U32(attrib_form, attrib_ptr); - - // fill attribute spec - attrib->name = (DWARF_AttributeName)name; - attrib->form = (DWARF_AttributeForm)form; - - // handle special case implicit_const - if (form == DWARF_AttributeForm_implicit_const){ - U8 *attrib_value = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - S64 value = dwarf_leb128_decode_S64(attrib_form, attrib_ptr); - implicit_const[i] = value; - } - } - - // fill abbreviation - SLLQueuePush(abbrev_first, abbrev_last, abbrev); - abbrev_count += 1; - abbrev->abbrev_code = abbrev_code; - abbrev->tag = (DWARF_Tag)tag; - abbrev->has_children = has_children; - abbrev->attrib_count = attrib_count; - abbrev->attrib_specs = attribs; - abbrev->implicit_const = implicit_const; - } - - // handle failure - if (!success){ - // TODO: emit error message - decoding_error = 1; - goto done_parse; - } - } - - // fill unit - if (full_parse){ - SLLQueuePush(unit_first, unit_last, unit); - unit_count += 1; - unit->offset = abbrev_unit_offset; - unit->first = abbrev_first; - unit->last = abbrev_last; - unit->count = abbrev_count; - } - } - - done_parse:; - - // fill result - DWARF_AbbrevParsed *result = push_array(arena, DWARF_AbbrevParsed, 1); - result->unit_first = unit_first; - result->unit_last = unit_last; - result->unit_count = unit_count; - result->decoding_error = decoding_error; - return(result); -} -#endif diff --git a/src/rdi_from_dwarf/rdi_dwarf.h b/src/rdi_from_dwarf/rdi_dwarf.h deleted file mode 100644 index 405cd817..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf.h +++ /dev/null @@ -1,1493 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_DWARF_H -#define RDI_DWARF_H - -// https://dwarfstd.org/doc/DWARF4.pdf -// https://dwarfstd.org/doc/DWARF5.pdf - -// TODO(allen): -// [ ] function to parse info just for unit headers & root attributes -// [ ] put together unit info from all sections in one structure -// [ ] actually check version numbers in unit header parsers - -#pragma pack(push,1) - -//////////////////////////////// -//~ Dwarf Format Code X Lists - -// unit type X(name, code) -#define DWARF_UnitTypeXList(X)\ -X(null, 0x00)\ -X(compile, 0x01)\ -X(type, 0x02)\ -X(partial, 0x03)\ -X(skeleton, 0x04)\ -X(split_compile, 0x05)\ -X(split_type, 0x06)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_UnitType{ -#define X(N,C) DWARF_UnitType_##N = C, - DWARF_UnitTypeXList(X) -#undef X -} DWARF_UnitType; - - -// tag X(name, code) -#define DWARF_TagXList(X)\ -X(null, 0x00)\ -X(array_type, 0x01)\ -X(class_type, 0x02)\ -X(entry_point, 0x03)\ -X(enumeration_type, 0x04)\ -X(formal_parameter, 0x05)\ -X(imported_declaration, 0x08)\ -X(label, 0x0a)\ -X(lexical_block, 0x0b)\ -X(member, 0x0d)\ -X(pointer_type, 0x0f)\ -X(reference_type, 0x10)\ -X(compile_unit, 0x11)\ -X(string_type, 0x12)\ -X(structure_type, 0x13)\ -X(subroutine_type, 0x15)\ -X(typedef, 0x16)\ -X(union_type, 0x17)\ -X(unspecified_parameters, 0x18)\ -X(variant, 0x19)\ -X(common_block, 0x1a)\ -X(common_inclusion, 0x1b)\ -X(inheritance, 0x1c)\ -X(inlined_subroutine, 0x1d)\ -X(module, 0x1e)\ -X(ptr_to_member_type, 0x1f)\ -X(set_type, 0x20)\ -X(subrange_type, 0x21)\ -X(with_stmt, 0x22)\ -X(access_declaration, 0x23)\ -X(base_type, 0x24)\ -X(catch_block, 0x25)\ -X(const_type, 0x26)\ -X(constant, 0x27)\ -X(enumerator, 0x28)\ -X(file_type, 0x29)\ -X(friend, 0x2a)\ -X(namelist, 0x2b)\ -X(namelist_item, 0x2c)\ -X(packed_type, 0x2d)\ -X(subprogram, 0x2e)\ -X(template_type_parameter, 0x2f)\ -X(template_value_parameter, 0x30)\ -X(thrown_type, 0x31)\ -X(try_block, 0x32)\ -X(variant_part, 0x33)\ -X(variable, 0x34)\ -X(volatile_type, 0x35)\ -X(dwarf_procedure, 0x36)\ -X(restrict_type, 0x37)\ -X(interface_type, 0x38)\ -X(namespace, 0x39)\ -X(imported_module, 0x3a)\ -X(unspecified_type, 0x3b)\ -X(partial_unit, 0x3c)\ -X(imported_unit, 0x3d)\ -X(condition, 0x3f)\ -X(shared_type, 0x40)\ -X(type_unit, 0x41)\ -X(rvalue_reference_type, 0x42)\ -X(template_alias, 0x43)\ -X(coarray_type, 0x44)\ -X(generic_subrange, 0x45)\ -X(dynamic_type, 0x46)\ -X(atomic_type, 0x47)\ -X(call_site, 0x48)\ -X(call_site_parameter, 0x49)\ -X(skeleton_unit, 0x4a)\ -X(immutable_type, 0x4b)\ -X(lo_user, 0x4080)\ -X(hi_user, 0xffff) - -typedef enum DWARF_Tag{ -#define X(N,C) DWARF_Tag_##N = C, - DWARF_TagXList(X) -#undef X -} DWARF_Tag; - - -// attribute classes: X(name,code) -#define DWARF_AttributeClassXList(X)\ -X(address, 0)\ -X(addrptr, 1)\ -X(block, 2)\ -X(constant, 3)\ -X(exprloc, 4)\ -X(flag, 5)\ -X(lineptr, 6)\ -X(loclist, 7)\ -X(loclistsptr, 8)\ -X(macptr, 9)\ -X(reference, 10)\ -X(rnglist, 11)\ -X(rnglistsptr, 12)\ -X(string, 13)\ -X(stroffsetsptr, 14) - -typedef U32 DWARF_AttributeClassFlags; -enum{ -#define X(N,C) DWARF_AttributeClassFlag_##N = (1 << C), - DWARF_AttributeClassXList(X) -#undef X - - DWARF_AttributeClassFlag_0 = 0, - DWARF_AttributeClassFlag_specialcase = ~0, - DWARF_AttributeClassFlag_sec_offset_classes = - (DWARF_AttributeClassFlag_addrptr | - DWARF_AttributeClassFlag_lineptr | - DWARF_AttributeClassFlag_loclist | - DWARF_AttributeClassFlag_loclistsptr | - DWARF_AttributeClassFlag_macptr | - DWARF_AttributeClassFlag_rnglist | - DWARF_AttributeClassFlag_rnglistsptr | - DWARF_AttributeClassFlag_stroffsetsptr | - 0), - -}; - - -// attribute name: X(name, code, classflag1, classflag2, classflag3, classflag4) -#define DWARF_AttributeNameXList(X)\ -X(null, 0x00, 0, 0, 0, 0)\ -X(sibling, 0x01, reference, 0, 0, 0)\ -X(location, 0x02, exprloc, loclist, 0, 0)\ -X(name, 0x03, string, 0, 0, 0)\ -X(ordering, 0x09, constant, 0, 0, 0)\ -X(byte_size, 0x0b, constant, exprloc, reference, 0)\ -X(bit_size, 0x0d, constant, exprloc, reference, 0)\ -X(stmt_list, 0x10, lineptr, 0, 0, 0)\ -X(low_pc, 0x11, address, 0, 0, 0)\ -X(high_pc, 0x12, address, constant, 0, 0)\ -X(language, 0x13, constant, 0, 0, 0)\ -X(discr, 0x15, reference, 0, 0, 0)\ -X(discr_value, 0x16, constant, 0, 0, 0)\ -X(visibility, 0x17, constant, 0, 0, 0)\ -X(import, 0x18, reference, 0, 0, 0)\ -X(string_length, 0x19, exprloc, loclist, reference, 0)\ -X(common_reference, 0x1a, reference, 0, 0, 0)\ -X(comp_dir, 0x1b, string, 0, 0, 0)\ -X(const_value, 0x1c, block, constant, string, 0)\ -X(containing_type, 0x1d, reference, 0, 0, 0)\ -X(default_value, 0x1e, constant, reference, flag, 0)\ -X(inline, 0x20, constant, 0, 0, 0)\ -X(is_optional, 0x21, flag, 0, 0, 0)\ -X(lower_bound, 0x22, constant, exprloc, reference, 0)\ -X(producer, 0x25, string, 0, 0, 0)\ -X(prototyped, 0x27, flag, 0, 0, 0)\ -X(return_addr, 0x2a, exprloc, loclist, 0, 0)\ -X(start_scope, 0x2c, constant, rnglist, 0, 0)\ -X(bit_stride, 0x2e, constant, exprloc, reference, 0)\ -X(upper_bound, 0x2f, constant, exprloc, reference, 0)\ -X(abstract_origin, 0x31, reference, 0, 0, 0)\ -X(accessibility, 0x32, constant, 0, 0, 0)\ -X(address_class, 0x33, constant, 0, 0, 0)\ -X(artificial, 0x34, flag, 0, 0, 0)\ -X(base_types, 0x35, reference, 0, 0, 0)\ -X(calling_convention, 0x36, constant, 0, 0, 0)\ -X(count, 0x37, constant, exprloc, reference, 0)\ -X(data_member_location, 0x38, constant, exprloc, loclist, 0)\ -X(decl_column, 0x39, constant, 0, 0, 0)\ -X(decl_file, 0x3a, constant, 0, 0, 0)\ -X(decl_line, 0x3b, constant, 0, 0, 0)\ -X(declaration, 0x3c, flag, 0, 0, 0)\ -X(discr_list, 0x3d, block, 0, 0, 0)\ -X(encoding, 0x3e, constant, 0, 0, 0)\ -X(external, 0x3f, flag, 0, 0, 0)\ -X(frame_base, 0x40, exprloc, loclist, 0, 0)\ -X(friend, 0x41, reference, 0, 0, 0)\ -X(identifier_case, 0x42, constant, 0, 0, 0)\ -X(namelist_item, 0x44, reference, 0, 0, 0)\ -X(priority, 0x45, reference, 0, 0, 0)\ -X(segment, 0x46, exprloc, loclist, 0, 0)\ -X(specification, 0x47, reference, 0, 0, 0)\ -X(static_link, 0x48, exprloc, loclist, 0, 0)\ -X(type, 0x49, reference, 0, 0, 0)\ -X(use_location, 0x4a, exprloc, loclist, 0, 0)\ -X(variable_parameter, 0x4b, flag, 0, 0, 0)\ -X(virtuality, 0x4c, constant, 0, 0, 0)\ -X(vtable_elem_location, 0x4d, exprloc, loclist, 0, 0)\ -X(allocated, 0x4e, constant, exprloc, reference, 0)\ -X(associated, 0x4f, constant, exprloc, reference, 0)\ -X(data_location, 0x50, exprloc, 0, 0, 0)\ -X(byte_stride, 0x51, constant, exprloc, reference, 0)\ -X(entry_pc, 0x52, address, constant, 0, 0)\ -X(use_UTF8, 0x53, flag, 0, 0, 0)\ -X(extension, 0x54, reference, 0, 0, 0)\ -X(ranges, 0x55, rnglist, 0, 0, 0)\ -X(trampoline, 0x56, address, flag, reference, string)\ -X(call_column, 0x57, constant, 0, 0, 0)\ -X(call_file, 0x58, constant, 0, 0, 0)\ -X(call_line, 0x59, constant, 0, 0, 0)\ -X(description, 0x5a, string, 0, 0, 0)\ -X(binary_scale, 0x5b, constant, 0, 0, 0)\ -X(decimal_scale, 0x5c, constant, 0, 0, 0)\ -X(small, 0x5d, reference, 0, 0, 0)\ -X(decimal_sign, 0x5e, constant, 0, 0, 0)\ -X(digit_count, 0x5f, constant, 0, 0, 0)\ -X(picture_string, 0x60, string, 0, 0, 0)\ -X(mutable, 0x61, flag, 0, 0, 0)\ -X(threads_scaled, 0x62, flag, 0, 0, 0)\ -X(explicit, 0x63, flag, 0, 0, 0)\ -X(object_pointer, 0x64, reference, 0, 0, 0)\ -X(endianity, 0x65, constant, 0, 0, 0)\ -X(elemental, 0x66, flag, 0, 0, 0)\ -X(pure, 0x67, flag, 0, 0, 0)\ -X(recursive, 0x68, flag, 0, 0, 0)\ -X(signature, 0x69, reference, 0, 0, 0)\ -X(main_subprogram, 0x6a, flag, 0, 0, 0)\ -X(data_bit_offset, 0x6b, constant, 0, 0, 0)\ -X(const_expr, 0x6c, flag, 0, 0, 0)\ -X(enum_class, 0x6d, flag, 0, 0, 0)\ -X(linkage_name, 0x6e, string, 0, 0, 0)\ -X(string_length_bit_size, 0x6f, constant, 0, 0, 0)\ -X(string_length_byte_size, 0x70, constant, 0, 0, 0)\ -X(rank, 0x71, constant, exprloc, 0, 0)\ -X(str_offsets_base, 0x72, stroffsetsptr, 0, 0, 0)\ -X(addr_base, 0x73, addrptr, 0, 0, 0)\ -X(rnglists_base, 0x74, rnglistsptr, 0, 0, 0)\ -X(dwo_name, 0x76, string, 0, 0, 0)\ -X(reference, 0x77, flag, 0, 0, 0)\ -X(rvalue_reference, 0x78, flag, 0, 0, 0)\ -X(macros, 0x79, macptr, 0, 0, 0)\ -X(call_all_calls, 0x7a, flag, 0, 0, 0)\ -X(call_all_source_calls, 0x7b, flag, 0, 0, 0)\ -X(call_all_tail_calls, 0x7c, flag, 0, 0, 0)\ -X(call_return_pc, 0x7d, address, 0, 0, 0)\ -X(call_value, 0x7e, exprloc, 0, 0, 0)\ -X(call_origin, 0x7f, exprloc, 0, 0, 0)\ -X(call_parameter, 0x80, reference, 0, 0, 0)\ -X(call_pc, 0x81, address, 0, 0, 0)\ -X(call_tail_call, 0x82, flag, 0, 0, 0)\ -X(call_target, 0x83, exprloc, 0, 0, 0)\ -X(call_target_clobbered, 0x84, exprloc, 0, 0, 0)\ -X(call_data_location, 0x85, exprloc, 0, 0, 0)\ -X(call_data_value, 0x86, exprloc, 0, 0, 0)\ -X(noreturn, 0x87, flag, 0, 0, 0)\ -X(alignment, 0x88, constant, 0, 0, 0)\ -X(export_symbols, 0x89, flag, 0, 0, 0)\ -X(deleted, 0x8a, flag, 0, 0, 0)\ -X(defaulted, 0x8b, constant, 0, 0, 0)\ -X(loclists_base, 0x8c, loclistsptr, 0, 0, 0)\ -X(lo_user, 0x2000, 0, 0, 0, 0)\ -X(hi_user, 0x3fff, 0, 0, 0, 0) - -typedef enum DWARF_AttributeName{ -#define X(N,C,f1,f2,f3,f4) DWARF_AttributeName_##N = C, - DWARF_AttributeNameXList(X) -#undef X -} DWARF_AttributeName; - - -// attribute forms: X(name, code, classflag) -#define DWARF_AttributeFormXList(X)\ -X(null, 0x00, 0)\ -X(addr, 0x01, address)\ -X(block2, 0x03, block)\ -X(block4, 0x04, block)\ -X(data2, 0x05, constant)\ -X(data4, 0x06, constant)\ -X(data8, 0x07, constant)\ -X(string, 0x08, string)\ -X(block, 0x09, block)\ -X(block1, 0x0a, block)\ -X(data1, 0x0b, constant)\ -X(flag, 0x0c, flag)\ -X(sdata, 0x0d, constant)\ -X(strp, 0x0e, string)\ -X(udata, 0x0f, constant)\ -X(ref_addr, 0x10, reference)\ -X(ref1, 0x11, reference)\ -X(ref2, 0x12, reference)\ -X(ref4, 0x13, reference)\ -X(ref8, 0x14, reference)\ -X(ref_udata, 0x15, reference)\ -X(indirect, 0x16, specialcase)\ -X(sec_offset, 0x17, sec_offset_classes)\ -X(exprloc, 0x18, exprloc)\ -X(flag_present, 0x19, flag)\ -X(strx, 0x1a, string)\ -X(addrx, 0x1b, address)\ -X(ref_sup4, 0x1c, reference)\ -X(strp_sup, 0x1d, string)\ -X(data16, 0x1e, constant)\ -X(line_strp, 0x1f, string)\ -X(ref_sig8, 0x20, reference)\ -X(implicit_const, 0x21, specialcase)\ -X(loclistx, 0x22, loclist)\ -X(rnglistx, 0x23, rnglist)\ -X(ref_sup8, 0x24, reference)\ -X(strx1, 0x25, string)\ -X(strx2, 0x26, string)\ -X(strx3, 0x27, string)\ -X(strx4, 0x28, string)\ -X(addrx1, 0x29, address)\ -X(addrx2, 0x2a, address)\ -X(addrx3, 0x2b, address)\ -X(addrx4, 0x2c, address) - -typedef enum DWARF_AttributeForm{ -#define X(N,C,f) DWARF_AttributeForm_##N = C, - DWARF_AttributeFormXList(X) -#undef X -} DWARF_AttributeForm; - - -// ops: X(name, code, opnum) -#define DWARF_OpXList(X)\ -X(addr, 0x03, 1)\ -X(deref, 0x06, 0)\ -X(const1u, 0x08, 1)\ -X(const1s, 0x09, 1)\ -X(const2u, 0x0a, 1)\ -X(const2s, 0x0b, 1)\ -X(const4u, 0x0c, 1)\ -X(const4s, 0x0d, 1)\ -X(const8u, 0x0e, 1)\ -X(const8s, 0x0f, 1)\ -X(constu, 0x10, 1)\ -X(consts, 0x11, 1)\ -X(dup, 0x12, 0)\ -X(drop, 0x13, 0)\ -X(over, 0x14, 0)\ -X(pick, 0x15, 1)\ -X(swap, 0x16, 0)\ -X(rot, 0x17, 0)\ -X(xderef, 0x18, 0)\ -X(abs, 0x19, 0)\ -X(and, 0x1a, 0)\ -X(div, 0x1b, 0)\ -X(minus, 0x1c, 0)\ -X(mod, 0x1d, 0)\ -X(mul, 0x1e, 0)\ -X(neg, 0x1f, 0)\ -X(not, 0x20, 0)\ -X(or, 0x21, 0)\ -X(plus, 0x22, 0)\ -X(plus_uconst, 0x23, 1)\ -X(shl, 0x24, 0)\ -X(shr, 0x25, 0)\ -X(shra, 0x26, 0)\ -X(xor, 0x27, 0)\ -X(bra, 0x28, 1)\ -X(eq, 0x29, 0)\ -X(ge, 0x2a, 0)\ -X(gt, 0x2b, 0)\ -X(le, 0x2c, 0)\ -X(lt, 0x2d, 0)\ -X(ne, 0x2e, 0)\ -X(skip, 0x2f, 1)\ -X(lit0, 0x30, 0)\ -X(lit1, 0x31, 0)\ -X(lit31, 0x4f, 0)\ -X(reg0, 0x50, 0)\ -X(reg1, 0x51, 0)\ -X(reg31, 0x6f, 0)\ -X(breg0, 0x70, 1)\ -X(breg1, 0x71, 1)\ -X(breg31, 0x8f, 1)\ -X(regx, 0x90, 1)\ -X(fbreg, 0x91, 1)\ -X(bregx, 0x92, 2)\ -X(piece, 0x93, 1)\ -X(deref_size, 0x94, 1)\ -X(xderef_size, 0x95, 1)\ -X(nop, 0x96, 0)\ -X(push_object_address, 0x97, 0)\ -X(call2, 0x98, 1)\ -X(call4, 0x99, 1)\ -X(call_ref, 0x9a, 1)\ -X(form_tls_address, 0x9b, 0)\ -X(call_frame_cfa, 0x9c, 0)\ -X(bit_piece, 0x9d, 2)\ -X(implicit_value, 0x9e, 2)\ -X(stack_value, 0x9f, 0)\ -X(implicit_pointer, 0xa0, 2)\ -X(addrx, 0xa1, 1)\ -X(constx, 0xa2, 1)\ -X(entry_value, 0xa3, 2)\ -X(const_type, 0xa4, 3)\ -X(regval_type, 0xa5, 2)\ -X(deref_type, 0xa6, 2)\ -X(xderef_type, 0xa7, 2)\ -X(convert, 0xa8, 1)\ -X(reinterpret, 0xa9, 1)\ -X(lo_user, 0xe0, 0)\ -X(hi_user, 0xff, 0) - -typedef enum DWARF_Op{ -#define X(N,C,k) DWARF_Op_##N = C, - DWARF_OpXList(X) -#undef X -} DWARF_Op; - - -// location list entry: X(name, code) -#define DWARF_LocationListEntryXList(X)\ -X(end_of_list, 0x00)\ -X(base_addressx, 0x01)\ -X(startx_endx, 0x02)\ -X(startx_length, 0x03)\ -X(offset_pair, 0x04)\ -X(default_location, 0x05)\ -X(base_address, 0x06)\ -X(start_end, 0x07)\ -X(start_length, 0x08) - -typedef enum DWARF_LocationListEntry{ -#define X(N,C) DWARF_LocationListEntry_##N = C, - DWARF_LocationListEntryXList(X) -#undef X -} DWARF_LocationListEntry; - - -// base type: X(name, code) -#define DWARF_BaseTypeXList(X)\ -X(address, 0x01)\ -X(boolean, 0x02)\ -X(complex_float, 0x03)\ -X(float, 0x04)\ -X(signed, 0x05)\ -X(signed_char, 0x06)\ -X(unsigned, 0x07)\ -X(unsigned_char, 0x08)\ -X(imaginary_float, 0x09)\ -X(packed_decimal, 0x0a)\ -X(numeric_string, 0x0b)\ -X(edited, 0x0c)\ -X(signed_fixed, 0x0d)\ -X(unsigned_fixed, 0x0e)\ -X(decimal_float, 0x0f)\ -X(UTF, 0x10)\ -X(UCS, 0x11)\ -X(ASCII, 0x12)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_BaseType{ -#define X(N,C) DWARF_BaseType_##N = C, - DWARF_BaseTypeXList(X) -#undef X -} DWARF_BaseType; - - -// decimal sign: X(name, code) -#define DWARF_DecimalSignXList(X)\ -X(unsigned, 0x01)\ -X(leading_overpunch, 0x02)\ -X(trailing_overpunch, 0x03)\ -X(leading_separate, 0x04)\ -X(trailing_separate, 0x05) - -typedef enum DWARF_DecimalSign{ -#define X(N,C) DWARF_DecimalSign_##N = C, - DWARF_DecimalSignXList(X) -#undef X -} DWARF_DecimalSign; - - -// endianity: X(name, code) -#define DWARF_EndianityXList(X)\ -X(default, 0x00)\ -X(big, 0x01)\ -X(little, 0x02)\ -X(lo_user, 0x40)\ -X(hi_user, 0xff) - -typedef enum DWARF_Endianity{ -#define X(N,C) DWARF_Endianity_##N = C, - DWARF_EndianityXList(X) -#undef X -} DWARF_Endianity; - - -// access: X(name, code) -#define DWARF_AccessXList(X)\ -X(public, 0x01)\ -X(protected, 0x02)\ -X(private, 0x03) - -typedef enum DWARF_Access{ -#define X(N,C) DWARF_Access_##N = C, - DWARF_AccessXList(X) -#undef X -} DWARF_Access; - - -// visibility: X(name, code) -#define DWARF_VisibilityXList(X)\ -X(local, 0x01)\ -X(exported, 0x02)\ -X(qualified, 0x03) - -typedef enum DWARF_Visibility{ -#define X(N,C) DWARF_Visibility_##N = C, - DWARF_VisibilityXList(X) -#undef X -} DWARF_Visibility; - - -// virtuality: X(name, code) -#define DWARF_VirtualityXList(X)\ -X(none, 0x00)\ -X(virtual, 0x01)\ -X(pure_virtual, 0x02) - -typedef enum DWARF_Virtuality{ -#define X(N,C) DWARF_Virtuality_##N = C, - DWARF_VirtualityXList(X) -#undef X -} DWARF_Virtuality; - - -// language: X(name, code, deflowerbound) -#define DWARF_LanguageXList(X)\ -X(C89, 0x0001, 0)\ -X(C, 0x0002, 0)\ -X(Ada83, 0x0003, 1)\ -X(C_plus_plus, 0x0004, 0)\ -X(Cobol74, 0x0005, 1)\ -X(Cobol85, 0x0006, 1)\ -X(Fortran77, 0x0007, 1)\ -X(Fortran90, 0x0008, 1)\ -X(Pascal83, 0x0009, 1)\ -X(Modula2, 0x000a, 1)\ -X(Java, 0x000b, 0)\ -X(C99, 0x000c, 0)\ -X(Ada95, 0x000d, 1)\ -X(Fortran95, 0x000e, 1)\ -X(PLI, 0x000f, 1)\ -X(ObjC, 0x0010, 0)\ -X(ObjC_plus_plus, 0x0011, 0)\ -X(UPC, 0x0012, 0)\ -X(D, 0x0013, 0)\ -X(Python, 0x0014, 0)\ -X(OpenCL, 0x0015, 0)\ -X(Go, 0x0016, 0)\ -X(Modula3, 0x0017, 1)\ -X(Haskell, 0x0018, 0)\ -X(C_plus_plus_03, 0x0019, 0)\ -X(C_plus_plus_11, 0x001a, 0)\ -X(OCaml, 0x001b, 0)\ -X(Rust, 0x001c, 0)\ -X(C11, 0x001d, 0)\ -X(Swift, 0x001e, 0)\ -X(Julia, 0x001f, 1)\ -X(Dylan, 0x0020, 0)\ -X(C_plus_plus_14, 0x0021, 0)\ -X(Fortran03, 0x0022, 1)\ -X(Fortran08, 0x0023, 1)\ -X(RenderScript, 0x0024, 0)\ -X(BLISS, 0x0025, 0)\ -X(lo_user, 0x8000, 0)\ -X(hi_user, 0xffff, 0) - -typedef enum DWARF_Language{ -#define X(N,C,k) DWARF_Language_##N = C, - DWARF_LanguageXList(X) -#undef X -} DWARF_Language; - - -// identifier case: X(name, code) -#define DWARF_IdentifierCaseXList(X)\ -X(case_sensitive, 0x00)\ -X(up_case, 0x01)\ -X(down_case, 0x02)\ -X(case_insensitive, 0x03) - -typedef enum DWARF_IdentifierCase{ -#define X(N,C) DWARF_IdentifierCase_##N = C, - DWARF_IdentifierCaseXList(X) -#undef X -} DWARF_IdentifierCase; - - -// calling convention: X(name, code) -#define DWARF_CallingConventionXList(X)\ -X(normal, 0x01)\ -X(program, 0x02)\ -X(nocall, 0x03)\ -X(pass_by_reference, 0x04)\ -X(pass_by_value, 0x05)\ -X(lo_user, 0x40)\ -X(hi_user, 0xff) - -typedef enum DWARF_CallingConvention{ -#define X(N,C) DWARF_CallingConvention_##N = C, - DWARF_CallingConventionXList(X) -#undef X -} DWARF_CallingConvention; - - -// inline: X(name, code) -#define DWARF_InlineXList(X)\ -X(not_inlined, 0x00)\ -X(inlined, 0x01)\ -X(declared_not_inlined, 0x02)\ -X(declared_inlined, 0x03) - -typedef enum DWARF_Inline{ -#define X(N,C) DWARF_Inline_##N = C, - DWARF_InlineXList(X) -#undef X -} DWARF_Inline; - - -// array ordering: X(name, code) -#define DWARF_ArrayOrderingXList(X)\ -X(row_major, 0x00)\ -X(col_major, 0x01) - -typedef enum DWARF_ArrayOrdering{ -#define X(N,C) DWARF_ArrayOrdering_##N = C, - DWARF_ArrayOrderingXList(X) -#undef X -} DWARF_ArrayOrdering; - - -// discriminant: X(name, code) -#define DWARF_DiscriminantXList(X)\ -X(label, 0x00)\ -X(range, 0x01) - -typedef enum DWARF_Discriminant{ -#define X(N,C) DWARF_Discriminant_##N = C, - DWARF_DiscriminantXList(X) -#undef X -} DWARF_Discriminant; - - -// name index: X(name, code) -#define DWARF_NameIndexXList(X)\ -X(compile_unit, 1)\ -X(type_unit, 2)\ -X(die_offset, 3)\ -X(parent, 4)\ -X(type_hash, 5)\ -X(lo_user, 0x2000)\ -X(hi_user, 0x3fff) - -typedef enum DWARF_NameIndex{ -#define X(N,C) DWARF_NameIndex_##N = C, - DWARF_NameIndexXList(X) -#undef X -} DWARF_NameIndex; - - -// defaulted: X(name, code) -#define DWARF_DefaultedXList(X)\ -X(no, 0x00)\ -X(in_class, 0x01)\ -X(out_of_class, 0x02) - -typedef enum DWARF_Defaulted{ -#define X(N,C) DWARF_Defaulted_##N = C, - DWARF_DefaultedXList(X) -#undef X -} DWARF_Defaulted; - -// call frame instruction: X(N, hi2bits, matchlow, low6bits, operand1, operand2) -// "CFA" -#define DWARF_CallFrameInsnXList(X)\ -X(advance_loc, 0x1, 0, 0, NULL, NULL)\ -X(offset, 0x2, 0, 0, ULEB, NULL)\ -X(restore, 0x3, 0, 0, NULL, NULL)\ -X(nop, 0x0, 1, 0, NULL, NULL)\ -X(set_loc, 0x0, 1, 0x01, ADDRESS, NULL)\ -X(advance_loc1, 0x0, 1, 0x02, 1BYTE, NULL)\ -X(advance_loc2, 0x0, 1, 0x03, 2BYTE, NULL)\ -X(advance_loc4, 0x0, 1, 0x04, 4BYTE, NULL)\ -X(offset_extended, 0x0, 1, 0x05, ULEB, ULEB)\ -X(restore_extended, 0x0, 1, 0x06, ULEB, NULL)\ -X(undefined, 0x0, 1, 0x07, ULEB, NULL)\ -X(same_value, 0x0, 1, 0x08, ULEB, NULL)\ -X(register, 0x0, 1, 0x09, ULEB, ULEB)\ -X(remember_state, 0x0, 1, 0x0a, NULL, NULL)\ -X(restore_state, 0x0, 1, 0x0b, NULL, NULL)\ -X(def_cfa, 0x0, 1, 0x0c, ULEB, ULEB)\ -X(def_cfa_register, 0x0, 1, 0x0d, ULEB, NULL)\ -X(def_cfa_offset, 0x0, 1, 0x0e, ULEB, NULL)\ -X(def_cfa_expression,0x0, 1, 0x0f, BLOCK, NULL)\ -X(expression, 0x0, 1, 0x10, ULEB, BLOCK)\ -X(offset_extended_sf,0x0, 1, 0x11, ULEB, SLEB)\ -X(def_cfa_sf, 0x0, 1, 0x12, ULEB, SLEB)\ -X(def_cfa_offset_sf, 0x0, 1, 0x13, SLEB, NULL)\ -X(val_offset, 0x0, 1, 0x14, ULEB, ULEB)\ -X(val_offset_sf, 0x0, 1, 0x15, ULEB, SLEB)\ -X(val_expression, 0x0, 1, 0x16, ULEB, BLOCK)\ -X(lo_user, 0x0, 1, 0x1c, NULL, NULL)\ -X(hi_user, 0x0, 1, 0x3f, NULL, NULL) - -// line number encoding codes -// (DWARF4.pdf + 7.21) (DWARF5.pdf + 7.22) - -// X(name, code) (V4 & V5) -#define DWARF_LineStdOpXList(X) \ -X(copy, 0x01)\ -X(advance_pc, 0x02)\ -X(advance_line, 0x03)\ -X(set_file, 0x04)\ -X(set_column, 0x05)\ -X(negate_stmt, 0x06)\ -X(set_basic_block, 0x07)\ -X(const_add_pc, 0x08)\ -X(fixed_advance_pc, 0x09)\ -X(set_prologue_end, 0x0a)\ -X(set_epilogue_begin, 0x0b)\ -X(set_isa, 0x0c) - -typedef enum DWARF_LineStdOp{ -#define X(N,C) DWARF_LineStdOp_##N = C, - DWARF_LineStdOpXList(X) -#undef X -} DWARF_LineStdOp; - -// X(name, code) (V4 & V5) -#define DWARF_LineExtOpXList(X) \ -X(end_sequence, 0x01)\ -X(set_address, 0x02)\ -X(define_file, 0x03)\ -X(set_discriminator, 0x04)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_LineExtOp{ -#define X(N,C) DWARF_LineExtOp_##N = C, - DWARF_LineExtOpXList(X) -#undef X -} DWARF_LineExtOp; - -// X(name, code) (V5) -#define DWARF_LineEntryFormatXList(X) \ -X(path, 0x1)\ -X(directory_index, 0x2)\ -X(timestamp, 0x3)\ -X(size, 0x4)\ -X(MD5, 0x5)\ -X(lo_user, 0x2000)\ -X(hi_user, 0x3fff) - -typedef enum DWARF_LineEntryFormat{ -#define X(N,C) DWARF_LineEntryFormat_##N = C, - DWARF_LineEntryFormatXList(X) -#undef X -} DWARF_LineEntryFormat; - -//////////////////////////////// -//~ Dwarf Parser Codes and Data Tables - -#define DWARF_SECTION_NAME_VARIANT_COUNT 3 - -// X(section_code_name, versionflags, section_name0, section_name1, section_name2) -#define DWARF_SectionNameXList(X,V4,V5)\ -X(Null, 0, "", "", "")\ -X(Loc, V4, ".debug_loc", ".debug_loc.dwo", "__debug_loc")\ -X(Str, V4|V5, ".debug_str", ".debug_str.dwo", "__debug_str")\ -X(LineStr, V5, ".debug_line_str", ".debug_line_str.dwo", "__debug_line_str")\ -X(CmpUnitIdx, V5, ".debug_cu_index", ".debug_cu_index.dwo", "__debug_cu_index")\ -X(TypeIdx, V5, ".debug_tu_index", ".debug_tu_index.dwo", "__debug_tu_index")\ -X(Supplement, V5, ".debug_sup", ".debug_sup.dwo", "__debug_sup")\ -X(Info, V4|V5, ".debug_info", ".debug_info.dwo", "__debug_info")\ -X(Abbrev, V4|V5, ".debug_abbrev", ".debug_abbrev.dwo", "__debug_abbrev")\ -X(PubNames, V4, ".debug_pubnames", ".debug_pubnames.dwo", "__debug_pubnames")\ -X(PubTypes, V4, ".debug_pubtypes", ".debug_pubtypes.dwo", "__debug_pubtypes")\ -X(Names, V5, ".debug_names", ".debug_names.dwo", "__debug_names")\ -X(Aranges, V4|V5, ".debug_aranges", ".debug_aranges.dwo", "__debug_aranges")\ -X(Line, V4|V5, ".debug_line", ".debug_line.dwo", "__debug_line")\ -X(MacInfo, V4, ".debug_macinfo", ".debug_macinfo.dwo", "__debug_macinfo")\ -X(Macro, V5, ".debug_macro", ".debug_macro.dwo", "__debug_macro")\ -X(Frame, V4|V5, ".debug_frame", ".debug_frame.dwo", "__debug_frame")\ -X(Ranges, V4, ".debug_ranges", ".debug_ranges.dwo", "__debug_ranges")\ -X(StrOffsets, V5, ".debug_str_offsets", ".debug_str_offsets.dwo", "__debug_str_offsets")\ -X(Addr, V5, ".debug_addr", ".debug_addr.dwo", "__debug_addr")\ -X(RngLists, V5, ".debug_rnglists", ".debug_rnglists.dwo", "__debug_rnglists")\ -X(LocLists, V5, ".debug_loclists", ".debug_loclists.dwo", "__debug_loclists") - - -typedef enum DWARF_SectionCode{ -#define X(c,vf,n0,n1,n2) DWARF_SectionCode_##c, - DWARF_SectionNameXList(X,0,0) -#undef X - DWARF_SectionCode_COUNT -} DWARF_SectionCode; - -typedef struct DWARF_SectionNameRow{ - String8 name[DWARF_SECTION_NAME_VARIANT_COUNT]; -} DWARF_SectionNameRow; - -read_only global DWARF_SectionNameRow dwarf_section_name_table[] = { -#define X(c,vf,n0,n1,n2) \ -{ { str8_lit_comp(n0), str8_lit_comp(n1), str8_lit_comp(n2) } }, - DWARF_SectionNameXList(X,0,0) -#undef X -}; - - -#pragma pack(pop) - - -//////////////////////////////// -//~ Dwarf Parser Types - -typedef struct DWARF_Parsed{ - ELF_Parsed *elf; - U32 debug_section_idx[DWARF_SectionCode_COUNT]; - String8 debug_section_name[DWARF_SectionCode_COUNT]; - String8 debug_data[DWARF_SectionCode_COUNT]; -} DWARF_Parsed; - - -// form decoding - -typedef struct DWARF_FormDecodeRules{ - union{ - // form decode fields - struct{ - U8 size; - B8 uleb128; - B8 sleb128; - B8 in_abbrev; - B8 auto_1; - B8 block; - B8 null_terminated; - }; - - // for alignment and padding to 8 - U64 x; - }; -} DWARF_FormDecodeRules; - -typedef struct DWARF_FormDecoded{ - U64 val; - U8 *dataptr; - B32 error; -} DWARF_FormDecoded; - - -// index section: .debug_cu_index .debug_tu_index -// (DWARF5.pdf + 7.3.5) - -// ** not implemented yet ** - -typedef struct DWARF_IndexParsed{ - U32 dummy; -} DWARF_IndexParsed; - - -// supplementary section: .debug_sup -// (DWARF5.pdf + 7.3.6) - -// ** not implemented yet ** - -typedef struct DWARF_SupParsed{ - U32 dummy; -} DWARF_SupParsed; - - -// info section: .debug_info -// (DWARF4.pdb + 7.5) (DWARF5.pdf + 7.5) - -typedef struct DWARF_InfoAttribVal{ - U64 val; - U8 *dataptr; -} DWARF_InfoAttribVal; - -typedef struct DWARF_InfoEntry{ - struct DWARF_InfoEntry *next_sibling; - struct DWARF_InfoEntry *first_child; - struct DWARF_InfoEntry *last_child; - U64 child_count; - struct DWARF_InfoEntry *parent; - - U64 info_offset; - struct DWARF_AbbrevDecl *abbrev_decl; - DWARF_InfoAttribVal *attrib_vals; -} DWARF_InfoEntry; - -#if 0 -typedef struct DWARF_InfoUnit{ - struct DWARF_InfoUnit *next; - - // header - U32 version; - U32 offset_size; - U32 address_size; - - // root attributes - DWARF_Language language; - U64 line_info_offset; - U64 vbase; - U64 str_offsets_base; - U64 addr_base; - U64 rnglists_base; - U64 loclists_base; - - // info entries - DWARF_InfoEntry *entry_root; - U64 entry_count; -} DWARF_InfoUnit; -#endif - -#if 0 -typedef struct DWARF_InfoParams{ - U64 unit_idx_min; - U64 unit_idx_max; -} DWARF_InfoParams; -#endif - -typedef struct DWARF_InfoUnit{ - struct DWARF_InfoUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 version; - U8 unit_type; // (DWARF_UnitType) - U8 address_size; - U64 abbrev_off; - - union{ - // unit_type: skeleton, split_compile - U64 dwo_id; - // unit_type: type, split_type - struct{ - U64 type_signature; - U64 type_offset; - }; - }; -} DWARF_InfoUnit; - -typedef struct DWARF_InfoParsed{ - DWARF_InfoUnit *unit_first; - DWARF_InfoUnit *unit_last; - U64 unit_count; -} DWARF_InfoParsed; - - -// abbreviations section: .debug_abbrev -// (DWARF4.pdf + 7.5.3) (DWARF5.pdf + 7.5.3) - -typedef struct DWARF_AbbrevAttribSpec{ - DWARF_AttributeName name; - DWARF_AttributeForm form; -} DWARF_AbbrevAttribSpec; - -typedef struct DWARF_AbbrevDecl{ - struct DWARF_AbbrevDecl *next; - U32 abbrev_code; - DWARF_Tag tag; - B8 has_children; - U8 __filler__; - U16 attrib_count; - DWARF_AbbrevAttribSpec *attrib_specs; - S64 *implicit_const; -} DWARF_AbbrevDecl; - -typedef struct DWARF_AbbrevUnit{ - struct DWARF_AbbrevUnit *next; - U64 offset; - DWARF_AbbrevDecl *first; - DWARF_AbbrevDecl *last; - U64 count; -} DWARF_AbbrevUnit; - -#if 0 -typedef struct DWARF_AbbrevParams{ - U64 unit_idx_min; - U64 unit_idx_max; -} DWARF_AbbrevParams; -#endif - -typedef struct DWARF_AbbrevParsed{ - DWARF_AbbrevUnit *unit_first; - DWARF_AbbrevUnit *unit_last; - U64 unit_count; - B32 decoding_error; -} DWARF_AbbrevParsed; - - -// name lookup tables (V4): .debug_pubnames .debug_pubtypes -// (DWARF4.pdf + 7.19) - -typedef struct DWARF_PubNamesUnit{ - struct DWARF_PubNamesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 version; - U64 info_off; - U64 info_length; -} DWARF_PubNamesUnit; - -typedef struct DWARF_PubNamesParsed{ - DWARF_PubNamesUnit *unit_first; - DWARF_PubNamesUnit *unit_last; - U64 unit_count; -} DWARF_PubNamesParsed; - - -// name lookup tables (V5): .debug_names -// (DWARF5.pdf + 6.1.1.4.1 & 7.19) - -typedef struct DWARF_NamesUnit{ - struct DWARF_NamesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - U32 comp_unit_count; - U32 local_type_unit_count; - U32 foreign_type_unit_count; - U32 bucket_count; - U32 name_count; - U32 abbrev_table_size; - String8 augmentation_string; - -} DWARF_NamesUnit; - -typedef struct DWARF_NamesParsed{ - DWARF_NamesUnit *unit_first; - DWARF_NamesUnit *unit_last; - U64 unit_count; -} DWARF_NamesParsed; - - -// address range table: .debug_aranges -// (DWARF4.pdf + 7.20) (DWARF5.pdf + 7.21) - -typedef struct DWARF_ArangesUnit{ - struct DWARF_ArangesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - U8 address_size; - U8 segment_selector_size; - U8 offset_size; - U64 info_off; -} DWARF_ArangesUnit; - -typedef struct DWARF_ArangesParsed{ - DWARF_ArangesUnit *unit_first; - DWARF_ArangesUnit *unit_last; - U64 unit_count; -} DWARF_ArangesParsed; - - -// line number information: .debug_line -// (DWARF4.pdf + 6.2.4 & 7.21) (DWARF5.pdf + 6.2.4 & 7.22) - -typedef struct DWARF_V4LineFileNamesEntry{ - struct DWARF_V4LineFileNamesEntry *next; - String8 file_name; - U64 include_directory_idx; - U64 last_modified_time; - U64 file_size; -} DWARF_V4LineFileNamesEntry; - -typedef struct DWARF_V4LineFileNamesList{ - DWARF_V4LineFileNamesEntry *first; - DWARF_V4LineFileNamesEntry *last; - U64 count; -} DWARF_V4LineFileNamesList; - -typedef struct DWARF_V5LinePathEntryFormat{ - U32 content_type; /* DWARF_LineEntryFormat */ - U32 form; /* DWARF_AttributeForm */ -} DWARF_V5LinePathEntryFormat; - -typedef struct DWARF_V5Directory{ - String8 path_str; - U64 path_off; - U64 path_sec_form; - U64 directory_index; - U64 timestamp; - U64 size; - U8 md5_checksum[16]; -} DWARF_V5Directory; - -typedef struct DWARF_LineUnit{ - struct DWARF_LineUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - -} DWARF_LineUnit; - -typedef struct DWARF_LineParsed{ - DWARF_LineUnit *unit_first; - DWARF_LineUnit *unit_last; - U64 unit_count; -} DWARF_LineParsed; - - -// macro information (V4): .debug_macinfo -// (DWARF4.pdf + 7.22) - -// ** not implemented yet ** - -typedef struct DWARF_MacInfoParsed{ - U32 dummy; -} DWARF_MacInfoParsed; - - -// macro information (V5): .debug_macro -// (DWARF5.pdf + 7.23) - -// ** not implemented yet ** - -typedef struct DWARF_MacroParsed{ - U32 dummy; -} DWARF_MacroParsed; - - -// call frame information: .debug_frame -// (DWARF4.pdf + 7.23) (DWARF5.pdf + 7.24) - -// ** not implemented yet ** - -typedef struct DWARF_FrameParsed{ - U32 dummy; -} DWARF_FrameParsed; - - -// range lists (V4): .debug_ranges -// (DWARF4.pdf + 7.24) - -// ** not implemented yet ** - -typedef struct DWARF_RangesParsed{ - U32 dummy; -} DWARF_RangesParsed; - - -// string offsets table: .debug_str_offsets -// (DWARF5.pdf + 7.26) - -// ** not implemented yet ** - -typedef struct DWARF_StrOffsetsParsed{ - U32 dummy; -} DWARF_StrOffsetsParsed; - - -// address table: .debug_addr -// (DWARF5.pdf + 7.27) - -typedef struct DWARF_AddrUnit{ - struct DWARF_AddrUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 dwarf_version; - U8 address_size; - U8 segment_selector_size; -} DWARF_AddrUnit; - -typedef struct DWARF_AddrParsed{ - DWARF_AddrUnit *unit_first; - DWARF_AddrUnit *unit_last; - U64 unit_count; -} DWARF_AddrParsed; - - -// range lists (V5): .debug_rnglists -// (DWARF5.pdf + 7.28 & 7.25) - -// ** not implemented yet ** - -typedef struct DWARF_RngListsParsed{ - U32 dummy; -} DWARF_RngListsParsed; - - -// location lists: .debug_loclists -// (DWARF5.pdf + 7.29) - -// ** not implemented yet ** - -typedef struct DWARF_LocListsParsed{ - U32 dummy; -} DWARF_LocListsParsed; - - -//////////////////////////////// -//~ Dwarf Decode Helpers - -#define DWARF_LEB128_ADV(p,o,s) do{ (s)=1; for(;; (p)+=1){\ -if ((p) == (o)) { (s)=0; break; } \ -if (((*(p))&0x80) == 0) { (p)+=1; break; } \ -} }while(0) - -#define DWARF_LEB128_ADV_NOCAP(p) for((p)+=1; ((*(p-1))&0x80) != 0; (p)+=1) - -static U64 dwarf_leb128_decode_U64(U8 *ptr, U8 *opl); -static S64 dwarf_leb128_decode_S64(U8 *ptr, U8 *opl); -static U32 dwarf_leb128_decode_U32(U8 *ptr, U8 *opl); - -#define dwarf_leb128_decode(T,ptr,opl) dwarf_leb128_decode_##T(ptr,opl) - -#define DWARF_LEB128_DECODE_ADV(T,x,p,o) do{ \ -U8 *first__ = (p); B32 success__; \ -DWARF_LEB128_ADV(p,o,success__); \ -if (success__) \ -(x) = dwarf_leb128_decode(T,first__, (p)); \ -}while(0) - - -//////////////////////////////// -//~ allen: ELF/DW Unwind Types -// -// TODO(rjf): OLD TYPES FROM UNWINDER CODE. bucketing this here, and deferring dwarf-based -// unwinding info to future DWARF/linux work. -// -#if 0 - -// * applies to (any X: unwind(ELF/DW, X)) - -// EH: Exception Frames -typedef U8 UNW_DW_EhPtrEnc; -enum{ - UNW_DW_EhPtrEnc_TYPE_MASK = 0x0F, - UNW_DW_EhPtrEnc_PTR = 0x00, // Pointer sized unsigned value - UNW_DW_EhPtrEnc_ULEB128 = 0x01, // Unsigned LE base-128 value - UNW_DW_EhPtrEnc_UDATA2 = 0x02, // Unsigned 16-bit value - UNW_DW_EhPtrEnc_UDATA4 = 0x03, // Unsigned 32-bit value - UNW_DW_EhPtrEnc_UDATA8 = 0x04, // Unsigned 64-bit value - UNW_DW_EhPtrEnc_SIGNED = 0x08, // Signed pointer - UNW_DW_EhPtrEnc_SLEB128 = 0x09, // Signed LE base-128 value - UNW_DW_EhPtrEnc_SDATA2 = 0x0A, // Signed 16-bit value - UNW_DW_EhPtrEnc_SDATA4 = 0x0B, // Signed 32-bit value - UNW_DW_EhPtrEnc_SDATA8 = 0x0C, // Signed 64-bit value -}; -enum{ - UNW_DW_EhPtrEnc_MODIF_MASK = 0x70, - UNW_DW_EhPtrEnc_PCREL = 0x10, // Value is relative to the current program counter. - UNW_DW_EhPtrEnc_TEXTREL = 0x20, // Value is relative to the .text section. - UNW_DW_EhPtrEnc_DATAREL = 0x30, // Value is relative to the .got or .eh_frame_hdr section. - UNW_DW_EhPtrEnc_FUNCREL = 0x40, // Value is relative to the function. - UNW_DW_EhPtrEnc_ALIGNED = 0x50, // Value is aligned to an address unit sized boundary. -}; -enum{ - UNW_DW_EhPtrEnc_INDIRECT = 0x80, // This flag indicates that value is stored in virtual memory. - UNW_DW_EhPtrEnc_OMIT = 0xFF, -}; - -typedef struct UNW_DW_EhPtrCtx{ - U64 raw_base_vaddr; // address where pointer is being read - U64 text_vaddr; // base address of section with instructions (used for encoding pointer on SH and IA64) - U64 data_vaddr; // base address of data section (used for encoding pointer on x86-64) - U64 func_vaddr; // base address of function where IP is located -} UNW_DW_EhPtrCtx; - -// CIE: Common Information Entry -typedef struct UNW_DW_CIEUnpacked{ - U8 version; - UNW_DW_EhPtrEnc lsda_encoding; - UNW_DW_EhPtrEnc addr_encoding; - - B8 has_augmentation_size; - U64 augmentation_size; - String8 augmentation; - - U64 code_align_factor; - S64 data_align_factor; - U64 ret_addr_reg; - - U64 handler_ip; - - U64 cfi_range_min; - U64 cfi_range_max; -} UNW_DW_CIEUnpacked; - -typedef struct UNW_DW_CIEUnpackedNode{ - struct UNW_DW_CIEUnpackedNode *next; - UNW_DW_CIEUnpacked cie; - U64 offset; -} UNW_DW_CIEUnpackedNode; - -// FDE: Frame Description Entry -typedef struct UNW_DW_FDEUnpacked{ - U64 ip_voff_min; - U64 ip_voff_max; - U64 lsda_ip; - - U64 cfi_range_min; - U64 cfi_range_max; -} UNW_DW_FDEUnpacked; - -// CFI: Call Frame Information -typedef struct UNW_DW_CFIRecords{ - B32 valid; - UNW_DW_CIEUnpacked cie; - UNW_DW_FDEUnpacked fde; -} UNW_DW_CFIRecords; - -typedef enum UNW_DW_CFICFARule{ - UNW_DW_CFICFARule_REGOFF, - UNW_DW_CFICFARule_EXPR, -} UNW_DW_CFICFARule; - -typedef struct UNW_DW_CFICFACell{ - UNW_DW_CFICFARule rule; - union{ - struct{ - U64 reg_idx; - S64 offset; - }; - U64 expr_min; - U64 expr_max; - }; -} UNW_DW_CFICFACell; - -typedef enum UNW_DW_CFIRegisterRule{ - UNW_DW_CFIRegisterRule_SAME_VALUE, - UNW_DW_CFIRegisterRule_UNDEFINED, - UNW_DW_CFIRegisterRule_OFFSET, - UNW_DW_CFIRegisterRule_VAL_OFFSET, - UNW_DW_CFIRegisterRule_REGISTER, - UNW_DW_CFIRegisterRule_EXPRESSION, - UNW_DW_CFIRegisterRule_VAL_EXPRESSION, -} UNW_DW_CFIRegisterRule; - -typedef struct UNW_DW_CFICell{ - UNW_DW_CFIRegisterRule rule; - union{ - S64 n; - struct{ - U64 expr_min; - U64 expr_max; - }; - }; -} UNW_DW_CFICell; - -typedef struct UNW_DW_CFIRow{ - struct UNW_DW_CFIRow *next; - UNW_DW_CFICell *cells; - UNW_DW_CFICFACell cfa_cell; -} UNW_DW_CFIRow; - -typedef struct UNW_DW_CFIMachine{ - U64 cells_per_row; - UNW_DW_CIEUnpacked *cie; - UNW_DW_EhPtrCtx *ptr_ctx; - UNW_DW_CFIRow *initial_row; - U64 fde_ip; -} UNW_DW_CFIMachine; - -typedef U8 UNW_DW_CFADecode; -enum{ - UNW_DW_CFADecode_NOP = 0x0, - // 1,2,4,8 reserved for literal byte sizes - UNW_DW_CFADecode_ADDRESS = 0x9, - UNW_DW_CFADecode_ULEB128 = 0xA, - UNW_DW_CFADecode_SLEB128 = 0xB, -}; - -typedef U16 UNW_DW_CFAControlBits; -enum{ - UNW_DW_CFAControlBits_DEC1_MASK = 0x00F, - UNW_DW_CFAControlBits_DEC2_MASK = 0x0F0, - UNW_DW_CFAControlBits_IS_REG_0 = 0x100, - UNW_DW_CFAControlBits_IS_REG_1 = 0x200, - UNW_DW_CFAControlBits_IS_REG_2 = 0x400, - UNW_DW_CFAControlBits_NEW_ROW = 0x800, -}; -#endif - -//////////////////////////////// -//~ Dwarf Parser Functions - -static DWARF_Parsed* dwarf_parsed_from_elf(Arena *arena, ELF_Parsed *elf); - -static DWARF_IndexParsed* dwarf_index_from_data(Arena *arena, String8 data); -static DWARF_SupParsed* dwarf_sup_from_data(Arena *arena, String8 data); -static DWARF_InfoParsed* dwarf_info_from_data(Arena *arena, String8 data); -static DWARF_PubNamesParsed* dwarf_pubnames_from_data(Arena *arena, String8 data); -static DWARF_NamesParsed* dwarf_names_from_data(Arena *arena, String8 data); -static DWARF_ArangesParsed* dwarf_aranges_from_data(Arena *arena, String8 data); -static DWARF_LineParsed* dwarf_line_from_data(Arena *arena, String8 data); -static DWARF_MacInfoParsed* dwarf_mac_info_from_data(Arena *arena, String8 data); -static DWARF_MacroParsed* dwarf_macro_from_data(Arena *arena, String8 data); -static DWARF_FrameParsed* dwarf_frame_from_data(Arena *arena, String8 data); -static DWARF_RangesParsed* dwarf_ranges_from_data(Arena *arena, String8 data); -static DWARF_StrOffsetsParsed* dwarf_str_offsets_from_data(Arena *arena, String8 data); -static DWARF_AddrParsed* dwarf_addr_from_data(Arena *arena, String8 data); -static DWARF_RngListsParsed* dwarf_rng_lists_from_data(Arena *arena, String8 data); -static DWARF_LocListsParsed* dwarf_loc_lists_from_data(Arena *arena, String8 data); - - -// parse helpers - -// (DWARF4.pdf + 7.2.2) (DWARF5.pdf + 7.2.2) -static void dwarf__initial_length(String8 data, - U8 **ptr_inout, U8 **unit_opl_out, B32 *is_64bit_out); - -static void -dwarf__line_v5_directories(U64 address_size, U64 offset_size, - DWARF_V5LinePathEntryFormat *format, U64 format_count, - DWARF_V5Directory *directories_out, U64 dir_count, - U8 **ptr_io, U8 *opl); - -// debug sections - -static String8 dwarf_name_from_debug_section(DWARF_Parsed *dwarf, DWARF_SectionCode sec_code); - -// abbrev functions - -static DWARF_AbbrevUnit* dwarf_abbrev_unit_from_offset(DWARF_AbbrevParsed *abbrev, U64 off); -static DWARF_AbbrevDecl* dwarf_abbrev_decl_from_code(DWARF_AbbrevUnit *unit, U32 code); - -// attribute decoding functions - -static DWARF_AttributeClassFlags dwarf_attribute_class_from_form(DWARF_AttributeForm form); -static DWARF_AttributeClassFlags dwarf_attribute_class_from_name(DWARF_AttributeName name); - -// form decoding functions - -static DWARF_FormDecodeRules -dwarf_form_decode_rule(DWARF_AttributeForm form, U64 address_size, U64 offset_size); - -static DWARF_FormDecoded -dwarf_form_decode(DWARF_FormDecodeRules *rules, U8 **ptr_io, U8 *opl, - DWARF_AbbrevDecl *abbrev_decl, U32 attrib_i); - -// string functions - -static String8 dwarf_string_from_unit_type(DWARF_UnitType type); -static String8 dwarf_string_from_tag(DWARF_Tag tag); -static String8 dwarf_string_from_attribute_name(DWARF_AttributeName name); -static String8 dwarf_string_from_attribute_form(DWARF_AttributeForm form); -static String8 dwarf_string_from_line_std_op(DWARF_LineStdOp op); -static String8 dwarf_string_from_line_ext_op(DWARF_LineExtOp op); -static String8 dwarf_string_from_line_entry_format(DWARF_LineEntryFormat format); -static String8 dwarf_string_from_section_code(DWARF_SectionCode sec_code); - -#endif //RDI_DWARF_H - diff --git a/src/rdi_from_dwarf/rdi_dwarf_stringize.c b/src/rdi_from_dwarf/rdi_dwarf_stringize.c deleted file mode 100644 index 67865813..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf_stringize.c +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ DWARF Stringize Functions - -static char dwarf_spaces[] = " "; - -static void -dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent){ - String8 unit_type_string = dwarf_string_from_unit_type((DWARF_UnitType)unit->unit_type); - - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, - unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*sunit_type=%.*s\n", indent, dwarf_spaces, - str8_varg(unit_type_string)); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*sabbrev_off=0x%llx\n", indent, dwarf_spaces, - unit->abbrev_off); - - switch (unit->unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - str8_list_pushf(arena, out, "%.*sdwo_id=%llu\n", indent, dwarf_spaces, unit->dwo_id); - }break; - - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - str8_list_pushf(arena, out, "%.*stype_signature=%llu\n", indent, dwarf_spaces, - unit->type_signature); - str8_list_pushf(arena, out, "%.*stype_offset=%llu\n", indent, dwarf_spaces, - unit->type_offset); - }break; - } -} - -static void -dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit, - U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off); - str8_list_pushf(arena, out, "%.*sinfo_length=0x%llx\n", indent, dwarf_spaces, - unit->info_length); -} - -static void -dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*scomp_unit_count=%u\n", indent, dwarf_spaces, - unit->comp_unit_count); - str8_list_pushf(arena, out, "%.*slocal_type_unit_count=%u\n", indent, dwarf_spaces, - unit->local_type_unit_count); - str8_list_pushf(arena, out, "%.*sforeign_type_unit_count=%u\n", indent, dwarf_spaces, - unit->foreign_type_unit_count); - str8_list_pushf(arena, out, "%.*sbucket_count=%u\n", indent, dwarf_spaces, - unit->bucket_count); - str8_list_pushf(arena, out, "%.*sname_count=%u\n", indent, dwarf_spaces, unit->name_count); - str8_list_pushf(arena, out, "%.*sabbrev_table_size=%u\n", indent, dwarf_spaces, - unit->abbrev_table_size); - str8_list_pushf(arena, out, "%.*saugmentation_string=%.*s\n", indent, dwarf_spaces, - str8_varg(unit->augmentation_string)); -} - -static void -dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces, - unit->segment_selector_size); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size); - str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off); -} - -static void -dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, - unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->dwarf_version); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces, - unit->segment_selector_size); -} diff --git a/src/rdi_from_dwarf/rdi_dwarf_stringize.h b/src/rdi_from_dwarf/rdi_dwarf_stringize.h deleted file mode 100644 index 30a13254..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf_stringize.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_DWARF_STRINGIZE_H -#define RDI_DWARF_STRINGIZE_H - -//////////////////////////////// -//~ DWARF Stringize Functions - -static void -dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent); - -static void -dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit, - U32 indent); - -static void -dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent); - -static void -dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent); - -static void -dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent); - - - -#endif //RDI_DWARF_STRINGIZE_H diff --git a/src/rdi_from_dwarf/rdi_elf.c b/src/rdi_from_dwarf/rdi_elf.c deleted file mode 100644 index bda90ef1..00000000 --- a/src/rdi_from_dwarf/rdi_elf.c +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ ELF Parser Functions - -static ELF_Parsed* -elf_parsed_from_data(Arena *arena, String8 elf_data){ - //- test magic number - B32 has_good_magic_number = 0; - if (elf_data.size >= sizeof(ELF_NIDENT) && - MemoryMatch(elf_data.str, elf_magic, sizeof(elf_magic))){ - has_good_magic_number = 1; - } - - //- determine elf class - U8 elf_class = ELF_Class_NONE; - if (has_good_magic_number){ - elf_class = elf_data.str[ELF_Identification_CLASS]; - } - - //- extract header information - B32 decoded_header = 0; - - U8 e_data_encoding = ELF_DataEncoding_NONE; - U16 e_machine = ELF_Machine_NONE; - - U64 e_entry = 0; - - U64 e_shoff = 0; - U16 e_shentsize = 0; - U16 e_shnum = 0; - - U64 e_phoff = 0; - U16 e_phentsize = 0; - U16 e_phnum = 0; - - U16 e_shstrndx = 0; - - switch (elf_class){ - case ELF_Class_NONE: /* not good */ break; - - case ELF_Class_32: - { - if (elf_data.size >= sizeof(ELF_Ehdr32)){ - ELF_Ehdr32 *hdr = (ELF_Ehdr32*)elf_data.str; - - decoded_header = 1; - e_data_encoding = hdr->e_ident[ELF_Identification_DATA]; - e_machine = hdr->e_machine; - e_entry = hdr->e_entry; - e_phoff = hdr->e_phoff; - e_shoff = hdr->e_shoff; - e_phentsize = hdr->e_phentsize; - e_phnum = hdr->e_phnum; - e_shentsize = hdr->e_shentsize; - e_shnum = hdr->e_shnum; - e_shstrndx = hdr->e_shstrndx; - } - }break; - - case ELF_Class_64: - { - if (elf_data.size >= sizeof(ELF_Ehdr64)){ - ELF_Ehdr64 *hdr = (ELF_Ehdr64*)elf_data.str; - - decoded_header = 1; - e_data_encoding = hdr->e_ident[ELF_Identification_DATA]; - e_machine = hdr->e_machine; - e_entry = hdr->e_entry; - e_phoff = hdr->e_phoff; - e_shoff = hdr->e_shoff; - e_phentsize = hdr->e_phentsize; - e_phnum = hdr->e_phnum; - e_shentsize = hdr->e_shentsize; - e_shnum = hdr->e_shnum; - e_shstrndx = hdr->e_shstrndx; - } - }break; - } - - //- validate & translate header values - B32 header_is_good = 0; - Arch arch = Arch_Null; - if (decoded_header){ - header_is_good = 1; - - // only supporting little-endian versions right now - if (header_is_good){ - if (e_data_encoding != ELF_DataEncoding_2LSB){ - header_is_good = 0; - } - } - - // make sure this is a supported machine type - if (header_is_good){ - switch (e_machine){ - default: header_is_good = 0; - case ELF_Machine_386: arch = Arch_x86; break; - case ELF_Machine_X86_64: arch = Arch_x64; break; - } - } - - // make sure section & segment sizes are correct - if (header_is_good){ - switch (elf_class){ - case ELF_Class_32: - { - if (e_shentsize != sizeof(ELF_Shdr32) || - e_phentsize != sizeof(ELF_Phdr32)){ - header_is_good = 0; - } - }break; - case ELF_Class_64: - { - if (e_shentsize != sizeof(ELF_Shdr64) || - e_phentsize != sizeof(ELF_Phdr64)){ - header_is_good = 0; - } - }break; - } - } - } - - //- extract extra information from the special first section - U64 section_count_raw = e_shnum; - U32 section_header_string_table_index = e_shstrndx; - if (header_is_good){ - if (e_shoff <= elf_data.size && e_shentsize <= elf_data.size && - e_shoff + e_shentsize <= elf_data.size){ - U64 size = 0; - U32 link = 0; - switch (elf_class){ - case ELF_Class_32: - { - ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + e_shoff); - size = shdr->sh_size; - link = shdr->sh_link; - }break; - case ELF_Class_64: - { - ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + e_shoff); - size = shdr->sh_size; - link = shdr->sh_link; - }break; - } - - // extended section count - if (size != 0){ - section_count_raw = size; - } - - // extended section header string table index - if (link != 0){ - section_header_string_table_index = link; - } - } - } - - //- clamp section & program arrays to size - U64 section_foff = 0; - U64 section_size = 0; - U64 section_count = 0; - - U64 segment_foff = 0; - U64 segment_size = 0; - U64 segment_count = 0; - - if (header_is_good){ - if (e_shentsize > 0){ - U64 section_opl_raw = e_shoff + e_shentsize*section_count_raw; - U64 section_opl = ClampTop(section_opl_raw, elf_data.size); - if (section_opl > e_shoff){ - section_foff = e_shoff; - section_size = e_shentsize; - section_count = (section_opl - e_shoff)/e_shentsize; - } - } - - if (e_phentsize > 0){ - U64 segment_opl_raw = e_phoff + e_phentsize*e_phnum; - U64 segment_opl = ClampTop(segment_opl_raw, elf_data.size); - if (segment_opl > e_phoff){ - segment_foff = e_phoff; - segment_size = e_phentsize; - segment_count = (segment_opl - e_phoff)/e_phentsize; - } - } - } - - //- determine the vbase for this file - U64 vbase = 0; - if (header_is_good){ - // find the first LOAD segment - U64 load_segment_off = 0; - { - U64 segment_cursor = segment_foff; - U64 segment_opl = segment_foff + segment_size*segment_count; - for (;segment_cursor < segment_opl; segment_cursor += segment_size){ - U32 p_type = *(U32*)(elf_data.str + segment_cursor); - if (p_type == ELF_SegmentType_LOAD){ - load_segment_off = segment_cursor; - break; - } - } - } - - // use the segment's p_vaddr to determine vbase - if (load_segment_off != 0){ - switch (elf_class){ - case ELF_Class_32: - { - ELF_Phdr32 *phdr = (ELF_Phdr32*)(elf_data.str + load_segment_off); - vbase = phdr->p_vaddr; - }break; - case ELF_Class_64: - { - ELF_Phdr64 *phdr = (ELF_Phdr64*)(elf_data.str + load_segment_off); - vbase = phdr->p_vaddr; - }break; - } - } - } - - //- locate the section header string table - U64 section_name_table_foff = 0; - U64 section_name_table_opl = 0; - if (header_is_good){ - if (section_header_string_table_index < section_count){ - U64 sec_foff = section_foff + section_header_string_table_index*section_size; - switch (elf_class){ - case ELF_Class_32: - { - ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + sec_foff); - section_name_table_foff = shdr->sh_offset; - section_name_table_opl = shdr->sh_offset + shdr->sh_size; - }break; - case ELF_Class_64: - { - ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + sec_foff); - section_name_table_foff = shdr->sh_offset; - section_name_table_opl = shdr->sh_offset + shdr->sh_size; - }break; - } - } - } - - //- format sections data - ELF_Shdr64 *sections = 0; - if (header_is_good && section_count > 0){ - switch (elf_class){ - case ELF_Class_32: - { - sections = push_array(arena, ELF_Shdr64, section_count); - { - ELF_Shdr32 *shdr32 = (ELF_Shdr32*)(elf_data.str + section_foff); - ELF_Shdr64 *shdr64 = sections; - for (U64 i = 0; i < section_count; i += 1, shdr32 += 1, shdr64 += 1){ - shdr64->sh_name = shdr32->sh_name; - shdr64->sh_type = shdr32->sh_type; - shdr64->sh_flags = shdr32->sh_flags; - shdr64->sh_addr = shdr32->sh_addr; - shdr64->sh_offset = shdr32->sh_offset; - shdr64->sh_size = shdr32->sh_size; - shdr64->sh_link = shdr32->sh_link; - shdr64->sh_info = shdr32->sh_info; - shdr64->sh_addralign = shdr32->sh_addralign; - shdr64->sh_entsize = shdr32->sh_entsize; - } - } - }break; - case ELF_Class_64: - { - sections = (ELF_Shdr64*)(elf_data.str + section_foff); - }break; - } - } - - //- extract section names - String8 *section_names = 0; - if (sections != 0 && section_count > 0){ - U8 *string_table_opl = elf_data.str + section_name_table_opl; - - section_names = push_array(arena, String8, section_count); - String8 *sec_name = section_names; - ELF_Shdr64 *sec = sections; - for (U64 i = 0; - i < section_count; - i += 1, sec += 1, sec_name += 1){ - U64 name_foff = section_name_table_foff + sec->sh_name; - if (section_name_table_foff <= name_foff && name_foff < section_name_table_opl){ - U8 *base = elf_data.str + name_foff; - U8 *opl = base; - for (;opl < string_table_opl && *opl != 0; opl += 1); - sec_name->str = base; - sec_name->size = (U64)(opl - base); - } - } - } - - //- format segments data - ELF_Phdr64 *segments = 0; - if (header_is_good && segment_count > 0){ - switch (elf_class){ - case ELF_Class_32: - { - segments = push_array(arena, ELF_Phdr64, segment_count); - { - ELF_Phdr32 *phdr32 = (ELF_Phdr32*)(elf_data.str + segment_foff); - ELF_Phdr64 *phdr64 = segments; - for (U64 i = 0; i < segment_count; i += 1, phdr32 += 1, phdr64 += 1){ - phdr64->p_type = phdr32->p_type; - phdr64->p_flags = phdr32->p_flags; - phdr64->p_offset = phdr32->p_offset; - phdr64->p_vaddr = phdr32->p_vaddr; - phdr64->p_paddr = phdr32->p_paddr; - phdr64->p_filesz = phdr32->p_filesz; - phdr64->p_memsz = phdr32->p_memsz; - phdr64->p_align = phdr32->p_align; - } - } - }break; - case ELF_Class_64: - { - segments = (ELF_Phdr64*)(elf_data.str + segment_foff); - }break; - } - } - - //- find special sections - U64 strtab_idx = 0; - U64 symtab_idx = 0; - U64 dynsym_idx = 0; - if (section_names != 0){ - for (U64 i = 0; i < section_count; i += 1){ - String8 name = section_names[i]; - if (str8_match(name, str8_lit(".strtab"), 0)){ - strtab_idx = i; - } - else if (str8_match(name, str8_lit(".symtab"), 0)){ - symtab_idx = i; - } - else if (str8_match(name, str8_lit(".dynsym"), 0)){ - dynsym_idx = i; - } - } - } - - - //- fill result - ELF_Parsed *result = 0; - if (header_is_good){ - result = push_array(arena, ELF_Parsed, 1); - result->data = elf_data; - result->elf_class = elf_class; - result->arch = arch; - result->sections = sections; - result->section_names = section_names; - result->section_foff = section_foff; - result->section_count = section_count; - result->segments = segments; - result->segment_foff = segment_foff; - result->segment_count = segment_count; - result->vbase = vbase; - result->entry_vaddr = e_entry; - result->section_name_table_foff = section_name_table_foff; - result->section_name_table_opl = section_name_table_opl; - result->strtab_idx = strtab_idx; - result->symtab_idx = symtab_idx; - result->dynsym_idx = dynsym_idx; - } - - return(result); -} - -static ELF_SectionArray -elf_section_array_from_elf(ELF_Parsed *elf){ - ELF_SectionArray result = {0}; - if (elf != 0){ - result.sections = elf->sections; - result.count = elf->section_count; - } - return(result); -} - -static String8Array -elf_section_name_array_from_elf(ELF_Parsed *elf){ - String8Array result = {0}; - if (elf != 0){ - result.v = elf->section_names; - result.count = elf->section_count; - } - return(result); -} - -static ELF_SegmentArray -elf_segment_array_from_elf(ELF_Parsed *elf){ - ELF_SegmentArray result = {0}; - if (elf != 0){ - result.segments = elf->segments; - result.count = elf->segment_count; - } - return(result); -} - -static String8 -elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset){ - String8 result = {0}; - if (elf != 0){ - if (offset > 0){ - U64 foff = elf->section_name_table_foff + offset; - if (elf->section_name_table_foff <= foff && foff < elf->section_name_table_opl){ - U8 *base = elf->data.str + foff; - U8 *section_opl = elf->data.str + elf->section_name_table_opl; - U8 *opl = base; - for (;opl < section_opl && *opl != 0; opl += 1); - result.str = base; - result.size = opl - base; - } - } - } - return(result); -} - -static String8 -elf_section_name_from_idx(ELF_Parsed *elf, U32 idx){ - String8 result = {0}; - if (elf != 0){ - if (idx < elf->section_count){ - result = elf->section_names[idx]; - } - } - return(result); -} - -static U32 -elf_section_idx_from_name(ELF_Parsed *elf, String8 name){ - U32 result = 0; - if (elf != 0){ - String8 *sec_name = elf->section_names; - U64 count = elf->section_count; - for (U64 i = 0; i < count; i += 1, sec_name += 1){ - if (str8_match(*sec_name, name, 0)){ - result = i; - break; - } - } - } - return(result); -} - -static String8 -elf_section_data_from_idx(ELF_Parsed *elf, U32 idx){ - String8 result = {0}; - if (elf != 0){ - if (idx < elf->section_count){ - ELF_Shdr64 *shdr = elf->sections + idx; - U64 off_raw = shdr->sh_offset; - U64 size = shdr->sh_size; - if (shdr->sh_flags & ELF_SectionType_NOBITS){ - size = 0; - } - U64 opl_raw = off_raw + size; - U64 opl = ClampTop(opl_raw, elf->data.size); - U64 off = ClampTop(off_raw, opl); - result.str = elf->data.str + off; - result.size = opl - off; - } - } - return(result); -} - -static ELF_SymArray -elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data){ - // converge to sym64 layout - ELF_Sym64 *symbols = 0; - U64 count = 0; - switch (elf_class){ - default:{}break; - - case ELF_Class_32: - { - count = data.size/sizeof(ELF_Sym32); - symbols = push_array(arena, ELF_Sym64, count); - { - ELF_Sym32 *sym32 = (ELF_Sym32*)(data.str); - ELF_Sym64 *sym64 = symbols; - for (U64 i = 0; i < count; i += 1, sym32 += 1, sym64 += 1){ - sym64->st_name = sym32->st_name; - sym64->st_value = sym32->st_value; - sym64->st_size = sym32->st_size; - sym64->st_info = sym32->st_info; - sym64->st_other = sym32->st_other; - sym64->st_shndx = sym32->st_shndx; - } - } - }break; - - case ELF_Class_64: - { - count = data.size/sizeof(ELF_Sym64); - symbols = (ELF_Sym64*)(data.str); - }break; - } - - // fill result - ELF_SymArray result = {0}; - result.symbols = symbols; - result.count = count; - return(result); -} - -// string functions - -static String8 -elf_string_from_section_type(ELF_SectionType section_type){ - String8 result = str8_lit("INVALID_SECTION_TYPE"); - switch (section_type){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SectionTypeXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_binding(ELF_SymbolBinding binding){ - String8 result = str8_lit("INVALID_SYMBOL_BINDING"); - switch (binding){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolBindingXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_type(ELF_SymbolType type){ - String8 result = str8_lit("INVALID_SYMBOL_TYPE"); - switch (type){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolTypeXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility){ - String8 result = str8_lit("INVALID_SYMBOL_VISIBILITY"); - switch (visibility){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolVisibilityXList(X) -#undef X - } - return(result); -} diff --git a/src/rdi_from_dwarf/rdi_elf.h b/src/rdi_from_dwarf/rdi_elf.h deleted file mode 100644 index 8643f8bf..00000000 --- a/src/rdi_from_dwarf/rdi_elf.h +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_ELF_H -#define RDI_ELF_H - -// https://refspecs.linuxfoundation.org/elf/elf.pdf - -//////////////////////////////// -//~ Elf Format Types - -// elf header - -#define ELF_NIDENT 16 - -typedef struct ELF_Ehdr32{ - U8 e_ident[ELF_NIDENT]; - U16 e_type; - U16 e_machine; - U32 e_version; - U32 e_entry; - U32 e_phoff; - U32 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; -} ELF_Ehdr32; - -typedef struct ELF_Ehdr64{ - U8 e_ident[ELF_NIDENT]; - U16 e_type; - U16 e_machine; - U32 e_version; - U64 e_entry; - U64 e_phoff; - U64 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; -} ELF_Ehdr64; - -typedef enum ELF_Type{ - ELF_Type_NONE = 0, - ELF_Type_REL = 1, - ELF_Type_EXEC = 2, - ELF_Type_DYN = 3, - ELF_Type_CORE = 4, - ELF_Type_LOOS = 0xfe00, - ELF_Type_HIOS = 0xfeff, - ELF_Type_LOPROC = 0xff00, - ELF_Type_HIPROC = 0xffff, -} ELF_Type; - -typedef enum ELF_Machine{ - ELF_Machine_NONE = 0, - ELF_Machine_M32 = 1, - ELF_Machine_SPARC = 2, - ELF_Machine_386 = 3, - ELF_Machine_68K = 4, - ELF_Machine_88K = 5, - ELF_Machine_860 = 7, - ELF_Machine_MIPS = 8, - ELF_Machine_S370 = 9, - ELF_Machine_MIPS_RS3_LE = 10, - ELF_Machine_PARISC = 15, - ELF_Machine_VPP500 = 17, - ELF_Machine_SPARC32PLUS = 18, - ELF_Machine_960 = 19, - ELF_Machine_PPC = 20, - ELF_Machine_PPC64 = 21, - ELF_Machine_S390 = 22, - ELF_Machine_V800 = 36, - ELF_Machine_FR20 = 37, - ELF_Machine_RH32 = 38, - ELF_Machine_RCE = 39, - ELF_Machine_ARM = 40, - ELF_Machine_ALPHA = 41, - ELF_Machine_SH = 42, - ELF_Machine_SPARCV9 = 43, - ELF_Machine_TRICORE = 44, - ELF_Machine_ARC = 45, - ELF_Machine_H8_300 = 46, - ELF_Machine_H8_300H = 47, - ELF_Machine_H8S = 48, - ELF_Machine_H8_500 = 49, - ELF_Machine_IA_64 = 50, - ELF_Machine_MIPS_X = 51, - ELF_Machine_COLDFIRE = 52, - ELF_Machine_68HC12 = 53, - ELF_Machine_MMA = 54, - ELF_Machine_PCP = 55, - ELF_Machine_NCPU = 56, - ELF_Machine_NDR1 = 57, - ELF_Machine_STARCORE = 58, - ELF_Machine_ME16 = 59, - ELF_Machine_ST100 = 60, - ELF_Machine_TINYJ = 61, - ELF_Machine_X86_64 = 62, - ELF_Machine_PDSP = 63, - ELF_Machine_PDP10 = 64, - ELF_Machine_PDP11 = 65, - ELF_Machine_FX66 = 66, - ELF_Machine_ST9PLUS = 67, - ELF_Machine_ST7 = 68, - ELF_Machine_68HC16 = 69, - ELF_Machine_68HC11 = 70, - ELF_Machine_68HC08 = 71, - ELF_Machine_68HC05 = 72, - ELF_Machine_SVX = 73, - ELF_Machine_ST19 = 74, - ELF_Machine_VAX = 75, - ELF_Machine_CRIS = 76, - ELF_Machine_JAVELIN = 77, - ELF_Machine_FIREPATH = 78, - ELF_Machine_ZSP = 79, - ELF_Machine_MMIX = 80, - ELF_Machine_HUANY = 81, - ELF_Machine_PRISM = 82, - ELF_Machine_AVR = 83, - ELF_Machine_FR30 = 84, - ELF_Machine_D10V = 85, - ELF_Machine_D30V = 86, - ELF_Machine_V850 = 87, - ELF_Machine_M32R = 88, - ELF_Machine_MN10300 = 89, - ELF_Machine_MN10200 = 90, - ELF_Machine_PJ = 91, - ELF_Machine_OPENRISC = 92, - ELF_Machine_ARC_A5 = 93, - ELF_Machine_XTENSA = 94, - ELF_Machine_VIDEOCORE = 95, - ELF_Machine_TMM_GPP = 96, - ELF_Machine_NS32K = 97, - ELF_Machine_TPC = 98, - ELF_Machine_SNP1K = 99, - ELF_Machine_ST200 = 100, -} ELF_Machine; - -typedef enum ELF_Version{ - ELF_Version_NONE = 0, - ELF_Version_CURRENT = 1, -} ELF_Version; - -typedef enum ELF_Identification{ - ELF_Identification_MAG0 = 0, - ELF_Identification_MAG1 = 1, - ELF_Identification_MAG2 = 2, - ELF_Identification_MAG3 = 3, - ELF_Identification_CLASS = 4, - ELF_Identification_DATA = 5, - ELF_Identification_VERSION = 6, - ELF_Identification_OSABI = 7, - ELF_Identification_ABIVERSION = 8, - ELF_Identification_PAD = 9, -} ELF_Identification; - -read_only global U8 elf_magic[] = {0x7F, 'E', 'L', 'F'}; - -typedef enum ELF_Class{ - ELF_Class_NONE = 0, - ELF_Class_32 = 1, - ELF_Class_64 = 2, -} ELF_Class; - -typedef enum ELF_DataEncoding{ - ELF_DataEncoding_NONE = 0, - ELF_DataEncoding_2LSB = 1, - ELF_DataEncoding_2MSB = 2, -} ELF_DataEncoding; - -typedef enum ELF_OsAbi{ - ELF_OsAbi_NONE = 0, - ELF_OsAbi_HPUX = 1, - ELF_OsAbi_NETBSD = 2, - ELF_OsAbi_LINUX = 3, - ELF_OsAbi_SOLARIS = 6, - ELF_OsAbi_AIX = 7, - ELF_OsAbi_IRIX = 8, - ELF_OsAbi_FREEBSD = 9, - ELF_OsAbi_TRU64 = 10, - ELF_OsAbi_MODESTO = 11, - ELF_OsAbi_OPENBSD = 12, - ELF_OsAbi_OPENVMS = 13, - ELF_OsAbi_NSK = 14, -} ELF_OsAbi; - -// sections - -typedef enum ELF_ReservedSectionIndex{ - ELF_ReservedSectionIndex_UNDEF = 0, - ELF_ReservedSectionIndex_LORESERVE = 0xFF00, - ELF_ReservedSectionIndex_LOPROC = 0xFF00, - ELF_ReservedSectionIndex_HIPROC = 0xFF1F, - ELF_ReservedSectionIndex_LOOS = 0xFF20, - ELF_ReservedSectionIndex_HIOS = 0xFF3F, - ELF_ReservedSectionIndex_ABS = 0xFFF1, - ELF_ReservedSectionIndex_COMMON = 0xFFF2, - ELF_ReservedSectionIndex_XINDEX = 0xFFFF, - ELF_ReservedSectionIndex_HIRESERVE = 0xFFFF, -} ELF_ReservedSectionIndex; - -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; -} ELF_Shdr32; - -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; -} ELF_Shdr64; - -// X(name, code) -#define ELF_SectionTypeXList(X)\ -X(NULL, 0)\ -X(PROGBITS, 1)\ -X(SYMTAB, 2)\ -X(STRTAB, 3)\ -X(RELA, 4)\ -X(HASH, 5)\ -X(DYNAMIC, 6)\ -X(NOTE, 7)\ -X(NOBITS, 8)\ -X(REL, 9)\ -X(SHLIB, 10)\ -X(DYNSYM, 11)\ -X(INIT_ARRAY, 14)\ -X(FINI_ARRAY, 15)\ -X(PREINIT_ARRAY, 16)\ -X(GROUP, 17)\ -X(SYMTAB_SHNDX, 18)\ -X(LOOS, 0x60000000)\ -X(HIOS, 0x6FFFFFFF)\ -X(LOPROC, 0x70000000)\ -X(HIPROC, 0x7FFFFFFF)\ -X(LOUSER, 0x80000000)\ -X(HIUSER, 0x8FFFFFFF) - -typedef enum ELF_SectionType{ -#define X(N,C) ELF_SectionType_##N = C, - ELF_SectionTypeXList(X) -#undef X -} ELF_SectionType; - -typedef enum ELF_SectionAttributeFlags{ - ELF_SectionAttributeFlag_WRITE = 0x001, - ELF_SectionAttributeFlag_ALLOC = 0x002, - ELF_SectionAttributeFlag_EXECINSTR = 0x004, - ELF_SectionAttributeFlag_MERGE = 0x010, - ELF_SectionAttributeFlag_STRINGS = 0x020, - ELF_SectionAttributeFlag_INFO_LINK = 0x040, - ELF_SectionAttributeFlag_LINK_ORDER = 0x080, - ELF_SectionAttributeFlag_OS_NONCONFORMING = 0x100, - ELF_SectionAttributeFlag_GROUP = 0x200, - ELF_SectionAttributeFlag_TLS = 0x400, - ELF_SectionAttributeFlag_MASKOS = 0x0FF00000, - ELF_SectionAttributeFlag_MASKPROC = 0xF0000000, -} ELF_SectionAttributeFlags; - -typedef enum ELF_SectionGroupFlags{ - ELF_SectionGroupFlag_COMDAT = 0x1, - ELF_SectionGroupFlag_MASKOS = 0x0FF00000, - ELF_SectionGroupFlag_MASKPROC = 0xF0000000, -} ELF_SectionGroupFlags; - -typedef enum ELF_ReservedSymbolTableIndex{ - ELF_ReservedSymbolTableIndex_UNDEF = 0, -} ELF_ReservedSymbolTableIndex; - -// symbol table - -typedef struct ELF_Sym32{ - U32 st_name; - U32 st_value; - U32 st_size; - U8 st_info; - U8 st_other; - U16 st_shndx; -} ELF_Sym32; - -typedef struct ELF_Sym64{ - U32 st_name; - U8 st_info; - U8 st_other; - U16 st_shndx; - U64 st_value; - U64 st_size; -} ELF_Sym64; - -#define ELF_SymBindingFromInfo(x) (ELF_SymbolBinding)((x)>>4) -#define ELF_SymTypeFromInfo(x) (ELF_SymbolType)((x)&0xF) -#define ELF_SymInfoFromBindingType(b,t) ((((b)<<4)&0xF)|((t)&0xF)) - -#define ELF_SymVisibilityFromOther(x) ((x)&0x3) -#define ELF_SymOtherFromVisibility(x) ((x)&0x3) - -#define ELF_SymbolBindingXList(X)\ -X(LOCAL, 0)\ -X(GLOBAL, 1)\ -X(WEAK, 2)\ -X(LOOS, 10)\ -X(HIOS, 12)\ -X(LOPROC, 13)\ -X(HIPROC, 15)\ - -typedef enum ELF_SymbolBinding{ -#define X(N,C) ELF_SymbolBinding_##N = C, - ELF_SymbolBindingXList(X) -#undef X -} ELF_SymbolBinding; - -#define ELF_SymbolTypeXList(X)\ -X(NOTYPE, 0)\ -X(OBJECT, 1)\ -X(FUNC, 2)\ -X(SECTION, 3)\ -X(FILE, 4)\ -X(COMMON, 5)\ -X(TLS, 6)\ -X(LOOS, 10)\ -X(HIOS, 12)\ -X(LOPROC, 13)\ -X(HIPROC, 15) - -typedef enum ELF_SymbolType{ -#define X(N,C) ELF_SymbolType_##N = C, - ELF_SymbolTypeXList(X) -#undef X -} ELF_SymbolType; - -#define ELF_SymbolVisibilityXList(X)\ -X(DEFAULT, 0)\ -X(INTERNAL, 1)\ -X(HIDDEN, 2)\ -X(PROTECTED, 3) - -typedef enum ELF_SymbolVisibility{ -#define X(N,C) ELF_SymbolVisibility_##N = C, - ELF_SymbolVisibilityXList(X) -#undef X -} ELF_SymbolVisibility; - -// relocation - -typedef struct ELF_Rel32{ - U32 r_offset; - U32 r_info; -} ELF_Rel32; - -typedef struct ELF_Rela32{ - U32 r_offset; - U32 r_info; - S32 r_addend; -} ELF_Rela32; - -typedef struct ELF_Rel64{ - U64 r_offset; - U64 r_info; -} ELF_Rel64; - -typedef struct ELF_Rela64{ - U64 r_offset; - U64 r_info; - S64 r_addend; -} ELF_Rela64; - -#define ELF_RelSymIndexFromInfo32(x) ((x)>>8) -#define ELF_RelTypeFromInfo32(x) ((x)&0xF) -#define ELF_RelInfoFromSymIndexType32(n,t) (((n)<<8)|((t)&0xF)) - -#define ELF_RelSymIndexFromInfo64(x) ((x)>>32) -#define ELF_RelTypeFromInfo64(x) ((x)&0xFFFFFFFFL) -#define ELF_RelInfoFromSymIndexType64(n,t) (((n)<<8)|((t)&0xFFFFFFFFL)) - - - -// program header - -typedef struct ELF_Phdr32{ - U32 p_type; - U32 p_offset; - U32 p_vaddr; - U32 p_paddr; - U32 p_filesz; - U32 p_memsz; - U32 p_flags; - U32 p_align; -} ELF_Phdr32; - -typedef struct ELF_Phdr64{ - U32 p_type; - U32 p_flags; - U64 p_offset; - U64 p_vaddr; - U64 p_paddr; - U64 p_filesz; - U64 p_memsz; - U64 p_align; -} ELF_Phdr64; - -typedef enum ELF_SegmentType{ - ELF_SegmentType_NULL = 0, - ELF_SegmentType_LOAD = 1, - ELF_SegmentType_DYNAMIC = 2, - ELF_SegmentType_INTERP = 3, - ELF_SegmentType_NOTE = 4, - ELF_SegmentType_SHLIB = 5, - ELF_SegmentType_PHDR = 6, - ELF_SegmentType_TLS = 7, - ELF_SegmentType_LOOS = 0x60000000, - ELF_SegmentType_HIOS = 0x6fffffff, - ELF_SegmentType_LOPROC = 0x70000000, - ELF_SegmentType_HIPROC = 0x7fffffff, -} ELF_SegmentType; - -typedef enum ELF_SegmentFlags{ - ELF_SegmentFlag_X = 0x1, - ELF_SegmentFlag_W = 0x2, - ELF_SegmentFlag_R = 0x4, - ELF_SegmentFlag_MASKOS = 0x0FF00000, - ELF_SegmentFlag_MASKPROC = 0xF0000000, -} ELF_SegmentFlags; - -//////////////////////////////// -//~ ELF Parser Types - -// elf top level - -typedef struct ELF_SectionArray{ - ELF_Shdr64 *sections; - U64 count; -} ELF_SectionArray; - -typedef struct ELF_SegmentArray{ - ELF_Phdr64 *segments; - U64 count; -} ELF_SegmentArray; - -typedef struct ELF_Parsed{ - String8 data; - ELF_Class elf_class; - Arch arch; - - ELF_Shdr64 *sections; - String8 *section_names; - U64 section_foff; - U64 section_count; - - ELF_Phdr64 *segments; - U64 segment_foff; - U64 segment_count; - - U64 vbase; - U64 entry_vaddr; - U64 section_name_table_foff; - U64 section_name_table_opl; - - U64 strtab_idx; - U64 symtab_idx; - U64 dynsym_idx; -} ELF_Parsed; - -// elf symtab - -typedef struct ELF_SymArray{ - ELF_Sym64 *symbols; - U64 count; -} ELF_SymArray; - -//////////////////////////////// -//~ ELF Parser Functions - -static ELF_Parsed* elf_parsed_from_data(Arena *arena, String8 elf_data); - -static ELF_SectionArray elf_section_array_from_elf(ELF_Parsed *elf); -static String8Array elf_section_name_array_from_elf(ELF_Parsed *elf); -static ELF_SegmentArray elf_segment_array_from_elf(ELF_Parsed *elf); - -static String8 elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset); -static String8 elf_section_name_from_idx(ELF_Parsed *elf, U32 idx); -static U32 elf_section_idx_from_name(ELF_Parsed *elf, String8 name); - -static String8 elf_section_data_from_idx(ELF_Parsed *elf, U32 idx); - -static ELF_SymArray elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data); - -// string functions - -static String8 elf_string_from_section_type(ELF_SectionType section_type); -static String8 elf_string_from_symbol_binding(ELF_SymbolBinding binding); -static String8 elf_string_from_symbol_type(ELF_SymbolType type); -static String8 elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility); - -#endif //RDI_ELF_H