mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-23 20:24:59 -07:00
WIP function padding
This commit is contained in:
+3
-13
@@ -1475,7 +1475,7 @@ lnk_build_guard_tables(TP_Context *tp,
|
||||
} else {
|
||||
// use relocation data in code sections to get function symbols
|
||||
for (U64 isect = 0; isect < obj->sect_count; ++isect) {
|
||||
LNK_Chunk *chunk = &obj->chunk_arr[isect];
|
||||
LNK_Chunk *chunk = obj->chunk_arr[isect];
|
||||
if (!chunk) {
|
||||
continue;
|
||||
}
|
||||
@@ -1782,7 +1782,7 @@ THREAD_POOL_TASK_FUNC(lnk_emit_base_relocs_from_objs_task)
|
||||
for (U64 obj_idx = range.min; obj_idx < range.max; ++obj_idx) {
|
||||
LNK_Obj *obj = task->obj_arr[obj_idx];
|
||||
for (U64 sect_idx = 0; sect_idx < obj->sect_count; sect_idx += 1) {
|
||||
B32 is_live = !lnk_chunk_is_discarded(&obj->chunk_arr[sect_idx]);
|
||||
B32 is_live = !lnk_chunk_is_discarded(obj->chunk_arr[sect_idx]);
|
||||
if (is_live) {
|
||||
LNK_RelocList reloc_list = obj->sect_reloc_list_arr[sect_idx];
|
||||
for (LNK_Reloc *reloc = reloc_list.first; reloc != 0; reloc = reloc->next) {
|
||||
@@ -2610,16 +2610,6 @@ lnk_apply_reloc(U64 base_addr,
|
||||
} break;
|
||||
}
|
||||
|
||||
#if BUILD_DEBUG
|
||||
if (str8_match(str8_lit("__ImageBase"), symbol->name, 0)) {
|
||||
Assert(symbol_isect == 0);
|
||||
Assert(symbol_voff == 0);
|
||||
Assert(symbol_foff == 0);
|
||||
Assert(symbol_vsize == 0);
|
||||
Assert(symbol_fsize == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
U64 reloc_align = 1;
|
||||
U64 reloc_size = 0;
|
||||
S64 reloc_value = 0;
|
||||
@@ -3521,7 +3511,7 @@ lnk_run(int argc, char **argv)
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, st, unique_obj_input_list.count, input_obj_arr);
|
||||
LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, st, config->function_pad_min, unique_obj_input_list.count, input_obj_arr);
|
||||
|
||||
ProfBegin("Machine Compat Check");
|
||||
for (U64 obj_idx = 0; obj_idx < obj_node_arr.count; ++obj_idx) {
|
||||
|
||||
+121
-63
@@ -183,11 +183,15 @@ lnk_chunk_deep_copy(Arena *arena, LNK_Chunk *chunk)
|
||||
stack->src_node = stack->src_node->next;
|
||||
stack->dst_node = stack->dst_node->next;
|
||||
|
||||
dst->ref = src->ref;
|
||||
dst->align = src->align;
|
||||
dst->sort_idx = push_str8_copy(arena, src->sort_idx);
|
||||
dst->type = src->type;
|
||||
dst->flags = src->flags;
|
||||
dst->ref = src->ref;
|
||||
dst->type = src->type;
|
||||
dst->align = src->align;
|
||||
dst->is_discarded = src->is_discarded;
|
||||
dst->sort_chunk = src->sort_chunk;
|
||||
dst->sort_idx = push_str8_copy(arena, src->sort_idx);
|
||||
dst->input_idx = src->input_idx;
|
||||
dst->flags = src->flags;
|
||||
dst->associate = src->associate;
|
||||
lnk_chunk_set_debugf(arena, dst, "%S", src->debug);
|
||||
|
||||
switch (src->type) {
|
||||
@@ -343,25 +347,37 @@ lnk_chunk_list_get_node_count(LNK_Chunk *chunk)
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_chunk_align_array_list_push(Arena *arena, Arena *scratch, LNK_ChunkAlignArrayList *list, U64 cap, U64 align_off, U64 align_size)
|
||||
lnk_chunk_pad_array_list_push(Arena *arena, Arena *scratch, LNK_ChunkPadArrayList *list, U64 cap, U64 align_off, U64 align_size)
|
||||
{
|
||||
if (align_size > 0) {
|
||||
if (list->last == 0 || list->last->data.count >= list->last->cap) {
|
||||
LNK_ChunkAlignArrayNode *node = push_array(scratch, LNK_ChunkAlignArrayNode, 1);
|
||||
LNK_ChunkPadArrayNode *node = push_array(scratch, LNK_ChunkPadArrayNode, 1);
|
||||
node->cap = cap;
|
||||
node->data.v = push_array_no_zero(arena, LNK_ChunkAlign, cap);
|
||||
node->data.v = push_array_no_zero(arena, LNK_ChunkPad, cap);
|
||||
|
||||
SLLQueuePush(list->first, list->last, node);
|
||||
++list->count;
|
||||
}
|
||||
|
||||
LNK_ChunkAlignArray *last_array = &list->last->data;
|
||||
LNK_ChunkAlign *align = &last_array->v[last_array->count++];
|
||||
LNK_ChunkPadArray *last_array = &list->last->data;
|
||||
LNK_ChunkPad *align = &last_array->v[last_array->count++];
|
||||
align->off = align_off;
|
||||
align->size = align_size;
|
||||
}
|
||||
}
|
||||
|
||||
internal
|
||||
LNK_CHUNK_VISITOR_SIG(lnk_offset_chunks)
|
||||
{
|
||||
LNK_OffsetChunks *offset_chunks = ud;
|
||||
U64 offset = offset_chunks->offset;
|
||||
LNK_ChunkLayout *layout = offset_chunks->layout;
|
||||
|
||||
layout->chunk_off_array[chunk->ref.chunk_id] += offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal LNK_ChunkLayout
|
||||
lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
{
|
||||
@@ -401,8 +417,8 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
stack->chunk_array.count = 1;
|
||||
stack->chunk_array.v = &root;
|
||||
|
||||
U64 align_cap = 4096;
|
||||
LNK_ChunkAlignArrayList align_list = {0};
|
||||
U64 pad_cap = 4096;
|
||||
LNK_ChunkPadArrayList pad_list = {0};
|
||||
|
||||
U64 cursor = 0;
|
||||
|
||||
@@ -416,22 +432,29 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
continue;
|
||||
}
|
||||
|
||||
// push align
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_align_array_list_push(arena, scratch.arena, &align_list, align_cap, cursor, align_size);
|
||||
cursor += align_size;
|
||||
|
||||
// store id -> chunk
|
||||
Assert(chunk->ref.chunk_id < total_chunk_count);
|
||||
Assert(layout.chunk_ptr_array[chunk->ref.chunk_id] == &g_null_chunk);
|
||||
layout.chunk_ptr_array[chunk->ref.chunk_id] = chunk;
|
||||
|
||||
// store id -> offset
|
||||
Assert(layout.chunk_off_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_off_array[chunk->ref.chunk_id] = cursor;
|
||||
|
||||
switch (chunk->type) {
|
||||
case LNK_Chunk_Leaf: {
|
||||
// push pad
|
||||
if (chunk->u.leaf.size < chunk->min_size) {
|
||||
U64 pad_size = chunk->min_size - chunk->u.leaf.size;
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, cursor, pad_size);
|
||||
cursor += pad_size;
|
||||
}
|
||||
|
||||
// push align
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, cursor, align_size);
|
||||
cursor += align_size;
|
||||
|
||||
// store id -> chunk
|
||||
Assert(chunk->ref.chunk_id < total_chunk_count);
|
||||
Assert(layout.chunk_ptr_array[chunk->ref.chunk_id] == &g_null_chunk);
|
||||
layout.chunk_ptr_array[chunk->ref.chunk_id] = chunk;
|
||||
|
||||
// store id -> offset
|
||||
Assert(layout.chunk_off_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_off_array[chunk->ref.chunk_id] = cursor;
|
||||
|
||||
// store id -> file size
|
||||
Assert(layout.chunk_file_size_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_file_size_array[chunk->ref.chunk_id] = chunk->u.leaf.size;
|
||||
@@ -445,11 +468,20 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
} break;
|
||||
|
||||
case LNK_Chunk_LeafArray: {
|
||||
#if BUILD_DEBUG
|
||||
for (U64 i = 0; i < chunk->u.arr->count; ++i) {
|
||||
Assert(chunk->u.arr->v[i]->type == LNK_Chunk_Leaf);
|
||||
}
|
||||
#endif
|
||||
// push align
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, cursor, align_size);
|
||||
cursor += align_size;
|
||||
|
||||
// store id -> chunk
|
||||
Assert(chunk->ref.chunk_id < total_chunk_count);
|
||||
Assert(layout.chunk_ptr_array[chunk->ref.chunk_id] == &g_null_chunk);
|
||||
layout.chunk_ptr_array[chunk->ref.chunk_id] = chunk;
|
||||
|
||||
// store id -> offset
|
||||
Assert(layout.chunk_off_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_off_array[chunk->ref.chunk_id] = cursor;
|
||||
|
||||
// apply sort
|
||||
if (chunk->sort_chunk) {
|
||||
lnk_chunk_array_sort(*chunk->u.arr);
|
||||
@@ -462,6 +494,20 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
} goto _continue;
|
||||
|
||||
case LNK_Chunk_List: {
|
||||
// push align
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, cursor, align_size);
|
||||
cursor += align_size;
|
||||
|
||||
// store id -> chunk
|
||||
Assert(chunk->ref.chunk_id < total_chunk_count);
|
||||
Assert(layout.chunk_ptr_array[chunk->ref.chunk_id] == &g_null_chunk);
|
||||
layout.chunk_ptr_array[chunk->ref.chunk_id] = chunk;
|
||||
|
||||
// store id -> offset
|
||||
Assert(layout.chunk_off_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_off_array[chunk->ref.chunk_id] = cursor;
|
||||
|
||||
// list -> array
|
||||
LNK_ChunkArray chunk_array = {0};
|
||||
chunk_array.v = push_array_no_zero(scratch.arena, LNK_ChunkPtr, chunk->u.list->count);
|
||||
@@ -488,29 +534,41 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
if (stack->next) {
|
||||
// pop node chunk from stack
|
||||
struct Stack *prev = stack->next;
|
||||
|
||||
Assert(prev->ichunk > 0);
|
||||
LNK_Chunk *chunk = prev->chunk_array.v[prev->ichunk-1];
|
||||
|
||||
U64 chunk_data_off = layout.chunk_off_array[chunk->ref.chunk_id];
|
||||
Assert(chunk_data_off != max_U64);
|
||||
Assert(chunk_data_off <= cursor);
|
||||
|
||||
U64 chunk_data_size = cursor - chunk_data_off;
|
||||
|
||||
// store id -> virt size (no pad and align)
|
||||
Assert(layout.chunk_virt_size_array[chunk->ref.chunk_id] == max_U64);
|
||||
layout.chunk_virt_size_array[chunk->ref.chunk_id] = chunk_data_size;
|
||||
|
||||
// push pad
|
||||
if (chunk_data_size < chunk->min_size) {
|
||||
U64 pad_size = chunk->min_size - chunk->u.leaf.size;
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, chunk_data_off, pad_size);
|
||||
|
||||
LNK_OffsetChunks ud = {0};
|
||||
ud.offset = pad_size;
|
||||
ud.layout = &layout;
|
||||
lnk_visit_chunks(0, chunk, lnk_offset_chunks, &ud);
|
||||
}
|
||||
|
||||
// align chunk end
|
||||
LNK_Chunk *chunk = prev->chunk_array.v[prev->ichunk-1];
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_align_array_list_push(arena, scratch.arena, &align_list, align_cap, cursor, align_size);
|
||||
|
||||
U64 chunk_start_off = layout.chunk_off_array[chunk->ref.chunk_id];
|
||||
Assert(chunk_start_off != max_U64);
|
||||
Assert(chunk_start_off <= cursor);
|
||||
|
||||
// store id -> virt size
|
||||
Assert(layout.chunk_virt_size_array[chunk->ref.chunk_id] == max_U64);
|
||||
U64 virt_chunk_size = cursor - chunk_start_off;
|
||||
layout.chunk_virt_size_array[chunk->ref.chunk_id] = virt_chunk_size;
|
||||
|
||||
// advance cursor
|
||||
U64 align_size = AlignPadPow2(cursor, chunk->align);
|
||||
lnk_chunk_pad_array_list_push(arena, scratch.arena, &pad_list, pad_cap, cursor, align_size);
|
||||
cursor += align_size;
|
||||
|
||||
// store id -> file size
|
||||
chunk_data_size = cursor - chunk_data_off;
|
||||
|
||||
// store id -> file size (pad + align)
|
||||
Assert(layout.chunk_file_size_array[chunk->ref.chunk_id] == max_U64);
|
||||
U64 file_chunk_size = cursor - chunk_start_off;
|
||||
layout.chunk_file_size_array[chunk->ref.chunk_id] = file_chunk_size;
|
||||
layout.chunk_file_size_array[chunk->ref.chunk_id] = chunk_data_size;
|
||||
}
|
||||
|
||||
// move to next frame
|
||||
@@ -520,11 +578,11 @@ lnk_layout_from_chunk(Arena *arena, LNK_Chunk *root, U64 total_chunk_count)
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
ProfBegin("Build Aligns Array");
|
||||
layout.align_array_count = 0;
|
||||
layout.align_array = push_array(arena, LNK_ChunkAlignArray, align_list.count);
|
||||
for (LNK_ChunkAlignArrayNode *node = align_list.first; node != 0; node = node->next) {
|
||||
layout.align_array[layout.align_array_count++] = node->data;
|
||||
ProfBegin("Build Pad Array");
|
||||
layout.pad_array_count = 0;
|
||||
layout.pad_array = push_array(arena, LNK_ChunkPadArray, pad_list.count);
|
||||
for (LNK_ChunkPadArrayNode *node = pad_list.first; node != 0; node = node->next) {
|
||||
layout.pad_array[layout.pad_array_count++] = node->data;
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
@@ -578,7 +636,7 @@ THREAD_POOL_TASK_FUNC(lnk_fill_chunks_task)
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(lnk_fill_aligns_task)
|
||||
THREAD_POOL_TASK_FUNC(lnk_fill_pads_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -588,12 +646,12 @@ THREAD_POOL_TASK_FUNC(lnk_fill_aligns_task)
|
||||
String8 buffer = task->buffer;
|
||||
U8 fill_byte = task->fill_byte;
|
||||
|
||||
for (U64 align_array_idx = range.min; align_array_idx < range.max; ++align_array_idx) {
|
||||
LNK_ChunkAlignArray align_array = layout.align_array[align_array_idx];
|
||||
for (U64 align_idx = 0; align_idx < align_array.count; ++align_idx) {
|
||||
LNK_ChunkAlign align = align_array.v[align_idx];
|
||||
Assert(align.off + align.size <= buffer.size);
|
||||
MemorySet(buffer.str + align.off, fill_byte, align.size);
|
||||
for (U64 pad_array_idx = range.min; pad_array_idx < range.max; ++pad_array_idx) {
|
||||
LNK_ChunkPadArray pad_array = layout.pad_array[pad_array_idx];
|
||||
for (U64 pad_idx = 0; pad_idx < pad_array.count; ++pad_idx) {
|
||||
LNK_ChunkPad pad = pad_array.v[pad_idx];
|
||||
Assert(pad.off + pad.size <= buffer.size);
|
||||
MemorySet(buffer.str + pad.off, fill_byte, pad.size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,9 +674,9 @@ lnk_serialize_chunk_layout(TP_Context *tp, LNK_ChunkLayout layout, String8 buffe
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_fill_chunks_task, &task);
|
||||
ProfEnd();
|
||||
|
||||
ProfBeginV("Fill Aligns [Array Count %llu]", layout.align_array_count);
|
||||
task.ranges = tp_divide_work(scratch.arena, layout.align_array_count, tp->worker_count);
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_fill_aligns_task, &task);
|
||||
ProfBeginV("Fill Pads [Array Count %llu]", layout.pad_array_count);
|
||||
task.ranges = tp_divide_work(scratch.arena, layout.pad_array_count, tp->worker_count);
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_fill_pads_task, &task);
|
||||
ProfEnd();
|
||||
|
||||
scratch_end(scratch);
|
||||
|
||||
+25
-16
@@ -28,6 +28,7 @@ typedef struct LNK_Chunk
|
||||
LNK_ChunkRef ref;
|
||||
LNK_ChunkType type;
|
||||
U64 align;
|
||||
U64 min_size;
|
||||
B32 is_discarded;
|
||||
B32 sort_chunk;
|
||||
String8 sort_idx;
|
||||
@@ -95,29 +96,29 @@ typedef struct LNK_ChunkOpList
|
||||
LNK_ChunkOp *last;
|
||||
} LNK_ChunkOpList;
|
||||
|
||||
typedef struct LNK_ChunkAlign
|
||||
typedef struct LNK_ChunkPad
|
||||
{
|
||||
U64 off;
|
||||
U64 size;
|
||||
} LNK_ChunkAlign;
|
||||
} LNK_ChunkPad;
|
||||
|
||||
typedef struct LNK_ChunkAlignArray
|
||||
typedef struct LNK_ChunkPadArray
|
||||
{
|
||||
U64 count;
|
||||
LNK_ChunkAlign *v;
|
||||
} LNK_ChunkAlignArray;
|
||||
typedef struct LNK_ChunkAlignArrayNode
|
||||
U64 count;
|
||||
LNK_ChunkPad *v;
|
||||
} LNK_ChunkPadArray;
|
||||
typedef struct LNK_ChunkPadArrayNode
|
||||
{
|
||||
struct LNK_ChunkAlignArrayNode *next;
|
||||
struct LNK_ChunkPadArrayNode *next;
|
||||
U64 cap;
|
||||
LNK_ChunkAlignArray data;
|
||||
} LNK_ChunkAlignArrayNode;
|
||||
typedef struct LNK_ChunkAlignArrayList
|
||||
LNK_ChunkPadArray data;
|
||||
} LNK_ChunkPadArrayNode;
|
||||
typedef struct LNK_ChunkPadArrayList
|
||||
{
|
||||
U64 count;
|
||||
LNK_ChunkAlignArrayNode *first;
|
||||
LNK_ChunkAlignArrayNode *last;
|
||||
} LNK_ChunkAlignArrayList;
|
||||
LNK_ChunkPadArrayNode *first;
|
||||
LNK_ChunkPadArrayNode *last;
|
||||
} LNK_ChunkPadArrayList;
|
||||
|
||||
typedef struct LNK_ChunkLayout
|
||||
{
|
||||
@@ -126,8 +127,8 @@ typedef struct LNK_ChunkLayout
|
||||
U64 *chunk_off_array; // discarded chunks have offset set to max_U64
|
||||
U64 *chunk_file_size_array; // discarded chunks have offset set to max_U64
|
||||
U64 *chunk_virt_size_array; // discarded chunks have offset set to max_U64
|
||||
U64 align_array_count;
|
||||
LNK_ChunkAlignArray *align_array;
|
||||
U64 pad_array_count;
|
||||
LNK_ChunkPadArray *pad_array;
|
||||
} LNK_ChunkLayout;
|
||||
|
||||
typedef struct LNK_ChunkManager
|
||||
@@ -136,6 +137,14 @@ typedef struct LNK_ChunkManager
|
||||
U64 total_chunk_count;
|
||||
} LNK_ChunkManager;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 offset;
|
||||
LNK_ChunkLayout *layout;
|
||||
} LNK_OffsetChunks;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_ChunkLayout layout;
|
||||
|
||||
@@ -2978,7 +2978,7 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
||||
U64 sc_count = 0;
|
||||
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->sect_count; ++chunk_idx) {
|
||||
LNK_Chunk *chunk = &obj->chunk_arr[chunk_idx];
|
||||
LNK_Chunk *chunk = obj->chunk_arr[chunk_idx];
|
||||
|
||||
if (!chunk || lnk_chunk_is_discarded(chunk)) {
|
||||
continue;
|
||||
@@ -5325,7 +5325,7 @@ THREAD_POOL_TASK_FUNC(lnk_collect_obj_virtual_ranges_task)
|
||||
dst->virt_ranges = push_array_no_zero(arena, Rng1U64, obj->sect_count);
|
||||
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->sect_count; ++chunk_idx) {
|
||||
LNK_Chunk *chunk = &obj->chunk_arr[chunk_idx];
|
||||
LNK_Chunk *chunk = obj->chunk_arr[chunk_idx];
|
||||
if (!chunk || lnk_chunk_is_discarded(chunk)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -938,7 +938,7 @@ lnk_build_import_lib(TP_Context *tp, TP_Arena *arena, COFF_MachineType machine,
|
||||
LNK_InputObj **inputs = lnk_array_from_input_obj_list(scratch.arena, input_obj_list);
|
||||
LNK_SectionTable *st = lnk_section_table_alloc(0,0,0);
|
||||
LNK_ObjList obj_list = {0};
|
||||
lnk_obj_list_push_parallel(tp, arena, &obj_list, st, input_obj_list.count, inputs);
|
||||
lnk_obj_list_push_parallel(tp, arena, &obj_list, st, 0, input_obj_list.count, inputs);
|
||||
|
||||
LNK_LibBuild import_lib = lnk_build_lib(scratch.arena, machine, time_stamp, dll_name, obj_list, exptab);
|
||||
B32 emit_second_member = 0; // MSVC linker refuses to link with lib that has the second member.
|
||||
|
||||
+164
-44
@@ -142,7 +142,7 @@ lnk_obj_search_chunks(Arena *arena, LNK_Obj *obj, String8 name, String8 postfix,
|
||||
str8_match(obj_sect_sort, postfix, 0);
|
||||
|
||||
if (is_match) {
|
||||
LNK_ChunkPtr chunk = &obj->chunk_arr[sect_idx];
|
||||
LNK_ChunkPtr chunk = obj->chunk_arr[sect_idx];
|
||||
|
||||
if (!collect_discarded && lnk_chunk_is_discarded(chunk)) {
|
||||
continue;
|
||||
@@ -332,8 +332,6 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
LNK_ObjNode *obj_node = task->obj_node_arr + task_id;
|
||||
LNK_Obj *obj = &obj_node->data;
|
||||
|
||||
//Assert(coff_data.size > 0);
|
||||
|
||||
// cache path, we need it for error reports and debug stuff
|
||||
String8 cached_path = push_str8_copy(arena, input->path);
|
||||
String8 cached_lib_path = push_str8_copy(arena, input->lib_path);
|
||||
@@ -353,9 +351,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
chunk_count += coff_info.section_count_no_null;
|
||||
chunk_count += 1; // :common_block
|
||||
|
||||
String8 *sect_name_arr = push_array_no_zero(arena, String8, chunk_count);
|
||||
String8 *sect_sort_arr = push_array_no_zero(arena, String8, chunk_count);
|
||||
LNK_Chunk *chunk_arr = push_array_no_zero(arena, LNK_Chunk, chunk_count);
|
||||
String8 *sect_name_arr = push_array_no_zero(arena, String8, chunk_count);
|
||||
String8 *sect_sort_arr = push_array_no_zero(arena, String8, chunk_count);
|
||||
LNK_Chunk *chunk_arr = push_array_no_zero(arena, LNK_Chunk, chunk_count);
|
||||
|
||||
// init section name and postfix array
|
||||
for (U64 sect_idx = 0; sect_idx < coff_info.section_count_no_null; sect_idx += 1) {
|
||||
@@ -391,6 +389,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
LNK_Chunk *chunk = &chunk_arr[sect_idx];
|
||||
chunk->ref = lnk_chunk_ref(0,0); // :chunk_ref_assign
|
||||
chunk->align = coff_align_size_from_section_flags(coff_sect->flags);
|
||||
chunk->min_size = 0;
|
||||
chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LNK_REMOVE);
|
||||
chunk->sort_chunk = 1;
|
||||
chunk->type = LNK_Chunk_Leaf;
|
||||
@@ -416,11 +415,16 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
master_common_block->u.list = push_array(arena, LNK_ChunkList, 1);
|
||||
lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", cached_path);
|
||||
|
||||
LNK_ChunkPtr *chunk_ptr_arr = push_array_no_zero(arena, LNK_ChunkPtr, chunk_count);
|
||||
for (U64 i = 0; i < chunk_count; ++i) {
|
||||
chunk_ptr_arr[i] = &chunk_arr[i];
|
||||
}
|
||||
|
||||
// convert from coff
|
||||
B32 is_big_obj = coff_info.type == COFF_DataType_BIG_OBJ;
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, is_big_obj, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_symbols, chunk_arr, master_common_block);
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, is_big_obj, task->function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_symbols, chunk_ptr_arr, master_common_block);
|
||||
LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr);
|
||||
LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_arr, symbol_arr);
|
||||
LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_ptr_arr, symbol_arr);
|
||||
|
||||
// fill out obj
|
||||
obj->data = input->data;
|
||||
@@ -432,7 +436,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
obj->sect_count = coff_info.section_count_no_null;
|
||||
obj->sect_name_arr = sect_name_arr;
|
||||
obj->sect_sort_arr = sect_sort_arr;
|
||||
obj->chunk_arr = chunk_arr;
|
||||
obj->chunk_arr = chunk_ptr_arr;
|
||||
obj->symbol_list = symbol_list;
|
||||
obj->sect_reloc_list_arr = reloc_list_arr;
|
||||
obj->directive_info = lnk_init_directives(arena, cached_path, coff_info.section_count_no_null, sect_name_arr, chunk_arr);
|
||||
@@ -478,7 +482,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_new_sect_scanner)
|
||||
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) {
|
||||
String8 sect_name = obj->sect_name_arr[chunk_idx];
|
||||
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx].flags & ~COFF_SectionFlags_LNK_FLAGS;
|
||||
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx]->flags & ~COFF_SectionFlags_LNK_FLAGS;
|
||||
|
||||
KeyValuePair *is_present = hash_table_search_string(ht, sect_name);
|
||||
if (is_present) {
|
||||
@@ -511,8 +515,8 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_counter)
|
||||
LNK_Obj *obj = &task->obj_arr[obj_idx].data;
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) {
|
||||
String8 name = obj->sect_name_arr[chunk_idx];
|
||||
LNK_Chunk *chunk = &obj->chunk_arr[chunk_idx];
|
||||
LNK_Section *sect = lnk_section_table_search(task->st, name);
|
||||
LNK_Chunk *chunk = obj->chunk_arr[chunk_idx];
|
||||
LNK_Section *sect = lnk_section_table_search(task->st, name);
|
||||
|
||||
U64 count = 0;
|
||||
lnk_visit_chunks(0, chunk, lnk_chunk_get_count_cb, &count);
|
||||
@@ -549,7 +553,7 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_ref_assigner)
|
||||
for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) {
|
||||
String8 name = obj->sect_name_arr[chunk_idx];
|
||||
String8 sort = obj->sect_sort_arr[chunk_idx];
|
||||
LNK_Chunk *chunk = &obj->chunk_arr[chunk_idx];
|
||||
LNK_Chunk *chunk = obj->chunk_arr[chunk_idx];
|
||||
|
||||
// :find_chunk_section
|
||||
LNK_Section *sect = lnk_section_table_search(task->st, name);
|
||||
@@ -570,7 +574,7 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_ref_assigner)
|
||||
}
|
||||
|
||||
internal LNK_ObjNodeArray
|
||||
lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 input_count, LNK_InputObj **inputs)
|
||||
lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 function_pad_min, U64 input_count, LNK_InputObj **inputs)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(arena->v, arena->count);
|
||||
@@ -580,10 +584,11 @@ lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_lis
|
||||
|
||||
ProfBegin("Obj Initer");
|
||||
{
|
||||
LNK_ObjIniter task = {0};
|
||||
task.inputs = inputs;
|
||||
task.obj_id_base = obj_id_base;
|
||||
task.obj_node_arr = obj_arr.v;
|
||||
LNK_ObjIniter task = {0};
|
||||
task.inputs = inputs;
|
||||
task.obj_id_base = obj_id_base;
|
||||
task.obj_node_arr = obj_arr.v;
|
||||
task.function_pad_min = function_pad_min;
|
||||
tp_for_parallel(tp, arena, input_count, lnk_obj_initer, &task);
|
||||
}
|
||||
ProfEnd();
|
||||
@@ -717,20 +722,19 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
LNK_Obj *obj,
|
||||
String8 obj_path,
|
||||
B32 is_big_obj,
|
||||
U64 function_pad_min,
|
||||
U64 string_table_off,
|
||||
U64 sect_count,
|
||||
COFF_SectionHeader *coff_sect_arr,
|
||||
COFF_Symbol32Array coff_symbols,
|
||||
LNK_Chunk *chunk_arr,
|
||||
LNK_ChunkPtr *chunk_ptr_arr,
|
||||
LNK_Chunk *master_common_block)
|
||||
{
|
||||
LNK_SymbolList weak_symbol_list = {0};
|
||||
|
||||
LNK_SymbolArray symbol_array = {0};
|
||||
symbol_array.count = coff_symbols.count;
|
||||
symbol_array.v = push_array(arena, LNK_Symbol, symbol_array.count);
|
||||
LNK_SymbolArray symbol_array;
|
||||
symbol_array.count = coff_symbols.count;
|
||||
symbol_array.v = push_array(arena, LNK_Symbol, symbol_array.count);
|
||||
|
||||
for (U64 symbol_idx = 0; symbol_idx < coff_symbols.count; symbol_idx += 1) {
|
||||
for (U64 symbol_idx = 0; symbol_idx < coff_symbols.count; ++symbol_idx) {
|
||||
COFF_Symbol32 *coff_symbol = &coff_symbols.v[symbol_idx];
|
||||
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
|
||||
|
||||
@@ -751,22 +755,32 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
break;
|
||||
}
|
||||
|
||||
COFF_SectionHeader *coff_sect_header = &coff_sect_arr[coff_symbol->section_number - 1];
|
||||
|
||||
if (coff_symbol->value > coff_sect_header->fsize) {
|
||||
lnk_error(LNK_Error_IllData, "%S: out of bounds section offset in symbol \"%S (%u)\"", obj_path, name, coff_symbol->value);
|
||||
break;
|
||||
}
|
||||
|
||||
LNK_DefinedSymbolVisibility visibility = LNK_DefinedSymbolVisibility_Static;
|
||||
if (coff_symbol->storage_class == COFF_SymStorageClass_EXTERNAL) {
|
||||
visibility = LNK_DefinedSymbolVisibility_Extern;
|
||||
}
|
||||
|
||||
|
||||
LNK_DefinedSymbolFlags flags = 0;
|
||||
if (coff_symbol->type.u.lsb == COFF_SymType_NULL && coff_symbol->type.u.msb == COFF_SymDType_FUNC) {
|
||||
if (coff_symbol->type.u.lsb == COFF_SymType_NULL &&
|
||||
coff_symbol->type.u.msb == COFF_SymDType_FUNC &&
|
||||
(coff_sect_header->flags & COFF_SectionFlag_CNT_CODE)) {
|
||||
flags |= LNK_DefinedSymbolFlag_IsFunc;
|
||||
}
|
||||
|
||||
COFF_ComdatSelectType selection = COFF_ComdatSelectType_ANY;
|
||||
U64 check_sum = 0;
|
||||
{
|
||||
B32 is_comdat = !!(coff_sect_arr[coff_symbol->section_number - 1].flags & COFF_SectionFlag_LNK_COMDAT);
|
||||
B32 has_static_def = is_comdat &&
|
||||
coff_symbol->value == 0 &&
|
||||
|
||||
LNK_Chunk *chunk = chunk_ptr_arr[coff_symbol->section_number-1];
|
||||
U64 offset = coff_symbol->value;
|
||||
COFF_ComdatSelectType selection = COFF_ComdatSelectType_ANY;
|
||||
U64 check_sum = 0;
|
||||
|
||||
if (coff_sect_header->flags & COFF_SectionFlag_LNK_COMDAT) {
|
||||
B32 has_static_def = coff_symbol->value == 0 &&
|
||||
coff_symbol->type.u.lsb == COFF_SymType_NULL &&
|
||||
coff_symbol->storage_class == COFF_SymStorageClass_STATIC &&
|
||||
coff_symbol->aux_symbol_count == 1;
|
||||
@@ -786,15 +800,122 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
break;
|
||||
}
|
||||
|
||||
LNK_Chunk *head_chunk = &chunk_arr[secdef_number - 1];
|
||||
LNK_Chunk *associate_chunk = &chunk_arr[coff_symbol->section_number - 1];
|
||||
LNK_Chunk *head_chunk = chunk_ptr_arr[secdef_number-1];
|
||||
LNK_Chunk *associate_chunk = chunk_ptr_arr[coff_symbol->section_number-1];
|
||||
Assert(head_chunk->type == LNK_Chunk_Leaf);
|
||||
Assert(associate_chunk->type == LNK_Chunk_Leaf);
|
||||
lnk_chunk_associate(arena, head_chunk, associate_chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LNK_Chunk *chunk = &chunk_arr[coff_symbol->section_number - 1];
|
||||
U64 offset = coff_symbol->value;
|
||||
|
||||
if (function_pad_min) {
|
||||
if ((flags & LNK_DefinedSymbolFlag_IsFunc)) {
|
||||
if (offset > 0) {
|
||||
// convert leaf to list chunk
|
||||
//
|
||||
// there is no way to know up front how many splits we have,
|
||||
// so lazily convert chunks when see two or more functions
|
||||
// in a section
|
||||
if (chunk->type == LNK_Chunk_Leaf) {
|
||||
// make a list chunk
|
||||
LNK_Chunk *chunk_list = push_array(arena, LNK_Chunk, 1);
|
||||
chunk_list->align = chunk->align;
|
||||
chunk_list->is_discarded = chunk->is_discarded;
|
||||
chunk_list->type = LNK_Chunk_List;
|
||||
chunk_list->sort_idx = chunk->sort_idx;
|
||||
chunk_list->sort_chunk = 0;
|
||||
chunk_list->input_idx = chunk->input_idx;
|
||||
chunk_list->flags = chunk->flags;
|
||||
chunk_list->associate = chunk->associate;
|
||||
chunk_list->u.list = push_array(arena, LNK_ChunkList, 1);
|
||||
|
||||
// reset chunk properties
|
||||
chunk->align = 1;
|
||||
chunk->min_size = function_pad_min;
|
||||
chunk->sort_chunk = 0;
|
||||
chunk->sort_idx = str8_zero();
|
||||
chunk->input_idx = 0;
|
||||
chunk->associate = 0;
|
||||
|
||||
// push leaf to list
|
||||
lnk_chunk_list_push(arena, chunk_list->u.list, chunk);
|
||||
|
||||
// set list as target chunk
|
||||
chunk = chunk_list;
|
||||
|
||||
// set list chunk to be head of this section
|
||||
chunk_ptr_arr[coff_symbol->section_number-1] = chunk_list;
|
||||
}
|
||||
|
||||
// find chunk that is near symbol
|
||||
U64 cursor = 0;
|
||||
LNK_ChunkNode *current = chunk->u.list->last;
|
||||
for (LNK_ChunkNode *c = chunk->u.list->first; c != 0; c = c->next) {
|
||||
Assert(c->data->type == LNK_Chunk_Leaf);
|
||||
if (cursor + c->data->u.leaf.size > coff_symbol->value) {
|
||||
current = c;
|
||||
break;
|
||||
}
|
||||
cursor += c->data->u.leaf.size;
|
||||
}
|
||||
|
||||
if (cursor < coff_symbol->value) {
|
||||
// bifurcate chunk at symbol offset
|
||||
U64 split_pos = coff_symbol->value - cursor;
|
||||
Rng1U64 left_data_range = rng_1u64(0, split_pos);
|
||||
Rng1U64 right_data_range = rng_1u64(left_data_range.max, current->data->u.leaf.size);
|
||||
String8 left_data = str8_substr(current->data->u.leaf, left_data_range);
|
||||
String8 right_data = str8_substr(current->data->u.leaf, right_data_range);
|
||||
|
||||
// create new chunk for new part
|
||||
LNK_Chunk *split_chunk = push_array(arena, LNK_Chunk, 1);
|
||||
split_chunk->align = 1;
|
||||
split_chunk->is_discarded = current->data->is_discarded;
|
||||
split_chunk->type = LNK_Chunk_Leaf;
|
||||
split_chunk->flags = current->data->flags;
|
||||
split_chunk->u.leaf = right_data;
|
||||
|
||||
LNK_ChunkNode *split_node = push_array(arena, LNK_ChunkNode, 1);
|
||||
split_node->data = split_chunk;
|
||||
|
||||
// update split chunk data
|
||||
current->data->u.leaf = left_data;
|
||||
|
||||
// insert split chunk after current chunk
|
||||
split_node->next = current->next;
|
||||
current->next = split_node;
|
||||
chunk->u.list->count += 1;
|
||||
|
||||
// point symbol to new split chunk
|
||||
chunk = split_chunk;
|
||||
offset = 0;
|
||||
} else {
|
||||
// chunk was already split at the offset
|
||||
chunk = current->data;
|
||||
offset = coff_symbol->value - cursor;
|
||||
}
|
||||
}
|
||||
|
||||
chunk->min_size = function_pad_min;
|
||||
}
|
||||
|
||||
// if symbol points to bifurcated section then we have an alias symbol (e.g. memmove is an alias to memcpy)
|
||||
// and we need to find chunk that is near symbol
|
||||
if (chunk->type == LNK_Chunk_List) {
|
||||
U64 cursor = 0;
|
||||
for (LNK_ChunkNode *c = chunk->u.list->first; c != 0; c = c->next) {
|
||||
if (cursor + c->data->u.leaf.size > coff_symbol->value) {
|
||||
chunk = c->data;
|
||||
offset = offset - cursor;
|
||||
break;
|
||||
}
|
||||
cursor += c->data->u.leaf.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert(chunk->type == LNK_Chunk_Leaf);
|
||||
lnk_init_defined_symbol_chunk(symbol, name, visibility, flags, chunk, offset, selection, check_sum);
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_UNDEFINED: {
|
||||
@@ -805,6 +926,7 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
LNK_Chunk *chunk = push_array_no_zero(arena, LNK_Chunk, 1);
|
||||
chunk->ref = lnk_chunk_ref(0,0); // :chunk_ref_assign
|
||||
chunk->align = 1;
|
||||
chunk->min_size = 0;
|
||||
chunk->is_discarded = 0;
|
||||
chunk->sort_chunk = 1;
|
||||
chunk->type = LNK_Chunk_Leaf;
|
||||
@@ -845,8 +967,6 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
#endif
|
||||
|
||||
lnk_init_weak_symbol(symbol, name, weak_ext->characteristics, &symbol_array.v[weak_ext->tag_index]);
|
||||
|
||||
lnk_symbol_list_push(arena, &weak_symbol_list, symbol);
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_ABS: {
|
||||
// Never code or data, synthetic symbol. COFF spec says bits in value are used
|
||||
@@ -873,14 +993,14 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
}
|
||||
|
||||
internal LNK_RelocList *
|
||||
lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_Chunk *chunk_arr, LNK_SymbolArray symbol_array)
|
||||
lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_ChunkPtr *chunk_ptr_arr, LNK_SymbolArray symbol_array)
|
||||
{
|
||||
LNK_RelocList *reloc_list_arr = push_array_no_zero(arena, LNK_RelocList, sect_count);
|
||||
for (U64 sect_idx = 0; sect_idx < sect_count; sect_idx += 1) {
|
||||
for (U64 sect_idx = 0; sect_idx < sect_count; ++sect_idx) {
|
||||
COFF_SectionHeader *coff_header = &coff_sect_arr[sect_idx];
|
||||
COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, coff_header);
|
||||
COFF_Reloc *coff_reloc_v = (COFF_Reloc *)(coff_data.str + coff_reloc_info.array_off);
|
||||
LNK_Chunk *sect_chunk = &chunk_arr[sect_idx];
|
||||
LNK_Chunk *sect_chunk = chunk_ptr_arr[sect_idx];
|
||||
reloc_list_arr[sect_idx] = lnk_reloc_list_from_coff_reloc_array(arena, machine, sect_chunk, symbol_array, coff_reloc_v, coff_reloc_info.count);
|
||||
}
|
||||
return reloc_list_arr;
|
||||
|
||||
@@ -40,7 +40,7 @@ typedef struct LNK_Obj
|
||||
String8 *sect_name_arr;
|
||||
String8 *sect_sort_arr;
|
||||
LNK_RelocList *sect_reloc_list_arr;
|
||||
LNK_Chunk *chunk_arr;
|
||||
LNK_ChunkPtr *chunk_arr;
|
||||
LNK_SymbolList symbol_list;
|
||||
LNK_DirectiveInfo directive_info;
|
||||
LNK_ExportParseList export_parse;
|
||||
@@ -92,6 +92,7 @@ typedef struct
|
||||
U64 obj_id_base;
|
||||
LNK_SectDefnList *defn_arr;
|
||||
LNK_SectionTable *st;
|
||||
U64 function_pad_min;
|
||||
} LNK_ObjIniter;
|
||||
|
||||
typedef struct
|
||||
@@ -177,12 +178,12 @@ internal LNK_InputObjList lnk_input_obj_list_from_string_list(Arena *arena, Stri
|
||||
internal LNK_Obj ** lnk_obj_arr_from_list(Arena *arena, LNK_ObjList list);
|
||||
internal LNK_ObjNodeArray lnk_obj_list_reserve(Arena *arena, LNK_ObjList *list, U64 count);
|
||||
internal LNK_ChunkList * lnk_collect_obj_chunks(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded);
|
||||
internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 input_count, LNK_InputObj **inputs);
|
||||
internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 function_pad_min, U64 input_count, LNK_InputObj **inputs);
|
||||
|
||||
internal LNK_Chunk * lnk_sect_chunk_array_from_coff(Arena *arena, U64 obj_id, String8 obj_path, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, String8 *sect_name_arr, String8 *sect_postfix_arr);
|
||||
internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, LNK_Obj *obj, String8 obj_path, B32 is_big_obj, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, COFF_Symbol32Array coff_symbols, LNK_Chunk *chunk_arr, LNK_Chunk *master_common_block);
|
||||
internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, LNK_Obj *obj, String8 obj_path, B32 is_big_obj, U64 function_pad_min, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, COFF_Symbol32Array coff_symbols, LNK_ChunkPtr *chunk_ptr_arr, LNK_Chunk *master_common_block);
|
||||
internal LNK_RelocList lnk_reloc_list_from_coff_reloc_array(Arena *arena, COFF_MachineType machine, LNK_Chunk *chunk, LNK_SymbolArray symbol_array, COFF_Reloc *reloc_v, U64 reloc_count);
|
||||
internal LNK_RelocList * lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_Chunk *sect_chunk_arr, LNK_SymbolArray symbol_array);
|
||||
internal LNK_RelocList * lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_ChunkPtr *chunk_ptr_arr, LNK_SymbolArray symbol_array);
|
||||
internal LNK_DirectiveInfo lnk_init_directives(Arena *arena, String8 obj_path, U64 chunk_count, String8 *sect_name_arr, LNK_Chunk *chunk_arr);
|
||||
|
||||
internal U32 lnk_obj_get_features(LNK_Obj *obj);
|
||||
|
||||
+28
-8
@@ -64,16 +64,36 @@ internal LNK_RelocList
|
||||
lnk_reloc_list_from_coff_reloc_array(Arena *arena, COFF_MachineType machine, LNK_Chunk *chunk, LNK_SymbolArray symbol_array, COFF_Reloc *reloc_v, U64 reloc_count)
|
||||
{
|
||||
LNK_RelocList reloc_list = {0};
|
||||
LNK_Reloc *reloc_arr = lnk_reloc_list_reserve(arena, &reloc_list, reloc_count);
|
||||
LNK_Reloc *reloc_ptr = reloc_arr;
|
||||
LNK_Reloc *reloc_opl = reloc_arr + reloc_count;
|
||||
|
||||
LNK_Reloc *reloc_arr = lnk_reloc_list_reserve(arena, &reloc_list, reloc_count);
|
||||
LNK_Reloc *reloc_ptr = reloc_arr;
|
||||
LNK_Reloc *reloc_opl = reloc_arr + reloc_count;
|
||||
COFF_Reloc *coff_reloc_ptr = reloc_v;
|
||||
for (; reloc_ptr < reloc_opl; reloc_ptr += 1, coff_reloc_ptr += 1) {
|
||||
|
||||
for (; reloc_ptr < reloc_opl; ++reloc_ptr, ++coff_reloc_ptr) {
|
||||
LNK_RelocType type = lnk_ext_reloc_type_from_coff(machine, coff_reloc_ptr->type);
|
||||
LNK_Chunk *reloc_chunk = chunk;
|
||||
U64 apply_off = coff_reloc_ptr->apply_off;
|
||||
LNK_Symbol *symbol = symbol_array.v + coff_reloc_ptr->isymbol;
|
||||
|
||||
if (chunk->type == LNK_Chunk_List) {
|
||||
U64 cursor = 0;
|
||||
for (LNK_ChunkNode *c = chunk->u.list->first; c != 0; c = c->next) {
|
||||
Assert(c->data->type == LNK_Chunk_Leaf);
|
||||
if (coff_reloc_ptr->apply_off < cursor + c->data->u.leaf.size) {
|
||||
reloc_chunk = c->data;
|
||||
apply_off = coff_reloc_ptr->apply_off - cursor;
|
||||
break;
|
||||
}
|
||||
cursor += c->data->u.leaf.size;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(coff_reloc_ptr->isymbol < symbol_array.count);
|
||||
reloc_ptr->chunk = chunk;
|
||||
reloc_ptr->type = lnk_ext_reloc_type_from_coff(machine, coff_reloc_ptr->type);
|
||||
reloc_ptr->apply_off = coff_reloc_ptr->apply_off;
|
||||
reloc_ptr->symbol = symbol_array.v + coff_reloc_ptr->isymbol;
|
||||
reloc_ptr->chunk = reloc_chunk;
|
||||
reloc_ptr->type = type;
|
||||
reloc_ptr->apply_off = apply_off;
|
||||
reloc_ptr->symbol = symbol;
|
||||
}
|
||||
return reloc_list;
|
||||
}
|
||||
|
||||
@@ -259,8 +259,8 @@ lnk_section_build_data(LNK_Section *sect, COFF_MachineType machine)
|
||||
sect->layout.chunk_off_array = 0;
|
||||
sect->layout.chunk_file_size_array = 0;
|
||||
sect->layout.chunk_virt_size_array = 0;
|
||||
sect->layout.align_array_count = 0;
|
||||
sect->layout.align_array = 0;
|
||||
sect->layout.pad_array_count = 0;
|
||||
sect->layout.pad_array = 0;
|
||||
}
|
||||
sect->is_loose = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user