check obj compatibility before initializing them

This commit is contained in:
Nikita Smith
2025-04-09 15:18:40 -07:00
committed by Ryan Fleury
parent 1eca5818a6
commit 307d3a7f4b
4 changed files with 41 additions and 29 deletions
+12 -22
View File
@@ -189,8 +189,8 @@ lnk_input_import_is_before(void *raw_a, void *raw_b)
int
lnk_input_import_compar(const void *raw_a, const void *raw_b)
{
const LNK_InputImport **a = (const LNK_InputImport **) raw_a;
const LNK_InputImport **b = (const LNK_InputImport **) raw_b;
LNK_InputImport * const *a = raw_a;
LNK_InputImport * const *b = raw_b;
int cmp = str8_compar_ignore_case(&(*a)->import_header.dll_name, &(*b)->import_header.dll_name);
if (cmp == 0) {
cmp = str8_compar_case_sensitive(&(*a)->import_header.func_name, &(*b)->import_header.func_name);
@@ -3761,29 +3761,19 @@ lnk_run(int argc, char **argv)
}
ProfEnd();
LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, sectab, 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) {
LNK_Obj *obj = &obj_node_arr.v[obj_idx].data;
// derive machine from obj
if (config->machine == COFF_MachineType_Unknown) {
config->machine = obj->machine;
} else if (config->machine != COFF_MachineType_X64) {
lnk_error_with_loc(LNK_Error_UnsupportedMachine, obj->path, obj->lib_path, "%S machine is supported", coff_string_from_machine_type(obj->machine));
} else {
// is obj machine compatible?
if (config->machine != obj->machine &&
obj->machine != COFF_MachineType_Unknown) { // obj with unknown machine type is compatible with any other machine type
lnk_error_obj(LNK_Error_IncompatibleObj, obj,
"conflicting machine types expected %S but got %S",
coff_string_from_machine_type(config->machine),
coff_string_from_machine_type(obj->machine));
LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, sectab, config->function_pad_min, config->machine, unique_obj_input_list.count, input_obj_arr);
//
// if the machine was omitted on the command line, derive machine from obj
//
if (config->machine == COFF_MachineType_Unknown) {
for (U64 obj_idx = 0; obj_idx < obj_node_arr.count; obj_idx += 1) {
if (obj_node_arr.v[obj_idx].data.machine != COFF_MachineType_Unknown) {
config->machine = obj_node_arr.v[obj_idx].data.machine;
break;
}
}
}
ProfEnd();
ProfBegin("Collect Directives");
for (U64 i = 0; i < obj_node_arr.count; ++i) {
+1 -1
View File
@@ -941,7 +941,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 *sectab = lnk_section_table_alloc(0,0,0);
LNK_ObjList obj_list = {0};
lnk_obj_list_push_parallel(tp, arena, &obj_list, sectab, 0, input_obj_list.count, inputs);
lnk_obj_list_push_parallel(tp, arena, &obj_list, sectab, 0, machine, 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.
+26 -4
View File
@@ -399,10 +399,30 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
//
// parse obj header
//
COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(input->data);
String8 raw_coff_section_table = str8_substr(input->data, coff_info.section_table_range);
String8 raw_coff_symbol_table = str8_substr(input->data, coff_info.symbol_table_range);
String8 raw_coff_string_table = str8_substr(input->data, coff_info.string_table_range);
COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(input->data);
//
// set & check machine compatibility
//
{
if (task->machine == COFF_MachineType_Unknown) {
ins_atomic_u32_eval_assign(&task->machine, coff_info.machine);
}
if (coff_info.machine != COFF_MachineType_Unknown && task->machine != coff_info.machine) {
lnk_error_with_loc(LNK_Error_IncompatibleObj, input->path, input->lib_path,
"conflicting machine types expected %S but got %S",
coff_string_from_machine_type(task->machine),
coff_string_from_machine_type(coff_info.machine));
}
}
//
// extract COFF info
//
String8 raw_coff_section_table = str8_substr(input->data, coff_info.section_table_range);
String8 raw_coff_symbol_table = str8_substr(input->data, coff_info.symbol_table_range);
String8 raw_coff_string_table = str8_substr(input->data, coff_info.string_table_range);
//
// error check: section table / symbol table / string table
@@ -714,6 +734,7 @@ lnk_obj_list_push_parallel(TP_Context *tp,
LNK_ObjList *obj_list,
LNK_SectionTable *sectab,
U64 *function_pad_min,
COFF_MachineType machine,
U64 input_count,
LNK_InputObj **inputs)
{
@@ -730,6 +751,7 @@ lnk_obj_list_push_parallel(TP_Context *tp,
task.obj_id_base = obj_id_base;
task.obj_node_arr = obj_arr.v;
task.function_pad_min = function_pad_min;
task.machine = machine;
tp_for_parallel(tp, arena, input_count, lnk_obj_initer, &task);
}
ProfEnd();
+2 -2
View File
@@ -54,7 +54,6 @@ typedef struct LNK_Obj
String8 path;
String8 lib_path;
U64 input_idx;
U64 common_symbol_size;
COFF_MachineType machine;
U64 chunk_count;
U64 sect_count;
@@ -114,6 +113,7 @@ typedef struct
LNK_SectDefnList *defn_arr;
LNK_SectionTable *sectab;
U64 *function_pad_min;
U32 machine;
} LNK_ObjIniter;
typedef struct
@@ -198,7 +198,7 @@ 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 *sectab, U64 *function_pad_min, 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 *sectab, U64 *function_pad_min, COFF_MachineType machine, 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, LNK_Obj *obj, String8 obj_path, String8 lib_path, B32 is_big_obj, U64 function_pad_min, U64 sect_count, COFF_SectionHeader *section_table, U64 symbol_count, void *symbol_table, String8 string_table, LNK_ChunkPtr *chunk_table, LNK_Chunk *master_common_block);