From d22962af8df0d2c3093d5a21e4af0357182fdc40 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 20 May 2025 11:16:05 -0700 Subject: [PATCH] warn about exporting entry point symbol --- src/linker/lnk.c | 32 +++++++++----------------------- src/linker/lnk_error.c | 2 +- src/linker/lnk_error.h | 1 + src/pe/pe_make_export_table.c | 29 ++++++++++++++++------------- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index c2ac24d9..3d610e47 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -3585,7 +3585,7 @@ lnk_run(int argc, char **argv) String8List input_disallow_lib_list = config->disallow_lib_list; String8List input_manifest_path_list = str8_list_copy(scratch.arena, &config->input_list[LNK_Input_Manifest]); String8List manifest_dep_list = str8_list_copy(scratch.arena, &config->manifest_dependency_list); - PE_ExportParseList export_symbol_list = config->export_symbol_list; + PE_ExportParseList export_symbol_list = {0}; HashTable *export_ht = hash_table_init(scratch.arena, max_U16/2); LNK_InputObjList input_obj_list = {0}; LNK_InputImportList input_import_list = {0}; @@ -4329,6 +4329,14 @@ lnk_run(int argc, char **argv) exp_n_next = exp_n->next; PE_ExportParse *exp = &exp_n->data; + if (str8_match(exp->name, config->entry_point_name, 0)) { + lnk_error_with_loc(LNK_Warning_TryingToExportEntryPoint, exp->obj_path, exp->lib_path, "exported entry point \"%S\"", exp->name); + } + if (str8_match(exp->alias, config->entry_point_name, 0)) { + lnk_error_with_loc(LNK_Warning_TryingToExportEntryPoint, exp->obj_path, exp->lib_path, "alias exports entry point \"%S=%S\"", exp->name, exp->alias); + continue; + } + if (!exp->is_forwarder) { // filter out unresolved exports LNK_Symbol *symbol = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, exp_n->data.name); @@ -4336,28 +4344,6 @@ lnk_run(int argc, char **argv) lnk_error_with_loc(LNK_Warning_IllExport, exp->obj_path, exp->lib_path, "unresolved export symbol %S\n", exp->name); continue; } - - // check export type - switch (exp->type) { - case COFF_ImportHeader_Code: { - COFF_ParsedSymbol defn = lnk_parsed_symbol_from_coff_symbol_idx(symbol->u.defined.obj, symbol->u.defined.symbol_idx); - B32 is_export_data = !COFF_SymbolType_IsFunc(defn.type); - if (is_export_data) { - lnk_error_with_loc(LNK_Warning_IllExport, exp->obj_path, exp->lib_path, "export \"%S\" is DATA but has type CODE", exp->name); - } - } break; - case COFF_ImportHeader_Data: { - COFF_ParsedSymbol defn = lnk_parsed_symbol_from_coff_symbol_idx(symbol->u.defined.obj, symbol->u.defined.symbol_idx); - B32 is_export_code = COFF_SymbolType_IsFunc(defn.type); - if (is_export_code) { - lnk_error_with_loc(LNK_Warning_IllExport, exp->obj_path, exp->lib_path, "export \"%S\" is CODE but has type DATA", exp->name); - } - } break; - case COFF_ImportHeader_Const: { - lnk_not_implemented("TODO: COFF_ImportHeader_Const"); - } break; - default: { InvalidPath; } break; - } } // push resolved export diff --git a/src/linker/lnk_error.c b/src/linker/lnk_error.c index c2ee9ba7..a0235975 100644 --- a/src/linker/lnk_error.c +++ b/src/linker/lnk_error.c @@ -79,7 +79,7 @@ lnk_error_with_loc_fv(LNK_ErrorCode code, String8 obj_path, String8 lib_path, ch lnk_error(code, "%S: %S", obj_path, text); } } else { - lnk_error(code, "%S", text); + lnk_error(code, "RADLINK: %S", text); } scratch_end(scratch); } diff --git a/src/linker/lnk_error.h b/src/linker/lnk_error.h index af146ade..a86b9086 100644 --- a/src/linker/lnk_error.h +++ b/src/linker/lnk_error.h @@ -88,6 +88,7 @@ typedef enum LNK_Warning_TLSAlign, LNK_Warning_DirectiveSectionWithRelocs, LNK_Warning_NoLargeAddressAwarenessForDll, + LNK_Warning_TryingToExportEntryPoint, LNK_Warning_Last, LNK_Error_Count diff --git a/src/pe/pe_make_export_table.c b/src/pe/pe_make_export_table.c index 1c60867b..7edb4fe5 100644 --- a/src/pe/pe_make_export_table.c +++ b/src/pe/pe_make_export_table.c @@ -92,17 +92,6 @@ pe_ordinal_export_is_before(void *raw_a, void *raw_b) internal PE_FinalizedExports pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list) { - // compute max ordinal and used ordinal flag array - U64 ordinal_low = max_U64; - B8 *is_ordinal_used = push_array(arena, B8, max_U16); - for (PE_ExportParseNode *exp_n = export_list.first; exp_n != 0; exp_n = exp_n->next) { - PE_ExportParse *exp = &exp_n->data; - if (exp->is_ordinal_assigned) { - ordinal_low = Min(ordinal_low, exp->ordinal); - is_ordinal_used[exp->ordinal] = 1; - } - } - PE_ExportParsePtrArray named_exports = {0}; PE_ExportParsePtrArray ordinal_exports = {0}; PE_ExportParsePtrArray forwarder_exports = {0}; @@ -139,6 +128,20 @@ pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list) pe_export_parse_list_concat_in_place(&export_list, &ordinal_exports_list); } + // compute max ordinal and used ordinal flag array + U64 ordinal_low = max_U64; + B8 *is_ordinal_used = push_array(arena, B8, max_U16); + for (PE_ExportParseNode *exp_n = export_list.first; exp_n != 0; exp_n = exp_n->next) { + PE_ExportParse *exp = &exp_n->data; + if (exp->is_ordinal_assigned) { + ordinal_low = Min(ordinal_low, exp->ordinal); + is_ordinal_used[exp->ordinal] = 1; + } + } + if (ordinal_low == max_U64) { + ordinal_low = 0; + } + // assign omitted ordinals { U16 last_ordinal = ordinal_low; @@ -259,8 +262,8 @@ pe_make_edata_obj(Arena *arena, str8_list_push(obj_writer->arena, &string_table_sect->data, export_name_cstr); // create symbol for the name string - String8 export_name_symbol_name = push_str8f(obj_writer->arena, "RAD_NAME:%S", name); - COFF_ObjSymbol *export_name_symbol = coff_obj_writer_push_symbol_extern(obj_writer, export_name_symbol_name, export_name_offset, string_table_sect); + String8 export_name_symbol_name = push_str8f(obj_writer->arena, "RADNAME:%S", name); + COFF_ObjSymbol *export_name_symbol = coff_obj_writer_push_symbol_static(obj_writer, export_name_symbol_name, export_name_offset, string_table_sect); // create slot for export virtual offset U64 export_name_voff_offset = name_voff_table_sect->data.total_size;