Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/base/base_context_cracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@
////////////////////////////////
//~ rjf: Arch Cracking

#if defined(ARCH_X64)
#if defined(ARCH_X64) || defined(ARCH_ARM64)
# define ARCH_64BIT 1
#elif defined(ARCH_X86)
#elif defined(ARCH_X86) || defined(ARCH_ARM32)
# define ARCH_32BIT 1
#endif

Expand Down
144 changes: 72 additions & 72 deletions src/linker/lnk.c

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions src/linker/lnk.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,23 @@ typedef struct LNK_Inputer
#define LNK_IMPORT_STUB "*** RAD_IMPORT_STUB ***"
#define LNK_NULL_SYMBOL "*** RAD_NULL_SYMBOL ***"

#define LNK_SECTION_FLAG_IS_LIVE (1 << 0)
#define LNK_SECTION_FLAG_IS_LIVE (1 << 0)
#define LNK_SECTION_FLAG_DEBUG_INFO (1 << 1)

typedef struct LNK_ImportTables
{
Arena *arena;
Arena *arena;
String8List delayed_dll_names;
String8List static_dll_names;
HashTable *static_imports;
HashTable *delayed_imports;
HashTable *static_imports;
HashTable *delayed_imports;
} LNK_ImportTables;

typedef struct LNK_Link
{
LNK_ObjList objs;
LNK_LibList libs;
LNK_ObjNode **last_symbol_input;
LNK_IncludeSymbolNode **last_include;
String8Node **last_cmd_lib;
String8Node **last_default_lib;
Expand Down
42 changes: 10 additions & 32 deletions src/linker/lnk_debug_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,29 +549,11 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
CV_TypeServerInfo ts = cv_type_server_info_from_leaf(leaf);

// search disk for type server
String8List match_list = lnk_file_search(scratch.arena, lib_dir_list, ts.name);

// chop file name from path and search on it
//
// TODO: check if ts.name is a path and in that case do file search
if (match_list.node_count == 0) {
String8 file_name = str8_skip_last_slash(ts.name);
match_list = lnk_file_search(scratch.arena, lib_dir_list, file_name);
}
String8 type_server_path = lnk_find_first_file(scratch.arena, lib_dir_list, ts.name);

// report no match
B32 do_debug_info_discard = 0;

// too many matches?
if (match_list.node_count > 1) {
if (!hash_table_search_path(ignored_path_ht, ts.name)) {
hash_table_push_path_u64(scratch.arena, ignored_path_ht, ts.name, 0);
lnk_error_obj(LNK_Warning_MultipleExternalTypeServers, obj_arr[obj_idx], "located multiple external type servers:");
lnk_supplement_error_list(match_list);
}
do_debug_info_discard = 1;
}
// no match?
else if (match_list.node_count == 0) {
if (type_server_path.size == 0) {
if (!hash_table_search_path(ignored_path_ht, ts.name)) {
hash_table_push_string_u64(scratch.arena, ignored_path_ht, ts.name, 0);
lnk_error_obj(LNK_Warning_MissingExternalTypeServer, obj_arr[obj_idx], "unable to open external type server %S", ts.name);
Expand All @@ -585,7 +567,6 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
continue;
}

String8 path = match_list.first->string;
{
struct HT_Value {
CV_TypeServerInfo ts;
Expand All @@ -594,7 +575,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
};

// was this type server queued?
KeyValuePair *is_path_queued = hash_table_search_path(type_server_path_ht, path);
KeyValuePair *is_path_queued = hash_table_search_path(type_server_path_ht, type_server_path);
if (is_path_queued) {
struct HT_Value *present = is_path_queued->value_raw;

Expand All @@ -616,12 +597,12 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla

// when we search matches on disk we store path on scratch,
// make path copy in case we need it for error reporting
path = push_str8_copy(tp_arena->v[0], path);
type_server_path = push_str8_copy(tp_arena->v[0], type_server_path);

// fill out type server info we read from obj
CV_TypeServerInfoNode *ts_info_node = push_array(scratch.arena, CV_TypeServerInfoNode, 1);
ts_info_node->data = ts;
ts_info_node->data.name = path;
ts_info_node->data.name = type_server_path;

// push to type server info list
SLLQueuePush(ts_info_list.first, ts_info_list.last, ts_info_node);
Expand All @@ -640,7 +621,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
value->ts_idx = ts_idx;

// update hash table
hash_table_push_path_raw(scratch.arena, type_server_path_ht, path, value);
hash_table_push_path_raw(scratch.arena, type_server_path_ht, type_server_path, value);
}
}
}
Expand Down Expand Up @@ -2953,12 +2934,9 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *obj_sect_header = &obj_section_table[sect_idx];

if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) {
continue;
}
if (lnk_is_coff_section_debug(obj, sect_idx)) {
continue;
}
if (obj_sect_header->flags & COFF_SectionFlag_LnkInfo) { continue; }
if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) { continue; }
if (obj_sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; }

