mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 22:08:41 +00: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
|
#endif
|
||||||
#define PtrFromInt(i) (void*)(i)
|
#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 AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1)))
|
||||||
#define AlignDownPow2(x,b) ((x)&(~((b) - 1)))
|
#define AlignDownPow2(x,b) ((x)&(~((b) - 1)))
|
||||||
#define AlignPadPow2(x,b) ((0-(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 (selection_out) *selection_out = sd->selection;
|
||||||
if (length_out) *length_out = sd->length;
|
if (length_out) *length_out = sd->length;
|
||||||
if (check_sum_out) *check_sum_out = sd->check_sum;
|
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 {
|
} else {
|
||||||
COFF_SymbolSecDef *sd = (COFF_SymbolSecDef *)((COFF_Symbol16 *)symbol.raw_symbol + 1);
|
COFF_SymbolSecDef *sd = (COFF_SymbolSecDef *)((COFF_Symbol16 *)symbol.raw_symbol + 1);
|
||||||
if (selection_out) *selection_out = sd->selection;
|
if (selection_out) *selection_out = sd->selection;
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct U32Node
|
||||||
|
{
|
||||||
|
struct U32Node *next;
|
||||||
|
U32 data;
|
||||||
|
} U32Node;
|
||||||
|
|
||||||
typedef struct U64Node
|
typedef struct U64Node
|
||||||
{
|
{
|
||||||
struct U64Node *next;
|
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),
|
.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");
|
ProfBegin("Define And Count Sections");
|
||||||
TP_Temp temp = tp_temp_begin(arena);
|
TP_Temp temp = tp_temp_begin(arena);
|
||||||
|
|||||||
+35
-9
@@ -225,6 +225,31 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
scratch_end(scratch);
|
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
|
// extract obj features from compile symbol in .debug$S
|
||||||
//
|
//
|
||||||
@@ -267,13 +292,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fill out obj
|
// fill out obj
|
||||||
obj->data = input->data;
|
obj->data = input->data;
|
||||||
obj->path = push_str8_copy(arena, input->path);
|
obj->path = push_str8_copy(arena, input->path);
|
||||||
obj->lib_path = push_str8_copy(arena, input->lib_path);
|
obj->lib_path = push_str8_copy(arena, input->lib_path);
|
||||||
obj->input_idx = obj_idx;
|
obj->input_idx = obj_idx;
|
||||||
obj->header = header;
|
obj->header = header;
|
||||||
obj->comdats = comdats;
|
obj->comdats = comdats;
|
||||||
obj->hotpatch = hotpatch;
|
obj->hotpatch = hotpatch;
|
||||||
|
obj->associated_sections = associated_sections;
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
}
|
}
|
||||||
@@ -466,13 +492,13 @@ lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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);
|
Assert(section_number > 0);
|
||||||
U32 symbol_idx = obj->comdats[section_number-1];
|
U32 symbol_idx = obj->comdats[section_number-1];
|
||||||
if (symbol_idx != max_U32) {
|
if (symbol_idx != max_U32) {
|
||||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
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 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ typedef struct LNK_Obj
|
|||||||
COFF_FileHeaderInfo header;
|
COFF_FileHeaderInfo header;
|
||||||
U32 *comdats;
|
U32 *comdats;
|
||||||
B8 hotpatch;
|
B8 hotpatch;
|
||||||
|
U32Node **associated_sections;
|
||||||
} LNK_Obj;
|
} LNK_Obj;
|
||||||
|
|
||||||
typedef struct LNK_ObjNode
|
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(LNK_Obj *obj, void *coff_symbol);
|
||||||
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
|
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 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);
|
internal B32 lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx);
|
||||||
|
|
||||||
// --- Helpers -----------------------------------------------------------------
|
// --- Helpers -----------------------------------------------------------------
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ lnk_can_replace_symbol(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
U32 dst_section_length;
|
U32 dst_section_length;
|
||||||
U32 dst_check_sum;
|
U32 dst_check_sum;
|
||||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
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) {
|
} else if (dst_interp == COFF_SymbolValueInterp_Common) {
|
||||||
dst_select = COFF_ComdatSelect_Largest;
|
dst_select = COFF_ComdatSelect_Largest;
|
||||||
dst_section_length = dst_parsed.value;
|
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_section_length, src_checks;
|
||||||
U32 src_check_sum;
|
U32 src_check_sum;
|
||||||
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
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) {
|
} else if (src_interp == COFF_SymbolValueInterp_Common) {
|
||||||
src_select = COFF_ComdatSelect_Largest;
|
src_select = COFF_ComdatSelect_Largest;
|
||||||
src_section_length = src_parsed.value;
|
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
|
internal void
|
||||||
lnk_on_symbol_replace(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
lnk_on_symbol_replace(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src)
|
||||||
{
|
{
|
||||||
Assert(dst != src);
|
switch (scope) {
|
||||||
if (scope == LNK_SymbolScope_Lib) {
|
case LNK_SymbolScope_Defined: {
|
||||||
dst->u.lib = src->u.lib;
|
COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dst->u.defined.obj, dst->u.defined.symbol_idx);
|
||||||
} else if (scope == LNK_SymbolScope_Defined) {
|
COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed);
|
||||||
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);
|
|
||||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
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);
|
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_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);
|
// make sure leader section is not removed from the output
|
||||||
AssertAlways(~src_sect->flags & COFF_SectionFlag_LnkRemove);
|
#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;
|
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_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);
|
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) {
|
if (current_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
break;
|
// 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?
|
// does weak symbol have a definition?
|
||||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, current_parsed.name);
|
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_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);
|
COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class);
|
||||||
if (defn_interp != COFF_SymbolValueInterp_Weak) {
|
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;
|
current_symbol = defn_symbol->u.defined;
|
||||||
|
} else {
|
||||||
break;
|
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
|
// replace weak symbol with it's tag
|
||||||
|
|||||||
Reference in New Issue
Block a user