mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-09 19:11:38 -07:00
WIP collect sections associations
This commit is contained in:
committed by
Ryan Fleury
parent
a4ac07162e
commit
a6b2cf64ba
@@ -348,7 +348,8 @@ C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t s
|
||||
#endif
|
||||
#define PtrFromInt(i) (void*)(i)
|
||||
|
||||
#define Compose64Bit(a,b) ((((U64)a) << 32) | ((U64)b));
|
||||
#define Compose64Bit(a,b) ((((U64)a) << 32) | ((U64)b))
|
||||
#define Compose32Bit(a,b) ((((U32)a) << 16) | ((U32)b))
|
||||
#define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1)))
|
||||
#define AlignDownPow2(x,b) ((x)&(~((b) - 1)))
|
||||
#define AlignPadPow2(x,b) ((0-(x)) & ((b) - 1))
|
||||
|
||||
@@ -296,7 +296,7 @@ coff_parse_secdef(COFF_ParsedSymbol symbol, B32 is_big_obj, COFF_ComdatSelectTyp
|
||||
if (selection_out) *selection_out = sd->selection;
|
||||
if (length_out) *length_out = sd->length;
|
||||
if (check_sum_out) *check_sum_out = sd->check_sum;
|
||||
if (number_out) *number_out = sd->number_lo | ((U32)sd->number_hi << 16);
|
||||
if (number_out) *number_out = Compose32Bit(sd->number_hi, sd->number_lo);
|
||||
} else {
|
||||
COFF_SymbolSecDef *sd = (COFF_SymbolSecDef *)((COFF_Symbol16 *)symbol.raw_symbol + 1);
|
||||
if (selection_out) *selection_out = sd->selection;
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct U32Node
|
||||
{
|
||||
struct U32Node *next;
|
||||
U32 data;
|
||||
} U32Node;
|
||||
|
||||
typedef struct U64Node
|
||||
{
|
||||
struct U64Node *next;
|
||||
|
||||
@@ -4053,8 +4053,6 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
||||
.null_sc = push_array(arena->v[0], LNK_SectionContrib, 1),
|
||||
};
|
||||
|
||||
tp_for_parallel(tp, 0, objs_count, lnk_remove_associative_sections_task, &task);
|
||||
|
||||
{
|
||||
ProfBegin("Define And Count Sections");
|
||||
TP_Temp temp = tp_temp_begin(arena);
|
||||
|
||||
+35
-9
@@ -224,6 +224,31 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//
|
||||
// collect sections associations
|
||||
//
|
||||
U32Node **associated_sections = push_array(arena, U32Node *, header.section_count_no_null + 1);
|
||||
{
|
||||
String8 string_table = str8_substr(input->data, header.string_table_range);
|
||||
String8 symbol_table = str8_substr(input->data, header.symbol_table_range);
|
||||
|
||||
COFF_ParsedSymbol symbol;
|
||||
for (U32 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = coff_parse_symbol(header, string_table, symbol_table, symbol_idx);
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
if (interp == COFF_SymbolValueInterp_Regular && symbol.storage_class == COFF_SymStorageClass_Static && symbol.aux_symbol_count > 0) {
|
||||
COFF_ComdatSelectType selection = COFF_ComdatSelect_Null;
|
||||
U32 section_number = 0;
|
||||
coff_parse_secdef(symbol, header.is_big_obj, &selection, §ion_number, 0, 0);
|
||||
if (selection != COFF_ComdatSelect_Associative) { continue; }
|
||||
|
||||
U32Node *associated_node = push_array(arena, U32Node, 1);
|
||||
associated_node->data = symbol.section_number;
|
||||
SLLStackPush(associated_sections[section_number], associated_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// extract obj features from compile symbol in .debug$S
|
||||
@@ -267,13 +292,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
|
||||
// fill out obj
|
||||
obj->data = input->data;
|
||||
obj->path = push_str8_copy(arena, input->path);
|
||||
obj->lib_path = push_str8_copy(arena, input->lib_path);
|
||||
obj->input_idx = obj_idx;
|
||||
obj->header = header;
|
||||
obj->comdats = comdats;
|
||||
obj->hotpatch = hotpatch;
|
||||
obj->data = input->data;
|
||||
obj->path = push_str8_copy(arena, input->path);
|
||||
obj->lib_path = push_str8_copy(arena, input->lib_path);
|
||||
obj->input_idx = obj_idx;
|
||||
obj->header = header;
|
||||
obj->comdats = comdats;
|
||||
obj->hotpatch = hotpatch;
|
||||
obj->associated_sections = associated_sections;
|
||||
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -466,13 +492,13 @@ lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
}
|
||||
|
||||
internal B32
|
||||
lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_length_out, U32 *check_sum_out)
|
||||
lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_number_out, U32 *section_length_out, U32 *check_sum_out)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
U32 symbol_idx = obj->comdats[section_number-1];
|
||||
if (symbol_idx != max_U32) {
|
||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
||||
coff_parse_secdef(secdef, obj->header.is_big_obj, select_out, 0, section_length_out, check_sum_out);
|
||||
coff_parse_secdef(secdef, obj->header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef struct LNK_Obj
|
||||
COFF_FileHeaderInfo header;
|
||||
U32 *comdats;
|
||||
B8 hotpatch;
|
||||
U32Node **associated_sections;
|
||||
} LNK_Obj;
|
||||
|
||||
typedef struct LNK_ObjNode
|
||||
@@ -109,7 +110,7 @@ internal U32 lnk_obj_get_vol_md(LNK_Obj *obj);
|
||||
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff(LNK_Obj *obj, void *coff_symbol);
|
||||
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
|
||||
internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
internal B32 lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_length_out, U32 *check_sum_out);
|
||||
internal B32 lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_number_out, U32 *section_length_out, U32 *check_sum_out);
|
||||
internal B32 lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx);
|
||||
|
||||
// --- Helpers -----------------------------------------------------------------
|
||||
|
||||
@@ -193,7 +193,7 @@ lnk_can_replace_symbol(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
||||
U32 dst_section_length;
|
||||
U32 dst_check_sum;
|
||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
||||
dst_is_comdat = lnk_try_comdat_props_from_section_number(dst->u.defined.obj, dst_parsed.section_number, &dst_select, &dst_section_length, &dst_check_sum);
|
||||
dst_is_comdat = lnk_try_comdat_props_from_section_number(dst->u.defined.obj, dst_parsed.section_number, &dst_select, 0, &dst_section_length, &dst_check_sum);
|
||||
} else if (dst_interp == COFF_SymbolValueInterp_Common) {
|
||||
dst_select = COFF_ComdatSelect_Largest;
|
||||
dst_section_length = dst_parsed.value;
|
||||
@@ -207,7 +207,7 @@ lnk_can_replace_symbol(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
||||
U32 src_section_length, src_checks;
|
||||
U32 src_check_sum;
|
||||
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
||||
src_is_comdat = lnk_try_comdat_props_from_section_number(src->u.defined.obj, src_parsed.section_number, &src_select, &src_section_length, &src_check_sum);
|
||||
src_is_comdat = lnk_try_comdat_props_from_section_number(src->u.defined.obj, src_parsed.section_number, &src_select, 0, &src_section_length, &src_check_sum);
|
||||
} else if (src_interp == COFF_SymbolValueInterp_Common) {
|
||||
src_select = COFF_ComdatSelect_Largest;
|
||||
src_section_length = src_parsed.value;
|
||||
@@ -308,23 +308,44 @@ lnk_can_replace_symbol(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
||||
internal void
|
||||
lnk_on_symbol_replace(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
||||
{
|
||||
Assert(dst != src);
|
||||
if (scope == LNK_SymbolScope_Lib) {
|
||||
dst->u.lib = src->u.lib;
|
||||
} else if (scope == LNK_SymbolScope_Defined) {
|
||||
COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dst->u.defined.obj, dst->u.defined.symbol_idx);
|
||||
COFF_ParsedSymbol src_parsed = lnk_parsed_symbol_from_coff_symbol_idx(src->u.defined.obj, src->u.defined.symbol_idx);
|
||||
COFF_SymbolValueInterpType dst_interp = coff_interp_symbol(dst_parsed.section_number, dst_parsed.value, dst_parsed.storage_class);
|
||||
COFF_SymbolValueInterpType src_interp = coff_interp_symbol(src_parsed.section_number, src_parsed.value, src_parsed.storage_class);
|
||||
switch (scope) {
|
||||
case LNK_SymbolScope_Defined: {
|
||||
COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dst->u.defined.obj, dst->u.defined.symbol_idx);
|
||||
COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed);
|
||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
||||
// remove replaced section from the output
|
||||
COFF_SectionHeader *dst_sect = lnk_coff_section_header_from_section_number(dst->u.defined.obj, dst_parsed.section_number);
|
||||
dst_sect->flags |= COFF_SectionFlag_LnkRemove;
|
||||
dst->u.defined = src->u.defined;
|
||||
|
||||
// remove associated sections from the output
|
||||
for (U32Node *associated_section = dst->u.defined.obj->associated_sections[dst_parsed.section_number];
|
||||
associated_section != 0;
|
||||
associated_section = associated_section->next) {
|
||||
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(dst->u.defined.obj, associated_section->data);
|
||||
section_header->flags |= COFF_SectionFlag_LnkRemove;
|
||||
}
|
||||
}
|
||||
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
||||
COFF_SectionHeader *src_sect = lnk_coff_section_header_from_section_number(src->u.defined.obj, src_parsed.section_number);
|
||||
AssertAlways(~src_sect->flags & COFF_SectionFlag_LnkRemove);
|
||||
|
||||
// make sure leader section is not removed from the output
|
||||
#if BUILD_DEBUG
|
||||
{
|
||||
COFF_ParsedSymbol src_parsed = lnk_parsed_symbol_from_coff_symbol_idx(src->u.defined.obj, src->u.defined.symbol_idx);
|
||||
COFF_SymbolValueInterpType src_interp = coff_interp_from_parsed_symbol(src_parsed);
|
||||
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
||||
COFF_SectionHeader *src_sect = lnk_coff_section_header_from_section_number(src->u.defined.obj, src_parsed.section_number);
|
||||
AssertAlways(~src_sect->flags & COFF_SectionFlag_LnkRemove);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
case LNK_SymbolScope_Import: {
|
||||
// illegal to replace imports
|
||||
InvalidPath;
|
||||
} break;
|
||||
case LNK_SymbolScope_Lib: {
|
||||
// nothing to replace
|
||||
} break;
|
||||
default: { InvalidPath; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,31 +572,38 @@ THREAD_POOL_TASK_FUNC(lnk_finalize_weak_symbols_task)
|
||||
break;
|
||||
}
|
||||
|
||||
// record visited symbol
|
||||
struct LookupLocation *loc = push_array(scratch.arena, struct LookupLocation, 1);
|
||||
loc->symbol = current_symbol;
|
||||
SLLQueuePush(lookup_first, lookup_last, loc);
|
||||
|
||||
COFF_ParsedSymbol current_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx);
|
||||
COFF_SymbolValueInterpType current_interp = coff_interp_symbol(current_parsed.section_number, current_parsed.value, current_parsed.storage_class);
|
||||
if (current_interp != COFF_SymbolValueInterp_Weak && current_interp != COFF_SymbolValueInterp_Undefined) {
|
||||
break;
|
||||
}
|
||||
if (current_interp == COFF_SymbolValueInterp_Weak) {
|
||||
// record visited symbol
|
||||
struct LookupLocation *loc = push_array(scratch.arena, struct LookupLocation, 1);
|
||||
loc->symbol = current_symbol;
|
||||
SLLQueuePush(lookup_first, lookup_last, loc);
|
||||
|
||||
// does weak symbol have the strong definition?
|
||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, current_parsed.name);
|
||||
COFF_ParsedSymbol defn_parsed = lnk_parsed_symbol_from_coff_symbol_idx(defn_symbol->u.defined.obj, defn_symbol->u.defined.symbol_idx);
|
||||
COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class);
|
||||
if (defn_interp != COFF_SymbolValueInterp_Weak) {
|
||||
// does weak symbol have a definition?
|
||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, current_parsed.name);
|
||||
COFF_ParsedSymbol defn_parsed = lnk_parsed_symbol_from_coff_symbol_idx(defn_symbol->u.defined.obj, defn_symbol->u.defined.symbol_idx);
|
||||
COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class);
|
||||
if (defn_interp != COFF_SymbolValueInterp_Weak) {
|
||||
current_symbol = defn_symbol->u.defined;
|
||||
break;
|
||||
}
|
||||
|
||||
// no definition fallback to the tag
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(current_parsed, current_symbol.obj->header.is_big_obj);
|
||||
COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index);
|
||||
COFF_SymbolValueInterpType tag_interp = coff_interp_symbol(tag_parsed.section_number, tag_parsed.value, tag_parsed.storage_class);
|
||||
current_symbol = (LNK_SymbolDefined){ .obj = current_symbol.obj, .symbol_idx = weak_ext->tag_index };
|
||||
} else if (current_interp == COFF_SymbolValueInterp_Undefined) {
|
||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, current_parsed.name);
|
||||
if (defn_symbol == 0) {
|
||||
MemoryZeroStruct(¤t_symbol);
|
||||
break;
|
||||
}
|
||||
current_symbol = defn_symbol->u.defined;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// no strong definition fallback to the tag
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(current_parsed, current_symbol.obj->header.is_big_obj);
|
||||
COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index);
|
||||
COFF_SymbolValueInterpType tag_interp = coff_interp_symbol(tag_parsed.section_number, tag_parsed.value, tag_parsed.storage_class);
|
||||
current_symbol = (LNK_SymbolDefined){ .obj = current_symbol.obj, .symbol_idx = weak_ext->tag_index };
|
||||
}
|
||||
|
||||
// replace weak symbol with it's tag
|
||||
|
||||
Reference in New Issue
Block a user