mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 10:10:11 -08:00
use iterators to access COFF sections and symbols
This commit is contained in:
1 parent
e3d49069bf
commit
da00fa9627
7 files changed
+445
-459
No files matched your search
+230
-250
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -130,7 +130,7 @@ typedef struct LNK_SectionDefinition
|
||||
COFF_SectionFlags flags;
|
||||
U64 contribs_count;
|
||||
struct LNK_Obj *obj;
|
||||
U64 obj_sect_idx;
|
||||
U64 obj_section_number;
|
||||
} LNK_SectionDefinition;
|
||||
|
||||
typedef struct LNK_CommonBlockContrib
|
||||
|
||||
+21
-22
@@ -76,8 +76,8 @@ THREAD_POOL_TASK_FUNC(lnk_parse_debug_h_task)
|
||||
LNK_CodeViewInput *task = raw_task;
|
||||
|
||||
LNK_Obj *obj = task->obj_arr[obj_idx];
|
||||
if (obj->coff.debug_h_sect_idx < obj->coff.sections.count) {
|
||||
String8 raw_debug_h = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_h_sect_idx);
|
||||
if (obj->coff.debug_h_section_number > 0) {
|
||||
String8 raw_debug_h = lnk_obj_section_data_from_number(obj, obj->coff.debug_h_section_number);
|
||||
CV_DebugH *debug_h = &task->debug_h_arr[obj_idx];
|
||||
LLVM_GHash ghash = {0};
|
||||
U64 ghash_read_size = str8_deserial_read_struct(raw_debug_h, 0, &ghash);
|
||||
@@ -699,9 +699,9 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
if (rrt->obj_time_stamps[rrt_obj_idx] != obj_file_props.modified) { continue; }
|
||||
|
||||
// invalidate debug section pointers
|
||||
obj->coff.debug_t_sect_idx = ~0;
|
||||
obj->coff.debug_p_sect_idx = ~0;
|
||||
obj->coff.debug_h_sect_idx = ~0;
|
||||
obj->coff.debug_t_section_number = 0;
|
||||
obj->coff.debug_p_section_number = 0;
|
||||
obj->coff.debug_h_section_number = 0;
|
||||
|
||||
// apply type index map
|
||||
obj->ti_range = rrt->obj_ti_ranges[rrt_obj_idx];
|
||||
@@ -733,15 +733,15 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
|
||||
for EachNode(n, String8Node, input.debug_s_list_arr[obj_idx].first) { total_debug_s_size += n->string.size; }
|
||||
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_t_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_t_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_t_section_number > 0) {
|
||||
total_debug_t_size += lnk_coff_section_header_from_section_number(obj, obj->coff.debug_t_section_number)->fsize;
|
||||
}
|
||||
if (obj->coff.debug_p_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_p_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_p_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_p_section_number > 0) {
|
||||
total_debug_p_size += lnk_coff_section_header_from_section_number(obj, obj->coff.debug_p_section_number)->fsize;
|
||||
}
|
||||
if (config->ghash) {
|
||||
if (obj->coff.debug_h_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_h_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_h_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_h_section_number > 0) {
|
||||
total_debug_h_size += lnk_coff_section_header_from_section_number(obj, obj->coff.debug_h_section_number)->fsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -783,16 +783,16 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
for EachIndex(obj_idx, obj_count) {
|
||||
LNK_Obj *obj = obj_arr[obj_idx];
|
||||
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
if (obj->coff.debug_t_section_number > 0) {
|
||||
raw_debug_t_arr[obj_idx].count = 1;
|
||||
raw_debug_t_arr[obj_idx].v = push_array(scratch.arena, String8, 1);
|
||||
raw_debug_t_arr[obj_idx].v[0] = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_t_sect_idx);
|
||||
raw_debug_t_arr[obj_idx].v[0] = lnk_obj_section_data_from_number(obj, obj->coff.debug_t_section_number);
|
||||
}
|
||||
|
||||
if (obj->coff.debug_p_sect_idx < obj->coff.sections.count) {
|
||||
if (obj->coff.debug_p_section_number > 0) {
|
||||
raw_debug_p_arr[obj_idx].count = 1;
|
||||
raw_debug_p_arr[obj_idx].v = push_array(scratch.arena, String8, 1);
|
||||
raw_debug_p_arr[obj_idx].v[0] = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_p_sect_idx);
|
||||
raw_debug_p_arr[obj_idx].v[0] = lnk_obj_section_data_from_number(obj, obj->coff.debug_p_section_number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2849,20 +2849,19 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
||||
LNK_Obj *obj = task->cv->obj_arr[obj_idx];
|
||||
|
||||
PDB_DbiSCArray *sc_array = &task->sc_arrays[obj_idx];
|
||||
sc_array->v = push_array_no_zero(arena, PDB_DbiSC, obj->coff.sections.count);
|
||||
sc_array->cap = obj->coff.sections.count;
|
||||
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
sc_array->v = push_array_no_zero(arena, PDB_DbiSC, obj->coff.sections.count_no_null);
|
||||
sc_array->cap = obj->coff.sections.count_no_null;
|
||||
|
||||
for LNK_EachCoffSection(it, obj) {
|
||||
// filter by section flags
|
||||
if (obj->coff.sections.headers[sect_idx].flags & (COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkRemove | LNK_SECTION_FLAG_DEBUG)) { continue; }
|
||||
if (*it.v.flags & (COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkRemove | LNK_SECTION_FLAG_DEBUG)) { continue; }
|
||||
|
||||
// skip unwind info for the section contribution
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
String8 section_name = lnk_obj_section_name_from_section_number(obj, it.v.section_number);
|
||||
if (str8_match(section_name, str8_lit(".pdata"), 0)) { continue; }
|
||||
|
||||
// load section and determine its type
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
LNK_ObjSection section = it.v;
|
||||
B32 is_virt = !!(*section.flags & COFF_SectionFlag_CntUninitializedData);
|
||||
|
||||
// pick section range
|
||||
|
||||
+150
-158
@@ -93,8 +93,8 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
lnk_error_input_obj(LNK_Error_IllData, input, "corrupted file, unable to read string table");
|
||||
}
|
||||
|
||||
COFF_SectionHeader *section_headers = push_array_no_zero(arena, COFF_SectionHeader, header.section_count_no_null);
|
||||
MemoryCopy(section_headers, raw_coff_section_table.str, raw_coff_section_table.size);
|
||||
COFF_SectionHeader *section_headers = push_array(arena, COFF_SectionHeader, header.section_count_no_null + 1);
|
||||
MemoryCopy(section_headers + 1, raw_coff_section_table.str, raw_coff_section_table.size);
|
||||
|
||||
//
|
||||
// section table pass
|
||||
@@ -103,13 +103,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
// - find debug info and meta-data leaders
|
||||
//
|
||||
COFF_SectionHeader *coff_section_table = (COFF_SectionHeader *)raw_coff_section_table.str;
|
||||
U32 debug_t_sect_idx = ~0;
|
||||
U32 debug_p_sect_idx = ~0;
|
||||
U32 debug_h_sect_idx = ~0;
|
||||
U32 llvm_addrsig_sect_idx = ~0;
|
||||
for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) {
|
||||
U32 debug_t_section_number = 0;
|
||||
U32 debug_p_section_number = 0;
|
||||
U32 debug_h_section_number = 0;
|
||||
U32 llvm_addrsig_section_number = 0;
|
||||
for EachIndex(sect_idx, header.section_count_no_null) {
|
||||
U64 section_number = sect_idx + 1;
|
||||
COFF_SectionHeader *coff_sect_header = &coff_section_table[sect_idx];
|
||||
COFF_SectionFlags *section_flags = §ion_headers[sect_idx].flags;
|
||||
COFF_SectionFlags *section_flags = §ion_headers[section_number].flags;
|
||||
String8 sect_name = coff_name_from_section_header(raw_coff_string_table, coff_sect_header);
|
||||
*section_flags = coff_sect_header->flags & ~3; // linker reserves low 2 bits for internal flags
|
||||
|
||||
@@ -123,15 +124,15 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
|
||||
if (str8_match(sect_name, str8_lit(".debug$T"), 0)) {
|
||||
debug_t_sect_idx = sect_idx;
|
||||
debug_t_section_number = section_number;
|
||||
} else if (str8_match(sect_name, str8_lit(".debug$P"), 0)) {
|
||||
debug_p_sect_idx = sect_idx;
|
||||
debug_p_section_number = section_number;
|
||||
} else if (str8_match(sect_name, str8_lit(".debug$H"), 0)) {
|
||||
debug_h_sect_idx = sect_idx;
|
||||
debug_h_section_number = section_number;
|
||||
}
|
||||
|
||||
if (llvm_addrsig_sect_idx == max_U32 && str8_match(sect_name, str8_lit(".llvm_addrsig"), 0)) {
|
||||
llvm_addrsig_sect_idx = sect_idx;
|
||||
if (llvm_addrsig_section_number == 0 && str8_match(sect_name, str8_lit(".llvm_addrsig"), 0)) {
|
||||
llvm_addrsig_section_number = section_number;
|
||||
}
|
||||
|
||||
if (~*section_flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
@@ -218,7 +219,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
coff_parse_secdef(symbol, header.is_big_obj, &select, §ion_number, 0, 0);
|
||||
if (select == COFF_ComdatSelect_Associative) {
|
||||
if (section_number == 0 || section_number > header.section_count_no_null) {
|
||||
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbol %S (No. 0x%x) associates with an out of bounds section 0x%x", symbol.name, symbol_idx, symbol.section_number);
|
||||
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbol %S (No. 0x%x) associates with an out of bounds section 0x%x", symbol.name, symbol_idx, section_number);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,8 +236,8 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
//
|
||||
U32 *comdats;
|
||||
{
|
||||
comdats = push_array_no_zero(arena, U32, header.section_count_no_null);
|
||||
MemorySet(comdats, 0xff, header.section_count_no_null * sizeof(comdats[0]));
|
||||
comdats = push_array_no_zero(arena, U32, header.section_count_no_null + 1);
|
||||
MemorySet(comdats, 0xff, (header.section_count_no_null + 1) * sizeof(comdats[0]));
|
||||
|
||||
COFF_ParsedSymbol symbol;
|
||||
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
@@ -247,13 +248,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
if (symbol.storage_class == COFF_SymStorageClass_Static) {
|
||||
if (symbol.section_number > 0 && symbol.section_number <= header.section_count_no_null) {
|
||||
COFF_SectionHeader *sect_header = &coff_section_table[symbol.section_number-1];
|
||||
if (section_headers[symbol.section_number-1].flags & COFF_SectionFlag_LnkCOMDAT) {
|
||||
if (section_headers[symbol.section_number].flags & COFF_SectionFlag_LnkCOMDAT) {
|
||||
if (symbol.aux_symbol_count) {
|
||||
U32 section_length = 0;
|
||||
coff_parse_secdef(symbol, header.is_big_obj, 0, 0, §ion_length, 0);
|
||||
if (sect_header->fsize == section_length) {
|
||||
if (comdats[symbol.section_number-1] == ~0) {
|
||||
comdats[symbol.section_number-1] = symbol_idx;
|
||||
if (comdats[symbol.section_number] == ~0) {
|
||||
comdats[symbol.section_number] = symbol_idx;
|
||||
} else {
|
||||
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbo (No. 0x%llx) tries to ovewrite comdat", symbol_idx);
|
||||
}
|
||||
@@ -277,9 +278,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
HashTable *visited_sections = hash_table_init(scratch.arena, 32);
|
||||
for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) {
|
||||
for (U32 curr_section = sect_idx;;) {
|
||||
U32 symbol_idx = comdats[curr_section];
|
||||
for (U32 section_number = 1; section_number <= header.section_count_no_null; section_number += 1) {
|
||||
for (U32 curr_section_number = section_number;;) {
|
||||
U32 symbol_idx = comdats[curr_section_number];
|
||||
|
||||
// is section COMDAT?
|
||||
if (symbol_idx == max_U32) {
|
||||
@@ -289,8 +290,8 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
// extract COMDAT info for current section
|
||||
COFF_ParsedSymbol symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx);
|
||||
COFF_ComdatSelectType select = COFF_ComdatSelect_Null;
|
||||
U32 section_number = 0;
|
||||
coff_parse_secdef(symbol, header.is_big_obj, &select, §ion_number, 0, 0);
|
||||
U32 associated_section_number = 0;
|
||||
coff_parse_secdef(symbol, header.is_big_obj, &select, &associated_section_number, 0, 0);
|
||||
|
||||
if (select != COFF_ComdatSelect_Associative) {
|
||||
// section terminates at non-associative COMDAT -- no loop
|
||||
@@ -298,18 +299,18 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
|
||||
// was section visited? -- loop found
|
||||
if (hash_table_search_u64(visited_sections, curr_section)) {
|
||||
COFF_ParsedSymbol symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, comdats[sect_idx]);
|
||||
lnk_error_input_obj(LNK_Error_AssociativeLoop, input, "section symbol %S (No. 0x%x) does not terminate on a non-associate COMDAT symbol", symbol.name, comdats[sect_idx]);
|
||||
if (hash_table_search_u64(visited_sections, curr_section_number)) {
|
||||
COFF_ParsedSymbol symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, comdats[section_number]);
|
||||
lnk_error_input_obj(LNK_Error_AssociativeLoop, input, "section symbol %S (No. 0x%x) does not terminate on a non-associate COMDAT symbol", symbol.name, comdats[section_number]);
|
||||
break;
|
||||
}
|
||||
|
||||
// track visited sections
|
||||
hash_table_push_u64_u64(scratch.arena, visited_sections, curr_section, 0);
|
||||
hash_table_push_u64_u64(scratch.arena, visited_sections, curr_section_number, 0);
|
||||
|
||||
// follow association
|
||||
Assert(section_number > 0);
|
||||
curr_section = section_number-1;
|
||||
Assert(associated_section_number > 0);
|
||||
curr_section_number = associated_section_number;
|
||||
}
|
||||
|
||||
// purge hash table for next run
|
||||
@@ -354,7 +355,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
CV_Symbol comp_symbol = {0};
|
||||
for EachIndex(sect_idx, header.section_count_no_null) {
|
||||
COFF_SectionHeader *sect_header = &coff_section_table[sect_idx];
|
||||
if (section_headers[sect_idx].flags & LNK_SECTION_FLAG_DEBUG) {
|
||||
if (section_headers[sect_idx + 1].flags & LNK_SECTION_FLAG_DEBUG) {
|
||||
String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name));
|
||||
if (str8_match(name, str8_lit(".debug$S"), 0)) {
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
@@ -392,17 +393,17 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
.data = input->data,
|
||||
.header = header,
|
||||
.sections = {
|
||||
.count = header.section_count_no_null,
|
||||
.count_no_null = header.section_count_no_null,
|
||||
.headers = section_headers,
|
||||
.comdats = comdats,
|
||||
.associations = associated_sections,
|
||||
.associated_section_numbers = associated_sections,
|
||||
},
|
||||
.symbols = symbols,
|
||||
.debug_t_sect_idx = debug_t_sect_idx,
|
||||
.debug_p_sect_idx = debug_p_sect_idx,
|
||||
.debug_h_sect_idx = debug_h_sect_idx,
|
||||
.llvm_addrsig_sect_idx = llvm_addrsig_sect_idx,
|
||||
.hotpatch = hotpatch,
|
||||
.symbols = symbols,
|
||||
.debug_t_section_number = debug_t_section_number,
|
||||
.debug_p_section_number = debug_p_section_number,
|
||||
.debug_h_section_number = debug_h_section_number,
|
||||
.llvm_addrsig_section_number = llvm_addrsig_section_number,
|
||||
.hotpatch = hotpatch,
|
||||
};
|
||||
obj->path = push_str8_copy(arena, input->path);
|
||||
obj->exclude_from_debug_info = input->exclude_from_debug_info;
|
||||
@@ -457,9 +458,9 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
{
|
||||
LNK_InputCoffSymbolTable *task = raw_task;
|
||||
LNK_Obj *obj = task->objs[task_id];
|
||||
COFF_ParsedSymbol symbol = {0};
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
for LNK_EachCoffSymbol(it, obj) {
|
||||
U64 symbol_idx = it.symbol_idx;
|
||||
COFF_ParsedSymbol symbol = it.v;
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
LNK_SymbolSearchType search_type = lnk_symbol_search_type_from_coff(obj, symbol, interp);
|
||||
switch (interp) {
|
||||
@@ -504,14 +505,14 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
internal LNK_ObjSymbolRef *
|
||||
lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
|
||||
{
|
||||
LNK_ObjSymbolRef *symlinks = push_array(arena, LNK_ObjSymbolRef, obj->coff.sections.count + 1);
|
||||
COFF_ParsedSymbol symbol = {0};
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
LNK_ObjSymbolRef *symlinks = push_array(arena, LNK_ObjSymbolRef, obj->coff.sections.count_no_null + 1);
|
||||
for LNK_EachCoffSymbol(it, obj) {
|
||||
U64 symbol_idx = it.symbol_idx;
|
||||
COFF_ParsedSymbol symbol = it.v;
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.headers[symbol.section_number - 1].flags;
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.headers[symbol.section_number].flags;
|
||||
if (~section_flags & COFF_SectionFlag_LnkCOMDAT) { continue; }
|
||||
|
||||
LNK_ObjSymbolRef *symlink = &symlinks[symbol.section_number];
|
||||
@@ -553,29 +554,30 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
|
||||
}
|
||||
|
||||
internal U32List
|
||||
lnk_obj_collect_associated_sections(Arena *arena, LNK_Obj *obj, U32 root_section, COFF_SectionFlags skip_flags)
|
||||
lnk_obj_collect_associated_section_numbers(Arena *arena, LNK_Obj *obj, U32 root_section_number, COFF_SectionFlags skip_flags)
|
||||
{
|
||||
Assert(1 <= root_section_number && root_section_number <= obj->coff.sections.count_no_null);
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
// track each child before enqueueing it because COFF associations can cycle
|
||||
HashMap seen_hm = {0};
|
||||
U32List queue = {0};
|
||||
|
||||
U32Node root_n = { root_section };
|
||||
U32Node root_n = { root_section_number };
|
||||
u32_list_push_node(&queue, &root_n);
|
||||
hash_map_push_u64_u64(scratch.arena, &seen_hm, root_section, 1);
|
||||
hash_map_push_u64_u64(scratch.arena, &seen_hm, root_section_number, 1);
|
||||
|
||||
// walk the complete descendant chain because associated COMDATs can nest
|
||||
for EachNode(parent_n, U32Node, queue.first) {
|
||||
for EachNode(associated_n, U32Node, obj->coff.sections.associations[parent_n->data]) {
|
||||
U32 child_section = associated_n->data;
|
||||
for EachNode(associated_n, U32Node, obj->coff.sections.associated_section_numbers[parent_n->data]) {
|
||||
U32 child_section_number = associated_n->data;
|
||||
|
||||
if (child_section == 0) { continue; }
|
||||
if (hash_map_search_u64_u64(&seen_hm, child_section)) { continue; }
|
||||
if (obj->coff.sections.headers[child_section - 1].flags & skip_flags) { continue; }
|
||||
if (child_section_number == 0) { continue; }
|
||||
if (hash_map_search_u64_u64(&seen_hm, child_section_number)) { continue; }
|
||||
if (obj->coff.sections.headers[child_section_number].flags & skip_flags) { continue; }
|
||||
|
||||
hash_map_push_u64_u64(scratch.arena, &seen_hm, child_section, 1);
|
||||
u32_list_push(arena, &queue, child_section);
|
||||
hash_map_push_u64_u64(scratch.arena, &seen_hm, child_section_number, 1);
|
||||
u32_list_push(arena, &queue, child_section_number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,9 +622,9 @@ lnk_push_obj_symbols(TP_Context *tp, TP_Arena *arena, LNK_SymbolTable *symtab, U
|
||||
internal COFF_ParsedSymbol
|
||||
lnk_obj_match_symbol(LNK_Obj *obj, String8 match_name)
|
||||
{
|
||||
COFF_ParsedSymbol symbol;
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
||||
for LNK_EachCoffSymbol(it, obj) {
|
||||
COFF_ParsedSymbol symbol = it.v;
|
||||
symbol.name = lnk_symbol_name_from_coff_symbol_idx(obj, it.symbol_idx);
|
||||
if (str8_match(symbol.name, match_name, 0)) {
|
||||
return symbol;
|
||||
}
|
||||
@@ -636,18 +638,6 @@ lnk_obj_get_features(LNK_Obj *obj)
|
||||
return lnk_obj_match_symbol(obj, str8_lit("@feat.00")).value;
|
||||
}
|
||||
|
||||
internal U32
|
||||
lnk_obj_get_comp_id(LNK_Obj *obj)
|
||||
{
|
||||
return lnk_obj_match_symbol(obj, str8_lit("@comp.id")).value;
|
||||
}
|
||||
|
||||
internal U32
|
||||
lnk_obj_get_vol_md(LNK_Obj *obj)
|
||||
{
|
||||
return lnk_obj_match_symbol(obj, str8_lit("@vol.md")).value;
|
||||
}
|
||||
|
||||
internal LNK_Lib *
|
||||
lnk_obj_get_lib(LNK_Obj *obj)
|
||||
{
|
||||
@@ -672,8 +662,9 @@ lnk_obj_get_removed_section_number(LNK_Obj *obj)
|
||||
}
|
||||
|
||||
internal B32
|
||||
lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *symlink_out)
|
||||
lnk_obj_get_comdat_symlink_from_section_number(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *symlink_out)
|
||||
{
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
LNK_ObjSymbolRef symlink = obj->symlinks[section_number];
|
||||
B32 is_valid = symlink.obj != 0;
|
||||
if (is_valid && symlink_out) {
|
||||
@@ -682,18 +673,12 @@ lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *s
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
internal COFF_SectionHeader *
|
||||
lnk_coff_section_table_from_obj(LNK_Obj *obj)
|
||||
{
|
||||
return obj->coff.sections.headers;
|
||||
}
|
||||
|
||||
internal String8
|
||||
lnk_obj_section_data_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
lnk_obj_section_data_from_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->coff.data, obj->coff.header.section_table_range).str;
|
||||
COFF_SectionHeader *section = §ion_table[sect_idx];
|
||||
COFF_SectionHeader *section = §ion_table[section_number-1];
|
||||
return str8_substr(obj->coff.data, r1u64s(section->foff, section->fsize));
|
||||
}
|
||||
|
||||
@@ -706,55 +691,40 @@ lnk_obj_foff_from_section_data_ptr(LNK_Obj *obj, void *ptr)
|
||||
return ptr_v - data_min;
|
||||
}
|
||||
|
||||
internal U64
|
||||
lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count);
|
||||
return section_number-1;
|
||||
}
|
||||
|
||||
internal U64
|
||||
lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
return sect_idx+1;
|
||||
}
|
||||
|
||||
internal String8
|
||||
lnk_obj_section_name_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
COFF_SectionHeader *section_header = &lnk_coff_section_table_from_obj(obj)[sect_idx];
|
||||
return coff_name_from_section_header(lnk_coff_string_table_from_obj(obj), section_header);
|
||||
}
|
||||
|
||||
internal String8
|
||||
lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
return lnk_obj_section_name_from_sect_idx(obj, section_number-1);
|
||||
}
|
||||
|
||||
internal LNK_ObjSection
|
||||
lnk_obj_section_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
LNK_ObjSection section = {0};
|
||||
section.obj = obj;
|
||||
section.sect_idx = sect_idx;
|
||||
section.section_number = sect_idx+1;
|
||||
section.header = &lnk_coff_section_table_from_obj(obj)[sect_idx];
|
||||
section.flags = §ion.header->flags;
|
||||
section.vrange = rng_1u64(section.header->voff, section.header->voff + section.header->vsize);
|
||||
section.frange = rng_1u64(section.header->foff, section.header->foff + section.header->fsize);
|
||||
section.reloc_count = section.header->reloc_count;
|
||||
return section;
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
COFF_SectionHeader *section_header = &obj->coff.sections.headers[section_number];
|
||||
return coff_name_from_section_header(lnk_coff_string_table_from_obj(obj), section_header);
|
||||
}
|
||||
|
||||
internal LNK_ObjSection
|
||||
lnk_obj_section_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
U64 sect_idx = lnk_obj_sect_idx_from_section_number(obj, section_number);
|
||||
return lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
COFF_SectionHeader *header = &obj->coff.sections.headers[section_number];
|
||||
LNK_ObjSection section = {
|
||||
.obj = obj,
|
||||
.section_number = section_number,
|
||||
.header = header,
|
||||
.flags = &header->flags,
|
||||
.vrange = rng_1u64(header->voff, header->voff + header->vsize),
|
||||
.frange = rng_1u64(header->foff, header->foff + header->fsize),
|
||||
.reloc_count = header->reloc_count,
|
||||
};
|
||||
return section;
|
||||
}
|
||||
|
||||
internal force_inline B32
|
||||
lnk_obj_section_iter_next(LNK_Obj *obj, LNK_ObjSectionIter *it)
|
||||
{
|
||||
U64 section_number = it->v.section_number + 1;
|
||||
B32 is_valid = section_number <= obj->coff.sections.count_no_null;
|
||||
if (is_valid) {
|
||||
it->v = lnk_obj_section_from_section_number(obj, section_number);
|
||||
}
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
internal COFF_RelocArray
|
||||
@@ -791,8 +761,8 @@ lnk_coff_reloc_info_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_number_out, U32 *section_length_out, U32 *check_sum_out)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
U32 symbol_idx = obj->coff.sections.comdats[section_number-1];
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
U32 symbol_idx = obj->coff.sections.comdats[section_number];
|
||||
if (symbol_idx != max_U32) {
|
||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
coff_parse_secdef(secdef, obj->coff.header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out);
|
||||
@@ -804,9 +774,8 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_
|
||||
internal COFF_SectionHeader *
|
||||
lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
U64 sect_idx = section_number - 1;
|
||||
return &obj->coff.sections.headers[sect_idx];
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count_no_null);
|
||||
return &obj->coff.sections.headers[section_number];
|
||||
}
|
||||
|
||||
internal force_inline U64
|
||||
@@ -826,6 +795,31 @@ lnk_obj_primary_symbol_idx_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
||||
return primary_idx;
|
||||
}
|
||||
|
||||
internal force_inline B32
|
||||
lnk_obj_symbol_iter_next(LNK_Obj *obj, LNK_ObjSymbolIter *it)
|
||||
{
|
||||
if (it->next_primary_idx >= obj->coff.symbols.count) {
|
||||
Assert(it->next_symbol_idx >= obj->coff.header.symbol_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Assert(it->next_symbol_idx < obj->coff.header.symbol_count);
|
||||
U64 symbol_size = obj->coff.header.is_big_obj ? sizeof(COFF_Symbol32) : sizeof(COFF_Symbol16);
|
||||
it->symbol_idx = it->next_symbol_idx;
|
||||
it->primary_idx = it->next_primary_idx;
|
||||
it->v = (COFF_ParsedSymbol){
|
||||
.value = obj->coff.symbols.values[it->primary_idx],
|
||||
.section_number = obj->coff.symbols.section_numbers[it->primary_idx],
|
||||
.type = obj->coff.symbols.types[it->primary_idx],
|
||||
.storage_class = obj->coff.symbols.storage_classes[it->primary_idx],
|
||||
.aux_symbol_count = obj->coff.symbols.aux_counts[it->primary_idx],
|
||||
.raw_symbol = lnk_coff_symbol_table_from_obj(obj).str + it->symbol_idx * symbol_size,
|
||||
};
|
||||
it->next_symbol_idx += 1 + it->v.aux_symbol_count;
|
||||
it->next_primary_idx += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
internal force_inline COFF_ParsedSymbol
|
||||
lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx)
|
||||
{
|
||||
@@ -863,16 +857,16 @@ THREAD_POOL_TASK_FUNC(lnk_collect_obj_chunks_task)
|
||||
LNK_SectionCollector *task = raw_task;
|
||||
LNK_Obj *obj = task->objs[task_id];
|
||||
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
for LNK_EachCoffSection(it, obj) {
|
||||
LNK_ObjSection section = it.v;
|
||||
|
||||
if (*section.flags & COFF_SectionFlag_LnkRemove && !task->collect_discarded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
String8 section_name = lnk_obj_section_name_from_section_number(obj, section.section_number);
|
||||
if (str8_match(section_name, task->name, 0)) {
|
||||
String8 section_data = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
String8 section_data = lnk_obj_section_data_from_number(obj, section.section_number);
|
||||
str8_list_push(arena, &task->out_lists[task_id], section_data);
|
||||
}
|
||||
}
|
||||
@@ -948,10 +942,10 @@ internal String8List
|
||||
lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
{
|
||||
String8List drectve_data = {0};
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
for LNK_EachCoffSection(it, obj) {
|
||||
LNK_ObjSection section = it.v;
|
||||
if (*section.flags & COFF_SectionFlag_LnkInfo) {
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
String8 section_name = lnk_obj_section_name_from_section_number(obj, section.section_number);
|
||||
if (str8_match(section_name, str8_lit(".drectve"), 0)) {
|
||||
if (*section.flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
lnk_error_obj(LNK_Error_IllData, obj, ".drectve section header has flag COFF_SectionFlag_CntUninitializedData");
|
||||
@@ -965,7 +959,7 @@ lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
lnk_error_obj(LNK_Error_IllData, obj, ".drectve must not have relocations");
|
||||
break;
|
||||
}
|
||||
str8_list_push(arena, &drectve_data, lnk_obj_section_data_from_sect_idx(obj, sect_idx));
|
||||
str8_list_push(arena, &drectve_data, lnk_obj_section_data_from_number(obj, section.section_number));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -997,9 +991,8 @@ lnk_symbol_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
{
|
||||
// count functions
|
||||
U64 count = 0;
|
||||
COFF_ParsedSymbol symbol;
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->coff.header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
for LNK_EachCoffSymbol(it, obj) {
|
||||
COFF_ParsedSymbol symbol = it.v;
|
||||
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
count += 1;
|
||||
}
|
||||
@@ -1008,13 +1001,12 @@ lnk_symbol_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
LNK_ObjSymbolMap *map = push_array(arena, LNK_ObjSymbolMap, 1);
|
||||
map->v = push_array_no_zero(arena, LNK_SectionOffsetSymbol, count);
|
||||
|
||||
U64 map_idx = 0;
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->coff.header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
for LNK_EachCoffSymbol(it, obj) {
|
||||
COFF_ParsedSymbol symbol = it.v;
|
||||
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
LNK_SectionOffsetSymbol *entry = &map->v[map->count++];
|
||||
entry->key = Compose64Bit(symbol.section_number, symbol.value);
|
||||
entry->symbol_idx = safe_cast_u32(symbol_idx);
|
||||
entry->symbol_idx = safe_cast_u32(it.symbol_idx);
|
||||
}
|
||||
}
|
||||
Assert(map->count == count);
|
||||
@@ -1057,11 +1049,11 @@ lnk_debug_s_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
|
||||
String8List raw_debug_s = {0};
|
||||
{
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
for LNK_EachCoffSection(it, obj) {
|
||||
LNK_ObjSection section = it.v;
|
||||
String8 section_name = lnk_obj_section_name_from_section_number(obj, section.section_number);
|
||||
if (str8_match(section_name, str8_lit(".debug$S"), 0)) {
|
||||
String8 debug_s = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
String8 debug_s = lnk_obj_section_data_from_number(obj, section.section_number);
|
||||
str8_list_push(scratch.arena, &raw_debug_s, debug_s);
|
||||
}
|
||||
}
|
||||
@@ -1120,11 +1112,11 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
//
|
||||
#define DebugRelocValueFromFileOffset(foff) hash_map_search_u64_u64(&debug_reloc_hm, foff)
|
||||
HashMap debug_reloc_hm = {0};
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
if (!str8_match(lnk_obj_section_name_from_sect_idx(obj, sect_idx), str8_lit(".debug$S"), 0)) { continue; }
|
||||
for LNK_EachCoffSection(it, obj) {
|
||||
LNK_ObjSection section = it.v;
|
||||
if (!str8_match(lnk_obj_section_name_from_section_number(obj, section.section_number), str8_lit(".debug$S"), 0)) { continue; }
|
||||
|
||||
String8 section_data = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
String8 section_data = lnk_obj_section_data_from_number(obj, section.section_number);
|
||||
COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, section.header);
|
||||
for EachIndex(reloc_idx, relocs.count) {
|
||||
COFF_Reloc *reloc = &relocs.v[reloc_idx];
|
||||
@@ -1244,9 +1236,9 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
// build inlinee id -> inlinee name
|
||||
//
|
||||
HashMap inlinee_hm = {0};
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
String8 raw_debug_t = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_t_sect_idx);
|
||||
CV_Signature debug_t_sig = cv_signature_from_debug_s(raw_debug_t);
|
||||
if (obj->coff.debug_t_section_number) {
|
||||
String8 raw_debug_t = lnk_obj_section_data_from_number(obj, obj->coff.debug_t_section_number);
|
||||
CV_Signature debug_t_sig = cv_signature_from_debug_s(raw_debug_t);
|
||||
if (debug_t_sig == CV_Signature_C13) {
|
||||
CV_DebugT debug_t = cv_debug_t_from_data(scratch.arena, str8_skip(raw_debug_t, sizeof(CV_Signature)), CV_LeafAlign);
|
||||
|
||||
@@ -1454,9 +1446,9 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
}
|
||||
|
||||
internal CV_Line *
|
||||
lnk_lines_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, U64 *line_count_out)
|
||||
lnk_lines_from_section_offset(LNK_ObjLineMap *map, U64 section_number, U64 offset, U64 *line_count_out)
|
||||
{
|
||||
U64 key = Compose64Bit(section_number, offset);
|
||||
U64 key = Compose64Bit(safe_cast_u32(section_number), safe_cast_u32(offset));
|
||||
|
||||
// upper bound search
|
||||
U64 min = 0;
|
||||
@@ -1518,9 +1510,9 @@ lnk_lines_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offse
|
||||
}
|
||||
|
||||
internal LNK_InlineSite *
|
||||
lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, LNK_Symbol *callee_symbol)
|
||||
lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U64 section_number, U64 offset, LNK_Symbol *callee_symbol)
|
||||
{
|
||||
U64 key = Compose64Bit(section_number, offset);
|
||||
U64 key = Compose64Bit(safe_cast_u32(section_number), safe_cast_u32(offset));
|
||||
|
||||
// find upper bound
|
||||
U64 min = 0;
|
||||
|
||||
+37
-22
@@ -21,10 +21,11 @@ typedef struct LNK_ObjSymbolArray
|
||||
|
||||
typedef struct LNK_ObjSectionArray
|
||||
{
|
||||
U64 count;
|
||||
// Parallel arrays are indexed by COFF section number; slot zero is null.
|
||||
U64 count_no_null;
|
||||
COFF_SectionHeader *headers;
|
||||
U32 *comdats;
|
||||
U32Node **associations;
|
||||
U32Node **associated_section_numbers;
|
||||
} LNK_ObjSectionArray;
|
||||
|
||||
typedef struct LNK_ObjCoff
|
||||
@@ -33,10 +34,10 @@ typedef struct LNK_ObjCoff
|
||||
COFF_FileHeaderInfo header;
|
||||
LNK_ObjSectionArray sections;
|
||||
LNK_ObjSymbolArray symbols;
|
||||
U32 debug_t_sect_idx;
|
||||
U32 debug_p_sect_idx;
|
||||
U32 debug_h_sect_idx;
|
||||
U32 llvm_addrsig_sect_idx;
|
||||
U32 debug_t_section_number;
|
||||
U32 debug_p_section_number;
|
||||
U32 debug_h_section_number;
|
||||
U32 llvm_addrsig_section_number;
|
||||
B8 hotpatch;
|
||||
} LNK_ObjCoff;
|
||||
|
||||
@@ -52,7 +53,7 @@ typedef struct LNK_Obj
|
||||
U32 input_idx;
|
||||
|
||||
// link state
|
||||
LNK_ObjSymbolRef *symlinks;
|
||||
LNK_ObjSymbolRef *symlinks; // indexed by COFF section number; slot zero is null
|
||||
|
||||
// link
|
||||
struct LNK_LibMemberRef *link_member;
|
||||
@@ -68,7 +69,6 @@ typedef struct LNK_Obj
|
||||
typedef struct LNK_ObjSection
|
||||
{
|
||||
LNK_Obj *obj;
|
||||
U64 sect_idx;
|
||||
U64 section_number;
|
||||
COFF_SectionHeader *header;
|
||||
COFF_SectionFlags *flags;
|
||||
@@ -77,6 +77,7 @@ typedef struct LNK_ObjSection
|
||||
U32 reloc_count;
|
||||
} LNK_ObjSection;
|
||||
|
||||
|
||||
typedef struct LNK_ObjNode
|
||||
{
|
||||
struct LNK_ObjNode *next;
|
||||
@@ -97,7 +98,26 @@ typedef struct LNK_ObjNodeArray
|
||||
LNK_ObjNode *v;
|
||||
} LNK_ObjNodeArray;
|
||||
|
||||
// --- Maps --------------------------------------------------------------
|
||||
// --- Iterators ---------------------------------------------------------------
|
||||
|
||||
typedef struct LNK_ObjSectionIter
|
||||
{
|
||||
LNK_ObjSection v;
|
||||
} LNK_ObjSectionIter;
|
||||
|
||||
typedef struct LNK_ObjSymbolIter
|
||||
{
|
||||
U64 next_symbol_idx;
|
||||
U64 next_primary_idx;
|
||||
U64 symbol_idx;
|
||||
U64 primary_idx;
|
||||
COFF_ParsedSymbol v;
|
||||
} LNK_ObjSymbolIter;
|
||||
|
||||
#define LNK_EachCoffSection(it, obj) (LNK_ObjSectionIter it = {0}; lnk_obj_section_iter_next((obj), &(it));)
|
||||
#define LNK_EachCoffSymbol(it, obj) (LNK_ObjSymbolIter it = {0}; lnk_obj_symbol_iter_next((obj), &(it));)
|
||||
|
||||
// --- Maps --------------------------------------------------------------------
|
||||
|
||||
typedef struct LNK_SectionOffsetSymbol
|
||||
{
|
||||
@@ -219,18 +239,14 @@ internal LNK_Obj ** lnk_array_from_obj_list(Arena *arena, LNK_ObjList list);
|
||||
internal void lnk_obj_list_push_node_many(LNK_ObjList *list, U64 count, LNK_ObjNode *nodes);
|
||||
internal void lnk_obj_list_push_node(LNK_ObjList *list, LNK_ObjNode *node);
|
||||
|
||||
internal void lnk_inputer_push_obj_symbols(TP_Context *tp, TP_Arena *arena, LNK_SymbolTable *symtab, U64 objs_count, LNK_ObjNode *objs);
|
||||
|
||||
// --- Metadata ----------------------------------------------------------------
|
||||
|
||||
internal U32 lnk_obj_get_features(LNK_Obj *obj);
|
||||
internal U32 lnk_obj_get_comp_id(LNK_Obj *obj);
|
||||
internal U32 lnk_obj_get_vol_md(LNK_Obj *obj);
|
||||
internal struct LNK_Lib * lnk_obj_get_lib(LNK_Obj *obj);
|
||||
internal String8 lnk_obj_get_lib_path(LNK_Obj *obj);
|
||||
internal U32 lnk_obj_get_removed_section_number(LNK_Obj *obj);
|
||||
internal B32 lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *symlink_out);
|
||||
internal U32List lnk_obj_collect_associated_sections(Arena *arena, LNK_Obj *obj, U32 root_section, COFF_SectionFlags skip_flags);
|
||||
internal B32 lnk_obj_get_comdat_symlink_from_section_number(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *symlink_out);
|
||||
internal U32List lnk_obj_collect_associated_section_numbers(Arena *arena, LNK_Obj *obj, U32 root_section_number, COFF_SectionFlags skip_flags);
|
||||
|
||||
// --- Symbol & Section Helpers ------------------------------------------------
|
||||
|
||||
@@ -240,19 +256,18 @@ internal force_inline String8 lnk_symbol_name_from_coff_symbol_idx(LNK
|
||||
internal force_inline U64 lnk_obj_primary_symbol_idx_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 String8 lnk_obj_section_data_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||
internal String8 lnk_obj_section_data_from_number(LNK_Obj *obj, U64 section_number);
|
||||
internal U64 lnk_obj_foff_from_section_data_ptr(LNK_Obj *obj, void *ptr);
|
||||
internal U64 lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
internal U64 lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||
internal String8 lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
internal String8 lnk_obj_section_name_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||
internal LNK_ObjSection lnk_obj_section_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||
internal LNK_ObjSection lnk_obj_section_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
internal COFF_RelocArray lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_header);
|
||||
internal String8 lnk_coff_string_table_from_obj(LNK_Obj *obj);
|
||||
internal String8 lnk_coff_symbol_table_from_obj(LNK_Obj *obj);
|
||||
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 force_inline B32 lnk_obj_section_iter_next(LNK_Obj *obj, LNK_ObjSectionIter *it);
|
||||
internal force_inline B32 lnk_obj_symbol_iter_next(LNK_Obj *obj, LNK_ObjSymbolIter *it);
|
||||
|
||||
// --- Helpers -----------------------------------------------------------------
|
||||
|
||||
internal String8List * lnk_collect_obj_sections(TP_Context *tp, TP_Arena *arena, U64 objs_count, LNK_Obj **objs, String8 name, B32 collect_discarded);
|
||||
@@ -272,7 +287,7 @@ internal U32 lnk_symbol_from_section_offset(LNK_ObjSymbolMap *map
|
||||
|
||||
// CodeView map
|
||||
internal LNK_ObjLineMap * lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj);
|
||||
internal CV_Line * lnk_lines_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, U64 *line_count_out);
|
||||
internal LNK_InlineSite * lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U32 section_number, U32 offset, LNK_Symbol *callee_symbol);
|
||||
internal CV_Line * lnk_lines_from_section_offset(LNK_ObjLineMap *map, U64 section_number, U64 offset, U64 *line_count_out);
|
||||
internal LNK_InlineSite * lnk_inline_site_from_section_offset(LNK_ObjLineMap *map, U64 section_number, U64 offset, LNK_Symbol *callee_symbol);
|
||||
internal CV_Line * lnk_line_from_inline_site(LNK_InlineSite *site, U32 offset);
|
||||
|
||||
@@ -10,8 +10,8 @@ typedef struct LNK_SectionContrib
|
||||
union {
|
||||
// used to sort sections to get deterministic output
|
||||
struct {
|
||||
U32 obj_idx; // index of the input obj that contributes to the image section
|
||||
U32 obj_sect_idx; // index into contributing obj's section table
|
||||
U32 obj_idx; // index of the input obj that contributes to the image section
|
||||
U32 obj_section_number; // COFF section number in the contributing obj
|
||||
};
|
||||
|
||||
// used after section layout is finalized
|
||||
|
||||
@@ -342,8 +342,8 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
case COFF_ComdatSelect_ExactMatch: {
|
||||
LNK_ObjSection dst_section = lnk_obj_section_from_section_number(dst_obj, dst_parsed.section_number);
|
||||
LNK_ObjSection src_section = lnk_obj_section_from_section_number(src_obj, src_parsed.section_number);
|
||||
String8 dst_data = lnk_obj_section_data_from_sect_idx(dst_obj, dst_section.sect_idx);
|
||||
String8 src_data = lnk_obj_section_data_from_sect_idx(src_obj, src_section.sect_idx);
|
||||
String8 dst_data = lnk_obj_section_data_from_number(dst_obj, dst_section.section_number);
|
||||
String8 src_data = lnk_obj_section_data_from_number(src_obj, src_section.section_number);
|
||||
|
||||
B32 is_exact_match = 0;
|
||||
if (dst_check_sum != 0 && src_check_sum != 0) {
|
||||
@@ -396,7 +396,7 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
*dst_section.flags |= COFF_SectionFlag_LnkRemove;
|
||||
|
||||
// remove associated sections from the output
|
||||
for (U32Node *associated_section = dst_ref.obj->coff.sections.associations[dst_parsed.section_number];
|
||||
for (U32Node *associated_section = dst_ref.obj->coff.sections.associated_section_numbers[dst_parsed.section_number];
|
||||
associated_section != 0;
|
||||
associated_section = associated_section->next) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_section_number(dst_ref.obj, associated_section->data);
|
||||
@@ -773,7 +773,7 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb
|
||||
switch (symbol_interp) {
|
||||
case COFF_SymbolValueInterp_Regular: {
|
||||
LNK_ObjSymbolRef symlink = {0};
|
||||
*symbol_out = lnk_obj_get_comdat_symlink(symbol.obj, symbol_parsed.section_number, &symlink) ? symlink : symbol;
|
||||
*symbol_out = lnk_obj_get_comdat_symlink_from_section_number(symbol.obj, symbol_parsed.section_number, &symlink) ? symlink : symbol;
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_Weak: {
|
||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx));
|
||||
|
||||
Reference in new issue
Block a user