U64 sect_number;
String8 sect_data;
Expand Down
54 changes: 15 additions & 39 deletions src/linker/lnk_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,51 +48,27 @@ lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_
return write_size;
}

internal String8List
lnk_file_search(Arena *arena, String8List dir_list, String8 file_path)
internal String8
lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
String8List match_list; MemoryZeroStruct(&match_list);

if (os_file_path_exists(file_path)) {
String8 str = push_str8_copy(arena, file_path);
str8_list_push(arena, &match_list, str);
}

PathStyle file_path_style = path_style_from_str8(file_path);
B32 is_relative = file_path_style != PathStyle_WindowsAbsolute &&
file_path_style != PathStyle_UnixAbsolute;

if (is_relative) {
for (String8Node *i = dir_list.first; i != 0; i = i->next) {
String8List path_list = {0};
str8_list_push(scratch.arena, &path_list, i->string);
str8_list_push(scratch.arena, &path_list, file_path);
String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute);
B32 file_exists = os_file_path_exists(path);
if (file_exists) {
B32 is_unique = 1;
OS_FileID file_id = os_id_from_file_path(path);
for (String8Node *k = match_list.first; k != 0; k = k->next) {
OS_FileID test_id = os_id_from_file_path(k->string);
int cmp = os_file_id_compare(test_id, file_id) != 0;
if (cmp == 0) {
is_unique = 0;
break;
}
}
if (is_unique) {
String8 str = push_str8_copy(arena, path);
str8_list_push(arena, &match_list, str);
}
String8 result = {0};
if (os_file_path_exists(path)) {
result = path;
} else {
Temp scratch = scratch_begin(&arena, 1);
String8 file_name = str8_skip_last_slash(path);
for EachNode(n, String8Node, dir_list.first) {
String8 full_path = push_str8f(scratch.arena, "%S/%S", n->string, file_name);
if (os_file_path_exists(full_path)) {
result = push_str8_copy(arena, full_path);
break;
}
}
scratch_end(scratch);
}

scratch_end(scratch);
ProfEnd();
return match_list;
return result;
}

internal OS_Handle
Expand Down
2 changes: 0 additions & 2 deletions src/linker/lnk_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void

// --- IO Functions ------------------------------------------------------------

internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path);

