dumper for Dwarf

This commit is contained in:
Nikita Smith
2025-01-08 03:13:48 -08:00
parent 543ee72f95
commit 98b9427446
14 changed files with 5800 additions and 979 deletions
+266
View File
@@ -0,0 +1,266 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_V2_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_v3(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_V3_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_v4(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_V4_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_v5(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_V5_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_gnu(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_GNU_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_llvm(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_LLVM_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_apple(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_APPLE_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind_mips(DW_AttribKind k)
{
switch (k) {
#define X(_N,_C) case DW_Attrib_##_N: return _C;
DW_AttribKind_ClassFlags_MIPS_XList(X)
#undef X
}
return DW_AttribClass_Null;
}
internal DW_AttribClass
dw_attrib_class_from_attrib_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
{
DW_AttribClass result = DW_AttribClass_Null;
while (ext) {
U64 z = 64-clz64(ext);
if (z == 0) {
break;
}
U64 flag = 1 << (z-1);
ext &= ~flag;
switch (flag) {
case DW_Ext_Null: break;
case DW_Ext_GNU: result = dw_attrib_class_from_attrib_kind_gnu(k); break;
case DW_Ext_LLVM: result = dw_attrib_class_from_attrib_kind_llvm(k); break;
case DW_Ext_APPLE: result = dw_attrib_class_from_attrib_kind_apple(k); break;
case DW_Ext_MIPS: result = dw_attrib_class_from_attrib_kind_mips(k); break;
default: InvalidPath; break;
}
if (result != DW_AttribClass_Null) {
break;
}
}
if (result == DW_AttribClass_Null) {
switch (ver) {
case DW_Version_Null: break;
case DW_Version_1: AssertAlways(!"DWARF V1 is not supported"); break;
case DW_Version_2: result = dw_attrib_class_from_attrib_kind_v2(k); break;
case DW_Version_3: result = dw_attrib_class_from_attrib_kind_v3(k); break;
case DW_Version_4: result = dw_attrib_class_from_attrib_kind_v4(k); break;
case DW_Version_5: result = dw_attrib_class_from_attrib_kind_v5(k); break;
default: InvalidPath; break;
}
}
return result;
}
internal DW_AttribClass
dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k)
{
#define X(_N,_C) case DW_Form_##_N: return _C;
switch (ver) {
case DW_Version_5: {
switch (k) {
DW_Form_AttribClass_V5_XList(X)
}
} break;
case DW_Version_4: {
switch (k) {
DW_Form_AttribClass_V4_XList(X)
}
} break;
case DW_Version_3: {
switch (k) {
DW_Form_AttribClass_V2_XList(X)
}
} break;
case DW_Version_2: {
switch (k) {
DW_Form_AttribClass_V2_XList(X)
}
} break;
case DW_Version_1: {
} break;
case DW_Version_Null: break;
}
#undef X
return DW_AttribClass_Null;
}
internal B32
dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind)
{
DW_AttribClass compat_flags = dw_attrib_class_from_form_kind(ver, form_kind);
B32 are_compat = (attrib_class & compat_flags) != 0;
return are_compat;
}
internal String8
dw_name_string_from_section_kind(DW_SectionKind k)
{
switch (k) {
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L);
DW_SectionKind_XList(X)
#undef X
}
return str8_zero();
}
internal String8
dw_mach_name_string_from_section_kind(DW_SectionKind k)
{
switch (k) {
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M);
DW_SectionKind_XList(X)
#undef X
}
return str8_zero();
}
internal String8
dw_dwo_name_string_from_section_kind(DW_SectionKind k)
{
switch (k) {
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D);
DW_SectionKind_XList(X)
#undef X
}
return str8_zero();
}
internal U64
dw_offset_size_from_mode(DW_Mode mode)
{
U64 result = 0;
switch (mode) {
case DW_Mode_Null: break;
case DW_Mode_32Bit: result = 4; break;
case DW_Mode_64Bit: result = 8; break;
default: InvalidPath; break;
}
return result;
}
internal DW_AttribClass
dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind)
{
// NOTE(rjf): DWARF's spec specifies two mappings:
// (DW_AttribKind) => List(DW_AttribClass)
// (DW_FormKind) => List(DW_AttribClass)
//
// This function's purpose is to find the overlapping class between an
// DW_AttribKind and DW_FormKind.
DW_AttribClass attrib_class = dw_attrib_class_from_attrib_kind(ver, ext, attrib_kind);
DW_AttribClass form_class = dw_attrib_class_from_form_kind(ver, form_kind);
if(relaxed)
{
if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
{
attrib_class = dw_attrib_class_from_attrib_kind(DW_Version_Last, ext, attrib_kind);
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
}
}
DW_AttribClass result = DW_AttribClass_Null;
if(attrib_class != DW_AttribClass_Null && form_class != DW_AttribClass_Null)
{
result = DW_AttribClass_Undefined;
for(U32 i = 0; i < 32; ++i)
{
U32 n = 1u << i;
if((attrib_class & n) != 0 && (form_class & n) != 0)
{
result = ((DW_AttribClass) n);
break;
}
}
}
if (attrib_kind != DW_Attrib_Null && form_kind != DW_Form_Null) {
//Assert(result != DW_AttribClass_Null && result != DW_AttribClass_Undefined);
}
return result;
}
+1690
View File
File diff suppressed because it is too large Load Diff
+225
View File
@@ -0,0 +1,225 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal String8
dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op)
{
String8 result = {0};
#define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit;
switch (ext) {
case DW_Ext_Null: break;
case DW_Ext_LLVM: break;
case DW_Ext_APPLE: break;
case DW_Ext_MIPS: break;
case DW_Ext_GNU: DW_Expr_GNU_XList(X); break;
}
switch (ver) {
case DW_Version_5: {
switch (op) {
DW_Expr_V5_XList(X)
}
} // fall-through
case DW_Version_4: {
switch (op) {
DW_Expr_V4_XList(X)
}
} // fall-through
case DW_Version_3: {
switch (op) {
DW_Expr_V3_XList(X)
}
} // fall-through
case DW_Version_2:
case DW_Version_1:
case DW_Version_Null:
break;
}
#undef X
result = push_str8f(arena, "%x", op);
exit:;
return result;
}
internal String8
dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
{
switch (kind) {
#define X(_N,_ID) case DW_Tag_##_N: return str8_lit(Stringify(_N));
DW_Tag_V3_XList(X)
DW_Tag_V5_XList(X)
DW_Tag_GNU_XList(X)
#undef X
}
return push_str8f(arena, "%llx", kind);
}
internal String8
dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind)
{
#define X(_N,...) case DW_Attrib_##_N: return str8_lit(Stringify(_N));
while (ext) {
U64 z = 64-clz64(ext);
if (z == 0) {
break;
}
U64 flag = 1 << (z-1);
ext &= ~flag;
switch (flag) {
case DW_Ext_Null: break;
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList(X) } break;
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList(X) } break;
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList(X) } break;
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList(X) } break;
default: InvalidPath; break;
}
}
switch (ver) {
case DW_Version_5: {
switch (kind) {
DW_AttribKind_V5_XList(X)
}
} // fall-through
case DW_Version_4: {
switch (kind) {
DW_AttribKind_V4_XList(X)
}
} // fall-through
case DW_Version_3: {
switch (kind) {
DW_AttribKind_V3_XList(X)
}
} // fall-through
case DW_Version_2: {
switch (kind) {
DW_AttribKind_V2_XList(X)
}
} // fall-through
case DW_Version_1: {
} // fall-through
case DW_Version_Null: break;
}
#undef X
return str8_zero();
}
internal String8
dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind)
{
#define X(_N,...) case DW_Form_##_N: return str8_lit(Stringify(_N));
switch (ver) {
case DW_Version_5: {
switch (kind) {
DW_Form_V5_XList(X)
}
} // fall-through
case DW_Version_4: {
switch (kind) {
DW_Form_V4_XList(X)
}
} // fall-through
case DW_Version_3:
case DW_Version_2: {
switch (kind) {
DW_Form_V2_XList(X)
}
} // fall-through
case DW_Version_Null: break;
}
#undef X
String8 result = push_str8f(arena, "%x", kind);
return result;
}
internal String8
dw_string_from_language(Arena *arena, DW_Language kind)
{
switch (kind) {
#define X(_N,_ID) case DW_Language_##_N: return str8_lit(Stringify(_N));
DW_Language_XList(X)
#undef X
}
return push_str8f(arena, "%x", kind);
}
internal String8
dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind)
{
switch (kind) {
#define X(_N,_ID) case DW_StdOpcode_##_N: return str8_lit(Stringify(_N));
DW_StdOpcode_XList(X)
#undef X
}
return push_str8f(arena, "%x", kind);
}
internal String8
dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind)
{
switch (kind) {
#define X(_N,_ID) case DW_ExtOpcode_##_N: return str8_lit(Stringify(_N));
DW_ExtOpcode_XList(X)
#undef X
default: InvalidPath; break;
}
return push_str8f(arena, "%x", kind);
}
internal String8
dw_string_from_loc_list_entry_kind(Arena *arena, DW_LocListEntryKind kind)
{
NotImplemented;
return str8_zero();
}
internal String8
dw_string_from_section_kind(Arena *arena, DW_SectionKind kind)
{
NotImplemented;
return str8_zero();
}
internal String8
dw_string_from_rng_list_entry_kind(Arena *arena, DW_RngListEntryKind kind)
{
NotImplemented;
return str8_zero();
}
internal String8
dw_string_from_register(Arena *arena, Arch arch, U64 reg_id)
{
String8 reg_str = str8_zero();
switch (arch) {
case Arch_Null: break;
case Arch_x86: {
switch (reg_id) {
#define X(_N, _ID, ...) case DW_Reg_x86_##_N: reg_str = str8_lit(Stringify(_ID)); break;
DW_Regs_X86_XList(X)
#undef X
}
} break;
case Arch_x64: {
switch (reg_id) {
#define X(_N, _ID, ...) case DW_Reg_x64_##_N: reg_str = str8_lit(Stringify(_ID)); break;
DW_Regs_X64_XList(X)
#undef X
}
} break;
case Arch_arm32: NotImplemented; break;
case Arch_arm64: NotImplemented; break;
default: InvalidPath; break;
}
if (reg_str.size == 0) {
reg_str = push_str8f(arena, "%#llx", reg_id);
}
return reg_str;
}
+7 -3
View File
@@ -1,11 +1,15 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal String8 dw_string_from_expr_op(Arena *arena, DW_ExprOp op);
#ifndef DWARF_ENUM_H
#define DWARF_ENUM_H
internal String8 dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op);
internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind);
internal String8 dw_string_from_attrib_kind(Arena *arena, DW_AttribKind kind);
internal String8 dw_string_from_form_kind(Arena *arena, DW_FormKind kind);
internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind);
internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind);
//internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id);
#endif // DWARF_ENUM_H
+51 -51
View File
@@ -9,7 +9,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
DW_SimpleLoc result = {DW_SimpleLocKind_Empty};
U8 op = 0;
if (based_range_read(base, range, 0, 1, &op)) {
if (dw_based_range_read(base, range, 0, 1, &op)) {
// step params
U64 size_param = 0;
B32 is_signed = 0;
@@ -48,7 +48,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
const_n:
{
U64 x = 0;
step_cursor += based_range_read(base, range, step_cursor, size_param, &x);
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &x);
if (is_signed) {
x = extend_sign64(x, size_param);
@@ -61,7 +61,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_Addr:
{
U64 offset = 0;
step_cursor += based_range_read(base, range, step_cursor, 8, &offset);
step_cursor += dw_based_range_read(base, range, step_cursor, 8, &offset);
U64 x = text_section_base + offset;
result.kind = DW_SimpleLocKind_Address;
result.addr = x;
@@ -70,7 +70,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_ConstU:
{
U64 x = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &x);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &x);
result.kind = DW_SimpleLocKind_Address;
result.addr = x;
} break;
@@ -78,7 +78,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_ConstS:
{
U64 x = 0;
step_cursor += based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
result.kind = DW_SimpleLocKind_Address;
result.addr = x;
} break;
@@ -106,7 +106,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_RegX:
{
U64 reg_idx = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &reg_idx);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &reg_idx);
result.kind = DW_SimpleLocKind_Register;
result.reg_idx = reg_idx;
} break;
@@ -117,7 +117,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_ImplicitValue:
{
U64 size = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
if (step_cursor + size <= range.max) {
result.kind = DW_SimpleLocKind_ValueLong;
result.val_long.str = (U8*)base + range.min + step_cursor;
@@ -141,15 +141,15 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
case DW_ExprOp_Piece:
{
U64 size = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
result.kind = DW_SimpleLocKind_Empty;
} break;
case DW_ExprOp_BitPiece:
{
U64 bit_size = 0, bit_off = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_size);
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_off);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_size);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_off);
result.kind = DW_SimpleLocKind_Empty;
} break;
@@ -222,7 +222,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
// decode op
U64 op_offset = cursor;
U8 op = 0;
if (based_range_read(task_base, task_range, op_offset, 1, &op)) {
if (dw_based_range_read(task_base, task_range, op_offset, 1, &op)) {
U64 after_op_off = cursor + 1;
// require piece op after 'implicit' location descriptions
@@ -267,26 +267,26 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
const_n:
{
U64 x = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &x);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &x);
} break;
case DW_ExprOp_Addr:
{
U64 offset = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, 8, &offset);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 8, &offset);
result.flags |= DW_ExprFlag_UsesTextBase;
} break;
case DW_ExprOp_ConstU:
{
U64 x = 0;
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &x);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &x);
} break;
case DW_ExprOp_ConstS:
{
U64 x = 0;
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, (S64*)&x);
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, (S64*)&x);
} break;
@@ -295,7 +295,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_FBReg:
{
S64 offset = 0;
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
result.flags |= DW_ExprFlag_UsesFrameBase;
} break;
@@ -312,15 +312,15 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31:
{
S64 offset = 0;
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
result.flags |= DW_ExprFlag_UsesRegisters;
} break;
case DW_ExprOp_BRegX:
{
U64 reg_idx = 0; S64 offset = 0;
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &reg_idx);
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &reg_idx);
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
result.flags |= DW_ExprFlag_UsesRegisters;
} break;
@@ -334,7 +334,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_Pick:
{
U64 idx = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, 1, &idx);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 1, &idx);
} break;
case DW_ExprOp_Over:
@@ -350,7 +350,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_DerefSize:
{
U64 size = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, 1, &size);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 1, &size);
result.flags |= DW_ExprFlag_UsesMemory;
} break;
@@ -394,7 +394,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_PlusUConst:
{
U64 y = 0;
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &y);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &y);
} break;
case DW_ExprOp_Shl:
@@ -418,7 +418,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_Bra:
{
S16 d = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, 2, &d);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 2, &d);
result.flags |= DW_ExprFlag_NonLinearFlow;
} break;
@@ -427,7 +427,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
callN:
{
U64 p = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &p);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &p);
result.flags |= DW_ExprFlag_UsesCallResolution|DW_ExprFlag_NonLinearFlow;
// add to task list
@@ -476,7 +476,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_RegX:
{
U64 reg_idx = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &reg_idx);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &reg_idx);
last_was_implicit_loc = 1;
} break;
@@ -486,7 +486,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_ImplicitValue:
{
U64 size = 0;
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &size);
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &size);
if (step_cursor + size > task_range.max) {
result.flags |= DW_ExprFlag_BadData;
goto finish;
@@ -506,7 +506,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_Piece:
{
U64 size = 0;
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &size);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &size);
result.flags |= DW_ExprFlag_UsesComposite;
last_was_implicit_loc = 0;
@@ -515,8 +515,8 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
case DW_ExprOp_BitPiece:
{
U64 bit_size = 0; U64 bit_off = 0;
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &bit_size);
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &bit_off);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &bit_size);
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &bit_off);
result.flags |= DW_ExprFlag_UsesComposite;
last_was_implicit_loc = 0;
@@ -590,7 +590,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
// decode op
U64 op_offset = cursor;
U8 op = 0;
if (based_range_read(base, range, op_offset, 1, &op)) {
if (dw_based_range_read(base, range, op_offset, 1, &op)) {
U64 after_op_off = cursor + 1;
// require piece op after 'implicit' location descriptions
@@ -639,7 +639,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
const_n:
{
U64 x = 0;
step_cursor += based_range_read(base, range, step_cursor, size_param, &x);
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &x);
if (is_signed) {
x = extend_sign64(x, size_param);
}
@@ -649,13 +649,13 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Addr:
{
U64 offset = 0;
step_cursor += based_range_read(base, range, step_cursor, 8, &offset);
step_cursor += dw_based_range_read(base, range, step_cursor, 8, &offset);
// earlier versions of GCC emit TLS offset with DW_ExprOp_Addr.
B32 is_text_relative;
{
U8 next_op = 0;
based_range_read_struct(base, range, step_cursor, &next_op);
dw_based_range_read_struct(base, range, step_cursor, &next_op);
is_text_relative = (next_op != DW_ExprOp_GNU_PushTlsAddress);
}
@@ -677,14 +677,14 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_ConstU:
{
U64 x = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &x);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &x);
dw_expr__stack_push(scratch.arena, &stack, x);
} break;
case DW_ExprOp_ConstS:
{
U64 x = 0;
step_cursor += based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
dw_expr__stack_push(scratch.arena, &stack, x);
} break;
@@ -694,7 +694,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_FBReg:
{
S64 offset = 0;
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
if (config->frame_base != 0) {
U64 x = *config->frame_base + offset;
dw_expr__stack_push(scratch.arena, &stack, x);
@@ -718,7 +718,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31:
{
S64 offset = 0;
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
U64 reg_idx = op - DW_ExprOp_BReg0;
DW_RegsX64 *regs = config->regs;
if (regs != 0) {
@@ -741,8 +741,8 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_BRegX:
{
U64 reg_idx = 0; S64 offset = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &reg_idx);
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &reg_idx);
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
DW_RegsX64 *regs = config->regs;
if (regs != 0) {
@@ -779,7 +779,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Pick:
{
U64 idx = 0;
step_cursor += based_range_read(base, range, step_cursor, 1, &idx);
step_cursor += dw_based_range_read(base, range, step_cursor, 1, &idx);
U64 x = dw_expr__stack_pick(&stack, idx);
dw_expr__stack_push(scratch.arena, &stack, x);
} break;
@@ -832,7 +832,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_DerefSize:
{
U64 raw_size = 0;
step_cursor += based_range_read(base, range, step_cursor, 1, &raw_size);
step_cursor += dw_based_range_read(base, range, step_cursor, 1, &raw_size);
U64 size = ClampTop(raw_size, 8);
U64 addr = dw_expr__stack_pop(&stack);
@@ -983,7 +983,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_PlusUConst:
{
U64 y = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &y);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &y);
U64 z = dw_expr__stack_pop(&stack);
U64 x = y + z;
dw_expr__stack_push(scratch.arena, &stack, x);
@@ -1088,14 +1088,14 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Skip:
{
S16 d = 0;
step_cursor += based_range_read(base, range, step_cursor, 2, &d);
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &d);
step_cursor = step_cursor + d;
} break;
case DW_ExprOp_Bra:
{
S16 d = 0;
step_cursor += based_range_read(base, range, step_cursor, 2, &d);
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &d);
U64 b = dw_expr__stack_pop(&stack);
if (b != 0) {
step_cursor = step_cursor + d;
@@ -1105,7 +1105,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Call2:
{
U16 p = 0;
step_cursor += based_range_read(base, range, step_cursor, 2, &p);
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &p);
if (config->call.func != 0) {
String8 sub_data = config->call.func(config->call.user_ptr, p);
dw_expr__call_push(scratch.arena, &call_stack, sub_data.str, sub_data.size);
@@ -1119,7 +1119,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Call4:
{
U32 p = 0;
step_cursor += based_range_read(base, range, step_cursor, 4, &p);
step_cursor += dw_based_range_read(base, range, step_cursor, 4, &p);
if (config->call.func != 0) {
String8 sub_data = config->call.func(config->call.user_ptr, p);
dw_expr__call_push(scratch.arena, &call_stack, sub_data.str, sub_data.size);
@@ -1165,7 +1165,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_RegX:
{
U64 reg_idx = 0;
step_cursor += based_range_read(base, range, step_cursor, size_param, &reg_idx);
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &reg_idx);
stashed_loc.kind = DW_SimpleLocKind_Register;
stashed_loc.reg_idx = reg_idx;
} break;
@@ -1176,7 +1176,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_ImplicitValue:
{
U64 size = 0;
step_cursor += based_range_read(base, range, step_cursor, size_param, &size);
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &size);
if (step_cursor + size <= range.max) {
void *data = (U8*)base + range.min + step_cursor;
stashed_loc.kind = DW_SimpleLocKind_ValueLong;
@@ -1216,13 +1216,13 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
case DW_ExprOp_Piece:
{
U64 size = 0;
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
bit_size = size*8;
} break;
case DW_ExprOp_BitPiece:
{
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_size);
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_off);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_size);
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_off);
is_bit_loc = 1;
} break;
}
+310 -288
View File
File diff suppressed because it is too large Load Diff
+41 -38
View File
@@ -50,6 +50,7 @@ struct DW_AbbrevTable
typedef struct DW_Section DW_Section;
struct DW_Section
{
String8 name;
String8 data;
DW_Mode mode;
B32 is_dwo;
@@ -201,7 +202,6 @@ struct DW_CompRoot
U64 size;
DW_CompUnitKind kind;
DW_Version version;
DW_Ext ext;
U64 address_size;
U64 abbrev_off;
U64 info_off;
@@ -228,10 +228,6 @@ struct DW_CompRoot
U64 high_pc;
DW_AttribValue ranges_attrib_value;
U64 base_addr;
// NOTE(rjf): Line/File Info For This Comp Unit
String8Array dir_table;
DW_LineVMFileArray file_table;
};
////////////////////////////////
@@ -314,32 +310,32 @@ struct DW_TagStubList
typedef struct DW_LineVMHeader DW_LineVMHeader;
struct DW_LineVMHeader
{
U64 unit_length;
U64 unit_opl;
U16 version;
U8 address_size; // NOTE(nick): duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str.
U8 segment_selector_size;
U64 header_length;
U64 program_off;
U8 min_inst_len;
U8 max_ops_for_inst;
U8 default_is_stmt;
S8 line_base;
U8 line_range;
U8 opcode_base;
U64 num_opcode_lens;
U8 *opcode_lens;
String8Array dir_table;
DW_LineVMFileArray file_table;
U64 unit_length;
U64 unit_opl;
DW_Version version;
U8 address_size; // Duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str.
U8 segment_selector_size;
U64 header_length;
U64 program_off;
U8 min_inst_len;
U8 max_ops_for_inst;
U8 default_is_stmt;
S8 line_base;
U8 line_range;
U8 opcode_base;
U64 num_opcode_lens;
U8 *opcode_lens;
String8Array dir_table;
DW_LineVMFileArray file_table;
};
typedef struct DW_LineVMState DW_LineVMState;
struct DW_LineVMState
{
U64 address; // NOTE(nick): Address of a machine instruction.
U32 op_index; // NOTE(nick): This is used by the VLIW instructions to indicate index of operation inside the instruction.
U64 address; // Address of a machine instruction.
U32 op_index; // This is used by the VLIW instructions to indicate index of operation inside the instruction.
// NOTE(nick): Line table doesn't contain full path to a file, instead
// Line table doesn't contain full path to a file, instead
// DWARF encodes path as two indices. First index will point into a directory
// table, and second points into a file name table.
U32 file_index;
@@ -347,10 +343,10 @@ struct DW_LineVMState
U32 line;
U32 column;
B32 is_stmt; // NOTE(nick): Indicates that "address" points to place suitable for a breakpoint.
B32 basic_block; // NOTE(nick): Indicates that the "address" is inside a basic block.
B32 is_stmt; // Indicates that "address" points to place suitable for a breakpoint.
B32 basic_block; // Indicates that the "address" is inside a basic block.
// NOTE(nick): Indicates that "address" points to place where function starts.
// Indicates that "address" points to place where function starts.
// Usually prologue is the place where compiler emits instructions to
// prepare stack for a function.
B32 prologue_end;
@@ -421,16 +417,23 @@ struct DW_PubStringsTable
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 dw_hash_from_string(String8 string);
internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, DW_AttribKind attrib, DW_FormKind form_kind);
internal U64 dw_hash_from_string(String8 string);
////////////////////////////////
//~ Specific Based Range Helpers
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value);
internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out);
#define dw_based_range_read_struct(base, range, offset, out) dw_based_range_read(base, range, offset, sizeof(*out), out)
internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 offset, U64 size, void *out);
internal String8 dw_based_range_read_string(void *base, Rng1U64 range, U64 offset);
internal void* dw_based_range_ptr(void *base, Rng1U64 range, U64 offset);
internal void* dw_based_range_ptr_size(void *base, Rng1U64 range, U64 offset, U64 size);
internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 offset, U64 *out_value);
internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_value);
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value);
internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out);
internal DW_Mode dw_mode_from_sec(DW_SectionArray *sections, DW_SectionKind kind);
internal B32 dw_sec_is_present(DW_SectionArray *sections, DW_SectionKind kind);
@@ -473,8 +476,8 @@ internal Rng1U64List dw_range_list_from_high_low_pc_and_ranges_a
////////////////////////////////
//~ rjf: Tag Parsing
internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off);
internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset);
internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off, B32 relaxed);
internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset, B32 relaxed);
internal DW_TagStub dw_stub_from_tag(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_Tag *tag);
//- rjf: line info
@@ -484,8 +487,8 @@ internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_ins
internal DW_LineSeqNode* dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl);
internal DW_LineNode* dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence);
internal DW_LineTableParseResult dw_parsed_line_table_from_comp_root(Arena *arena, DW_SectionArray *sections, DW_CompRoot *root);
internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_CompRoot *unit, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out);
internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_CompRoot *unit, DW_LineVMHeader *header_out);
internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out);
internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, String8 compile_dir, String8 unit_name, DW_LineVMHeader *header_out);
#endif // DWARF_PARSE_H
+19 -19
View File
@@ -338,7 +338,7 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
case DW_EhPtrEnc_UData8: size_param = 8; goto ufixed;
ufixed:
{
based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
dw_based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
after_pointer_off = pointer_off + size_param;
} break;
@@ -352,7 +352,7 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
case DW_EhPtrEnc_SData8:size_param = 8; goto sfixed;
sfixed:
{
based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
dw_based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
after_pointer_off = pointer_off + size_param;
// sign extension
U64 sign_bit = size_param*8 - 1;
@@ -363,13 +363,13 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
case DW_EhPtrEnc_ULEB128:
{
U64 size = based_range_read_uleb128(frame_base, frame_range, pointer_off, &raw_pointer);
U64 size = dw_based_range_read_uleb128(frame_base, frame_range, pointer_off, &raw_pointer);
after_pointer_off = pointer_off + size;
} break;
case DW_EhPtrEnc_SLEB128:
{
U64 size = based_range_read_sleb128(frame_base, frame_range, pointer_off,
U64 size = dw_based_range_read_sleb128(frame_base, frame_range, pointer_off,
(S64*)&raw_pointer);
after_pointer_off = pointer_off + size;
} break;
@@ -415,34 +415,34 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
// get version
U64 version_off = off;
U8 version = 0;
based_range_read(base, range, version_off, 1, &version);
dw_based_range_read(base, range, version_off, 1, &version);
// check version
if (version == 1 || version == 3) {
// read augmentation
U64 augmentation_off = version_off + 1;
String8 augmentation = based_range_read_string(base, range, augmentation_off);
String8 augmentation = dw_based_range_read_string(base, range, augmentation_off);
// read code align
U64 code_align_factor_off = augmentation_off + augmentation.size + 1;
U64 code_align_factor = 0;
U64 code_align_factor_size = based_range_read_uleb128(base, range, code_align_factor_off, &code_align_factor);
U64 code_align_factor_size = dw_based_range_read_uleb128(base, range, code_align_factor_off, &code_align_factor);
// read data align
U64 data_align_factor_off = code_align_factor_off + code_align_factor_size;
S64 data_align_factor = 0;
U64 data_align_factor_size = based_range_read_sleb128(base, range, data_align_factor_off, &data_align_factor);
U64 data_align_factor_size = dw_based_range_read_sleb128(base, range, data_align_factor_off, &data_align_factor);
// return address register
U64 ret_addr_reg_off = data_align_factor_off + data_align_factor_size;
U64 after_ret_addr_reg_off = 0;
U64 ret_addr_reg = 0;
if (version == 1) {
based_range_read(base, range, ret_addr_reg_off, 1, &ret_addr_reg);
dw_based_range_read(base, range, ret_addr_reg_off, 1, &ret_addr_reg);
after_ret_addr_reg_off = ret_addr_reg_off + 1;
} else {
U64 ret_addr_reg_size = based_range_read_uleb128(base, range, ret_addr_reg_off, &ret_addr_reg);
U64 ret_addr_reg_size = dw_based_range_read_uleb128(base, range, ret_addr_reg_off, &ret_addr_reg);
after_ret_addr_reg_off = ret_addr_reg_off + ret_addr_reg_size;
}
@@ -459,7 +459,7 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
U64 augmentation_size = 0;
if (augmentation.size > 0 && augmentation.str[0] == 'z') {
has_augmentation_size = 1;
U64 aug_size_size = based_range_read_uleb128(base, range, aug_size_off, &augmentation_size);
U64 aug_size_size = dw_based_range_read_uleb128(base, range, aug_size_off, &augmentation_size);
after_aug_size_off += aug_size_size;
}
@@ -476,19 +476,19 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
for (U8 *ptr = augmentation.str + 1, *opl = augmentation.str + augmentation.size; ptr < opl; ++ptr) {
switch (*ptr) {
case 'L': {
based_range_read_struct(base, range, aug_data_cursor, &lsda_encoding);
dw_based_range_read_struct(base, range, aug_data_cursor, &lsda_encoding);
aug_data_cursor += sizeof(lsda_encoding);
} break;
case 'P': {
DW_EhPtrEnc handler_encoding = DW_EhPtrEnc_Omit;
based_range_read_struct(base, range, aug_data_cursor, &handler_encoding);
dw_based_range_read_struct(base, range, aug_data_cursor, &handler_encoding);
U64 ptr_off = aug_data_cursor + sizeof(handler_encoding);
U64 ptr_size = dw_unwind_parse_pointer_x64(base, range, ptr_ctx, handler_encoding, ptr_off, &handler_ip);
aug_data_cursor = ptr_off + ptr_size;
} break;
case 'R': {
based_range_read_struct(base, range, aug_data_cursor, &addr_encoding);
dw_based_range_read_struct(base, range, aug_data_cursor, &addr_encoding);
aug_data_cursor += sizeof(addr_encoding);
} break;
default: {
@@ -547,7 +547,7 @@ dw_unwind_parse_fde_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, DW_CIEU
if (cie->has_augmentation_size) {
// augmentation size
U64 augmentation_size = 0;
U64 aug_size_size = based_range_read_uleb128(base, range, aug_data_off, &augmentation_size);
U64 aug_size_size = dw_based_range_read_uleb128(base, range, aug_data_off, &augmentation_size);
U64 after_aug_size_off = aug_data_off + aug_size_size;
// extract lsda (only thing that can actually be in FDE's augmentation data as far as we know)
@@ -863,7 +863,7 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
DW_CFAControlBits control_bits = 0;
// decode opcode/operand0
if (!based_range_read(base, range, cfi_off, 1, &opcode)) {
if (!dw_based_range_read(base, range, cfi_off, 1, &opcode)) {
result = 1;
goto done;
}
@@ -897,7 +897,7 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
} break;
default: {
if (d <= 8) {
based_range_read(base, range, decode_cursor, d, out);
dw_based_range_read(base, range, decode_cursor, d, out);
o_size = d;
}
} break;
@@ -905,10 +905,10 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
o_size = dw_unwind_parse_pointer_x64(base, range, ptr_ctx, cie->addr_encoding, decode_cursor, out);
} break;
case DW_CFADecode_ULEB128: {
o_size = based_range_read_uleb128(base, range, decode_cursor, out);
o_size = dw_based_range_read_uleb128(base, range, decode_cursor, out);
} break;
case DW_CFADecode_SLEB128: {
o_size = based_range_read_sleb128(base, range, decode_cursor, (S64*)out);
o_size = dw_based_range_read_sleb128(base, range, decode_cursor, (S64*)out);
} break;
}
decode_cursor += o_size;
+1 -1
View File
@@ -1677,7 +1677,7 @@ cv_c13_line_array_from_data(Arena *arena, String8 c13_data, U64 sec_base, CV_C13
{
CV_C13Line line = raw_lines[line_idx];
result.voffs[line_idx] = sec_base + parsed_lines.sec_off_lo + line.off;
result.line_nums[line_idx] = CV_C13LineFlags_ExtractLineNumber(line.flags);
result.line_nums[line_idx] = CV_C13LineFlags_Extract_LineNumber(line.flags);
}
// emit voff ender
+9 -9
View File
@@ -3699,9 +3699,9 @@ THREAD_POOL_TASK_FUNC(lnk_convert_types_to_rdi_task)
} break;
case CV_LeafKind_POINTER: {
CV_LeafPointer *ptr = (CV_LeafPointer *) src.data.str;
CV_PointerKind ptr_kind = CV_PointerAttribs_ExtractKind(ptr->attribs);
CV_PointerMode ptr_mode = CV_PointerAttribs_ExtractMode(ptr->attribs);
U32 ptr_size = CV_PointerAttribs_ExtractSize(ptr->attribs);
CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(ptr->attribs);
CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(ptr->attribs);
U32 ptr_size = CV_PointerAttribs_Extract_Size(ptr->attribs);
(void)ptr_kind;
// parse ahead type chain and squash modifiers
@@ -4010,7 +4010,7 @@ THREAD_POOL_TASK_FUNC(lnk_convert_types_to_rdi_task)
for (U64 cursor = 0; cursor + sizeof(CV_LeafMethodListMember) <= method_list_leaf.data.size; ) {
// parse CodeView method overload info
CV_LeafMethodListMember *list_member = (CV_LeafMethodListMember *) (method_list_leaf.data.str + cursor);
CV_MethodProp prop = CV_FieldAttribs_ExtractMethodProp(list_member->attribs);
CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(list_member->attribs);
cursor += sizeof(CV_LeafMethodListMember);
U32 vftable_offset = 0;
if (prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) {
@@ -4037,7 +4037,7 @@ THREAD_POOL_TASK_FUNC(lnk_convert_types_to_rdi_task)
case CV_LeafKind_ONEMETHOD: {
// parse CodeView method
CV_LeafOneMethod *one_method = (CV_LeafOneMethod *) (src.data.str + cursor);
CV_MethodProp prop = CV_FieldAttribs_ExtractMethodProp(one_method->attribs);
CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(one_method->attribs);
cursor += sizeof(CV_LeafOneMethod);
U32 vftable_offset = 0;
if (prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) {
@@ -4493,21 +4493,21 @@ THREAD_POOL_TASK_FUNC(lnk_find_obj_compiler_info_task)
AssertAlways(sizeof(CV_SymCompile) <= symbol.data.size);
CV_SymCompile *compile = (CV_SymCompile *)symbol.data.str;
comp_info->arch = compile->machine;
comp_info->language = CV_CompileFlags_ExtractLanguage(compile->flags);
comp_info->language = CV_CompileFlags_Extract_Language(compile->flags);
comp_info->compiler_name = str8_cstring_capped(compile + 1, symbol.data.str + symbol.data.size);
goto exit;
} else if (symbol.kind == CV_SymKind_COMPILE2) {
AssertAlways(sizeof(CV_SymCompile2) <= symbol.data.size);
CV_SymCompile2 *compile2 = (CV_SymCompile2 *)symbol.data.str;
comp_info->arch = compile2->machine;
comp_info->language = CV_Compile2Flags_ExtractLanguage(compile2->flags);
comp_info->language = CV_Compile2Flags_Extract_Language(compile2->flags);
comp_info->compiler_name = str8_cstring_capped(compile2 + 1, symbol.data.str + symbol.data.size);
goto exit;
} else if (symbol.kind == CV_SymKind_COMPILE3) {
AssertAlways(sizeof(CV_SymCompile3) <= symbol.data.size);
CV_SymCompile3 *compile3 = (CV_SymCompile3 *)symbol.data.str;
comp_info->arch = compile3->machine;
comp_info->language = CV_Compile3Flags_ExtractLanguage(compile3->flags);
comp_info->language = CV_Compile3Flags_Extract_Language(compile3->flags);
comp_info->compiler_name = str8_cstring_capped(compile3 + 1, symbol.data.str + symbol.data.size);
goto exit;
}
@@ -5104,7 +5104,7 @@ THREAD_POOL_TASK_FUNC(lnk_convert_symbols_to_rdi_task)
CV_LvarAddrGap *gaps = (CV_LvarAddrGap *) (defrange_subfield_register + 1);
U64 gap_count = (symbol.data.size - sizeof(*defrange_subfield_register)) / sizeof(gaps[0]);
RDI_RegCode reg_rdi = rdi_reg_code_from_cv(comp_info.arch, defrange_subfield_register->reg);
U32 value_pos = CV_DefrangeSubfieldRegister_ExtractParentOffset(defrange_subfield_register->field_offset);
U32 value_pos = CV_DefrangeSubfieldRegister_Extract_ParentOffset(defrange_subfield_register->field_offset);
U32 value_size = cv_size_from_reg(comp_info.arch, defrange_subfield_register->reg) - value_pos;
Rng1U64 defrange = lnk_virt_range_from_sect_off_size(defrange_subfield_register->range.sec, defrange_subfield_register->range.off, defrange_subfield_register->range.len, task->image_sects, obj, symbol.kind, symbol.offset);
Rng1U64List ranges = cv_make_defined_range_list_from_gaps(arena, defrange, gaps, gap_count);
+75 -31
View File
@@ -86,6 +86,50 @@ mscrt_parse_func_info(Arena *arena,
////////////////////////////////
internal U64
mscrt_v4_parse_u32(String8 raw_data, U64 offset, U32 *uint_out)
{
U64 cursor = offset;
U8 one = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &one);
if ((one & 0xF) == 15) {
U8 two = 0, three = 0, four = 0, five = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &two);
cursor += str8_deserial_read_struct(raw_data, cursor, &three);
cursor += str8_deserial_read_struct(raw_data, cursor, &four);
cursor += str8_deserial_read_struct(raw_data, cursor, &five);
*uint_out = (U32)two | ((U32)three << 8) | ((U32)four << 16) | ((U32)five << 24);
} else if ((one & 0xF) == 7) {
U8 two = 0, three = 0, four = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &two);
cursor += str8_deserial_read_struct(raw_data, cursor, &three);
cursor += str8_deserial_read_struct(raw_data, cursor, &four);
*uint_out = ((U32)one >> 4) | ((U32)two << 4) | ((U32)three << 12) | ((U32)four << 20);
} else if ((one & 0x7) == 3) {
U8 two = 0, three = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &two);
cursor += str8_deserial_read_struct(raw_data, cursor, &three);
*uint_out = ((U32)one >> 3) | ((U32)two << 5) | ((U32)three << 13);
} else if ((one & 0x3) == 1) {
U8 two = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &two);
*uint_out = ((U32)one >> 2) | ((U32)two << 6);
} else {
*uint_out = one >> 1;
}
U64 read_size = cursor - offset;
return read_size;
}
internal U64
mscrt_v4_parse_s32(String8 raw_data, U64 offset, S32 *int_out)
{
return str8_deserial_read_struct(raw_data, offset, int_out);
}
internal U64
mscrt_parse_handler_type_v4(String8 raw_data, U64 offset, U64 func_voff, MSCRT_EhHandlerTypeV4 *handler)
{
@@ -93,15 +137,15 @@ mscrt_parse_handler_type_v4(String8 raw_data, U64 offset, U64 func_voff, MSCRT_E
cursor += str8_deserial_read_struct(raw_data, cursor, &handler->flags);
if (handler->flags & MSCRT_EhHandlerV4Flag_Adjectives) {
cursor += str8_deserial_read_struct(raw_data, cursor, &handler->adjectives);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &handler->adjectives);
}
if (handler->flags & MSCRT_EhHandlerV4Flag_DispType) {
cursor += str8_deserial_read_struct(raw_data, cursor, &handler->type_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &handler->type_voff);
}
if (handler->flags & MSCRT_EhHandlerV4Flag_DispCatchObj) {
cursor += str8_deserial_read_struct(raw_data, cursor, &handler->catch_obj_voff);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &handler->catch_obj_voff);
}
cursor += str8_deserial_read_struct(raw_data, cursor, &handler->catch_code_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &handler->catch_code_voff);
U32 cont_type = (handler->flags & MSCRT_EhHandlerV4Flag_ContVOffMask) >> MSCRT_EhHandlerV4Flag_ContVOffShift;
if (handler->flags & MSCRT_EhHandlerV4Flag_ContIsVOff) {
@@ -109,14 +153,14 @@ mscrt_parse_handler_type_v4(String8 raw_data, U64 offset, U64 func_voff, MSCRT_E
case MSCRT_ContV4Type_NoMetadata: break;
case MSCRT_ContV4Type_OneFuncRelAddr: {
S32 v = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &v);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &v);
handler->catch_funclet_cont_addr[0] = (U64)v;
handler->catch_funclet_cont_addr_count = 1;
} break;
case MSCRT_ContV4Type_TwoFuncRelAddr: {
S32 v1 = 0, v2 = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &v1);
cursor += str8_deserial_read_struct(raw_data, cursor, &v2);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &v1);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &v2);
handler->catch_funclet_cont_addr[0] = (U64)v1;
handler->catch_funclet_cont_addr[1] = (U64)v2;
handler->catch_funclet_cont_addr_count = 2;
@@ -128,14 +172,14 @@ mscrt_parse_handler_type_v4(String8 raw_data, U64 offset, U64 func_voff, MSCRT_E
} break;
case MSCRT_ContV4Type_OneFuncRelAddr: {
U32 v = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &v);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &v);
handler->catch_funclet_cont_addr[0] = func_voff + (U64)v;
handler->catch_funclet_cont_addr_count = 1;
} break;
case MSCRT_ContV4Type_TwoFuncRelAddr: {
U32 v1 = 0, v2 = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &v1);
cursor += str8_deserial_read_struct(raw_data, cursor, &v2);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &v1);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &v2);
handler->catch_funclet_cont_addr[0] = func_voff + (U64)v1;
handler->catch_funclet_cont_addr[1] = func_voff + (U64)v2;
handler->catch_funclet_cont_addr_count = 2;
@@ -156,7 +200,7 @@ mscrt_parse_handler_type_v4_array(Arena *arena,
{
U64 cursor = offset;
U32 count = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &count);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &count);
MSCRT_EhHandlerTypeV4 *handlers = 0;
if (count) {
@@ -179,7 +223,7 @@ mscrt_parse_unwind_v4_entry(String8 raw_data, U64 offset, MSCRT_UnwindEntryV4 *e
U64 cursor = offset;
U32 type_and_next_off = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &type_and_next_off);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &type_and_next_off);
entry_out->type = type_and_next_off & 0x3;
entry_out->next_off = type_and_next_off >> 2;
@@ -187,11 +231,11 @@ mscrt_parse_unwind_v4_entry(String8 raw_data, U64 offset, MSCRT_UnwindEntryV4 *e
switch (entry_out->type) {
case MSCRT_UnwindMapV4Type_DtorWithObj:
case MSCRT_UnwindMapV4Type_DtorWithPtrToObj: {
cursor += str8_deserial_read_struct(raw_data, cursor, &entry_out->action);
cursor += str8_deserial_read_struct(raw_data, cursor, &entry_out->object);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &entry_out->action);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &entry_out->object);
} break;
case MSCRT_UnwindMapV4Type_VOFF: {
cursor += str8_deserial_read_struct(raw_data, cursor, &entry_out->action);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &entry_out->action);
} break;
case MSCRT_UnwindMapV4Type_NoUW: {
// no action and/or object is associated with this type
@@ -209,7 +253,7 @@ internal U64
mscrt_parse_unwind_map_v4(Arena *arena, String8 raw_data, U64 off, MSCRT_UnwindMapV4 *map_out)
{
U64 cursor = off;
cursor += str8_deserial_read_struct(raw_data, cursor, &map_out->count);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &map_out->count);
map_out->v = push_array(arena, MSCRT_UnwindEntryV4, map_out->count);
for (U32 i = 0; i < map_out->count; ++i) {
cursor += mscrt_parse_unwind_v4_entry(raw_data, cursor, &map_out->v[i]);
@@ -230,17 +274,17 @@ mscrt_parse_try_block_map_array_v4(Arena *arena,
U64 cursor = off;
U32 try_block_map_count = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &try_block_map_count);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &try_block_map_count);
MSCRT_TryBlockMapV4 *try_block_map = push_array(arena, MSCRT_TryBlockMapV4, try_block_map_count);
for (U32 itry = 0; itry < try_block_map_count; ++itry) {
MSCRT_TryBlockMapV4 *try_block = &try_block_map[itry];
cursor += str8_deserial_read_struct(raw_data, cursor, &try_block->try_low);
cursor += str8_deserial_read_struct(raw_data, cursor, &try_block->try_high);
cursor += str8_deserial_read_struct(raw_data, cursor, &try_block->catch_high);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &try_block->try_low);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &try_block->try_high);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &try_block->catch_high);
S32 handler_array_voff = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &handler_array_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &handler_array_voff);
U64 handler_array_foff = coff_foff_from_voff(sections, section_count, (U32)handler_array_voff);
mscrt_parse_handler_type_v4_array(arena, raw_data, handler_array_foff, func_voff, &try_block->handlers);
@@ -263,7 +307,7 @@ mscrt_parse_ip2state_map_v4(Arena *arena,
U64 cursor = off;
U32 count = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &count);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &count);
U32 *voffs = push_array(arena, U32, count);
S32 *states = push_array(arena, S32, count);
@@ -271,13 +315,13 @@ mscrt_parse_ip2state_map_v4(Arena *arena,
U32 prev_voff = func_voff;
for (U32 i = 0; i < count; ++i) {
// virtual offsets are encoded as deltas
cursor += str8_deserial_read_struct(raw_data, cursor, &voffs[i]);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &voffs[i]);
voffs[i] += prev_voff;
prev_voff = voffs[i];
// states are encoded with +1 to avoid encoding negative integers
U32 encoded_state = 0;
cursor += str8_deserial_read_struct(raw_data, cursor, &encoded_state);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &encoded_state);
states[i] = (S32)encoded_state - 1;
}
@@ -303,22 +347,22 @@ mscrt_parse_func_info_v4(Arena *arena,
MSCRT_FuncInfo32V4 func_info = {0};
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.header);
if (func_info.header & MSCRT_FuncInfoV4Flag_IsBBT) {
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.bbt_flags);
cursor += mscrt_v4_parse_u32(raw_data, cursor, &func_info.bbt_flags);
}
if (func_info.header & MSCRT_FuncInfoV4Flag_UnwindMap) {
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.unwind_map_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &func_info.unwind_map_voff);
}
if (func_info.header & MSCRT_FuncInfoV4Flag_TryBlockMap) {
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.try_block_map_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &func_info.try_block_map_voff);
}
if (func_info.header & MSCRT_FuncInfoV4Flag_IsSeparated) {
// TODO: separted IP state map
NotImplemented;
} else {
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.ip_to_state_map_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &func_info.ip_to_state_map_voff);
}
if (func_info.header & MSCRT_FuncInfoV4Flag_IsCatch) {
cursor += str8_deserial_read_struct(raw_data, cursor, &func_info.wrt_frame_establisher_voff);
cursor += mscrt_v4_parse_s32(raw_data, cursor, &func_info.wrt_frame_establisher_voff);
}
MSCRT_UnwindMapV4 unwind_map = {0};
@@ -387,8 +431,8 @@ mscrt_catch_blocks_from_data_x8664(Arena *arena,
String8 handler_name = str8_zero();
/* TODO:
{
SYMS_UnitID uid = syms_group_uid_from_voff__accelerated(group, handler_voff);
SYMS_UnitAccel *unit = syms_group_unit_from_uid(group, uid);
UnitID uid = syms_group_uid_from_voff__accelerated(group, handler_voff);
UnitAccel *unit = syms_group_unit_from_uid(group, uid);
SYMS_SymbolID sid = syms_group_proc_sid_from_uid_voff__accelerated(group, uid, handler_voff);
handler_name = syms_group_symbol_name_from_sid(temp.arena, group, unit, sid);
}
+2831 -413
View File
File diff suppressed because it is too large Load Diff
+153 -74
View File
@@ -9,31 +9,63 @@
#define rd_printf(f, ...) str8_list_pushf(arena, out, "%S" f, indent, __VA_ARGS__)
#define rd_newline() str8_list_pushf(arena, out, "");
#define rd_errorf(f, ...) rd_printf("ERROR: "f, __VA_ARGS__)
#define rd_errorf(f, ...) rd_stderr("ERROR: "f, __VA_ARGS__)
#define rd_warningf(f, ...) rd_stderr("WARNING: "f, __VA_ARGS__)
#define rd_indent() do { if (indent.size + RD_INDENT_WIDTH <= RD_INDENT_MAX) { indent.size += RD_INDENT_WIDTH; } else { Assert(!"indent overflow"); } } while (0)
#define rd_unindent() do { if (indent.size >= RD_INDENT_WIDTH) { indent.size -= RD_INDENT_WIDTH; } else { Assert(!"unbalanced indent"); } } while (0)
#define rd_unindent() do { if (indent.size >= RD_INDENT_WIDTH) { indent.size -= RD_INDENT_WIDTH; } else { Assert(!"unbalanced indent"); } } while (0)
typedef U64 RD_Option;
enum RD_OptionEnum
{
RD_Option_Help = (1 << 0),
RD_Option_Version = (1 << 1),
RD_Option_Headers = (1 << 2),
RD_Option_Sections = (1 << 3),
RD_Option_Debug = (1 << 4),
RD_Option_Imports = (1 << 5),
RD_Option_Exports = (1 << 6),
RD_Option_Disasm = (1 << 7),
RD_Option_Rawdata = (1 << 8),
RD_Option_Tls = (1 << 9),
RD_Option_Codeview = (1 << 10),
RD_Option_Symbols = (1 << 11),
RD_Option_Relocs = (1 << 12),
RD_Option_Exceptions = (1 << 13),
RD_Option_LoadConfig = (1 << 14),
RD_Option_Resources = (1 << 15),
RD_Option_LongNames = (1 << 16),
};
#define RD_Option_Help (1ull << 0)
#define RD_Option_Version (1ull << 1)
#define RD_Option_Headers (1ull << 2)
#define RD_Option_Sections (1ull << 3)
#define RD_Option_Debug (1ull << 4)
#define RD_Option_Imports (1ull << 5)
#define RD_Option_Exports (1ull << 6)
#define RD_Option_Disasm (1ull << 7)
#define RD_Option_Rawdata (1ull << 8)
#define RD_Option_Tls (1ull << 9)
#define RD_Option_Codeview (1ull << 10)
#define RD_Option_Symbols (1ull << 11)
#define RD_Option_Relocs (1ull << 12)
#define RD_Option_Exceptions (1ull << 13)
#define RD_Option_LoadConfig (1ull << 14)
#define RD_Option_Resources (1ull << 15)
#define RD_Option_LongNames (1ull << 16)
// DWARF
#define RD_Option_DebugInfo (1ull << 17)
#define RD_Option_DebugAbbrev (1ull << 18)
#define RD_Option_DebugLine (1ull << 19)
#define RD_Option_DebugStr (1ull << 20)
#define RD_Option_DebugLoc (1ull << 21)
#define RD_Option_DebugRanges (1ull << 22)
#define RD_Option_DebugARanges (1ull << 23)
#define RD_Option_DebugAddr (1ull << 24)
#define RD_Option_DebugLocLists (1ull << 25)
#define RD_Option_DebugRngLists (1ull << 26)
#define RD_Option_DebugPubNames (1ull << 27)
#define RD_Option_DebugPubTypes (1ull << 28)
#define RD_Option_DebugLineStr (1ull << 29)
#define RD_Option_DebugStrOffsets (1ull << 30)
#define RD_Option_Dwarf \
(RD_Option_DebugInfo | \
RD_Option_DebugAbbrev | \
RD_Option_DebugLine | \
RD_Option_DebugStr | \
RD_Option_DebugLoc | \
RD_Option_DebugRanges | \
RD_Option_DebugARanges | \
RD_Option_DebugAddr | \
RD_Option_DebugLocLists | \
RD_Option_DebugRngLists | \
RD_Option_DebugPubNames | \
RD_Option_DebugPubTypes | \
RD_Option_DebugLineStr | \
RD_Option_DebugStrOffsets)
#define RD_Option_RelaxDwarfParser (1ull << 31ull)
// RDI
#define RD_Option_NoRdi (1ull << 32ull)
typedef struct RD_Marker
{
@@ -66,77 +98,124 @@ typedef struct RD_DisasmResult
U64 size;
} RD_DisasmResult;
typedef struct RD_Section
{
String8 name;
String8 raw_data;
} RD_Section;
typedef struct RD_SectionArray
{
U64 count;
RD_Section *v;
} RD_SectionArray;
typedef struct RD_Line
{
String8 file_path;
U32 line_num;
} RD_Line;
////////////////////////////////
//- Markers
// raddump
internal B32 rd_is_pe(String8 raw_data);
internal void rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input_path, String8 raw_data);
// Markers
internal RD_MarkerArray * rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 string_table_off, U64 section_count, COFF_Symbol32Array symbols);
//- Disasm
// Sections
internal RD_SectionArray rd_sections_from_coff_section_table(Arena *arnea, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections);
// Disasm
internal RD_DisasmResult rd_disasm_next_instruction(Arena *arena, Arch arch, U64 addr, String8 raw_code);
internal void rd_format_disasm(Arena *arena, String8List *out, String8 indent, Arch arch, U64 image_base, U64 sect_off, U64 marker_count, RD_Marker *markers, String8 raw_code);
internal void rd_print_disasm (Arena *arena, String8List *out, String8 indent, Arch arch, U64 image_base, U64 sect_off, U64 marker_count, RD_Marker *markers, String8 raw_code);
//- Raw Data
// Raw Data
internal String8 rd_format_hex_array(Arena *arena, U8 *ptr, U64 size);
internal void rd_format_raw_data(Arena *arena, String8List *out, String8 indent, U64 bytes_per_row, U64 marker_count, RD_Marker *markers, String8 raw_data);
internal void rd_print_raw_data (Arena *arena, String8List *out, String8 indent, U64 bytes_per_row, U64 marker_count, RD_Marker *markers, String8 raw_data);
//- CodeView
// DWARF
internal void cv_format_binary_annots(Arena *arena, String8List *out, String8 indent, CV_Arch arch, String8 raw_data);
internal void cv_format_lvar_addr_range(Arena *arena, String8List *out, String8 indent, CV_LvarAddrRange range);
internal void cv_format_lvar_addr_gap(Arena *arena, String8List *out, String8 indent, String8 raw_data);
internal void cv_format_lvar_attr(Arena *arena, String8List *out, String8 indent, CV_LocalVarAttr attr);
internal void cv_format_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, U32 type, String8 raw_symbol);
internal U64 cv_format_leaf(Arena *arena, String8List *out, String8 indent, CV_LeafKind kind, String8 raw_leaf);
internal void cv_format_debug_t(Arena *arena, String8List *out, String8 indent, CV_DebugT debug_t);
internal void cv_format_symbols_c13(Arena *arena, String8List *out, String8 indent, String8 raw_data);
internal void cv_format_lines_c13(Arena *arena, String8List *out, String8 indent, String8 raw_lines);
internal void cv_format_file_checksums(Arena *arena, String8List *out, String8 indent, String8 raw_chksums);
internal void cv_format_string_table(Arena *arena, String8List *out, String8 indent, String8 raw_strtab);
internal void cv_format_inlinee_lines(Arena *arena, String8List *out, String8 indent, String8 raw_data);
internal void cv_format_symbols_section(Arena *arena, String8List *out, String8 indent, String8 raw_ss);
internal String8List dw_string_list_from_expression (Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64);
internal String8 dw_format_expression_single_line(Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64);
internal String8 dw_format_eh_ptr_enc (Arena *arena, DW_EhPtrEnc enc);
internal void dw_print_cfi_program (Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64);
//- COFF
internal void dw_print_eh_frame (Arena *arena, String8List *out, String8 indent, String8 raw_eh_frame, Arch arch, DW_Version ver, DW_Ext ext, DW_EhPtrCtx *ptr_ctx);
internal void dw_print_debug_info (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed);
internal void dw_print_debug_abbrev (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_line (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, B32 relaxed);
internal void dw_print_debug_str (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed);
internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed);
internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_vranges, Arch arch);
internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_vranges);
internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections);
internal void coff_format_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ArchiveMemberHeader header, String8 long_names);
internal void coff_format_section_table(Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_Symbol32Array symbols, U64 sect_count, COFF_SectionHeader *sect_headers);
internal void coff_disasm_sections(Arena *arena, String8List *out, String8 indent, String8 raw_data, COFF_MachineType machine, U64 image_base, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_raw_data_sections(Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_format_relocs(Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, COFF_Symbol32Array symbols);
internal void coff_format_symbol_table(Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_big_obj, U64 string_table_off, COFF_Symbol32Array symbols);
internal void coff_format_big_obj_header(Arena *arena, String8List *out, String8 indent, COFF_HeaderBigObj *header);
internal void coff_format_header(Arena *arena, String8List *out, String8 indent, COFF_Header *header);
internal void coff_format_import(Arena *arena, String8List *out, String8 indent, COFF_ImportHeader *header);
internal void coff_format_big_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_format_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_format_archive(Arena *arena, String8List *out, String8 indent, String8 raw_archive, RD_Option opts);
// CodeView
//- MSVC CRT
internal void cv_print_binary_annots (Arena *arena, String8List *out, String8 indent, CV_Arch arch, String8 raw_data);
internal void cv_print_lvar_addr_range(Arena *arena, String8List *out, String8 indent, CV_LvarAddrRange range);
internal void cv_print_lvar_addr_gap (Arena *arena, String8List *out, String8 indent, String8 raw_data);
internal void cv_print_lvar_attr (Arena *arena, String8List *out, String8 indent, CV_LocalVarAttr attr);
internal void cv_print_symbol (Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV_TypeIndex min_itype, CV_SymKind type, String8 raw_symbol);
internal U64 cv_print_leaf (Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_itype, CV_LeafKind kind, String8 raw_leaf);
internal void cv_print_debug_t (Arena *arena, String8List *out, String8 indent, CV_DebugT debug_t);
internal void cv_print_symbols_c13 (Arena *arena, String8List *out, String8 indent, CV_Arch arch, String8 raw_data);
internal void cv_print_lines_c13 (Arena *arena, String8List *out, String8 indent, String8 raw_lines);
internal void cv_print_file_checksums (Arena *arena, String8List *out, String8 indent, String8 raw_chksums);
internal void cv_print_string_table (Arena *arena, String8List *out, String8 indent, String8 raw_strtab);
internal void cv_print_inlinee_lines (Arena *arena, String8List *out, String8 indent, String8 raw_data);
internal void cv_print_symbols_section(Arena *arena, String8List *out, String8 indent, CV_Arch arch, String8 raw_ss);
internal void mscrt_format_eh_handler_type32(Arena *arena, String8List *out, String8 indent, MSCRT_EhHandlerType32 *handler);
// COFF
//- PE
internal void coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ArchiveMemberHeader header, String8 long_names);
internal void coff_print_seciton_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_Symbol32Array symbols, U64 sect_count, COFF_SectionHeader *sect_headers);
internal void coff_disasm_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, COFF_MachineType machine, U64 image_base, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_raw_data_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_print_relocs (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, COFF_Symbol32Array symbols);
internal void coff_print_symbol_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_big_obj, U64 string_table_off, COFF_Symbol32Array symbols);
internal void coff_print_big_obj_header (Arena *arena, String8List *out, String8 indent, COFF_HeaderBigObj *header);
internal void coff_print_header (Arena *arena, String8List *out, String8 indent, COFF_Header *header);
internal void coff_print_import (Arena *arena, String8List *out, String8 indent, COFF_ImportHeader *header);
internal void coff_print_big_obj (Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_print_obj (Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_print_archive (Arena *arena, String8List *out, String8 indent, String8 raw_archive, RD_Option opts);
internal void pe_format_data_directory_ranges(Arena *arena, String8List *out, String8 indent, U64 count, PE_DataDirectory *dirs);
internal void pe_format_optional_header32(Arena *arena, String8List *out, String8 indent, PE_OptionalHeader32 *opt_header, PE_DataDirectory *dirs);
internal void pe_format_optional_header32plus(Arena *arena, String8List *out, String8 indent, PE_OptionalHeader32Plus *opt_header, PE_DataDirectory *dirs);
internal void pe_format_load_config32(Arena *arena, String8List *out, String8 indent, PE_LoadConfig32 *lc);
internal void pe_format_load_config64(Arena *arena, String8List *out, String8 indent, PE_LoadConfig64 *lc);
internal void pe_format_tls(Arena *arena, String8List *out, String8 indent, PE_ParsedTLS tls);
internal void pe_format_debug_directory(Arena *arena, String8List *out, String8 indent, String8 raw_data, String8 raw_dir);
internal void pe_format_export_table(Arena *arena, String8List *out, String8 indent, PE_ParsedExportTable exptab);
internal void pe_format_static_import_table(Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedStaticImportTable imptab);
internal void pe_format_delay_import_table(Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedDelayImportTable imptab);
internal void pe_format_resources(Arena *arena, String8List *out, String8 indent, PE_ResourceDir *root);
internal void pe_format_exceptions_x8664(Arena *arena, String8List *out, String8 indent, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 except_frange);
internal void pe_format_exceptions(Arena *arena, String8List *out, String8 indent, COFF_MachineType machine, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 except_frange);
internal void pe_format_base_relocs(Arena *arena, String8List *out, String8 indent, COFF_MachineType machine, U64 image_base, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 base_reloc_franges);
internal void pe_format(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
// MSVC CRT
////////////////////////////////
internal void mscrt_print_eh_handler_type32(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, MSCRT_EhHandlerType32 *handler);
internal void format_preamble(Arena *arena, String8List *out, String8 indent, String8 input_path, String8 raw_data);
// PE
internal void pe_print_data_directory_ranges(Arena *arena, String8List *out, String8 indent, U64 count, PE_DataDirectory *dirs);
internal void pe_print_optional_header32 (Arena *arena, String8List *out, String8 indent, PE_OptionalHeader32 *opt_header, PE_DataDirectory *dirs);
internal void pe_print_optional_header32plus(Arena *arena, String8List *out, String8 indent, PE_OptionalHeader32Plus *opt_header, PE_DataDirectory *dirs);
internal void pe_print_load_config32 (Arena *arena, String8List *out, String8 indent, PE_LoadConfig32 *lc);
internal void pe_print_load_config64 (Arena *arena, String8List *out, String8 indent, PE_LoadConfig64 *lc);
internal void pe_print_tls (Arena *arena, String8List *out, String8 indent, PE_ParsedTLS tls);
internal void pe_print_debug_diretory (Arena *arena, String8List *out, String8 indent, String8 raw_data, String8 raw_dir);
internal void pe_print_export_table (Arena *arena, String8List *out, String8 indent, PE_ParsedExportTable exptab);
internal void pe_print_static_import_table (Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedStaticImportTable imptab);
internal void pe_print_delay_import_table (Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedDelayImportTable imptab);
internal void pe_print_resources (Arena *arena, String8List *out, String8 indent, PE_ResourceDir *root);
internal void pe_print_exceptions_x8664 (Arena *arena, String8List *out, String8 indent, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 except_frange, RDI_Parsed *rdi);
internal void pe_print_exceptions (Arena *arena, String8List *out, String8 indent, COFF_MachineType machine, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 except_frange, RDI_Parsed *rdi);
internal void pe_print_base_relocs (Arena *arena, String8List *out, String8 indent, COFF_MachineType machine, U64 image_base, U64 section_count, COFF_SectionHeader *sections, String8 raw_data, Rng1U64 base_reloc_franges, RDI_Parsed *rdi);
internal void pe_print (Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts, RDI_Parsed *rdi);
#endif // RADDUMP_H
+122 -52
View File
@@ -6,16 +6,25 @@
////////////////////////////////
#include "linker/base_ext/base_blake3.h"
#include "linker/base_ext/base_blake3.c"
#include "third_party/xxHash/xxhash.c"
#include "third_party/xxHash/xxhash.h"
#include "third_party/radsort/radsort.h"
#include "third_party/md5/md5.c"
#include "third_party/md5/md5.h"
#include "third_party/zydis/zydis.h"
#include "third_party/zydis/zydis.c"
#include "third_party/rad_lzb_simple/rad_lzb_simple.h"
#include "third_party/rad_lzb_simple/rad_lzb_simple.c"
////////////////////////////////
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "async/async.h"
#include "rdi_format/rdi_format_local.h"
#include "rdi_make/rdi_make_local.h"
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_enum.h"
@@ -28,9 +37,19 @@
#include "msf/msf.h"
#include "msf/msf_parse.h"
#include "pdb/pdb.h"
#include "pdb/pdb_parse.h"
#include "rdi_from_pdb/rdi_from_pdb.h"
#include "dwarf/dwarf.h"
#include "dwarf/dwarf_parse.h"
#include "dwarf/dwarf_expr.h"
#include "dwarf/dwarf_unwind.h"
#include "dwarf/dwarf_enum.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "async/async.c"
#include "rdi_format/rdi_format_local.c"
#include "rdi_make/rdi_make_local.c"
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_enum.c"
@@ -43,9 +62,16 @@
#include "msf/msf.c"
#include "msf/msf_parse.c"
#include "pdb/pdb.c"
#include "pdb/pdb_parse.c"
#include "rdi_from_pdb/rdi_from_pdb.c"
#include "dwarf/dwarf.c"
#include "dwarf/dwarf_parse.c"
#include "dwarf/dwarf_expr.c"
#include "dwarf/dwarf_unwind.c"
#include "dwarf/dwarf_enum.c"
#include "linker/base_ext/base_core.h"
#include "linker/base_ext/base_core.c"
#include "linker/base_ext/base_inc.h"
#include "linker/base_ext/base_inc.c"
#include "linker/path_ext/path.h"
#include "linker/path_ext/path.c"
#include "linker/thread_pool/thread_pool.h"
@@ -66,29 +92,66 @@ global read_only struct
char *name;
char *help;
} g_rd_dump_option_map[] = {
{ RD_Option_Help, "help", "Print help and exit" },
{ RD_Option_Version, "v", "Print version and exit" },
{ RD_Option_Headers, "headers", "Dump DOS header, file header, optional header, and/or archive header" },
{ RD_Option_Sections, "sections", "Dump section headers as table" },
{ RD_Option_Rawdata, "rawdata", "Dump raw section data" },
{ RD_Option_Codeview, "cv", "Dump CodeView" },
{ RD_Option_Disasm, "disasm", "Disassemble code sections" },
{ RD_Option_Symbols, "symbols", "Dump COFF symbol table" },
{ RD_Option_Relocs, "relocs", "Dump relocations" },
{ RD_Option_Exceptions, "exceptions", "Dump exceptions" },
{ RD_Option_Tls, "tls", "Dump Thread Local Storage directory" },
{ RD_Option_Debug, "debug", "Dump debug directory" },
{ RD_Option_Imports, "imports", "Dump import table" },
{ RD_Option_Exports, "exports", "Dump export table" },
{ RD_Option_LoadConfig, "loadconfig", "Dump load config" },
{ RD_Option_Resources, "resources", "Dump resource directory" },
{ RD_Option_LongNames, "longnames", "Dump archive long names" },
{ RD_Option_Help, "help", "Print help and exit" },
{ RD_Option_Version, "version", "Print version and exit" },
{ RD_Option_Headers, "headers", "Dump DOS header, file header, optional header, and/or archive header" },
{ RD_Option_Sections, "sections", "Dump section headers as table" },
{ RD_Option_Rawdata, "rawdata", "Dump raw section data" },
{ RD_Option_Codeview, "cv", "Dump CodeView" },
{ RD_Option_Disasm, "disasm", "Disassemble code sections" },
{ RD_Option_Symbols, "symtab", "Dump COFF symbol table" },
{ RD_Option_Relocs, "relocs", "Dump relocations" },
{ RD_Option_Exceptions, "exceptions", "Dump exceptions" },
{ RD_Option_Tls, "tls", "Dump Thread Local Storage directory" },
{ RD_Option_Debug, "debug", "Dump debug directory" },
{ RD_Option_Imports, "imports", "Dump import table" },
{ RD_Option_Exports, "exports", "Dump export table" },
{ RD_Option_LoadConfig, "loadconfig", "Dump load config" },
{ RD_Option_Resources, "resources", "Dump resource directory" },
{ RD_Option_LongNames, "longnames", "Dump archive long names" },
{ RD_Option_DebugInfo, "debug_info", "Dump .debug_info" },
{ RD_Option_DebugAbbrev, "debug_abbrev", "Dump .debug_abbrev" },
{ RD_Option_DebugLine, "debug_line", "Dump .debug_line" },
{ RD_Option_DebugStr, "debug_str", "Dump .debug_str" },
{ RD_Option_DebugLoc, "debug_loc", "Dump .debug_loc" },
{ RD_Option_DebugRanges, "debug_ranges", "Dump .debug_ranges" },
{ RD_Option_DebugARanges, "debug_aranges", "Dump .debug_aranges" },
{ RD_Option_DebugAddr, "debug_addr", "Dump .debug_addr" },
{ RD_Option_DebugLocLists, "debug_loclists", "Dump .debug_loclists" },
{ RD_Option_DebugRngLists, "debug_rnglists", "Dump .debug_rnglists" },
{ RD_Option_DebugPubNames, "debug_pubnames", "Dump .debug_pubnames" },
{ RD_Option_DebugPubTypes, "debug_pubtypes", "Dump .debug_putypes" },
{ RD_Option_DebugLineStr, "debug_linestr", "Dump .debug_linestr" },
{ RD_Option_DebugStrOffsets, "debug_stroffsets", "Dump .debug_stroffsets" },
{ RD_Option_Dwarf, "dwarf", "Dump all DWARF sections" },
{ RD_Option_RelaxDwarfParser, "relax_dwarf_parser", "Relaxes version requirement on attribute and form encodings" },
{ RD_Option_NoRdi, "nordi", "Don't load RAD Debug Info" },
{ RD_Option_Help, "h", "Alias for -help" },
{ RD_Option_Version, "v", "Alias for -version" },
{ RD_Option_Sections, "s", "Alias for -sections" },
{ RD_Option_Exceptions, "e", "Alias for -exceptions" },
{ RD_Option_Imports, "i", "Alias for -imports" },
{ RD_Option_Exports, "x", "Alias for -exports" },
{ RD_Option_LoadConfig, "l", "Alias for -loadconifg" },
{ RD_Option_Resources, "c", "Alias for -resources" },
{ RD_Option_Relocs, "r", "Alias for -relocs" },
};
internal void
entry_point(CmdLine *cmdline)
{
Temp scratch = scratch_begin(0,0);
Arena *arena = arena_alloc();
// make indent
String8List *out = push_array(arena, String8List, 1);
String8 indent;
{
U64 indent_buffer_size = RD_INDENT_WIDTH * RD_INDENT_MAX;
U8 *indent_buffer = push_array(arena, U8, indent_buffer_size);
MemorySet(indent_buffer, ' ', indent_buffer_size);
indent = str8(indent_buffer, 0);
}
// parse options
RD_Option opts = 0;
@@ -107,8 +170,8 @@ entry_point(CmdLine *cmdline)
}
if (opt == 0) {
fprintf(stderr, "Unknown argument: \"%.*s\"\n", str8_varg(cmd->string));
os_abort(1);
rd_errorf("Unknown argument: \"%S\"", cmd->string);
goto exit;
}
opts |= opt;
@@ -117,66 +180,73 @@ entry_point(CmdLine *cmdline)
// print help
if (opts & RD_Option_Help) {
int longest_cmd_switch = 0;
for (U64 opt_idx = 0; opt_idx < ArrayCount(g_rd_dump_option_map); ++opt_idx) {
fprintf(stdout, "-%s %s\n", g_rd_dump_option_map[opt_idx].name, g_rd_dump_option_map[opt_idx].help);
longest_cmd_switch = Max(longest_cmd_switch, strlen(g_rd_dump_option_map[opt_idx].name));
}
os_abort(0);
rd_printf(BUILD_TITLE_STRING_LITERAL);
rd_newline();
rd_printf("# Help");
rd_indent();
for (U64 opt_idx = 0; opt_idx < ArrayCount(g_rd_dump_option_map); ++opt_idx) {
char *name = g_rd_dump_option_map[opt_idx].name;
char *help = g_rd_dump_option_map[opt_idx].help;
int indent_size = longest_cmd_switch - strlen(name) + 1;
rd_printf("-%s%.*s%s", g_rd_dump_option_map[opt_idx].name, indent_size, indent.str, g_rd_dump_option_map[opt_idx].help);
}
rd_unindent();
goto exit;
}
// print version
if (opts & RD_Option_Version) {
fprintf(stdout, BUILD_TITLE_STRING_LITERAL "\n");
fprintf(stdout, "\traddump <options> <inputs>\n");
os_abort(0);
rd_printf(BUILD_TITLE_STRING_LITERAL);
rd_printf("\traddump <options> <inputs>");
goto exit;
}
// input check
if (cmdline->inputs.node_count == 0) {
fprintf(stderr, "No input file specified\n");
os_abort(1);
rd_errorf("No input file specified");
goto exit;
} else if (cmdline->inputs.node_count > 1) {
fprintf(stderr, "Too many inputs specified, expected one\n");
os_abort(1);
rd_errorf("Too many inputs specified, expected one");
goto exit;
}
// read input
String8 file_path = str8_list_first(&cmdline->inputs);
String8 raw_data = os_data_from_file_path(scratch.arena, file_path);
String8 raw_data = os_data_from_file_path(arena, file_path);
// is read ok?
if (raw_data.size == 0) {
fprintf(stderr, "Unable to read input file \"%.*s\"\n", str8_varg(file_path));
os_abort(1);
}
// make indent
String8 indent;
{
U64 indent_buffer_size = RD_INDENT_WIDTH * RD_INDENT_MAX;
U8 *indent_buffer = push_array(scratch.arena, U8, indent_buffer_size);
MemorySet(indent_buffer, ' ', indent_buffer_size);
indent = str8(indent_buffer, 0);
rd_errorf("Unable to read input file \"%S\"", file_path);
goto exit;
}
// format input
String8List out = {0};
format_preamble(scratch.arena, &out, indent, file_path, raw_data);
rd_format_preamble(arena, out, indent, file_path, raw_data);
if (coff_is_archive(raw_data) || coff_is_thin_archive(raw_data)) {
coff_format_archive(scratch.arena, &out, indent, raw_data, opts);
coff_print_archive(arena, out, indent, raw_data, opts);
} else if (coff_is_big_obj(raw_data)) {
coff_format_big_obj(scratch.arena, &out, indent, raw_data, opts);
coff_print_big_obj(arena, out, indent, raw_data, opts);
} else if (coff_is_obj(raw_data)) {
coff_format_obj(scratch.arena, &out, indent, raw_data, opts);
} else if (is_pe(raw_data)) {
pe_format(scratch.arena, &out, indent, raw_data, opts);
coff_print_obj(arena, out, indent, raw_data, opts);
} else if (rd_is_pe(raw_data)) {
RDI_Parsed *rdi = 0;
if (!(opts & RD_Option_NoRdi)) {
rdi = rd_rdi_from_pe(arena, file_path, raw_data);
}
pe_print(arena, out, indent, raw_data, opts, rdi);
} else if (pe_is_res(raw_data)) {
//tool_out_coff_res(stdout, file_data);
}
exit:;
// print formatted string
String8 out_string = str8_list_join(scratch.arena, &out, &(StringJoin){ .sep = str8_lit("\n"),});
String8 out_string = str8_list_join(arena, out, &(StringJoin){ .sep = str8_lit("\n"),});
fprintf(stdout, "%.*s", str8_varg(out_string));
scratch_end(scratch);
arena_release(arena);
}