mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 22:08:41 +00:00
infer subsystem when only entry point is specified
This commit is contained in:
committed by
Ryan Fleury
parent
b0db2b19f8
commit
d9eb26a830
+124
-153
@@ -875,6 +875,49 @@ lnk_make_linker_coff_obj(Arena *arena,
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal String8
|
||||||
|
lnk_make_linker_obj(Arena *arena, LNK_Config *config)
|
||||||
|
{
|
||||||
|
ProfBeginFunction();
|
||||||
|
|
||||||
|
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(COFF_TimeStamp_Max, config->machine);
|
||||||
|
|
||||||
|
// Emit __ImageBase symbol.
|
||||||
|
//
|
||||||
|
// This symbol is used with REL32 to compute delta from current IP
|
||||||
|
// to the image base. CRT uses this trick to get to HINSTANCE * without
|
||||||
|
// passing it around as a function argument.
|
||||||
|
//
|
||||||
|
// 100h: lea rax, [rip + ffffff00h] ; -100h
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit("__ImageBase"), 0, COFF_SymStorageClass_External);
|
||||||
|
|
||||||
|
{ // load config symbols
|
||||||
|
if (config->machine == COFF_MachineType_X86) {
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_ENCLAVE_CONFIG_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
||||||
|
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FLAGS_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FIDS_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FIDS_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_IAT_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_IAT_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_LONGJMP_TABLE_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_LONGJMP_COUNT_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_EHCONT_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_EHCONT_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 obj = coff_obj_writer_serialize(arena, obj_writer);
|
||||||
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
|
||||||
|
ProfEnd();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
lnk_get_lib_name(String8 path)
|
lnk_get_lib_name(String8 path)
|
||||||
{
|
{
|
||||||
@@ -922,49 +965,6 @@ lnk_push_loaded_lib(Arena *arena, HashTable *loaded_lib_ht, String8 path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
|
||||||
lnk_make_linker_obj(Arena *arena, LNK_Config *config)
|
|
||||||
{
|
|
||||||
ProfBeginFunction();
|
|
||||||
|
|
||||||
COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(COFF_TimeStamp_Max, config->machine);
|
|
||||||
|
|
||||||
// Emit __ImageBase symbol.
|
|
||||||
//
|
|
||||||
// This symbol is used with REL32 to compute delta from current IP
|
|
||||||
// to the image base. CRT uses this trick to get to HINSTANCE * without
|
|
||||||
// passing it around as a function argument.
|
|
||||||
//
|
|
||||||
// 100h: lea rax, [rip + ffffff00h] ; -100h
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit("__ImageBase"), 0, COFF_SymStorageClass_External);
|
|
||||||
|
|
||||||
{ // load config symbols
|
|
||||||
if (config->machine == COFF_MachineType_X86) {
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_ENCLAVE_CONFIG_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
|
||||||
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FLAGS_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FIDS_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_FIDS_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_IAT_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_IAT_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_LONGJMP_TABLE_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_LONGJMP_COUNT_SYMBOL_NAME), 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_EHCONT_TABLE_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(MSCRT_GUARD_EHCONT_COUNT_SYMBOL_NAME) , 0, COFF_SymStorageClass_External);
|
|
||||||
}
|
|
||||||
|
|
||||||
String8 obj = coff_obj_writer_serialize(arena, obj_writer);
|
|
||||||
coff_obj_writer_release(&obj_writer);
|
|
||||||
|
|
||||||
ProfEnd();
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
lnk_queue_lib_member_for_input(Arena *arena,
|
lnk_queue_lib_member_for_input(Arena *arena,
|
||||||
LNK_Config *config,
|
LNK_Config *config,
|
||||||
@@ -1761,129 +1761,95 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
|
|||||||
} break;
|
} break;
|
||||||
case State_SearchEntryPoint: {
|
case State_SearchEntryPoint: {
|
||||||
ProfBegin("Search Entry Point");
|
ProfBegin("Search Entry Point");
|
||||||
LNK_Symbol *entry_point_symbol = 0;
|
|
||||||
|
|
||||||
B32 is_entry_point_unspecified = config->entry_point_name.size == 0;
|
// loop over all possible subsystems and entry point names and pick
|
||||||
if (is_entry_point_unspecified) {
|
// subsystem that has a defined entry point symbol
|
||||||
if (config->subsystem == PE_WindowsSubsystem_UNKNOWN) {
|
if (config->entry_point_name.size == 0) {
|
||||||
// we don't have a subsystem and entry point name,
|
PE_WindowsSubsystem subsys_first = config->subsystem;
|
||||||
// so we loop over every subsystem and search potential entry
|
PE_WindowsSubsystem subsys_last = config->subsystem == PE_WindowsSubsystem_UNKNOWN ? PE_WindowsSubsystem_COUNT : config->subsystem+1;
|
||||||
// points in the symbol table
|
LNK_Symbol *entry_point_symbol = 0;
|
||||||
for EachIndex(subsys_idx, PE_WindowsSubsystem_COUNT) {
|
for (U64 subsys_idx = subsys_first; subsys_idx < subsys_last; subsys_idx += 1) {
|
||||||
String8Array name_arr = pe_get_entry_point_names(config->machine, (PE_WindowsSubsystem)subsys_idx, config->file_characteristics);
|
String8Array entry_points = pe_get_entry_point_names(config->machine, (PE_WindowsSubsystem)subsys_idx, config->file_characteristics);
|
||||||
for EachIndex(entry_idx, name_arr.count) {
|
for EachIndex(i, entry_points.count) {
|
||||||
entry_point_symbol = lnk_symbol_table_search(symtab, name_arr.v[entry_idx]);
|
LNK_Symbol *symbol = lnk_symbol_table_search(symtab, entry_points.v[i]);
|
||||||
if (entry_point_symbol) {
|
|
||||||
config->subsystem = (PE_WindowsSubsystem)subsys_idx;
|
|
||||||
config->entry_point_name = name_arr.v[entry_idx];
|
|
||||||
goto dbl_break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search for potential entry points in libs
|
|
||||||
if (config->entry_point_name.size) {
|
|
||||||
for EachIndex(subsys_idx, PE_WindowsSubsystem_COUNT) {
|
|
||||||
String8Array name_arr = pe_get_entry_point_names(config->machine, (PE_WindowsSubsystem)subsys_idx, config->file_characteristics);
|
|
||||||
for EachIndex(entry_idx, name_arr.count) {
|
|
||||||
for EachIndex(i, ArrayCount(lib_index)) {
|
|
||||||
for (LNK_LibNode *lib_n = lib_index[i].first; lib_n != 0; lib_n = lib_n->next) {
|
|
||||||
if (lnk_search_lib(&lib_n->data, name_arr.v[entry_idx], 0)) {
|
|
||||||
config->subsystem = (PE_WindowsSubsystem)subsys_idx;
|
|
||||||
config->entry_point_name = name_arr.v[entry_idx];
|
|
||||||
goto dbl_break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dbl_break:;
|
|
||||||
} else {
|
|
||||||
// we have subsystem but no entry point name, get potential entry point names
|
|
||||||
// and see which is in the symbol table
|
|
||||||
String8Array name_arr = pe_get_entry_point_names(config->machine, config->subsystem, config->file_characteristics);
|
|
||||||
for EachIndex(entry_idx, name_arr.count) {
|
|
||||||
LNK_Symbol *symbol = lnk_symbol_table_search(symtab, name_arr.v[entry_idx]);
|
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
if (config->entry_point_name.size) {
|
config->subsystem = subsys_idx;
|
||||||
lnk_error(LNK_Error_EntryPoint,
|
config->entry_point_name = entry_points.v[i];
|
||||||
"multiple entry point symbols found: %S(%S) and %S(%S)",
|
goto found_entry_and_subsystem;
|
||||||
entry_point_symbol->name, entry_point_symbol->defined.obj->path,
|
|
||||||
symbol->name, symbol->defined.obj->path);
|
|
||||||
} else {
|
|
||||||
config->entry_point_name = name_arr.v[entry_idx];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// search for entry point in libs
|
|
||||||
if (!config->entry_point_name.size) {
|
|
||||||
for EachIndex(entry_idx, name_arr.count) {
|
|
||||||
for EachIndex(i, ArrayCount(lib_index)) {
|
|
||||||
for (LNK_LibNode *lib_n = lib_index[i].first; lib_n != 0; lib_n = lib_n->next) {
|
|
||||||
if (lnk_search_lib(&lib_n->data, name_arr.v[entry_idx], 0)) {
|
|
||||||
config->entry_point_name = name_arr.v[entry_idx];
|
|
||||||
goto dbl_break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbl_break2:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// redirect user entry to appropriate CRT entry
|
|
||||||
if (str8_match_lit("wmain", config->entry_point_name, 0)) {
|
|
||||||
config->entry_point_name = str8_lit("wmainCRTStartup");
|
|
||||||
} else if (str8_match_lit("main", config->entry_point_name, 0)) {
|
|
||||||
config->entry_point_name = str8_lit("mainCRTStartup");
|
|
||||||
} else if (str8_match_lit("WinMain", config->entry_point_name, 0)) {
|
|
||||||
config->entry_point_name = str8_lit("WinMainCRTStartup");
|
|
||||||
} else if (str8_match_lit("wWinMain", config->entry_point_name, 0)) {
|
|
||||||
config->entry_point_name = str8_lit("wWinMainCRTStartup");
|
|
||||||
}
|
}
|
||||||
|
found_entry_and_subsystem:;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate undefined symbol so in case obj is in lib it will be linked
|
// search for entry point in libs
|
||||||
|
if (config->entry_point_name.size == 0 && config->subsystem != PE_WindowsSubsystem_UNKNOWN) {
|
||||||
|
String8Array entry_points = pe_get_entry_point_names(config->machine, config->subsystem, config->file_characteristics);
|
||||||
|
for EachIndex(entry_idx, entry_points.count) {
|
||||||
|
for EachIndex(i, ArrayCount(lib_index)) {
|
||||||
|
for (LNK_LibNode *lib_n = lib_index[i].first; lib_n != 0; lib_n = lib_n->next) {
|
||||||
|
if (lnk_search_lib(&lib_n->data, entry_points.v[entry_idx], 0)) {
|
||||||
|
config->entry_point_name = entry_points.v[entry_idx];
|
||||||
|
goto found_entry_in_libs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found_entry_in_libs:;
|
||||||
|
}
|
||||||
|
|
||||||
|
// infer subsystem from entry point name
|
||||||
|
if (config->entry_point_name.size != 0 && config->subsystem == PE_WindowsSubsystem_UNKNOWN) {
|
||||||
|
for EachIndex(subsys_idx, PE_WindowsSubsystem_COUNT) {
|
||||||
|
String8Array entry_points = pe_get_entry_point_names(config->machine, subsys_idx, config->file_characteristics);
|
||||||
|
for EachIndex(i, entry_points.count) {
|
||||||
|
if (str8_match(entry_points.v[i], config->entry_point_name, 0)) {
|
||||||
|
config->subsystem = subsys_idx;
|
||||||
|
goto subsystem_inferred_from_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subsystem_inferred_from_entry:;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have an entry point name?
|
||||||
if (config->entry_point_name.size) {
|
if (config->entry_point_name.size) {
|
||||||
|
// redirect user entry to appropriate CRT entry
|
||||||
|
String8 crt_entry_point_name = msvcrt_ctr_entry_from_user_entry(config->entry_point_name);
|
||||||
|
config->entry_point_name = crt_entry_point_name.size ? crt_entry_point_name : config->entry_point_name;
|
||||||
|
|
||||||
|
// generate undefined symbol for entry point
|
||||||
|
//
|
||||||
// TODO: config_refactor
|
// TODO: config_refactor
|
||||||
String8List value_strings = {0};
|
String8List value_strings = {0};
|
||||||
str8_list_push(scratch.arena, &value_strings, config->entry_point_name);
|
str8_list_push(scratch.arena, &value_strings, config->entry_point_name);
|
||||||
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, str8_lit("include"), value_strings, 0);
|
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, str8_lit("include"), value_strings, 0);
|
||||||
}
|
|
||||||
// no entry point, print out error and exit
|
// do we have a subsystem?
|
||||||
else {
|
if (config->subsystem != PE_WindowsSubsystem_UNKNOWN) {
|
||||||
lnk_error(LNK_Error_EntryPoint, "unable to find entry point symbol");
|
// if subsystem version not specified set default values
|
||||||
}
|
if (config->subsystem_ver.major == 0 && config->subsystem_ver.minor == 0) {
|
||||||
|
config->subsystem_ver = lnk_get_default_subsystem_version(config->subsystem, config->machine);
|
||||||
// by default terminal server is enabled for windows and console applications
|
}
|
||||||
if (~config->flags & LNK_ConfigFlag_NoTsAware &&
|
|
||||||
~config->file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) {
|
// check subsystem version against allowed min version
|
||||||
if (config->subsystem == PE_WindowsSubsystem_WINDOWS_GUI || config->subsystem == PE_WindowsSubsystem_WINDOWS_CUI) {
|
Version min_subsystem_ver = lnk_get_min_subsystem_version(config->subsystem, config->machine);
|
||||||
config->dll_characteristics |= PE_DllCharacteristic_TERMINAL_SERVER_AWARE;
|
if (version_compar(config->subsystem_ver, min_subsystem_ver) < 0) {
|
||||||
|
lnk_error(LNK_Error_Cmdl, "subsystem version %I64u.%I64u can't be lower than %I64u.%I64u",
|
||||||
|
config->subsystem_ver.major, config->subsystem_ver.minor, min_subsystem_ver.major, min_subsystem_ver.minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// by default terminal server is enabled for windows and console applications
|
||||||
|
if (~config->flags & LNK_ConfigFlag_NoTsAware && ~config->file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) {
|
||||||
|
if (config->subsystem == PE_WindowsSubsystem_WINDOWS_GUI || config->subsystem == PE_WindowsSubsystem_WINDOWS_CUI) {
|
||||||
|
config->dll_characteristics |= PE_DllCharacteristic_TERMINAL_SERVER_AWARE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lnk_error(LNK_Error_NoSubsystem, "unknown subsystem, please use /SUBSYSTEM to set subsytem type you need");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have a subsystem?
|
|
||||||
if (config->subsystem == PE_WindowsSubsystem_UNKNOWN) {
|
|
||||||
lnk_error(LNK_Error_NoSubsystem, "unknown subsystem, please use /SUBSYSTEM to set subsytem type you need");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config->subsystem_ver.major == 0 && config->subsystem_ver.minor == 0) {
|
|
||||||
// subsystem version not specified, set default values
|
|
||||||
config->subsystem_ver = lnk_get_default_subsystem_version(config->subsystem, config->machine);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check subsystem version against allowed min version
|
|
||||||
Version min_subsystem_ver = lnk_get_min_subsystem_version(config->subsystem, config->machine);
|
|
||||||
int ver_cmp = version_compar(config->subsystem_ver, min_subsystem_ver);
|
|
||||||
if (ver_cmp < 0) {
|
|
||||||
lnk_error(LNK_Error_Cmdl, "subsystem version %I64u.%I64u can't be lower than %I64u.%I64u",
|
|
||||||
config->subsystem_ver.major, config->subsystem_ver.minor, min_subsystem_ver.major, min_subsystem_ver.minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
} break;
|
} break;
|
||||||
case State_InputLinkerObjs: {
|
case State_InputLinkerObjs: {
|
||||||
@@ -2215,6 +2181,11 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
|
|||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
|
|
||||||
|
if (config->entry_point_name.size == 0) {
|
||||||
|
lnk_error(LNK_Error_EntryPoint, "unable to find entry point symbol");
|
||||||
|
}
|
||||||
|
|
||||||
ProfBegin("Report Unresolved Symbols");
|
ProfBegin("Report Unresolved Symbols");
|
||||||
{
|
{
|
||||||
U64 count = 0;
|
U64 count = 0;
|
||||||
|
|||||||
+2
-3
@@ -201,7 +201,7 @@ internal String8 lnk_manifest_from_inputs(Arena *arena, LNK_IO_Flags io_flags, S
|
|||||||
|
|
||||||
internal String8 lnk_make_null_obj(Arena *arena);
|
internal String8 lnk_make_null_obj(Arena *arena);
|
||||||
internal String8 lnk_make_res_obj(Arena *arena, String8List res_file_list, String8List res_path_list, COFF_MachineType machine, U32 time_stamp, String8 work_dir, PathStyle system_path_style, String8 obj_name);
|
internal String8 lnk_make_res_obj(Arena *arena, String8List res_file_list, String8List res_path_list, COFF_MachineType machine, U32 time_stamp, String8 work_dir, PathStyle system_path_style, String8 obj_name);
|
||||||
internal String8 lnk_make_linker_coff_obj(Arena *arena, COFF_TimeStamp time_stamp, COFF_MachineType machine, String8 cwd_path, String8 exe_path, String8 pdb_path, String8 cmd_line, String8 obj_name);
|
internal String8 lnk_make_linker_obj(Arena *arena, LNK_Config *config);
|
||||||
|
|
||||||
// --- Link Context ------------------------------------------------------------
|
// --- Link Context ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -211,8 +211,7 @@ internal B32 lnk_is_lib_loaded(HashTable *loaded_lib_ht, String8 lib_path);
|
|||||||
internal void lnk_push_disallow_lib(Arena *arena, HashTable *disallow_lib_ht, String8 path);
|
internal void lnk_push_disallow_lib(Arena *arena, HashTable *disallow_lib_ht, String8 path);
|
||||||
internal void lnk_push_loaded_lib(Arena *arena, HashTable *loaded_lib_ht, String8 path);
|
internal void lnk_push_loaded_lib(Arena *arena, HashTable *loaded_lib_ht, String8 path);
|
||||||
|
|
||||||
internal LNK_InputObjList lnk_push_linker_symbols(Arena *arena, LNK_Config *config);
|
internal void lnk_queue_lib_member_for_input(Arena *arena, LNK_Config *config, LNK_Symbol *pull_in_ref, LNK_Lib *lib, U32 member_idx, LNK_InputImportList *input_import_list, LNK_InputObjList *input_obj_list);
|
||||||
internal void lnk_queue_lib_member_for_input(Arena *arena, LNK_Config *config, LNK_Symbol *pull_in_ref, LNK_Lib *lib, U32 member_idx, LNK_InputImportList *input_import_list, LNK_InputObjList *input_obj_list);
|
|
||||||
|
|
||||||
internal LNK_LinkContext lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config);
|
internal LNK_LinkContext lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user