Files
raddebugger/src/rdi_from_dwarf/rdi_dwarf.h
T
2024-05-23 15:09:53 -07:00

1494 lines
44 KiB
C

// 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{ 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