polish help in radlink

This commit is contained in:
Nikita Smith
2026-02-13 19:17:53 -08:00
parent 519bc154ec
commit fbc3cbd6eb
13 changed files with 480 additions and 526 deletions
+99 -91
View File
@@ -5,9 +5,7 @@ internal U64
void_list_count_nodes(VoidNode *head) void_list_count_nodes(VoidNode *head)
{ {
U64 node_count = 0; U64 node_count = 0;
for (VoidNode *curr = head; curr != 0; curr = curr->next) { for EachNode(curr, VoidNode, head) { node_count += 1; }
++node_count;
}
return node_count; return node_count;
} }
@@ -49,15 +47,33 @@ u64_list_concat_in_place(U64List *list, U64List *to_concat)
SLLConcatInPlace(list, to_concat); SLLConcatInPlace(list, to_concat);
} }
internal U64Array internal B32
u64_array_from_list(Arena *arena, U64List *list) u32_array_compare(U32Array a, U32Array b)
{ {
U64Array result; B32 are_equal = 0;
result.count = 0; if (a.count == b.count) {
result.v = push_array(arena, U64, list->count); int cmp = MemoryCompare(a.v, b.v, sizeof(a.v[0]) * a.count);
for (U64Node *n = list->first; n != NULL; n = n->next) { are_equal = (cmp == 0);
result.v[result.count++] = n->data;
} }
return are_equal;
}
internal void
u32_array_counts_to_offsets(U64 count, U32 *arr)
{
U32 next_offset = 0;
for (U64 i = 0; i < count; i += 1) {
U32 current_offset = next_offset;
next_offset += arr[i];
arr[i] = current_offset;
}
}
internal U32 *
u32_array_offsets_from_counts(Arena *arena, U32 *v, U64 count)
{
U32 *result = push_array_copy_u32(arena, v, count);
u32_array_counts_to_offsets(count, result);
return result; return result;
} }
@@ -68,13 +84,7 @@ u32_array_sort(U64 count, U32 *v)
} }
internal void internal void
u64_array_sort(U64 count, U64 *v) u32_pair_sort_radix(U64 count, PairU32 *arr)
{
radsort(v, count, u64_is_before);
}
internal void
u32_pair_radix_sort(U64 count, PairU32 *arr)
{ {
Temp scratch = scratch_begin(0,0); Temp scratch = scratch_begin(0,0);
@@ -98,9 +108,9 @@ u32_pair_radix_sort(U64 count, PairU32 *arr)
++count2[digit2]; ++count2[digit2];
} }
counts_to_offsets_array_u32((1 << bit_count0), count0); u32_array_counts_to_offsets((1 << bit_count0), count0);
counts_to_offsets_array_u32((1 << bit_count1), count1); u32_array_counts_to_offsets((1 << bit_count1), count1);
counts_to_offsets_array_u32((1 << bit_count2), count2); u32_array_counts_to_offsets((1 << bit_count2), count2);
for (U64 i = 0; i < count; ++i) { for (U64 i = 0; i < count; ++i) {
U32 digit0 = (arr[i].v0 >> 0) % (1 << bit_count0); U32 digit0 = (arr[i].v0 >> 0) % (1 << bit_count0);
@@ -122,15 +132,59 @@ u32_pair_radix_sort(U64 count, PairU32 *arr)
scratch_end(scratch); scratch_end(scratch);
} }
internal B32 internal U64 *
u32_array_compare(U32Array a, U32Array b) offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count)
{ {
B32 are_equal = 0; U64 *result = push_array_copy_u64(arena, v, count);
if (a.count == b.count) { u64_array_counts_to_offsets(count, result);
int cmp = MemoryCompare(a.v, b.v, sizeof(a.v[0]) * a.count); return result;
are_equal = (cmp == 0);
} }
return are_equal;
internal void
u64_array_counts_to_offsets(U64 count, U64 *arr)
{
U64 next_offset = 0;
for (U64 i = 0; i < count; i += 1) {
U64 current_offset = next_offset;
next_offset += arr[i];
arr[i] = current_offset;
}
}
internal void
u64_array_sort(U64 count, U64 *v)
{
radsort(v, count, u64_is_before);
}
internal U64
u64_array_max(U64 count, U64 *v)
{
U64 result = 0;
for (U64 i = 0; i < count; i += 1) {
result = Max(v[i], result);
}
return result;
}
internal U64
u64_array_min(U64 count, U64 *v)
{
U64 result = max_U64;
for (U64 i = 0; i < count; i += 1) {
result = Min(v[i], result);
}
return result;
}
internal U64
sum_array_u64(U64 count, U64 *v)
{
U64 result = 0;
for (U64 i = 0; i < count; i += 1) {
result += v[i];
}
return result;
} }
internal U64Array internal U64Array
@@ -160,81 +214,35 @@ u64_array_remove_duplicates(Arena *arena, U64Array in)
return result; return result;
} }
internal U64 internal void
sum_array_u64(U64 count, U64 *v) s64_list_push_node(S64List *list, S64Node *n)
{ {
U64 result = 0; SLLQueuePush(list->first, list->last, n);
for (U64 i = 0; i < count; i += 1) { list->count += 1;
result += v[i];
}
return result;
} }
internal U64 internal S64Node *
sum_matrix_u64(U64 rows, U64 cols, U64 **v) s64_list_push(Arena *arena, S64List *list, S64 v)
{ {
U64 result = 0; S64Node *n = push_array(arena, S64Node, 1);
for (U64 i = 0; i < rows; ++i) { n->next = 0;
result += sum_array_u64(cols, v[i]); n->v = v;
} s64_list_push_node(list, n);
return result; return n;
}
internal U64
max_array_u64(U64 count, U64 *v)
{
U64 result = 0;
for (U64 i = 0; i < count; i += 1) {
result = Max(v[i], result);
}
return result;
}
internal U64
min_array_u64(U64 count, U64 *v)
{
U64 result = max_U64;
for (U64 i = 0; i < count; i += 1) {
result = Min(v[i], result);
}
return result;
} }
internal void internal void
counts_to_offsets_array_u32(U64 count, U32 *arr) s64_list_concat_in_place(S64List *list, S64List *to_concat)
{ {
U32 next_offset = 0; SLLConcatInPlace(list, to_concat);
for (U64 i = 0; i < count; i += 1) {
U32 current_offset = next_offset;
next_offset += arr[i];
arr[i] = current_offset;
}
} }
internal void internal S64Array
counts_to_offsets_array_u64(U64 count, U64 *arr) s64_array_from_list(Arena *arena, S64List *list)
{ {
U64 next_offset = 0; S64Array result = {0};
for (U64 i = 0; i < count; i += 1) { result.v = push_array(arena, S64, list->count);
U64 current_offset = next_offset; for EachNode(n, S64Node, list->first) { result.v[result.count++] = n->v; }
next_offset += arr[i];
arr[i] = current_offset;
}
}
internal U32 *
offsets_from_counts_array_u32(Arena *arena, U32 *v, U64 count)
{
U32 *result = push_array_copy_u32(arena, v, count);
counts_to_offsets_array_u32(count, result);
return result;
}
internal U64 *
offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count)
{
U64 *result = push_array_copy_u64(arena, v, count);
counts_to_offsets_array_u64(count, result);
return result; return result;
} }
+47 -20
View File
@@ -3,6 +3,12 @@
#pragma once #pragma once
typedef struct VoidNode
{
struct VoidNode *next;
void *v;
} VoidNode;
typedef struct U32Node typedef struct U32Node
{ {
struct U32Node *next; struct U32Node *next;
@@ -22,32 +28,53 @@ typedef struct U64List
U64Node *last; U64Node *last;
} U64List; } U64List;
typedef struct VoidNode typedef struct S64Node
{ {
struct VoidNode *next; S64 v;
void *v; struct S64Node *next;
} VoidNode; } S64Node;
typedef struct S64List
{
U64 count;
S64Node *first;
S64Node *last;
} S64List;
typedef struct S64Array
{
U64 count;
S64 *v;
} S64Array;
//////////////////////////////// ////////////////////////////////
internal U64 void_list_count_nodes (VoidNode *head);
internal void void_node_concat (VoidNode **head, VoidNode *node);
internal void void_node_concat_atomic(VoidNode **head, VoidNode *node);
internal void u64_list_push_node (U64List *list, U64Node *n); internal void u64_list_push_node (U64List *list, U64Node *n);
internal U64Node * u64_list_push(Arena *arena, U64List *list, U64 data); internal U64Node * u64_list_push (Arena *arena, U64List *list, U64 v);
internal void u64_list_concat_in_place(U64List *list, U64List *to_concat); internal void u64_list_concat_in_place(U64List *list, U64List *to_concat);
internal B32 u32_array_compare (U32Array a, U32Array b);
internal U32 * u32_array_offsets_from_counts(Arena *arena, U32 *v, U64 count);
internal void u32_array_counts_to_offsets (U64 count, U32 *arr);
internal void u32_array_sort (U64 count, U32 *v);
internal void u32_pair_sort_radix (U64 count, PairU32 *arr);
internal U64 * offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count);
internal void u64_array_counts_to_offsets (U64 count, U64 *arr);
internal void u64_array_sort (U64 count, U64 *v);
internal U64 u64_array_max (U64 count, U64 *v);
internal U64 u64_array_min (U64 count, U64 *v);
internal U64 sum_array_u64 (U64 count, U64 *v);
internal U64 sum_array_u64 (U64 count, U64 *v);
internal U64Array u64_array_remove_duplicates (Arena *arena, U64Array in);
internal U64Array u64_array_from_list (Arena *arena, U64List *list); internal U64Array u64_array_from_list (Arena *arena, U64List *list);
internal U64Array u64_array_remove_duplicates(Arena *arena, U64Array in); internal void s64_list_push_node (S64List *list, S64Node *n);
internal S64Node * s64_list_push (Arena *arena, S64List *list, S64 v);
internal void u32_array_sort(U64 count, U32 *v); internal void s64_list_concat_in_place(S64List *list, S64List *to_concat);
internal void u64_array_sort(U64 count, U64 *v); internal S64Array s64_array_from_list (Arena *arena, S64List *list);
internal B32 u32_array_compare(U32Array a, U32Array b);
internal U64 sum_array_u64(U64 count, U64 *v);
internal U64 max_array_u64(U64 count, U64 *v);
internal U64 min_array_u64(U64 count, U64 *v);
internal void counts_to_offsets_array_u32(U64 count, U32 *arr);
internal void counts_to_offsets_array_u64(U64 count, U64 *arr);
internal U32 * offsets_from_counts_array_u32(Arena *arena, U32 *v, U64 count);
internal U64 * offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count);
+109 -99
View File
@@ -117,115 +117,117 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
internal LNK_CmdLine
lnk_make_default_cmd_line(Arena *arena, LNK_CmdLine user_cmd_line)
{
LNK_CmdLine cmd_line = {0};
// setup default flags
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Align, "%u", KB(4));
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Debug, "none");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_FileAlign, "%u", 512);
if (lnk_cmd_line_has_switch(user_cmd_line, LNK_CmdSwitch_Dll)) {
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_SubSystem, "%S", pe_string_from_subsystem(PE_WindowsSubsystem_WINDOWS_GUI));
}
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\"");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_NxCompat, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
if (!lnk_cmd_line_has_switch(user_cmd_line, LNK_CmdSwitch_Brepro)) {
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix());
}
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4));
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count);
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MemoryMapFiles, "");
if (BUILD_DEBUG) {
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "debug");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "io_write");
} else {
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_Ignore, "%u", LNK_Error_InvalidTypeIndex);
}
// default section merges
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".xdata=.rdata");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".00cfg=.rdata");
// TODO: .tls must be always first contribution in .data section because compiler generates TLS relative movs
//lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".tls=.data");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".idata=.data");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".didat=.data");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".edata=.rdata");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".RAD_LINK_PE_DEBUG_DIR=.rdata");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Merge, ".RAD_LINK_PE_DEBUG_DATA=.rdata");
// sections to remove from the image
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".debug");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gehcont");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gfids");
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gxfg");
// set limits on unresolved symbol errors
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MapLinesForUnresolvedSymbols, "");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_UnresolvedSymbolLimit, "1000");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit, "10");
// set default max worker count
if (lnk_cmd_line_has_switch(user_cmd_line, LNK_CmdSwitch_Rad_SharedThreadPool)) {
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "");
}
if ( ! lnk_cmd_line_has_switch(user_cmd_line, LNK_CmdSwitch_Rad_MtPath)) {
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MtPath, "%s", LNK_MANIFEST_MERGE_TOOL_NAME);
}
// when /FORCE is specified on the command line, do not stop on these errors
#if 0
if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Force)) {
g_error_mode_arr[LNK_Error_UnresolvedSymbol] = LNK_ErrorMode_Continue;
}
#endif
// in release build ignore unknown switches
lnk_cmd_line_push_optionf(arena, &cmd_line, LNK_CmdSwitch_Rad_Ignore, "%d", LNK_Warning_UnknownSwitch * (BUILD_DEBUG * -1));
return cmd_line;
}
internal LNK_Config * internal LNK_Config *
lnk_config_from_argcv(Arena *arena, int argc, char **argv) lnk_config_from_argcv(Arena *arena, int argc, char **argv)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
String8List raw_cmd_line = {0}; String8List raw_cmd_line = {0};
for EachIndex(i, argc) { for (U64 i = 1; i < argc; i += 1) { str8_list_push(arena, &raw_cmd_line, str8_cstring(argv[i])); }
str8_list_push(arena, &raw_cmd_line, str8_cstring(argv[i]));
}
// remove exe name first argument #if PROFILE_TELEMETRY
str8_list_pop_front(&raw_cmd_line); tmMessage(0, TMMF_ICON_NOTE, "Command Line: %.*s", str8_varg(str8_list_join(scratch.arena, &raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") })));
// parse command line
String8List unwrapped_cmd_line = lnk_unwrap_rsp(scratch.arena, raw_cmd_line);
LNK_CmdLine cmd_line = lnk_cmd_line_parse_windows_rules(scratch.arena, unwrapped_cmd_line);
// setup default flags
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Align, "%u", KB(4));
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Debug, "none");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_FileAlign, "%u", 512);
if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Dll)) {
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_SubSystem, "%S", pe_string_from_subsystem(PE_WindowsSubsystem_WINDOWS_GUI));
}
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\"");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_NxCompat, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Brepro)) {
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix());
}
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4));
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count);
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TargetOs, "windows");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_MemoryMapFiles, "");
#if BUILD_DEBUG
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "debug");
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "io_write");
#else
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SuppressError, "%u", LNK_Error_InvalidTypeIndex);
#endif #endif
// default section merges // make command line
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".xdata=.rdata"); LNK_CmdLine cmd_line = {0};
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".00cfg=.rdata"); {
// TODO: .tls must be always first contribution in .data section because compiler generates TLS relative movs String8List unwrapped_cmd_line = lnk_unwrap_rsp(scratch.arena, raw_cmd_line);
//lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".tls=.data"); LNK_CmdLine user_cmd_line = lnk_cmd_line_parse_windows_rules(scratch.arena, unwrapped_cmd_line);
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".idata=.data"); LNK_CmdLine default_cmd_line = lnk_make_default_cmd_line(scratch.arena, user_cmd_line);
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".didat=.data"); lnk_cmd_line_concat_in_place(&cmd_line, &default_cmd_line);
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".edata=.rdata"); lnk_cmd_line_concat_in_place(&cmd_line, &user_cmd_line);
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".RAD_LINK_PE_DEBUG_DIR=.rdata");
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Merge, ".RAD_LINK_PE_DEBUG_DATA=.rdata");
// sections to remove from the image
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".debug");
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gehcont");
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gfids");
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_RemoveSection, ".gxfg");
// set limits on unresolved symbol errors
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_MapLinesForUnresolvedSymbols, "");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_UnresolvedSymbolLimit, "1000");
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit, "10");
// set default max worker count
if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Rad_SharedThreadPool)) {
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "");
}
if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Rad_MtPath)) {
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_MtPath, "%s", LNK_MANIFEST_MERGE_TOOL_NAME);
}
// when /FORCE is specified on the command line, do not stop on these errors
if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Force)) {
g_error_mode_arr[LNK_Error_UnresolvedSymbol] = LNK_ErrorMode_Continue;
} }
// init config // init config
LNK_Config *config = lnk_config_from_cmd_line(raw_cmd_line, cmd_line); LNK_Config *config = lnk_config_from_cmd_line(raw_cmd_line, cmd_line);
#if PROFILE_TELEMETRY
{
String8 cmdl = str8_list_join(scratch.arena, &config->raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") });
tmMessage(0, TMMF_ICON_NOTE, "Command Line: %.*s", str8_varg(cmdl));
}
#endif
if (lnk_get_log_status(LNK_Log_Debug)) {
String8 full_cmd_line = str8_list_join(scratch.arena, &raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") });
fprintf(stderr, "--------------------------------------------------------------------------------\n");
fprintf(stderr, "Command Line: %.*s\n", str8_varg(full_cmd_line));
fprintf(stderr, "Work Dir : %.*s\n", str8_varg(config->work_dir));
fprintf(stderr, "--------------------------------------------------------------------------------\n");
}
scratch_end(scratch); scratch_end(scratch);
return config; return config;
} }
@@ -1762,7 +1764,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
link->last_default_lib = &config->input_default_lib_list.first; link->last_default_lib = &config->input_default_lib_list.first;
link->last_obj_lib = &config->input_obj_lib_list.first; link->last_obj_lib = &config->input_obj_lib_list.first;
link->last_cmd_lib = &config->input_list[LNK_Input_Lib].first; link->last_cmd_lib = &config->input_list[LNK_Input_Lib].first;
link->lib_member_infos_ht = hash_table_init(link->arena, Max(config->input_list[LNK_Input_Lib].node_count * 2, 512)); link->lib_member_infos_ht = hash_table_init(link->arena, Max(config->input_list[LNK_Input_Lib].node_count * 2, 1024));
link->try_to_resolve_entry_point = 1; link->try_to_resolve_entry_point = 1;
// input :null_obj // input :null_obj
@@ -1914,10 +1916,10 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
exp_n_next = exp_n->next; exp_n_next = exp_n->next;
PE_ExportParse *exp = &exp_n->data; PE_ExportParse *exp = &exp_n->data;
if (str8_match(exp->name, config->entry_point_name, 0)) { if (exp->name.size && 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); 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)) { if (exp->alias.size && 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); lnk_error_with_loc(LNK_Warning_TryingToExportEntryPoint, exp->obj_path, exp->lib_path, "alias exports entry point \"%S=%S\"", exp->name, exp->alias);
continue; continue;
} }
@@ -5066,6 +5068,14 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
Temp scratch = scratch_begin(arena->v, arena->count); Temp scratch = scratch_begin(arena->v, arena->count);
if (lnk_get_log_status(LNK_Log_Debug)) {
String8 full_cmd_line = str8_list_join(scratch.arena, &config->raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") });
fprintf(stderr, "--------------------------------------------------------------------------------\n");
fprintf(stderr, "Command Line: %.*s\n", str8_varg(full_cmd_line));
fprintf(stderr, "Work Dir : %.*s\n", str8_varg(config->work_dir));
fprintf(stderr, "--------------------------------------------------------------------------------\n");
}
// //
// Input Context // Input Context
// //
@@ -5148,7 +5158,7 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
String8List rdi_data = lnk_build_rad_debug_info(tp, String8List rdi_data = lnk_build_rad_debug_info(tp,
arena, arena,
config->target_os, OperatingSystem_Windows,
rdi_arch_from_coff_machine(config->machine), rdi_arch_from_coff_machine(config->machine),
config->image_name, config->image_name,
image_ctx.image_data, image_ctx.image_data,
+16 -2
View File
@@ -92,8 +92,7 @@ internal LNK_CmdOption *
lnk_cmd_line_push_option_list(Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8List value_strings) lnk_cmd_line_push_option_list(Arena *arena, LNK_CmdLine *cmd_line, String8 string, String8List value_strings)
{ {
// fill out node // fill out node
LNK_CmdOption *opt = push_array_no_zero(arena, LNK_CmdOption, 1); LNK_CmdOption *opt = push_array(arena, LNK_CmdOption, 1);
opt->next = 0;
opt->string = string; opt->string = string;
opt->value_strings = value_strings; opt->value_strings = value_strings;
@@ -126,6 +125,21 @@ lnk_cmd_line_push_option_if_not_present(Arena *arena, LNK_CmdLine *cmd_line, cha
return 0; return 0;
} }
internal void
lnk_cmd_line_concat_in_place(LNK_CmdLine *list, LNK_CmdLine *to_concat)
{
if (list->option_count > 0) {
list->option_count += to_concat->option_count;
list->last_option->next = to_concat->first_option;
list->last_option = to_concat->last_option;
str8_list_concat_in_place(&list->input_list, &to_concat->input_list);
str8_list_concat_in_place(&list->raw_cmd_line, &to_concat->raw_cmd_line);
} else {
*list = *to_concat;
}
MemoryZeroStruct(to_concat);
}
internal LNK_CmdLine internal LNK_CmdLine
lnk_cmd_line_parse_windows_rules(Arena *arena, String8List arg_list) lnk_cmd_line_parse_windows_rules(Arena *arena, String8List arg_list)
{ {
+2
View File
@@ -28,5 +28,7 @@ internal B32 lnk_cmd_line_has_option(LNK_CmdLine cmd_line, char *str
internal LNK_CmdOption * lnk_cmd_line_push_option(Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value); internal LNK_CmdOption * lnk_cmd_line_push_option(Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value);
internal LNK_CmdOption * lnk_cmd_line_push_option_if_not_present(Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value); internal LNK_CmdOption * lnk_cmd_line_push_option_if_not_present(Arena *arena, LNK_CmdLine *cmd_line, char *string, char *value);
internal void lnk_cmd_line_concat_in_place(LNK_CmdLine *list, LNK_CmdLine *to_concat);
internal String8List lnk_data_from_cmd_line(Arena *arena, LNK_CmdLine cmd_line); internal String8List lnk_data_from_cmd_line(Arena *arena, LNK_CmdLine cmd_line);
+165 -207
View File
@@ -5,161 +5,95 @@ global read_only LNK_CmdSwitch g_cmd_switch_map[] =
{ {
{ LNK_CmdSwitch_Null, 0, "", "", "" }, { LNK_CmdSwitch_Null, 0, "", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "NOT_IMPLEMENTED", "", "" }, { LNK_CmdSwitch_NotImplemented, 0, "NOT_IMPLEMENTED", "", "" },
{ LNK_CmdSwitch_Align, 0, "ALIGN", ":#", "" }, { LNK_CmdSwitch_Align, 0, "ALIGN", ":#", "Set section alignment in the virtual address space." },
{ LNK_CmdSwitch_AllowBind, 0, "ALLOWBIND", "[:NO]", "" }, { LNK_CmdSwitch_AllowBind, 0, "ALLOWBIND", "[:NO]", "Toggles bind bit in the image header." },
{ LNK_CmdSwitch_AllowIsolation, 0, "ALLOWISOLATION", "[:NO]", "" }, { LNK_CmdSwitch_AllowIsolation, 0, "ALLOWISOLATION", "[:NO]", "Toggles isolation bit in the image header." },
{ LNK_CmdSwitch_AlternateName, 1, "ALTERNATENAME", "Creates an a symbol alias \"FROM=TO\"." }, { LNK_CmdSwitch_AlternateName, 1, "ALTERNATENAME", ":FROM=TO", "Creates a symbol alias \"FROM=TO\"." },
{ LNK_CmdSwitch_AppContainer, 0, "APPCONTAINER", "[:NO]", "" }, { LNK_CmdSwitch_AppContainer, 0, "APPCONTAINER", "[:NO]", "Toggles app container bit in the image header." },
{ LNK_CmdSwitch_NotImplemented, 0, "ASSEMBLYDEBUG", "", "" }, // .NET { LNK_CmdSwitch_Base, 0, "BASE", "{ADDRESS[,SIZE]|@FILENAME,KEY}", "Set default image base address." },
{ LNK_CmdSwitch_NotImplemented, 0, "ASSEMBLYLINKRESOURCE", "", "" }, // .NET { LNK_CmdSwitch_Brepro, 0, "BREPRO", "", "No support." },
{ LNK_CmdSwitch_NotImplemented, 0, "ASSEMBLYMODULE", "", "" }, // .NET { LNK_CmdSwitch_Debug, 0, "DEBUG", "[:{FULL|NONE}]", "Controls debug info level." },
{ LNK_CmdSwitch_NotImplemented, 0, "ASSEMBLYRESOURCE", "", "" }, // .NET { LNK_CmdSwitch_DefaultLib, 1, "DEFAULTLIB", ":LIBNAME", "Set default library." },
{ LNK_CmdSwitch_Base, 0, "BASE", "{ADDRESS[,SIZE]|@FILENAME,KEY}", "" }, { LNK_CmdSwitch_Delay, 0, "DELAY", ":{NOBIND|UNLOAD}", "Controls emission of unload and bind tables." },
{ LNK_CmdSwitch_Brepro, 0, "BREPRO", "", "Not supported" }, { LNK_CmdSwitch_DelayLoad, 0, "DELAYLOAD", ":DLL", "Delay load DLL." },
{ LNK_CmdSwitch_NotImplemented, 0, "CLRIMAGETYPE", "", "" }, // .NET { LNK_CmdSwitch_Dll, 0, "DLL", "", "Link to a DLL." },
{ LNK_CmdSwitch_NotImplemented, 0, "CLRLOADEROPTIMIZATION","", "" }, // .NET { LNK_CmdSwitch_DisallowLib, 1, "DISALLOWLIB", ":LIBRARY", "Prevents LIBRARY from being linked.", },
{ LNK_CmdSwitch_NotImplemented, 0, "CLRSUPPORTLASTERROR", "", "" }, // .NET { LNK_CmdSwitch_DynamicBase, 0, "DYNAMICBASE", "[:NO]", "Enable random base address in the linked image." },
{ LNK_CmdSwitch_NotImplemented, 0, "CLRTHREADATTRIBUTE", "", "" }, // .NET { LNK_CmdSwitch_Entry, 1, "ENTRY", ":FUNCTION", "Name of the entry point symbol." },
{ LNK_CmdSwitch_NotImplemented, 0, "CLRUNMANAGEDCODECHECK","", "" }, // .NET { LNK_CmdSwitch_Export, 1, "EXPORT", ":SYMBOL", "Create an export entry for SYMBOL." },
{ LNK_CmdSwitch_Debug, 0, "DEBUG", "[:{FULL|NONE}]", "" }, { LNK_CmdSwitch_FailIfMismatch, 1, "FAILIFMISMATCH", "{id=value}", "Fails to link if same ids have conflicting values." },
{ LNK_CmdSwitch_Dump, 0, "DUMP", "", "" }, { LNK_CmdSwitch_FileAlign, 0, "FILEALIGN", ":#", "Set section alignment in the file." },
{ LNK_CmdSwitch_NotImplemented, 0, "DEF", ":FILENAME", "" }, { LNK_CmdSwitch_Fixed, 0, "FIXED", "[:NO]", "Load the image at the default base address." },
{ LNK_CmdSwitch_DefaultLib, 1, "DEFAULTLIB", ":LIBNAME", "" }, { LNK_CmdSwitch_FunctionPadMin, 0, "FUNCTIONPADMIN", ":#", "Minimum function byte size." },
{ LNK_CmdSwitch_Delay, 0, "DELAY", ":{NOBIND|UNLOAD}", "" }, { LNK_CmdSwitch_Heap, 0, "HEAP", "RESERVE[,COMMIT]", "Set reserve and commit size for the heap." },
{ LNK_CmdSwitch_DelayLoad, 0, "DELAYLOAD", ":DLL", "" }, { LNK_CmdSwitch_HighEntropyVa, 0, "HIGHENTROPYVA", "[:NO]", "Indicate that image supports full 64-bit address space ASLR." },
{ LNK_CmdSwitch_NotImplemented, 0, "DELAYSIGN", "", "" }, { LNK_CmdSwitch_Ignore, 0, "IGNORE", ":#", "Ignore a warning." },
{ LNK_CmdSwitch_NotImplemented, 0, "DEPENDENTLOADFLAG", "", "" }, { LNK_CmdSwitch_ImpLib, 0, "IMPLIB", ":FILENAME", "Set file name for the import library." },
{ LNK_CmdSwitch_Dll, 0, "DLL", "", "" }, { LNK_CmdSwitch_Include, 1, "INCLUDE", ":SYMBOL", "Force a link against SYMBOL." },
{ LNK_CmdSwitch_NotImplemented, 0, "DRIVER", "", "" }, { LNK_CmdSwitch_InferAsanLibs, 1, "INFERASANLIBS", "[:NO]", "No support." },
{ LNK_CmdSwitch_DisallowLib, 1, "DISALLOWLIB", ":LIBRARY", "", }, { LNK_CmdSwitch_InferAsanLibsNo, 1, "INFERASANLIBSNO", "", "No support.", },
{ LNK_CmdSwitch_D2, 0, "D2", "" }, { LNK_CmdSwitch_LargeAddressAware, 0, "LARGEADDRESSAWARE", "[:NO]", "For images that can handle addresses > 2GiB." },
{ LNK_CmdSwitch_EditAndContinue, 1, "EDITANDCONTINUE", "[:NO]", "" }, { LNK_CmdSwitch_Lib, 0, "LIB", "", "Turn linker into lib.exe." },
{ LNK_CmdSwitch_DynamicBase, 0, "DYNAMICBASE", "[:NO]", "" }, { LNK_CmdSwitch_LibPath, 0, "LIBPATH", ":DIR", "Add DIR for the linker to search for libraries." },
{ LNK_CmdSwitch_NotImplemented, 0, "EMITVOLATILEMETADATA", "", "" }, { LNK_CmdSwitch_Machine, 0, "MACHINE", ":{X64|X86}", "Image target platform." },
{ LNK_CmdSwitch_Entry, 1, "ENTRY", ":FUNCTION", "" }, { LNK_CmdSwitch_Manifest, 0, "MANIFEST", "[:{EMBED[,ID=#]|NO]", "Controls whether the linker should create a side manifest." },
{ LNK_CmdSwitch_ErrorReport, 0, "ERRORREPORT", "", "Deprecated starting Windows Vista." }, { LNK_CmdSwitch_ManifestDependency, 1, "MANIFESTDEPENDENCY", ":\"manifest dependency XML string\"", "Add a manifest dependency." },
{ LNK_CmdSwitch_Export, 1, "EXPORT", ":SYMBOL", "" }, { LNK_CmdSwitch_ManifestFile, 0, "MANIFESTFILE", ":FILENAME", "Specifies a manifest file." },
{ LNK_CmdSwitch_NotImplemented, 0, "EXPORTADMIN", "", "" }, { LNK_CmdSwitch_ManifestInput, 0, "MANIFESTINPUT", ":FILENAME", "Manifest that is embedded in the image." },
{ LNK_CmdSwitch_Experimental, 0, "EXPERIMENTAL", "Not supported." }, { LNK_CmdSwitch_ManifestUac, 0, "MANIFESTUAC", ":{NO|{'level'={'asInvoker'|'highestAvailable'|'requireAdministrator'} ['uiAccess'={'true'|'false'}]}}", "Controls UAC information in the manifest." },
{ LNK_CmdSwitch_FastFail, 0, "FASTFAIL", "", "Not used." }, { LNK_CmdSwitch_Merge, 1, "MERGE", ":FROM=TO", "Merges sections." },
{ LNK_CmdSwitch_FailIfMismatch, 1, "FAILIFMISMATCH", "{id=value}", "" }, { LNK_CmdSwitch_Natvis, 0, "NATVIS", ":FILENAME", "NATVIS to embed in the PDB." },
{ LNK_CmdSwitch_NotImplemented, 0, "FASTGENPROFILE", "", "" }, { LNK_CmdSwitch_NoDefaultLib, 1, "NODEFAULTLIB", ":LIBNAME", "Ignore a /DEFAULTLIB." },
{ LNK_CmdSwitch_FileAlign, 0, "FILEALIGN", ":#", "" }, { LNK_CmdSwitch_NoDefaultLib, 0, "NOD", ":LIBNAME", "Alias for /NODEFAULTLIB." },
{ LNK_CmdSwitch_Fixed, 0, "FIXED", "[:NO]", "" }, { LNK_CmdSwitch_NoExp, 0, "NOEXP", "", "No support." },
{ LNK_CmdSwitch_NotImplemented, 0, "FORCE", "", "" }, { LNK_CmdSwitch_NoImpLib, 0, "NOIMPLIB", "", "Do not create the import library." },
{ LNK_CmdSwitch_FunctionPadMin, 0, "FUNCTIONPADMIN", ":#", "Not Implemented" }, { LNK_CmdSwitch_NxCompat, 0, "NXCOMPAT", "[:NO]", "Image is compatible with data execution prevention." },
{ LNK_CmdSwitch_NotImplemented, 0, "GUARD", "", "" }, { LNK_CmdSwitch_Opt, 0, "OPT", "{REF|ICF}", "Optimizations." },
{ LNK_CmdSwitch_GuardSym, 1, "GUARDSYM", "", "", }, { LNK_CmdSwitch_Out, 0, "OUT", ":FILENAME", "File name of the output image." },
{ LNK_CmdSwitch_NotImplemented, 0, "GENPROFILE", "", "" }, { LNK_CmdSwitch_Pdb, 0, "PDB", ":FILENAME", "File name of the output PDB." },
{ LNK_CmdSwitch_Heap, 0, "HEAP", "RESERVE[,COMMIT]", "" }, { LNK_CmdSwitch_PdbAltPath, 0, "PDBALTPATH", ":PATH", "Alternative output path for the PDB." },
{ LNK_CmdSwitch_HighEntropyVa, 0, "HIGHENTROPYVA", "[:NO]", "" }, { LNK_CmdSwitch_PdbPageSize, 0, "PDBPAGESIZE", ":#", "Page size must be power of two." },
{ LNK_CmdSwitch_NotImplemented, 0, "IDLOUT", "", "" }, { LNK_CmdSwitch_Release, 1, "RELEASE", "", "Write image checksum." },
{ LNK_CmdSwitch_Ignore, 0, "IGNORE", ":#", "" }, { LNK_CmdSwitch_Stack, 1, "STACK", ":RESERVE[,COMMIT]", "Set reserve and commit size for the stack." },
{ LNK_CmdSwitch_NotImplemented, 0, "IGNOREIDL", "", "" }, { LNK_CmdSwitch_SubSystem, 1, "SUBSYSTEM", ":{CONSOLE|NATIVE|WINDOWS}[,#[.##]]", "Set subsystem for the image." },
{ LNK_CmdSwitch_NotImplemented, 0, "ILK", "", "" }, { LNK_CmdSwitch_TsAware, 0, "TSAWARE", "[:NO]", "Image is terminal server aware." },
{ LNK_CmdSwitch_ImpLib, 0, "IMPLIB", ":FILENAME", "" }, { LNK_CmdSwitch_Version, 0, "VERSION", "", "Image version." },
{ LNK_CmdSwitch_Include, 1, "INCLUDE", "", "" },
{ LNK_CmdSwitch_Incremental, 0, "INCREMENTAL", "[:NO]", "Incremental linking is not supported." },
{ LNK_CmdSwitch_NotImplemented, 0, "INTEGRITYCHECK", "", "" },
{ LNK_CmdSwitch_InferAsanLibs, 1, "INFERASANLIBS", "[:NO]", "" },
{ LNK_CmdSwitch_InferAsanLibsNo, 1, "INFERASANLIBSNO", "", "", },
{ LNK_CmdSwitch_NotImplemented, 0, "KERNEL", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "KEYCONTAINER", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "KEYFILE", "", "" },
{ LNK_CmdSwitch_LargeAddressAware, 0, "LARGEADDRESSAWARE", "[:NO]", "" },
{ LNK_CmdSwitch_Lib, 0, "LIB", "" },
{ LNK_CmdSwitch_LibPath, 0, "LIBPATH", ":DIR", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "LINKERREPO", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "LINKERREPOTARGET", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "LTCG", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "LTCGOUT", "", "" },
{ LNK_CmdSwitch_Machine, 0, "MACHINE", ":{X64|X86}", "" },
{ LNK_CmdSwitch_Manifest, 0, "MANIFEST", "[:{EMBED[,ID=#]|NO]", "" },
{ LNK_CmdSwitch_ManifestDependency, 1, "MANIFESTDEPENDENCY", ":\"manifest dependency XML string\"", "" },
{ LNK_CmdSwitch_ManifestFile, 0, "MANIFESTFILE", ":FILENAME", "" },
{ LNK_CmdSwitch_ManifestInput, 0, "MANIFESTINPUT", ":FILENAME", "" },
{ LNK_CmdSwitch_ManifestUac, 0, "MANIFESTUAC", ":{NO|{'level'={'asInvoker'|'highestAvailable'|'requireAdministrator'} ['uiAccess'={'true'|'false'}]}}", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "MAP", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "MAPINFO", "", "" },
{ LNK_CmdSwitch_Merge, 1, "MERGE", ":from=to", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "MIDL", "", "" },
{ LNK_CmdSwitch_Natvis, 0, "NATVIS", ":FILENAME", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "NOASSEMBLY", "", "" },
{ LNK_CmdSwitch_NoDefaultLib, 1, "NODEFAULTLIB", ":LIBNAME", "" },
{ LNK_CmdSwitch_NoDefaultLib, 0, "NOD", ":LIBNAME", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "NOENTRY", "", "" },
{ LNK_CmdSwitch_NoExp, 0, "NOEXP", "", ".exp is not supported." },
{ LNK_CmdSwitch_NoImpLib, 0, "NOIMPLIB", "", "" },
{ LNK_CmdSwitch_NoLogo, 0, "NOLOGO", "", "" },
{ LNK_CmdSwitch_NxCompat, 0, "NXCOMPAT", "[:NO]", "" },
{ LNK_CmdSwitch_Opt, 0, "OPT", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "ORDER", "", "" },
{ LNK_CmdSwitch_Out, 0, "OUT", ":FILENAME", "" },
{ LNK_CmdSwitch_Pdb, 0, "PDB", ":FILENAME", "" },
{ LNK_CmdSwitch_PdbAltPath, 0, "PDBALTPATH", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "PDBSTRIPPED", "", "" },
{ LNK_CmdSwitch_PdbPageSize, 0, "PDBPAGESIZE", ":#", "Page size must be power of two" },
{ LNK_CmdSwitch_NotImplemented, 0, "PROFILE", "", "" },
{ LNK_CmdSwitch_Release, 1, "RELEASE", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "SAFESEH", "", "" },
{ LNK_CmdSwitch_Section, 1, "SECTION", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "SOURCELINK", "", "" },
{ LNK_CmdSwitch_Stack, 1, "STACK", ":RESERVE[,COMMIT]", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "STUB", "", "" },
{ LNK_CmdSwitch_SubSystem, 1, "SUBSYSTEM", ":{CONSOLE|NATIVE|WINDOWS}[,#[.##]]", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "SWAPRUN", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "TLBID", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "TLBOUT", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "TIME", "", "" },
{ LNK_CmdSwitch_TsAware, 0, "TSAWARE", "[:NO]", "" },
{ LNK_CmdSwitch_ThrowingNew, 1, "THROWINGNEW", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "USERPROFILE", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "VERBOSE", "", "" },
{ LNK_CmdSwitch_Version, 0, "VERSION", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WINMD", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WINMDDELAYSIGN", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WINMDKEYCONTAINER", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WINMDKEYFILE", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WHOLEARCHIVE", "", "" },
{ LNK_CmdSwitch_NotImplemented, 0, "WX", "", "" },
//- internal switches
{ LNK_CmdSwitch_Rad_Age, 0, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." }, { LNK_CmdSwitch_Rad_Age, 0, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." },
{ LNK_CmdSwitch_Rad_AltPchDir, 0, "RAD_ALT_PCH_DIR", ":PATH", "Alternative directory to search for PCH object files." }, { LNK_CmdSwitch_Rad_AltPchDir, 0, "RAD_ALT_PCH_DIR", ":PATH", "Alternative directory to search for PCH object files." },
{ LNK_CmdSwitch_Rad_BuildInfo, 0, "RAD_BUILD_INFO", "", "Print build info and exit." }, { LNK_CmdSwitch_Rad_BuildInfo, 0, "RAD_BUILD_INFO", "", "Print build info and exit." },
{ LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, 0, "RAD_CHECK_UNUSED_DELAY_LOAD_DLL", "[:NO]", "" }, { LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, 0, "RAD_CHECK_UNUSED_DELAY_LOAD_DLL", "[:NO]", "Check for unused delay load dlls." },
{ LNK_CmdSwitch_Rad_Map, 0, "RAD_MAP", ":FILENAME", "Emit file with the output image's layout description." }, { LNK_CmdSwitch_Rad_Map, 0, "RAD_MAP", ":FILENAME", "Emit file with the output image's layout description." },
{ LNK_CmdSwitch_Rad_MapLinesForUnresolvedSymbols, 0, "RAD_MAP_LINES_FOR_UNRESOLVED_SYMBOLS", "[:NO]", "Use debug info to print source file location for unresolved symbol" }, { LNK_CmdSwitch_Rad_MapLinesForUnresolvedSymbols, 0, "RAD_MAP_LINES_FOR_UNRESOLVED_SYMBOLS", "[:NO]", "Use debug info to print source file location for unresolved symbol" },
{ LNK_CmdSwitch_Rad_MemoryMapFiles, 0, "RAD_MEMORY_MAP_FILES", "[:NO]", "When enabled, files are memory-mapped instead of being read entirely on request." }, { LNK_CmdSwitch_Rad_MemoryMapFiles, 0, "RAD_MEMORY_MAP_FILES", "[:NO]", "When enabled, files are memory-mapped instead of being read entirely on request." },
{ LNK_CmdSwitch_Rad_Debug, 0, "RAD_DEBUG", "[:NO]", "Emit RAD debug info file." }, { LNK_CmdSwitch_Rad_Debug, 0, "RAD_DEBUG", "[:NO]", "Emit RAD debug info file." },
{ LNK_CmdSwitch_Rad_DebugAltPath, 0, "RAD_DEBUGALTPATH", "", "" }, { LNK_CmdSwitch_Rad_DebugAltPath, 0, "RAD_DEBUGALTPATH", ":PATH", "Alternative output path fof the RDI." },
{ LNK_CmdSwitch_Rad_DebugName, 0, "RAD_DEBUG_NAME", ":FILENAME", "Sets file name for RAD debug info file." }, { LNK_CmdSwitch_Rad_DebugName, 0, "RAD_DEBUG_NAME", ":FILENAME", "Set file name for RAD debug info file." },
{ LNK_CmdSwitch_Rad_DelayBind, 0, "RAD_DELAY_BIND", "[:NO]", "" }, { LNK_CmdSwitch_Rad_DelayBind, 0, "RAD_DELAY_BIND", "[:NO]", "Emit bindable imports." },
{ LNK_CmdSwitch_Rad_DoMerge, 0, "RAD_DO_MERGE", "[:NO]", "" }, { LNK_CmdSwitch_Rad_DoMerge, 0, "RAD_DO_MERGE", "[:NO]", "Set whether the linker should execute /MERGE." },
{ LNK_CmdSwitch_Rad_EnvLib, 0, "RAD_ENV_LIB", "[:NO]", "" }, { LNK_CmdSwitch_Rad_EnvLib, 0, "RAD_ENV_LIB", "[:NO]", "Collect libraries from %%LIB%% and %%LIBPATH%% varibles." },
{ LNK_CmdSwitch_Rad_Exe, 0, "RAD_EXE", "[:NO]", "" }, { LNK_CmdSwitch_Rad_Exe, 0, "RAD_EXE", "[:NO]", "Set EXE bit in the image header." },
{ LNK_CmdSwitch_Rad_Guid, 0, "RAD_GUID", ":{IMAGEBLAKE3|XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX}", "" }, { LNK_CmdSwitch_Rad_Guid, 0, "RAD_GUID", ":{IMAGEBLAKE3|XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX}", "The image guid that is embeded in the debug info." },
{ LNK_CmdSwitch_Rad_LargePages, 0, "RAD_LARGE_PAGES", "[:NO]", "Disabled by default on Windows." }, { LNK_CmdSwitch_Rad_LargePages, 0, "RAD_LARGE_PAGES", "[:NO]", "Disabled by default on Windows." },
{ LNK_CmdSwitch_Rad_LinkVer, 0, "RAD_LINK_VER", ":##,##", "" }, { LNK_CmdSwitch_Rad_LinkVer, 0, "RAD_LINK_VER", ":##,##", "Linker version." },
{ LNK_CmdSwitch_Rad_Log, 0, "RAD_LOG", ":{ALL,INPUT_OBJ,INPUT_LIB,IO,LINK_STATS,TIMERS}", "" }, { LNK_CmdSwitch_Rad_Log, 0, "RAD_LOG", ":{ALL,INPUT_OBJ,INPUT_LIB,IO,LINK_STATS,TIMERS}", "Loggers." },
{ LNK_CmdSwitch_Rad_MtPath, 0, "RAD_MT_PATH", ":EXEPATH", "Exe path to manifest tool, default: " LNK_MANIFEST_MERGE_TOOL_NAME }, { LNK_CmdSwitch_Rad_MtPath, 0, "RAD_MT_PATH", ":EXEPATH", "Exe path to the manifest tool (default: " LNK_MANIFEST_MERGE_TOOL_NAME ")" },
{ LNK_CmdSwitch_Rad_OsVer, 0, "RAD_OS_VER", ":##,##", "" }, { LNK_CmdSwitch_Rad_OsVer, 0, "RAD_OS_VER", ":##,##", "OS version." },
{ LNK_CmdSwitch_Rad_PageSize, 0, "RAD_PAGE_SIZE", ":#", "Must be power of two." }, { LNK_CmdSwitch_Rad_PageSize, 0, "RAD_PAGE_SIZE", ":#", "Must be power of two." },
{ LNK_CmdSwitch_Rad_PathStyle, 0, "RAD_PATH_STYLE", ":{WindowsAbsolute|UnixAbsolute}", "" }, { LNK_CmdSwitch_Rad_PathStyle, 0, "RAD_PATH_STYLE", ":{WindowsAbsolute|UnixAbsolute}", "Set path style in the PDB." },
{ LNK_CmdSwitch_Rad_PdbHashTypeNameLength, 0, "RAD_PDB_HASH_TYPE_NAME_LENGTH", ":#", "Number of hash bytes to use to replace type name. Default 8 bytes (Max 16)." }, { LNK_CmdSwitch_Rad_PdbHashTypeNameLength, 0, "RAD_PDB_HASH_TYPE_NAME_LENGTH", ":#", "Number of hash bytes to use to replace type name. Default 8 bytes (Max 16)." },
{ LNK_CmdSwitch_Rad_PdbHashTypeNameMap, 0, "RAD_PDB_HASH_TYPE_NAME_MAP", ":FILENAME", "Produce map file with hash -> type name mappings." }, { LNK_CmdSwitch_Rad_PdbHashTypeNameMap, 0, "RAD_PDB_HASH_TYPE_NAME_MAP", ":FILENAME", "Produce map file with hash -> type name mappings." },
{ LNK_CmdSwitch_Rad_PdbHashTypeNames, 0, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." }, { LNK_CmdSwitch_Rad_PdbHashTypeNames, 0, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." },
{ LNK_CmdSwitch_Rad_RemoveSection, 0, "RAD_REMOVE_SECTION", ":NAME", "Removes a section from output image." }, { LNK_CmdSwitch_Rad_RemoveSection, 0, "RAD_REMOVE_SECTION", ":NAME", "Removes a section from the image." },
{ LNK_CmdSwitch_Rad_SharedThreadPool, 0, "RAD_SHARED_THREAD_POOL", "[:STRING]", "Default value \"" LNK_DEFAULT_THREAD_POOL_NAME "\"" }, { LNK_CmdSwitch_Rad_SharedThreadPool, 0, "RAD_SHARED_THREAD_POOL", "[:STRING]", "Default value \"" LNK_DEFAULT_THREAD_POOL_NAME "\"" },
{ LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, 0, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Sets maximum number of workers in a thread pool." }, { LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, 0, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Set maximum number of workers in a thread pool." },
{ LNK_CmdSwitch_Rad_SuppressError, 0, "RAD_SUPPRESS_ERROR", ":#", "" }, { LNK_CmdSwitch_Rad_Ignore, 0, "RAD_IGNORE", ":#", "Ignore the specified RAD linker warning." },
{ LNK_CmdSwitch_Rad_TargetOs, 0, "RAD_TARGET_OS", ":{WINDOWS,LINUX,MAC}" },
{ LNK_CmdSwitch_Rad_WriteTempFiles, 0, "RAD_WRITE_TEMP_FILES", "[:NO]", "When speicifed linker writes image and debug info to temporary files and renames after link is done." }, { LNK_CmdSwitch_Rad_WriteTempFiles, 0, "RAD_WRITE_TEMP_FILES", "[:NO]", "When speicifed linker writes image and debug info to temporary files and renames after link is done." },
{ LNK_CmdSwitch_Rad_TimeStamp, 0, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." }, { LNK_CmdSwitch_Rad_TimeStamp, 0, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." },
{ LNK_CmdSwitch_Rad_UnresolvedSymbolLimit, 0, "RAD_UNRESOLVED_SYMBOL_LIMIT", ":#", "Limits number of unresolved symbol errors linker reports." }, { LNK_CmdSwitch_Rad_UnresolvedSymbolLimit, 0, "RAD_UNRESOLVED_SYMBOL_LIMIT", ":#", "Limits number of unresolved symbol errors linker reports." },
{ LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit, 0, "RAD_UNRESOLVED_SYMBOL_REF_LIMIT", ":#", "Limit number of unresolved symbol references linker reports." }, { LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit, 0, "RAD_UNRESOLVED_SYMBOL_REF_LIMIT", ":#", "Limit number of unresolved symbol references linker reports." },
{ LNK_CmdSwitch_Rad_Version, 0, "RAD_VERSION", "", "Print version and exit." }, { LNK_CmdSwitch_Rad_Version, 0, "RAD_VERSION", "", "Print version and exit." },
{ LNK_CmdSwitch_Rad_Workers, 0, "RAD_WORKERS", ":#", "Sets number of workers created in the pool. Number is capped at 1024. When /RAD_SHARED_THREAD_POOL is specified this number cant exceed /RAD_SHARED_THREAD_POOL_MAX_WORKERS." }, { LNK_CmdSwitch_Rad_Workers, 0, "RAD_WORKERS", ":#", "Set number of workers created in the pool. Number is capped at 1024. When /RAD_SHARED_THREAD_POOL is specified this number cant exceed /RAD_SHARED_THREAD_POOL_MAX_WORKERS." },
{ LNK_CmdSwitch_Help, 0, "HELP", "", "" }, { LNK_CmdSwitch_Help, 0, "HELP", "", "" },
{ LNK_CmdSwitch_Help, 0, "?", "", "" }, { LNK_CmdSwitch_Help, 0, "?", "", "" },
@@ -454,6 +388,24 @@ lnk_try_parse_u64(String8 string, LNK_ParseU64Flags flags, U64 *value_out)
return 1; return 1;
} }
internal B32
lnk_try_parse_s64(String8 string, LNK_ParseU64Flags flags, S64 *value_out)
{
if (try_s64_from_str8_c_rules(string, value_out)) {
if (flags & LNK_ParseU64Flag_CheckUnder32bit) {
if (*value_out > max_S64) {
return 0;
}
}
if (flags & LNK_ParseU64Flag_CheckPow2) {
if (!IsPow2(*value_out)) {
return 0;
}
}
}
return 1;
}
internal B32 internal B32
lnk_cmd_switch_parse_u64(LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U64 *value_out, LNK_ParseU64Flags flags) lnk_cmd_switch_parse_u64(LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, U64 *value_out, LNK_ParseU64Flags flags)
@@ -493,6 +445,19 @@ lnk_cmd_switch_parse_u64_list(Arena *arena, LNK_Obj *obj, LNK_CmdSwitchType cmd_
return 1; return 1;
} }
internal B32
lnk_cmd_switch_parse_s64_list(Arena *arena, LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, S64List *list_out, LNK_ParseU64Flags flags)
{
for EachNode(string_n, String8Node, value_strings.first) {
S64 v;
if (!lnk_try_parse_s64(string_n->string, flags, &v)) {
return 0;
}
s64_list_push(arena, list_out, v);
}
return 1;
}
internal B32 internal B32
lnk_cmd_switch_parse_flag(LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, LNK_SwitchState *value_out) lnk_cmd_switch_parse_flag(LNK_Obj *obj, LNK_CmdSwitchType cmd_switch, String8List value_strings, LNK_SwitchState *value_out)
{ {
@@ -1022,33 +987,67 @@ lnk_print_help(void)
{ {
Temp scratch = scratch_begin(0,0); Temp scratch = scratch_begin(0,0);
fprintf(stdout, "--- Help -------------------------------------------------------\n"); static char spaces[] = " ";
U64 name_max_size = 0;
U64 args_max_size = 0;
U64 desc_max_size = 0;
for EachElement(i, g_cmd_switch_map) {
name_max_size = Max(name_max_size, strlen(g_cmd_switch_map[i].name));
args_max_size = Max(args_max_size, strlen(g_cmd_switch_map[i].args));
desc_max_size = Max(desc_max_size, strlen(g_cmd_switch_map[i].desc));
}
fprintf(stdout, "--- Help -------------------------------------------------------------------------------------------------------------------\n");
fprintf(stdout, " %s\n", BUILD_TITLE_STRING_LITERAL); fprintf(stdout, " %s\n", BUILD_TITLE_STRING_LITERAL);
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, " Usage: radlink.exe [Options] [Files] [@rsp]\n"); fprintf(stdout, " Usage: radlink.exe [Options] [Files] [@rsp]\n");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, " Options:\n"); fprintf(stdout, " Options:\n");
for (U64 i = 0; i < ArrayCount(g_cmd_switch_map); ++i) { U64 option_indent_size = 4;
U64 option_name_max_size = 60;
for EachElement(i, g_cmd_switch_map) {
Temp temp = temp_begin(scratch.arena); Temp temp = temp_begin(scratch.arena);
U64 name_size = strlen(g_cmd_switch_map[i].name);
U64 args_size = strlen(g_cmd_switch_map[i].args);
U64 desc_size = strlen(g_cmd_switch_map[i].desc);
char *name = g_cmd_switch_map[i].name; char *name = g_cmd_switch_map[i].name;
char *args = g_cmd_switch_map[i].args; char *args = g_cmd_switch_map[i].args;
char *desc = g_cmd_switch_map[i].desc; char *desc = g_cmd_switch_map[i].desc;
LNK_CmdSwitchType type = g_cmd_switch_map[i].type; LNK_CmdSwitchType type = g_cmd_switch_map[i].type;
if (strcmp(name, "") == 0 || if (strcmp(name, "") == 0 || strcmp(name, "NOT_IMPLEMENTED") == 0 || type == LNK_CmdSwitch_Help) {
strcmp(name, "NOT_IMPLEMENTED") == 0 ||
type == LNK_CmdSwitch_Help) {
continue; continue;
} }
String8 name_args = push_str8f(temp.arena, "%s%s", name, args); String8List fmt = {0};
fprintf(stdout, " /%-32.*s %s%s\n", str8_list_pushf(temp.arena, &fmt, "%.*s", option_indent_size, spaces);
str8_varg(name_args),
desc, str8_list_pushf(temp.arena, &fmt, "/");
type == LNK_CmdSwitch_NotImplemented ? "Not Implemented" : "");
B32 put_option_args_on_new_line = name_size + args_size > option_name_max_size;
if (put_option_args_on_new_line) {
str8_list_pushf(temp.arena, &fmt, "%s%s", name, args[0] == ':' ? ":" : "");
} else {
str8_list_pushf(temp.arena, &fmt, "%s%s", name, args);
}
U64 desc_indent_size = fmt.total_size < option_name_max_size ? option_name_max_size - fmt.total_size : 0;
str8_list_pushf(temp.arena, &fmt, "%.*s", desc_indent_size, spaces);
str8_list_pushf(temp.arena, &fmt, "%s", desc);
str8_list_pushf(temp.arena, &fmt, "\n");
if (put_option_args_on_new_line) {
str8_list_pushf(temp.arena, &fmt, "%.*s", Min(option_name_max_size, option_indent_size + name_size + 1), spaces);
str8_list_pushf(temp.arena, &fmt, "%s\n", args[0] == ':' ? args + 1 : args);
}
String8 line = str8_list_join(temp.arena, &fmt, 0);
fprintf(stdout, "%.*s", str8_varg(line));
temp_end(temp); temp_end(temp);
} }
@@ -1219,10 +1218,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
} }
} break; } break;
case LNK_CmdSwitch_Brepro: {
// not supported -- ignore
} break;
case LNK_CmdSwitch_Debug: { case LNK_CmdSwitch_Debug: {
if (value_strings.node_count == 0) { if (value_strings.node_count == 0) {
config->debug_mode = LNK_DebugMode_Full; config->debug_mode = LNK_DebugMode_Full;
@@ -1285,14 +1280,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->dll_characteristics, PE_DllCharacteristic_DYNAMIC_BASE); lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->dll_characteristics, PE_DllCharacteristic_DYNAMIC_BASE);
} break; } break;
case LNK_CmdSwitch_Dump: {
lnk_error_cmd_switch(LNK_Error_Cmdl, obj, cmd_switch, "unsupported switch; binary dump is done by passing /DUMP to link.exe");
} break;
case LNK_CmdSwitch_D2: {
// not supported -- ignore
} break;
case LNK_CmdSwitch_Entry: { case LNK_CmdSwitch_Entry: {
String8 new_entry_point_name = {0}; String8 new_entry_point_name = {0};
lnk_cmd_switch_parse_string_copy(config->arena, obj, cmd_switch, value_strings, &new_entry_point_name); lnk_cmd_switch_parse_string_copy(config->arena, obj, cmd_switch, value_strings, &new_entry_point_name);
@@ -1305,10 +1292,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
config->entry_point_name = new_entry_point_name; config->entry_point_name = new_entry_point_name;
} break; } break;
case LNK_CmdSwitch_ErrorReport: {
// not supported -- ignore
} break;
case LNK_CmdSwitch_Export: { case LNK_CmdSwitch_Export: {
PE_ExportParse export_parse = {0}; PE_ExportParse export_parse = {0};
if (lnk_parse_export_directive_ex(config->arena, value_strings, obj, &export_parse)) { if (lnk_parse_export_directive_ex(config->arena, value_strings, obj, &export_parse)) {
@@ -1351,14 +1334,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
} }
} break; } break;
case LNK_CmdSwitch_Experimental: {
// not supported
} break;
case LNK_CmdSwitch_FastFail: {
// do nothing
} break;
case LNK_CmdSwitch_FailIfMismatch: { case LNK_CmdSwitch_FailIfMismatch: {
if (value_strings.node_count != 1) { if (value_strings.node_count != 1) {
lnk_error_cmd_switch_invalid_param_count(LNK_Error_Cmdl, obj, cmd_switch); lnk_error_cmd_switch_invalid_param_count(LNK_Error_Cmdl, obj, cmd_switch);
@@ -1440,13 +1415,13 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
if (lnk_cmd_switch_parse_u64(obj, cmd_switch, value_strings, &error_code, 0)) { if (lnk_cmd_switch_parse_u64(obj, cmd_switch, value_strings, &error_code, 0)) {
switch (error_code) { switch (error_code) {
case LNK_MsWarningCode_UnsuedDelayLoadDll: { case LNK_MsWarningCode_UnsuedDelayLoadDll: {
lnk_suppress_error(LNK_Warning_UnusedDelayLoadDll); lnk_ignore_error(LNK_Warning_UnusedDelayLoadDll);
} break; } break;
case LNK_MsWarningCode_MissingExternalTypeServer: { case LNK_MsWarningCode_MissingExternalTypeServer: {
lnk_suppress_error(LNK_Warning_MissingExternalTypeServer); lnk_ignore_error(LNK_Warning_MissingExternalTypeServer);
} break; } break;
case LNK_MsWarningCode_SectionFlagsConflict: { case LNK_MsWarningCode_SectionFlagsConflict: {
lnk_suppress_error(LNK_Warning_SectionFlagsConflict); lnk_ignore_error(LNK_Warning_SectionFlagsConflict);
} break; } break;
default: { default: {
lnk_not_implemented("TODO: /IGNORE:%llu", error_code); lnk_not_implemented("TODO: /IGNORE:%llu", error_code);
@@ -1465,15 +1440,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
} }
} break; } break;
case LNK_CmdSwitch_Incremental: {
LNK_SwitchState state;
if (lnk_cmd_switch_parse_flag(obj, cmd_switch, value_strings, &state)) {
if (state == LNK_SwitchState_Yes) {
lnk_error_cmd_switch(LNK_Warning_Cmdl, obj, cmd_switch, "incremental linkage is not supported");
}
}
} break;
case LNK_CmdSwitch_LargeAddressAware: { case LNK_CmdSwitch_LargeAddressAware: {
lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->file_characteristics, PE_ImageFileCharacteristic_LARGE_ADDRESS_AWARE); lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->file_characteristics, PE_ImageFileCharacteristic_LARGE_ADDRESS_AWARE);
} break; } break;
@@ -1673,10 +1639,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
config->build_imp_lib = 0; config->build_imp_lib = 0;
} break; } break;
case LNK_CmdSwitch_NoLogo: {
// we don't print logo
} break;
case LNK_CmdSwitch_NxCompat: { case LNK_CmdSwitch_NxCompat: {
lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->dll_characteristics, PE_DllCharacteristic_NX_COMPAT); lnk_cmd_switch_set_flag_16(obj, cmd_switch, value_strings, &config->dll_characteristics, PE_DllCharacteristic_NX_COMPAT);
} break; } break;
@@ -2036,30 +1998,26 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
} }
} break; } break;
case LNK_CmdSwitch_Rad_SuppressError: { case LNK_CmdSwitch_Rad_Ignore: {
U64List error_code_list = {0}; S64List error_code_list = {0};
if (lnk_cmd_switch_parse_u64_list(scratch.arena, obj, cmd_switch, value_strings, &error_code_list, 0)) { if ( ! lnk_cmd_switch_parse_s64_list(scratch.arena, obj, cmd_switch, value_strings, &error_code_list, 0)) {
for (U64Node *error_code_n = error_code_list.first; error_code_n != 0; error_code_n = error_code_n->next) { lnk_error_cmd_switch(LNK_Error_Cmdl, obj, cmd_switch, "failed to parse input code");
if (error_code_n->data < LNK_Error_Count) { break;
lnk_suppress_error(error_code_n->data);
} else {
lnk_error_cmd_switch(LNK_Warning_Cmdl, obj, cmd_switch, "unknown error code %llu", error_code_n->data);
} }
}
}
} break;
case LNK_CmdSwitch_Rad_TargetOs: { for EachNode(error_code_n, S64Node, error_code_list.first) {
if (value_strings.node_count == 1) { S64 code = error_code_n->v;
String8 os_string = str8_list_first(&value_strings);
OperatingSystem target_os = operating_system_from_string(os_string); if (abs_s64(code) >= LNK_Error_Count) {
if (target_os != OperatingSystem_Null) { lnk_error_cmd_switch(LNK_Warning_Cmdl, obj, cmd_switch, "unknown error code %llu", (U64)abs_s64(code));
config->target_os = target_os; continue;
} else { }
lnk_error_cmd_switch(LNK_Error_Cmdl, obj, cmd_switch, "unknown operating system type %S", os_string);
if (code > 0) {
lnk_ignore_error(code);
} else if (code < 0) {
lnk_activate_error(abs_s64(code));
} }
} else {
lnk_error_cmd_switch(LNK_Warning_Cmdl, obj, cmd_switch, "expected 1 parameter");
} }
} break; } break;
+6 -73
View File
@@ -42,25 +42,23 @@ typedef enum
LNK_CmdSwitch_DefaultLib, LNK_CmdSwitch_DefaultLib,
LNK_CmdSwitch_Delay, LNK_CmdSwitch_Delay,
LNK_CmdSwitch_DelayLoad, LNK_CmdSwitch_DelayLoad,
LNK_CmdSwitch_DisallowLib,
LNK_CmdSwitch_Dll, LNK_CmdSwitch_Dll,
LNK_CmdSwitch_DynamicBase, LNK_CmdSwitch_DynamicBase,
LNK_CmdSwitch_Dump,
LNK_CmdSwitch_D2,
LNK_CmdSwitch_Entry, LNK_CmdSwitch_Entry,
LNK_CmdSwitch_ErrorReport,
LNK_CmdSwitch_Experimental,
LNK_CmdSwitch_Export, LNK_CmdSwitch_Export,
LNK_CmdSwitch_FailIfMismatch, LNK_CmdSwitch_FailIfMismatch,
LNK_CmdSwitch_FastFail,
LNK_CmdSwitch_FileAlign, LNK_CmdSwitch_FileAlign,
LNK_CmdSwitch_Fixed, LNK_CmdSwitch_Fixed,
LNK_CmdSwitch_FunctionPadMin, LNK_CmdSwitch_FunctionPadMin,
LNK_CmdSwitch_Force,
LNK_CmdSwitch_Heap, LNK_CmdSwitch_Heap,
LNK_CmdSwitch_HighEntropyVa, LNK_CmdSwitch_HighEntropyVa,
LNK_CmdSwitch_Ignore, LNK_CmdSwitch_Ignore,
LNK_CmdSwitch_ImpLib, LNK_CmdSwitch_ImpLib,
LNK_CmdSwitch_Include, LNK_CmdSwitch_Include,
LNK_CmdSwitch_Incremental, LNK_CmdSwitch_InferAsanLibs,
LNK_CmdSwitch_InferAsanLibsNo,
LNK_CmdSwitch_LargeAddressAware, LNK_CmdSwitch_LargeAddressAware,
LNK_CmdSwitch_Lib, LNK_CmdSwitch_Lib,
LNK_CmdSwitch_LibPath, LNK_CmdSwitch_LibPath,
@@ -75,81 +73,18 @@ typedef enum
LNK_CmdSwitch_NoDefaultLib, LNK_CmdSwitch_NoDefaultLib,
LNK_CmdSwitch_NoExp, LNK_CmdSwitch_NoExp,
LNK_CmdSwitch_NoImpLib, LNK_CmdSwitch_NoImpLib,
LNK_CmdSwitch_NoLogo,
LNK_CmdSwitch_NxCompat, LNK_CmdSwitch_NxCompat,
LNK_CmdSwitch_Opt, LNK_CmdSwitch_Opt,
LNK_CmdSwitch_Out, LNK_CmdSwitch_Out,
LNK_CmdSwitch_Pdb, LNK_CmdSwitch_Pdb,
LNK_CmdSwitch_PdbAltPath, LNK_CmdSwitch_PdbAltPath,
LNK_CmdSwitch_PdbPageSize, LNK_CmdSwitch_PdbPageSize,
LNK_CmdSwitch_Release,
LNK_CmdSwitch_Stack, LNK_CmdSwitch_Stack,
LNK_CmdSwitch_SubSystem, LNK_CmdSwitch_SubSystem,
LNK_CmdSwitch_Time, LNK_CmdSwitch_Time,
LNK_CmdSwitch_TsAware, LNK_CmdSwitch_TsAware,
// -- NOT Implemented:
LNK_CmdSwitch_AssemblyDebug,
LNK_CmdSwitch_AssemblyLinkResource,
LNK_CmdSwitch_AssemblyModule,
LNK_CmdSwitch_AssemblyResource,
LNK_CmdSwitch_ClrImageType,
LNK_CmdSwitch_ClrLoaderOptimization,
LNK_CmdSwitch_ClrSupportLastError,
LNK_CmdSwitch_ClrThreadAttribute,
LNK_CmdSwitch_ClrRunManagedCodeCheck,
LNK_CmdSwitch_ClrUnmanagedCheck,
LNK_CmdSwitch_Def,
LNK_CmdSwitch_DelaySign,
LNK_CmdSwitch_DependentLoadFlag,
LNK_CmdSwitch_Driver,
LNK_CmdSwitch_DisallowLib,
LNK_CmdSwitch_EditAndContinue,
LNK_CmdSwitch_EmitVolatileMetadata,
LNK_CmdSwitch_ExportAdmin,
LNK_CmdSwitch_FastGenProfile,
LNK_CmdSwitch_Force,
LNK_CmdSwitch_Guard,
LNK_CmdSwitch_GuardSym,
LNK_CmdSwitch_GenProfile,
LNK_CmdSwitch_IdlOut,
LNK_CmdSwitch_IgnoreIdl,
LNK_CmdSwitch_Ilk,
LNK_CmdSwitch_IntegrityCheck,
LNK_CmdSwitch_InferAsanLibs,
LNK_CmdSwitch_InferAsanLibsNo,
LNK_CmdSwitch_Kernel,
LNK_CmdSwitch_KeyContainer,
LNK_CmdSwitch_KeyFile,
LNK_CmdSwitch_LinkerRepro,
LNK_CmdSwitch_LinkerReproTarget,
LNK_CmdSwitch_Ltcg,
LNK_CmdSwitch_LtcgOut,
LNK_CmdSwitch_Map,
LNK_CmdSwitch_MapInfo,
LNK_CmdSwitch_Midl,
LNK_CmdSwitch_NoAssembly,
LNK_CmdSwitch_NoEntry,
LNK_CmdSwitch_Order,
LNK_CmdSwitch_PdbStripped,
LNK_CmdSwitch_Profile,
LNK_CmdSwitch_Release,
LNK_CmdSwitch_SafeSeh,
LNK_CmdSwitch_Section,
LNK_CmdSwitch_SourceLink,
LNK_CmdSwitch_Stub,
LNK_CmdSwitch_SwapRun,
LNK_CmdSwitch_TlbId,
LNK_CmdSwitch_ThrowingNew,
LNK_CmdSwitch_UserProfile,
LNK_CmdSwitch_Verbose,
LNK_CmdSwitch_Version, LNK_CmdSwitch_Version,
LNK_CmdSwitch_Winmd,
LNK_CmdSwitch_WinmdDelaySign,
LNK_CmdSwitch_WinmdKeyContainer,
LNK_CmdSwitch_WinmdKeyFile,
LNK_CmdSwitch_WholeArchive,
LNK_CmdSwitch_Wx,
LNK_CmdSwitch_Rad_Age, LNK_CmdSwitch_Rad_Age,
LNK_CmdSwitch_Rad_AltPchDir, LNK_CmdSwitch_Rad_AltPchDir,
@@ -180,8 +115,7 @@ typedef enum
LNK_CmdSwitch_Rad_RemoveSection, LNK_CmdSwitch_Rad_RemoveSection,
LNK_CmdSwitch_Rad_SharedThreadPool, LNK_CmdSwitch_Rad_SharedThreadPool,
LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers,
LNK_CmdSwitch_Rad_SuppressError, LNK_CmdSwitch_Rad_Ignore,
LNK_CmdSwitch_Rad_TargetOs,
LNK_CmdSwitch_Rad_TimeStamp, LNK_CmdSwitch_Rad_TimeStamp,
LNK_CmdSwitch_Rad_UnresolvedSymbolLimit, LNK_CmdSwitch_Rad_UnresolvedSymbolLimit,
LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit, LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit,
@@ -361,7 +295,6 @@ typedef struct LNK_Config
Version link_ver; Version link_ver;
Version os_ver; Version os_ver;
Version image_ver; Version image_ver;
OperatingSystem target_os;
COFF_MachineType machine; COFF_MachineType machine;
PE_WindowsSubsystem subsystem; PE_WindowsSubsystem subsystem;
Version subsystem_ver; Version subsystem_ver;
+8 -7
View File
@@ -40,12 +40,7 @@ lnk_string_from_error_mode(LNK_ErrorMode mode)
internal void internal void
lnk_errorfv(LNK_ErrorCode code, char *fmt, va_list args) lnk_errorfv(LNK_ErrorCode code, char *fmt, va_list args)
{ {
if (g_error_mode_arr[code] == LNK_ErrorMode_Ignore) { if (lnk_is_error_code_ignored(code)) { return; }
return;
}
if (lnk_is_error_code_ignored(code)) {
return;
}
Temp scratch = scratch_begin(0,0); Temp scratch = scratch_begin(0,0);
String8 message = push_str8fv(scratch.arena, fmt, args); String8 message = push_str8fv(scratch.arena, fmt, args);
@@ -118,11 +113,17 @@ lnk_supplement_error_list(String8List list)
} }
internal void internal void
lnk_suppress_error(LNK_ErrorCode code) lnk_ignore_error(LNK_ErrorCode code)
{ {
g_error_code_status_arr[code] = LNK_ErrorCodeStatus_Ignore; g_error_code_status_arr[code] = LNK_ErrorCodeStatus_Ignore;
} }
internal void
lnk_activate_error(LNK_ErrorCode code)
{
g_error_code_status_arr[code] = LNK_ErrorCodeStatus_Active;
}
internal LNK_ErrorCodeStatus internal LNK_ErrorCodeStatus
lnk_get_error_code_status(LNK_ErrorCode code) lnk_get_error_code_status(LNK_ErrorCode code)
{ {
+2 -1
View File
@@ -126,7 +126,8 @@ internal void lnk_error(LNK_ErrorCode code, char *fmt, ...);
internal void lnk_error_with_loc(LNK_ErrorCode code, String8 obj_path, String8 lib_path, char *fmt, ...); internal void lnk_error_with_loc(LNK_ErrorCode code, String8 obj_path, String8 lib_path, char *fmt, ...);
internal void lnk_supplement_error(char *fmt, ...); internal void lnk_supplement_error(char *fmt, ...);
internal void lnk_supplement_error_list(String8List list); internal void lnk_supplement_error_list(String8List list);
internal void lnk_suppress_error(LNK_ErrorCode code); internal void lnk_ignore_error(LNK_ErrorCode code);
internal void lnk_activate_error(LNK_ErrorCode code);
#define lnk_is_error_code_active(code) (lnk_get_error_code_status(code) == LNK_ErrorCodeStatus_Active) #define lnk_is_error_code_active(code) (lnk_get_error_code_status(code) == LNK_ErrorCodeStatus_Active)
#define lnk_is_error_code_ignored(code) (lnk_get_error_code_status(code) == LNK_ErrorCodeStatus_Ignore) #define lnk_is_error_code_ignored(code) (lnk_get_error_code_status(code) == LNK_ErrorCodeStatus_Ignore)
+1 -1
View File
@@ -250,7 +250,7 @@ lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, LNK_IO_Flags
// assign offsets into file buffer // assign offsets into file buffer
U64 *off_arr = push_array_no_zero(scratch.arena, U64, path_arr.count); U64 *off_arr = push_array_no_zero(scratch.arena, U64, path_arr.count);
MemoryCopyTyped(off_arr, reader.size_arr, path_arr.count); MemoryCopyTyped(off_arr, reader.size_arr, path_arr.count);
counts_to_offsets_array_u64(path_arr.count, off_arr); u64_array_counts_to_offsets(path_arr.count, off_arr);
reader.io_flags = io_flags; reader.io_flags = io_flags;
reader.data_arr = str8_array_reserve(arena, path_arr.count); reader.data_arr = str8_array_reserve(arena, path_arr.count);
+1 -1
View File
@@ -2350,7 +2350,7 @@ gsi_build_ex(TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 symbol_data_
U64 buffer_size = sum_array_u64(gsi->bucket_count, serial_task.bucket_size_arr); U64 buffer_size = sum_array_u64(gsi->bucket_count, serial_task.bucket_size_arr);
serial_task.buffer = push_array_no_zero(arena, U8, buffer_size); serial_task.buffer = push_array_no_zero(arena, U8, buffer_size);
serial_task.bucket_off_arr = push_array_copy_u64(scratch.arena, serial_task.bucket_size_arr, gsi->bucket_count); serial_task.bucket_off_arr = push_array_copy_u64(scratch.arena, serial_task.bucket_size_arr, gsi->bucket_count);
counts_to_offsets_array_u64(gsi->bucket_count, serial_task.bucket_off_arr); u64_array_counts_to_offsets(gsi->bucket_count, serial_task.bucket_off_arr);
// prepare GSI records // prepare GSI records
serial_task.sort_record_arr_arr = push_array_no_zero(scratch.arena, PDB_GsiSortRecord *, gsi->bucket_count); serial_task.sort_record_arr_arr = push_array_no_zero(scratch.arena, PDB_GsiSortRecord *, gsi->bucket_count);
+20 -20
View File
@@ -2072,9 +2072,9 @@ THREAD_POOL_TASK_FUNC(rdib_string_map_radix_sort_element_idx_task)
ProfEnd(); ProfEnd();
ProfBegin("Histogram Counts -> Offsets"); ProfBegin("Histogram Counts -> Offsets");
counts_to_offsets_array_u32(ArrayCount(histo_bot), &histo_bot[0]); u32_array_counts_to_offsets(ArrayCount(histo_bot), &histo_bot[0]);
counts_to_offsets_array_u32(ArrayCount(histo_mid), &histo_mid[0]); u32_array_counts_to_offsets(ArrayCount(histo_mid), &histo_mid[0]);
counts_to_offsets_array_u32(ArrayCount(histo_top), &histo_top[0]); u32_array_counts_to_offsets(ArrayCount(histo_top), &histo_top[0]);
ProfEnd(); ProfEnd();
ProfBegin("Sort Bot"); ProfBegin("Sort Bot");
@@ -2140,7 +2140,7 @@ rdib_string_map_sort_buckets(TP_Context *tp, RDIB_StringMapBucket **buckets, U64
#endif #endif
ProfBegin("Chunk Histo -> Offsets"); ProfBegin("Chunk Histo -> Offsets");
task.chunk_offsets = offsets_from_counts_array_u32(scratch.arena, task.chunk_histo, chunk_idx_opl); task.chunk_offsets = u32_array_offsets_from_counts(scratch.arena, task.chunk_histo, chunk_idx_opl);
ProfEnd(); ProfEnd();
ProfBegin("Sort on chunk index"); ProfBegin("Sort on chunk index");
@@ -2148,7 +2148,7 @@ rdib_string_map_sort_buckets(TP_Context *tp, RDIB_StringMapBucket **buckets, U64
ProfEnd(); ProfEnd();
ProfBegin("Sort on element index"); ProfBegin("Sort on element index");
task.chunk_offsets = offsets_from_counts_array_u32(scratch.arena, task.chunk_histo, chunk_idx_opl); task.chunk_offsets = u32_array_offsets_from_counts(scratch.arena, task.chunk_histo, chunk_idx_opl);
task.ranges = tp_divide_work(scratch.arena, chunk_idx_opl, tp->worker_count); task.ranges = tp_divide_work(scratch.arena, chunk_idx_opl, tp->worker_count);
tp_for_parallel(tp, 0, tp->worker_count, rdib_string_map_radix_sort_element_idx_task, &task); tp_for_parallel(tp, 0, tp->worker_count, rdib_string_map_radix_sort_element_idx_task, &task);
ProfEnd(); ProfEnd();
@@ -2698,9 +2698,9 @@ THREAD_POOL_TASK_FUNC(rdib_index_run_map_radix_sort_element_idx_task)
ProfEnd(); ProfEnd();
ProfBegin("Histogram Counts -> Offsets"); ProfBegin("Histogram Counts -> Offsets");
counts_to_offsets_array_u32(ArrayCount(histo_bot), &histo_bot[0]); u32_array_counts_to_offsets(ArrayCount(histo_bot), &histo_bot[0]);
counts_to_offsets_array_u32(ArrayCount(histo_mid), &histo_mid[0]); u32_array_counts_to_offsets(ArrayCount(histo_mid), &histo_mid[0]);
counts_to_offsets_array_u32(ArrayCount(histo_top), &histo_top[0]); u32_array_counts_to_offsets(ArrayCount(histo_top), &histo_top[0]);
ProfEnd(); ProfEnd();
ProfBegin("Sort Bot"); ProfBegin("Sort Bot");
@@ -2766,7 +2766,7 @@ rdib_index_run_map_sort_buckets(TP_Context *tp, RDIB_IndexRunBucket **buckets, U
#endif #endif
ProfBegin("Chunk Histo -> Offsets"); ProfBegin("Chunk Histo -> Offsets");
task.chunk_offsets = offsets_from_counts_array_u32(scratch.arena, task.chunk_histo, chunk_idx_opl); task.chunk_offsets = u32_array_offsets_from_counts(scratch.arena, task.chunk_histo, chunk_idx_opl);
ProfEnd(); ProfEnd();
ProfBegin("Sort on chunk index"); ProfBegin("Sort on chunk index");
@@ -2774,7 +2774,7 @@ rdib_index_run_map_sort_buckets(TP_Context *tp, RDIB_IndexRunBucket **buckets, U
ProfEnd(); ProfEnd();
ProfBegin("Sort on element index"); ProfBegin("Sort on element index");
task.chunk_offsets = offsets_from_counts_array_u32(scratch.arena, task.chunk_histo, chunk_idx_opl); task.chunk_offsets = u32_array_offsets_from_counts(scratch.arena, task.chunk_histo, chunk_idx_opl);
task.ranges = tp_divide_work(scratch.arena, chunk_idx_opl, tp->worker_count); task.ranges = tp_divide_work(scratch.arena, chunk_idx_opl, tp->worker_count);
tp_for_parallel(tp, 0, tp->worker_count, rdib_index_run_map_radix_sort_element_idx_task, &task); tp_for_parallel(tp, 0, tp->worker_count, rdib_index_run_map_radix_sort_element_idx_task, &task);
ProfEnd(); ProfEnd();
@@ -3253,9 +3253,9 @@ rdib_sort_procs_radix_32(RDIB_Procedure **v, U64 count)
ProfEnd(); ProfEnd();
ProfBegin("Counts -> Offsets"); ProfBegin("Counts -> Offsets");
counts_to_offsets_array_u32(ArrayCount(count_8lo), count_8lo); u32_array_counts_to_offsets(ArrayCount(count_8lo), count_8lo);
counts_to_offsets_array_u32(ArrayCount(count_8hi), count_8hi); u32_array_counts_to_offsets(ArrayCount(count_8hi), count_8hi);
counts_to_offsets_array_u32(ArrayCount(count_16), count_16 ); u32_array_counts_to_offsets(ArrayCount(count_16), count_16 );
ProfEnd(); ProfEnd();
ProfBegin("Order 8 Lo"); ProfBegin("Order 8 Lo");
@@ -3357,13 +3357,13 @@ rdib_data_from_vmap(Arena *arena, U64 range_count, RDIB_VMapRange *ranges)
++voff_count2[voff_digit2]; ++voff_count2[voff_digit2];
} }
counts_to_offsets_array_u32((1 << size_bit_count0), size_count0); u32_array_counts_to_offsets((1 << size_bit_count0), size_count0);
counts_to_offsets_array_u32((1 << size_bit_count1), size_count1); u32_array_counts_to_offsets((1 << size_bit_count1), size_count1);
counts_to_offsets_array_u32((1 << size_bit_count2), size_count2); u32_array_counts_to_offsets((1 << size_bit_count2), size_count2);
counts_to_offsets_array_u32((1 << voff_bit_count0), voff_count0); u32_array_counts_to_offsets((1 << voff_bit_count0), voff_count0);
counts_to_offsets_array_u32((1 << voff_bit_count1), voff_count1); u32_array_counts_to_offsets((1 << voff_bit_count1), voff_count1);
counts_to_offsets_array_u32((1 << voff_bit_count2), voff_count2); u32_array_counts_to_offsets((1 << voff_bit_count2), voff_count2);
// //
// Sort on range size (high to low) // Sort on range size (high to low)
@@ -4517,7 +4517,7 @@ THREAD_POOL_TASK_FUNC(rdib_build_src_line_map_task)
// than 4GiB in line table anyway. // than 4GiB in line table anyway.
radsort(ln_voff_arr, ln_voff_count, pair_u32_is_before_v0); radsort(ln_voff_arr, ln_voff_count, pair_u32_is_before_v0);
} else { } else {
u32_pair_radix_sort(ln_voff_count, ln_voff_arr); u32_pair_sort_radix(ln_voff_count, ln_voff_arr);
} }
ProfEnd(); ProfEnd();