internal OS_Handle lnk_file_open_with_rename_permissions(String8 path);
internal B32 lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file);
internal B32 lnk_file_rename(OS_Handle handle, String8 new_name);
Expand Down
20 changes: 13 additions & 7 deletions src/linker/lnk_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ lnk_first_member_sort_key_is_before(void *raw_a, void *raw_b)
internal B32
lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_Lib *lib_out)
{
ProfBeginFunction();

// is data archive?
COFF_ArchiveType type = coff_archive_type_from_data(data);
if (type == COFF_Archive_Null) {
Expand Down Expand Up @@ -112,7 +110,7 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_L
// parse symbol names
{
Temp scratch = scratch_begin(&arena, 1);
String8List symbol_name_list = str8_split_by_string_chars(scratch.arena, first_member.string_table, str8_lit("\0"), StringSplitFlag_KeepEmpties);
String8List symbol_name_list = str8_split_by_string_chars(scratch.arena, first_member.string_table, str8_lit("\0"), 0);
Assert(symbol_name_list.node_count >= first_member.symbol_count);
symbol_names = str8_array_from_list(arena, &symbol_name_list);
scratch_end(scratch);
Expand Down Expand Up @@ -147,7 +145,6 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_L
lib_out->long_names = parse.long_names;
lib_out->input_idx = input_idx;

ProfEnd();
return 1;
}

Expand Down Expand Up @@ -228,13 +225,22 @@ lnk_lib_set_link_symbol(LNK_Lib *lib, U32 member_idx, LNK_Symbol *link_symbol)
{
local_persist LNK_Symbol null_symbol;

LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol);
B32 is_first_set = (slot == 0);
B32 is_first_set;

LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol);

for (;;) {
is_first_set = (slot == 0);

// update slot symbol if it is empty or link symbol comes before symbol in the slot
if (slot && slot != &null_symbol) {
if (lnk_symbol_is_before(slot, link_symbol)) {
if (!str8_starts_with(link_symbol->name, str8_lit("__imp_")) && str8_starts_with(slot->name, str8_lit("__imp_"))) {
// replace import address symbol with jump thunk symbol
slot = link_symbol;
is_first_set = 1;
} else if (str8_starts_with(link_symbol->name, str8_lit("__imp_")) && !str8_starts_with(slot->name, str8_lit("__imp_"))) {
// no need to replace
} else if (lnk_symbol_is_before(slot, link_symbol)) {
slot = link_symbol;
}
} else {
Expand Down
69 changes: 37 additions & 32 deletions src/linker/lnk_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,19 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
}
}
}

//
// mark debug info sections
//
{
for EachIndex(sect_idx, header.section_count_no_null) {
COFF_SectionHeader *sect_header = &coff_section_table[sect_idx];
String8 sect_name = str8_cstring_capped(sect_header->name, sect_header->name + sizeof(sect_header->name));
if (str8_starts_with(sect_name, str8_lit(".debug$"))) {
sect_header->flags |= LNK_SECTION_FLAG_DEBUG_INFO;
}
}
}

B8 hotpatch = 0;
if (header.machine == COFF_MachineType_X64) {
Expand All @@ -271,25 +284,27 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
Temp scratch = scratch_begin(&arena, 1);

CV_Symbol comp_symbol = {0};
for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) {
for EachIndex(sect_idx, header.section_count_no_null) {
COFF_SectionHeader *sect_header = &coff_section_table[sect_idx];
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);
String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize));
CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data);
for (String8Node *symbols_n = debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first; symbols_n != 0; symbols_n = symbols_n->next) {
CV_SymbolList symbol_list = {0};
cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2);
if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) {
comp_symbol = symbol_list.first->data;
goto found_comp_symbol;
} else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) {
comp_symbol = symbol_list.last->data;
goto found_comp_symbol;
if (sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) {
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);
String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize));
CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data);
for EachNode(symbols_n, String8Node, debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first) {
CV_SymbolList symbol_list = {0};
cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2);
if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) {
comp_symbol = symbol_list.first->data;
goto found_comp_symbol;
} else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) {
comp_symbol = symbol_list.last->data;
goto found_comp_symbol;
}
}
temp_end(temp);
}
temp_end(temp);
}
}
found_comp_symbol:;
Expand All @@ -312,8 +327,6 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
obj->associated_sections = associated_sections;
obj->node = &task->objs[task_id];
obj->link_member = input->link_member;

ProfEnd();
}

internal LNK_ObjNode *
Expand Down Expand Up @@ -529,6 +542,12 @@ lnk_coff_string_table_from_obj(LNK_Obj *obj)
return str8_substr(obj->data, obj->header.string_table_range);
}

internal String8
lnk_coff_symbol_table_from_obj(LNK_Obj *obj)
{
return str8_substr(obj->data, obj->header.symbol_table_range);
}

internal COFF_RelocArray
lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number)
{
Expand All @@ -552,20 +571,6 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_
return 0;
}

internal B32
lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx)
{
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, sect_idx+1);

String8 full_name = coff_name_from_section_header(string_table, section_header);
String8 name, postfix;
coff_parse_section_name(full_name, &name, &postfix);

B32 is_debug = str8_match(name, str8_lit(".debug"), 0);
return is_debug;
}

internal COFF_ParsedSymbol
lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
{
Expand Down
2 changes: 1 addition & 1 deletion src/linker/lnk_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Ob
internal COFF_RelocArray lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_header);
internal COFF_SectionHeader * lnk_coff_section_table_from_obj(LNK_Obj *obj);
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 B32 lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx);

// --- Helpers -----------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion src/linker/lnk_symbol_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob
LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, tag_parsed.name);
tag_interp = lnk_interp_from_symbol(dep_symbol);
}
if (tag_interp == COFF_SymbolValueInterp_Weak) { goto exit; }
if (tag_interp == COFF_SymbolValueInterp_Weak) { break; }
}
} else if (current_interp == COFF_SymbolValueInterp_Undefined) {
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name);
Expand Down
1 change: 1 addition & 0 deletions src/os/core/win32/os_core_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,7 @@ internal void
os_mutex_release(Mutex mutex)
{
OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(mutex.u64[0]);
DeleteCriticalSection(&entity->mutex);
os_w32_entity_release(entity);
}

Expand Down
Loading