mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
d2r2: hook up scope containers to contained types / namespaces; fix address table parsing
This commit is contained in:
@@ -908,13 +908,25 @@ dw2_read_offset_table(String8 data, U64 off, DW2_OffsetTable *out)
|
|||||||
// rjf: version 5: read rest (this section only exists in 5+)
|
// rjf: version 5: read rest (this section only exists in 5+)
|
||||||
if(version == DW_Version_5)
|
if(version == DW_Version_5)
|
||||||
{
|
{
|
||||||
// rjf: skip padding
|
// rjf: read address / segment selector size (these need to be 0 in non-address offset tables)
|
||||||
off += sizeof(U16);
|
U8 addr_size = 0;
|
||||||
|
U8 segment_selector_size = 0;
|
||||||
|
off += str8_deserial_read_struct(data, off, &addr_size);
|
||||||
|
off += str8_deserial_read_struct(data, off, &segment_selector_size);
|
||||||
|
|
||||||
|
// rjf: determine entry size
|
||||||
|
U64 entry_size = dw_size_from_format(format);
|
||||||
|
if(addr_size != 0)
|
||||||
|
{
|
||||||
|
entry_size = addr_size + segment_selector_size;
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: fill table info
|
// rjf: fill table info
|
||||||
out->format = format;
|
out->format = format;
|
||||||
out->version = version;
|
out->version = version;
|
||||||
out->entry_size = dw_size_from_format(format);
|
out->addr_size = addr_size;
|
||||||
|
out->segment_selector_size = segment_selector_size;
|
||||||
|
out->entry_size = entry_size;
|
||||||
out->entries_count = (unit_data_off_opl - off) / out->entry_size;
|
out->entries_count = (unit_data_off_opl - off) / out->entry_size;
|
||||||
out->entries = data.str + off;
|
out->entries = data.str + off;
|
||||||
|
|
||||||
@@ -934,7 +946,21 @@ dw2_try_offset_from_table_idx(DW2_OffsetTable *tbl, U64 idx, U64 *out)
|
|||||||
{
|
{
|
||||||
U64 entry_size = tbl->entry_size;
|
U64 entry_size = tbl->entry_size;
|
||||||
U64 entry_off = idx * entry_size;
|
U64 entry_off = idx * entry_size;
|
||||||
|
if(tbl->addr_size != 0)
|
||||||
|
{
|
||||||
|
U64 segment_off = entry_off;
|
||||||
|
U64 addr_off = entry_off + tbl->segment_selector_size;
|
||||||
|
U64 segment = 0;
|
||||||
|
U64 addr = 0;
|
||||||
|
MemoryCopy(&segment, (U8 *)tbl->entries + segment_off, tbl->segment_selector_size);
|
||||||
|
MemoryCopy(&addr, (U8 *)tbl->entries + addr_off, tbl->addr_size);
|
||||||
|
// TODO(rjf): @segment_based_addressing
|
||||||
|
*out = addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
MemoryCopy(out, (U8 *)tbl->entries + entry_off, entry_size);
|
MemoryCopy(out, (U8 *)tbl->entries + entry_off, entry_size);
|
||||||
|
}
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ struct DW2_OffsetTable
|
|||||||
{
|
{
|
||||||
DW_Format format;
|
DW_Format format;
|
||||||
DW_Version version;
|
DW_Version version;
|
||||||
|
U8 addr_size;
|
||||||
|
U8 segment_selector_size;
|
||||||
U64 entry_size;
|
U64 entry_size;
|
||||||
U64 entries_count;
|
U64 entries_count;
|
||||||
void *entries;
|
void *entries;
|
||||||
|
|||||||
@@ -281,10 +281,15 @@ e_interpret(String8 bytecode)
|
|||||||
U8 byte_size = (imm.u64&0x00FF00)>>8;
|
U8 byte_size = (imm.u64&0x00FF00)>>8;
|
||||||
U8 byte_off = (imm.u64&0xFF0000)>>16;
|
U8 byte_off = (imm.u64&0xFF0000)>>16;
|
||||||
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(e_interpret_ctx->reg_arch, rdi_reg_code);
|
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(e_interpret_ctx->reg_arch, rdi_reg_code);
|
||||||
REGS_Rng rng = regs_reg_code_rng_table_from_arch(e_interpret_ctx->reg_arch)[base_reg_code];
|
REGS_Rng *rng_table = regs_reg_code_rng_table_from_arch(e_interpret_ctx->reg_arch);
|
||||||
|
B32 good_read = 0;
|
||||||
|
if(0 <= rdi_reg_code && rdi_reg_code < regs_reg_code_count_from_arch(e_interpret_ctx->reg_arch))
|
||||||
|
{
|
||||||
|
REGS_Rng rng = rng_table[base_reg_code];
|
||||||
U64 off = (U64)rng.byte_off + byte_off;
|
U64 off = (U64)rng.byte_off + byte_off;
|
||||||
U64 size = (U64)byte_size;
|
U64 size = (U64)byte_size;
|
||||||
B32 good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
|
good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
|
||||||
|
}
|
||||||
if(!good_read)
|
if(!good_read)
|
||||||
{
|
{
|
||||||
result.code = E_InterpretationCode_BadRegRead;
|
result.code = E_InterpretationCode_BadRegRead;
|
||||||
|
|||||||
@@ -2455,7 +2455,6 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
// rjf: build type
|
// rjf: build type
|
||||||
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
|
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
|
||||||
dst_type->kind = RDI_TypeKind_Function;
|
dst_type->kind = RDI_TypeKind_Function;
|
||||||
dst_type->name = name;
|
|
||||||
dst_type->direct_type = direct_type;
|
dst_type->direct_type = direct_type;
|
||||||
dst_type->byte_size = arch_addr_size;
|
dst_type->byte_size = arch_addr_size;
|
||||||
|
|
||||||
@@ -2914,7 +2913,8 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
(type->kind == RDI_TypeKind_Struct ||
|
(type->kind == RDI_TypeKind_Struct ||
|
||||||
type->kind == RDI_TypeKind_Union ||
|
type->kind == RDI_TypeKind_Union ||
|
||||||
type->kind == RDI_TypeKind_Class ||
|
type->kind == RDI_TypeKind_Class ||
|
||||||
type->kind == RDI_TypeKind_Enum))
|
type->kind == RDI_TypeKind_Enum ||
|
||||||
|
type->kind == RDI_TypeKind_Alias))
|
||||||
{
|
{
|
||||||
// rjf: produce UDT
|
// rjf: produce UDT
|
||||||
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &lane_udts, chunk_count);
|
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &lane_udts, chunk_count);
|
||||||
@@ -3238,6 +3238,19 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
//- rjf: convert all symbols
|
//- rjf: convert all symbols
|
||||||
//
|
//
|
||||||
|
typedef struct D2R2_ScopeContainerNode D2R2_ScopeContainerNode;
|
||||||
|
struct D2R2_ScopeContainerNode
|
||||||
|
{
|
||||||
|
D2R2_ScopeContainerNode *next;
|
||||||
|
U64 info_off;
|
||||||
|
RDIM_Scope *scope;
|
||||||
|
};
|
||||||
|
typedef struct D2R2_ScopeContainerMap D2R2_ScopeContainerMap;
|
||||||
|
struct D2R2_ScopeContainerMap
|
||||||
|
{
|
||||||
|
D2R2_ScopeContainerNode **slots;
|
||||||
|
U64 slots_count;
|
||||||
|
};
|
||||||
typedef struct D2R2_SubUnitWorkArtifacts D2R2_SubUnitWorkArtifacts;
|
typedef struct D2R2_SubUnitWorkArtifacts D2R2_SubUnitWorkArtifacts;
|
||||||
struct D2R2_SubUnitWorkArtifacts
|
struct D2R2_SubUnitWorkArtifacts
|
||||||
{
|
{
|
||||||
@@ -3248,13 +3261,18 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
RDIM_ScopeChunkList scopes;
|
RDIM_ScopeChunkList scopes;
|
||||||
RDIM_InlineSiteChunkList inline_sites;
|
RDIM_InlineSiteChunkList inline_sites;
|
||||||
};
|
};
|
||||||
|
D2R2_ScopeContainerMap *scope_container_map = 0;
|
||||||
D2R2_SubUnitWorkArtifacts *sub_unit_work_artifacts = 0;
|
D2R2_SubUnitWorkArtifacts *sub_unit_work_artifacts = 0;
|
||||||
ProfScope("convert all symbols")
|
ProfScope("convert all symbols")
|
||||||
{
|
{
|
||||||
if(lane_idx() == 0)
|
if(lane_idx() == 0)
|
||||||
{
|
{
|
||||||
|
scope_container_map = push_array(scratch.arena, D2R2_ScopeContainerMap, 1);
|
||||||
|
scope_container_map->slots_count = total_tag_count_estimate/8 + 1;
|
||||||
|
scope_container_map->slots = push_array(scratch.arena, D2R2_ScopeContainerNode *, scope_container_map->slots_count);
|
||||||
sub_unit_work_artifacts = push_array(scratch.arena, D2R2_SubUnitWorkArtifacts, sub_unit_works_count);
|
sub_unit_work_artifacts = push_array(scratch.arena, D2R2_SubUnitWorkArtifacts, sub_unit_works_count);
|
||||||
}
|
}
|
||||||
|
lane_sync_u64(&scope_container_map, 0);
|
||||||
lane_sync_u64(&sub_unit_work_artifacts, 0);
|
lane_sync_u64(&sub_unit_work_artifacts, 0);
|
||||||
U64 work_take_idx_ = 0;
|
U64 work_take_idx_ = 0;
|
||||||
U64 *work_take_idx_ptr = &work_take_idx_;
|
U64 *work_take_idx_ptr = &work_take_idx_;
|
||||||
@@ -4205,10 +4223,22 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
//
|
//
|
||||||
RDIM_Symbol *new_symbol = 0;
|
RDIM_Symbol *new_symbol = 0;
|
||||||
RDIM_Scope *new_scope_open = 0;
|
RDIM_Scope *new_scope_open = 0;
|
||||||
|
B32 parent_tag_is_container_to_deduped_tags = 0;
|
||||||
switch(tag.kind)
|
switch(tag.kind)
|
||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
|
|
||||||
|
//- rjf: determine if parent tag is a container to deduplicated tags
|
||||||
|
case DW_TagKind_Namespace:
|
||||||
|
case DW_TagKind_StructureType:
|
||||||
|
case DW_TagKind_UnionType:
|
||||||
|
case DW_TagKind_ClassType:
|
||||||
|
case DW_TagKind_EnumerationType:
|
||||||
|
case DW_TagKind_Typedef:
|
||||||
|
{
|
||||||
|
parent_tag_is_container_to_deduped_tags = 1;
|
||||||
|
}break;
|
||||||
|
|
||||||
//- rjf: subprograms (procedures)
|
//- rjf: subprograms (procedures)
|
||||||
case DW_TagKind_SubProgram:
|
case DW_TagKind_SubProgram:
|
||||||
{
|
{
|
||||||
@@ -4268,6 +4298,44 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
//- rjf: if we've determined that the parent tag is a container to
|
||||||
|
// deduplicated tags (types, namespaces), then we need to record
|
||||||
|
// the .debug_info offset -> scope mapping for this scope, so it
|
||||||
|
// can be equipped as a container later.
|
||||||
|
//
|
||||||
|
if(parent_tag_is_container_to_deduped_tags)
|
||||||
|
{
|
||||||
|
U64 info_off = 0;
|
||||||
|
RDIM_Scope *scope = 0;
|
||||||
|
for(D2R2_ParentNode *n = top_parent; n != 0; n = n->next)
|
||||||
|
{
|
||||||
|
if(n->scope != 0)
|
||||||
|
{
|
||||||
|
info_off = n->info_off;
|
||||||
|
scope = n->scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(scope != 0)
|
||||||
|
{
|
||||||
|
D2R2_ScopeContainerNode *n = push_array(scratch.arena, D2R2_ScopeContainerNode, 1);
|
||||||
|
n->info_off = info_off;
|
||||||
|
n->scope = scope;
|
||||||
|
U64 hash = u64_hash_from_str8(str8_struct(&info_off));
|
||||||
|
U64 slot_idx = hash%scope_container_map->slots_count;
|
||||||
|
for(B32 gathered = 0; !gathered;)
|
||||||
|
{
|
||||||
|
U64 expected_head_value = ins_atomic_u64_eval(&scope_container_map->slots[slot_idx]);
|
||||||
|
n->next = (D2R2_ScopeContainerNode *)expected_head_value;
|
||||||
|
if(expected_head_value == ins_atomic_u64_eval_cond_assign(&scope_container_map->slots[slot_idx], (U64)n, expected_head_value))
|
||||||
|
{
|
||||||
|
gathered = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
//- rjf: equip new symbols with container info
|
//- rjf: equip new symbols with container info
|
||||||
//
|
//
|
||||||
@@ -4464,9 +4532,26 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rjf: find container scopes
|
||||||
|
RDIM_Scope *container_scope = 0;
|
||||||
|
{
|
||||||
|
U64 info_off = container_ancestor_info_off;
|
||||||
|
U64 hash = u64_hash_from_str8(str8_struct(&info_off));
|
||||||
|
U64 slot_idx = hash%scope_container_map->slots_count;
|
||||||
|
for(D2R2_ScopeContainerNode *n = scope_container_map->slots[slot_idx]; n != 0; n = n->next)
|
||||||
|
{
|
||||||
|
if(n->info_off == info_off)
|
||||||
|
{
|
||||||
|
container_scope = n->scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: find container types/namespaces
|
// rjf: find container types/namespaces
|
||||||
RDIM_Type *container_type = 0;
|
RDIM_Type *container_type = 0;
|
||||||
RDIM_Namespace *container_namespace = 0;
|
RDIM_Namespace *container_namespace = 0;
|
||||||
|
if(!container_scope)
|
||||||
{
|
{
|
||||||
U64 info_off = container_ancestor_info_off;
|
U64 info_off = container_ancestor_info_off;
|
||||||
U64 unit_num = rng1u64_array_num_from_value__binary_search(&unit_info_tag_ranges_array, info_off);
|
U64 unit_num = rng1u64_array_num_from_value__binary_search(&unit_info_tag_ranges_array, info_off);
|
||||||
@@ -4510,6 +4595,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rjf: fill
|
// rjf: fill
|
||||||
|
dst_udt->container_scope = container_scope;
|
||||||
dst_udt->container_type = container_type;
|
dst_udt->container_type = container_type;
|
||||||
dst_udt->container_namespace = container_namespace;
|
dst_udt->container_namespace = container_namespace;
|
||||||
}
|
}
|
||||||
@@ -4532,6 +4618,22 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rjf: find container scopes
|
||||||
|
RDIM_Scope *container_scope = 0;
|
||||||
|
{
|
||||||
|
U64 info_off = container_ancestor_info_off;
|
||||||
|
U64 hash = u64_hash_from_str8(str8_struct(&info_off));
|
||||||
|
U64 slot_idx = hash%scope_container_map->slots_count;
|
||||||
|
for(D2R2_ScopeContainerNode *n = scope_container_map->slots[slot_idx]; n != 0; n = n->next)
|
||||||
|
{
|
||||||
|
if(n->info_off == info_off)
|
||||||
|
{
|
||||||
|
container_scope = n->scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: find container types/namespaces
|
// rjf: find container types/namespaces
|
||||||
RDIM_Type *container_type = 0;
|
RDIM_Type *container_type = 0;
|
||||||
RDIM_Namespace *container_namespace = 0;
|
RDIM_Namespace *container_namespace = 0;
|
||||||
@@ -4578,6 +4680,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rjf: fill
|
// rjf: fill
|
||||||
|
dst_namespace->parent_scope = container_scope;
|
||||||
dst_namespace->parent_type = container_type;
|
dst_namespace->parent_type = container_type;
|
||||||
dst_namespace->parent_namespace = container_namespace;
|
dst_namespace->parent_namespace = container_namespace;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_B
|
|||||||
if(src_section->sh_flags & ELF_Shf_Write) { flags |= RDI_BinarySectionFlag_Write; }
|
if(src_section->sh_flags & ELF_Shf_Write) { flags |= RDI_BinarySectionFlag_Write; }
|
||||||
if(src_section->sh_flags & ELF_Shf_ExecInstr) { flags |= RDI_BinarySectionFlag_Execute; }
|
if(src_section->sh_flags & ELF_Shf_ExecInstr) { flags |= RDI_BinarySectionFlag_Execute; }
|
||||||
|
|
||||||
// rjf: make rdi section
|
// rjf: make rdi section if not empty
|
||||||
|
if(name.size != 0 || voff_opl != voff_first || foff_opl != foff_first)
|
||||||
|
{
|
||||||
RDIM_BinarySection *dst_section = rdim_binary_section_list_push(arena, &result);
|
RDIM_BinarySection *dst_section = rdim_binary_section_list_push(arena, &result);
|
||||||
dst_section->name = name;
|
dst_section->name = name;
|
||||||
dst_section->flags = flags;
|
dst_section->flags = flags;
|
||||||
@@ -29,5 +31,6 @@ e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_B
|
|||||||
dst_section->foff_first = foff_first;
|
dst_section->foff_first = foff_first;
|
||||||
dst_section->foff_opl = foff_opl;
|
dst_section->foff_opl = foff_opl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-12
@@ -1,6 +1,15 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: Architecture Tables
|
||||||
|
|
||||||
|
@table(name, name_lower)
|
||||||
|
REGS_ArchTable:
|
||||||
|
{
|
||||||
|
{X64 x64}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: X64 Tables
|
//~ rjf: X64 Tables
|
||||||
|
|
||||||
@@ -200,18 +209,6 @@ REGS_AliasTableX64:
|
|||||||
{mm7 st7 0 64 Vector}
|
{mm7 st7 0 64 Vector}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ rjf: Architecture Tables
|
|
||||||
|
|
||||||
@table(name, name_lower)
|
|
||||||
REGS_ArchTable:
|
|
||||||
{
|
|
||||||
{X64 x64}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ rjf: X64 Generators
|
|
||||||
|
|
||||||
@enum REGS_RegCodeX64:
|
@enum REGS_RegCodeX64:
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
|
|||||||
Reference in New Issue
Block a user