ubsan cleanup

This commit is contained in:
Nikita Smith
2026-02-13 20:59:26 -08:00
parent fbc3cbd6eb
commit 1f51c6f25b
16 changed files with 180 additions and 110 deletions
+50 -10
View File
@@ -79,19 +79,21 @@ u64_up_to_pow2(U64 x){
} }
internal S32 internal S32
extend_sign32(U32 x, U32 size){ extend_sign32(U32 x, U32 size)
U32 high_bit = size * 8; {
U32 shift = 32 - high_bit; U32 n = size * 8;
S32 result = ((S32)x << shift) >> shift; U32 m = (U32)1 << (n - 1);
return result; S32 r = (S32)((x ^ m) - m);
return r;
} }
internal S64 internal S64
extend_sign64(U64 x, U64 size){ extend_sign64(U64 x, U64 size)
U64 high_bit = size * 8; {
U64 shift = 64 - high_bit; U64 n = size * 8;
S64 result = ((S64)x << shift) >> shift; U64 m = (U64)1 << (n - 1);
return result; S64 r = (S64)((x ^ m) - m);
return r;
} }
internal F32 internal F32
@@ -286,6 +288,44 @@ memory_is_zero(void *ptr, U64 size)
return result; return result;
} }
internal void UBSAN_NO_ALIGN
memory_write32(void *ptr, U32 v)
{
MemoryCopy(ptr, &v, sizeof(v));
}
internal U8 UBSAN_NO_ALIGN
memory_read8(void *ptr)
{
U8 result;
MemoryCopy(&result, ptr, sizeof(result));
return result;
}
internal U16 UBSAN_NO_ALIGN
memory_read16(void *ptr)
{
U16 result;
MemoryCopy(&result, ptr, sizeof(result));
return result;
}
internal U32 UBSAN_NO_ALIGN
memory_read32(void *ptr)
{
U32 result;
MemoryCopy(&result, ptr, sizeof(result));
return result;
}
internal U64 UBSAN_NO_ALIGN
memory_read64(void *ptr)
{
U64 result;
MemoryCopy(&result, ptr, sizeof(result));
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Text 2D Coordinate/Range Functions //~ rjf: Text 2D Coordinate/Range Functions
+24 -9
View File
@@ -7,12 +7,13 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Foreign Includes //~ rjf: Foreign Includes
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdint.h>
#include <inttypes.h>
//////////////////////////////// ////////////////////////////////
//~ rjf: Third Party Includes //~ rjf: Third Party Includes
@@ -181,8 +182,9 @@
//~ rjf: Member Offsets //~ rjf: Member Offsets
#define Member(T,m) (((T*)0)->m) #define Member(T,m) (((T*)0)->m)
#define OffsetOf(T,m) IntFromPtr(&Member(T,m)) #define OffsetOf(T,m) offsetof(T, m)
#define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off))) #define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off)))
#define MemberFromPtr(T,ptr,m) (void*)((((U8 *)ptr)+OffsetOf(T,m)))
#define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m)) #define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m))
//////////////////////////////// ////////////////////////////////
@@ -366,9 +368,9 @@ CheckNil(nil,p) ? \
#if COMPILER_MSVC #if COMPILER_MSVC
# if defined(__SANITIZE_ADDRESS__) # if defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1 # define ASAN_ENABLED 1
# define NO_ASAN __declspec(no_sanitize_address) # define ASAN_NO_ADDR __declspec(no_sanitize_address)
# else # else
# define NO_ASAN # define UBSAN_NO_ALIGN
# endif # endif
#elif COMPILER_CLANG #elif COMPILER_CLANG
# if defined(__has_feature) # if defined(__has_feature)
@@ -376,9 +378,15 @@ CheckNil(nil,p) ? \
# define ASAN_ENABLED 1 # define ASAN_ENABLED 1
# endif # endif
# endif # endif
# define NO_ASAN __attribute__((no_sanitize("address"))) # define ASAN_NO_ADDR __attribute__((no_sanitize("address")))
#else # define UBSAN_NO_ALIGN __attribute__((no_sanitize("alignment")))
# define NO_ASAN #endif
#ifndef ASAN_NO_ADDR
# define ASAN_NO_ADDR
#endif
#ifndef UBSAN_NO_ALIGN
# define UBSAN_NO_ALIGN
#endif #endif
#if ASAN_ENABLED #if ASAN_ENABLED
@@ -1001,6 +1009,13 @@ internal F32 sign_from_side_F32(Side side);
internal B32 memory_is_zero(void *ptr, U64 size); internal B32 memory_is_zero(void *ptr, U64 size);
internal void memory_write32(void *ptr, U32 v);
internal U8 memory_read8(void *ptr);
internal U16 memory_read16(void *ptr);
internal U32 memory_read32(void *ptr);
internal U64 memory_read64(void *ptr);
//////////////////////////////// ////////////////////////////////
//~ rjf: Text 2D Coordinate/Range Functions //~ rjf: Text 2D Coordinate/Range Functions
+1 -1
View File
@@ -29,7 +29,7 @@ cv_numeric_from_data_range(U8 *first, U8 *opl)
CV_NumericParsed result = {0}; CV_NumericParsed result = {0};
if(first + 2 <= opl) if(first + 2 <= opl)
{ {
U16 x = *(U16*)first; U16 x = memory_read16(first);
if(x < 0x8000) if(x < 0x8000)
{ {
result.kind = CV_NumericKind_USHORT; result.kind = CV_NumericKind_USHORT;
@@ -447,7 +447,7 @@ fp_metrics_from_font(FP_Handle handle)
return result; return result;
} }
fp_hook NO_ASAN FP_RasterResult fp_hook ASAN_NO_ADDR FP_RasterResult
fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, String8 string) fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, String8 string)
{ {
ProfBeginFunction(); ProfBeginFunction();
+1 -1
View File
@@ -54,6 +54,6 @@ fp_hook FP_Handle fp_font_open(String8 path);
fp_hook FP_Handle fp_font_open_from_static_data_string(String8 *data_ptr); fp_hook FP_Handle fp_font_open_from_static_data_string(String8 *data_ptr);
fp_hook void fp_font_close(FP_Handle handle); fp_hook void fp_font_close(FP_Handle handle);
fp_hook FP_Metrics fp_metrics_from_font(FP_Handle font); fp_hook FP_Metrics fp_metrics_from_font(FP_Handle font);
fp_hook NO_ASAN FP_RasterResult fp_raster(Arena *arena, FP_Handle font, F32 size, FP_RasterFlags flags, String8 string); fp_hook ASAN_NO_ADDR FP_RasterResult fp_raster(Arena *arena, FP_Handle font, F32 size, FP_RasterFlags flags, String8 string);
#endif // FONT_PROVIDER_H #endif // FONT_PROVIDER_H
+3 -3
View File
@@ -238,9 +238,9 @@ bit_array_set_bit32(U32Array bit_array, U64 idx, B32 state)
U64 word_idx = idx / 32; U64 word_idx = idx / 32;
U64 bit_idx = idx % 32; U64 bit_idx = idx % 32;
if (state) { if (state) {
bit_array.v[word_idx] |= (1 << bit_idx); bit_array.v[word_idx] |= (1u << bit_idx);
} else { } else {
bit_array.v[word_idx] &= ~(1 << bit_idx); bit_array.v[word_idx] &= ~(1u << bit_idx);
} }
} }
@@ -269,7 +269,7 @@ bit_array_is_bit_set(U32Array bit_arr, U64 bit_pos)
Assert(word_idx < bit_arr.count); Assert(word_idx < bit_arr.count);
U32 word = bit_arr.v[word_idx]; U32 word = bit_arr.v[word_idx];
U64 bit_idx = bit_pos % 32; U64 bit_idx = bit_pos % 32;
B32 is_set = !!(word & (1 << bit_idx)); B32 is_set = !!(word & (1u << bit_idx));
return is_set; return is_set;
} }
+24 -21
View File
@@ -170,17 +170,18 @@ cv_deserial_leaf(String8 raw_data, U64 off, U64 align, CV_Leaf *leaf_out)
// do we have enough bytes to read header? // do we have enough bytes to read header?
Assert(raw_data.size >= sizeof(CV_LeafHeader)); Assert(raw_data.size >= sizeof(CV_LeafHeader));
CV_LeafHeader *header = (CV_LeafHeader*)(raw_data.str + off); StaticAssert(sizeof(CV_LeafHeader) == 4, g_leaf_header_size_check);
CV_LeafHeader header = { .v = memory_read32(raw_data.str + off) };
// leaf size must have enough bytes for the kind enum // leaf size must have enough bytes for the kind enum
Assert(header->size >= sizeof(CV_LeafKind)); Assert(header.size >= sizeof(CV_LeafKind));
// do we have enough bytes to read leaf data? // do we have enough bytes to read leaf data?
Assert(sizeof(CV_LeafSize) + header->size <= raw_data.size); Assert(sizeof(CV_LeafSize) + header.size <= raw_data.size);
// fill out leaf // fill out leaf
leaf_out->kind = header->kind; leaf_out->kind = header.kind;
leaf_out->data = str8(raw_data.str + sizeof(CV_LeafHeader), header->size - sizeof(CV_LeafKind)); leaf_out->data = str8(raw_data.str + sizeof(CV_LeafHeader), header.size - sizeof(CV_LeafKind));
U64 leaf_size = AlignPow2(sizeof(CV_LeafHeader) + leaf_out->data.size, align); U64 leaf_size = AlignPow2(sizeof(CV_LeafHeader) + leaf_out->data.size, align);
Assert(leaf_size <= raw_data.size); Assert(leaf_size <= raw_data.size);
@@ -449,12 +450,20 @@ cv_parse_debug_s_c13_list(Arena *arena, String8List raw_debug_s)
return debug_s; return debug_s;
} }
internal force_inline UBSAN_NO_ALIGN CV_Signature
cv_signature_from_debug_s(String8 raw_debug_s)
{
CV_Signature sig;
MemoryCopy(&sig, raw_debug_s.str, sizeof(sig));
return sig;
}
internal CV_DebugS internal CV_DebugS
cv_parse_debug_s(Arena *arena, String8 raw_debug_s) cv_parse_debug_s(Arena *arena, String8 raw_debug_s)
{ {
CV_DebugS result; MemoryZeroStruct(&result); CV_DebugS result; MemoryZeroStruct(&result);
if (raw_debug_s.size >= sizeof(CV_Signature)) { if (raw_debug_s.size >= sizeof(CV_Signature)) {
CV_Signature sig = *(CV_Signature *)raw_debug_s.str; CV_Signature sig = cv_signature_from_debug_s(raw_debug_s);
switch (sig) { switch (sig) {
case CV_Signature_C13: { case CV_Signature_C13: {
String8 raw_debug_s_past_sig = str8_substr(raw_debug_s, r1u64(sizeof(sig), raw_debug_s.size)); String8 raw_debug_s_past_sig = str8_substr(raw_debug_s, r1u64(sizeof(sig), raw_debug_s.size));
@@ -1130,11 +1139,9 @@ internal String8
cv_debug_t_get_raw_leaf(CV_DebugT debug_t, U64 leaf_idx) cv_debug_t_get_raw_leaf(CV_DebugT debug_t, U64 leaf_idx)
{ {
Assert(leaf_idx < debug_t.count); Assert(leaf_idx < debug_t.count);
U8 *leaf_ptr = debug_t.v[leaf_idx]; U8 *leaf_ptr = debug_t.v[leaf_idx];
CV_LeafSize *size_ptr = (CV_LeafSize *)leaf_ptr; CV_LeafSize size = memory_read16(debug_t.v[leaf_idx]);
CV_LeafSize total_size = sizeof(*size_ptr) + *size_ptr; return str8(leaf_ptr, sizeof(size) + size);
String8 raw_leaf = str8(leaf_ptr, total_size);
return raw_leaf;
} }
internal CV_LeafHeader * internal CV_LeafHeader *
@@ -1474,19 +1481,16 @@ cv_symbol_tree_from_symbol_list(Arena *arena, CV_SymbolList list)
internal U64 internal U64
cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align) cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align)
{ {
Temp scratch = scratch_begin(0, 0);
struct Stack { struct Stack {
struct Stack *next; struct Stack *next;
CV_Symbol *symbol; CV_Symbol *symbol;
U64 offset; U64 offset;
}; };
Temp scratch = scratch_begin(0, 0);
struct Stack *stack = 0; struct Stack *stack = 0;
struct Stack *free_list = 0; struct Stack *free_list = 0;
U32 cursor = safe_cast_u32(base_offset);
U64 cursor = base_offset; for EachNode(symbol_n, CV_SymbolNode, list.first) {
for (CV_SymbolNode *symbol_n = list.first; symbol_n != 0; symbol_n = symbol_n->next) {
CV_Symbol symbol = symbol_n->data; CV_Symbol symbol = symbol_n->data;
if (cv_is_scope_symbol(symbol.kind)) { if (cv_is_scope_symbol(symbol.kind)) {
// NOTE: We don't patch 'next' offset in PROC symbols because // NOTE: We don't patch 'next' offset in PROC symbols because
@@ -1494,10 +1498,9 @@ cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align)
// zeroed. LLD is on the same page. // zeroed. LLD is on the same page.
Assert(symbol.data.size >= sizeof(U32)*2); Assert(symbol.data.size >= sizeof(U32)*2);
// patch symbol parent // patch parent symbol offset
if (stack) { if (stack) {
U32 *parent_off_ptr = (U32 *)symbol.data.str; memory_write32(symbol.data.str, stack->offset);
*parent_off_ptr = stack->offset;
} }
// reuse/alloc frame // reuse/alloc frame
@@ -1516,7 +1519,7 @@ cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align)
} else if (cv_is_end_symbol(symbol.kind)) { } else if (cv_is_end_symbol(symbol.kind)) {
// patch symbol end // patch symbol end
U32 *end_off_ptr = (U32 *)stack->symbol->data.str + /* skip parent off */ 1; U32 *end_off_ptr = (U32 *)stack->symbol->data.str + /* skip parent off */ 1;
*end_off_ptr = cursor; memory_write32(end_off_ptr, cursor);
// recycle frame // recycle frame
struct Stack *free_frame = stack; struct Stack *free_frame = stack;
+7 -3
View File
@@ -5,10 +5,13 @@
//- Symbol and Leaf Headers //- Symbol and Leaf Headers
typedef struct CV_LeafHeader typedef union CV_LeafHeader
{ {
CV_LeafSize size; struct {
CV_LeafKind kind; CV_LeafSize size;
CV_LeafKind kind;
};
U32 v;
} CV_LeafHeader; } CV_LeafHeader;
typedef struct CV_SymbolHeader typedef struct CV_SymbolHeader
@@ -404,6 +407,7 @@ internal CV_SymbolList cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_Symb
internal CV_DebugS cv_parse_debug_s_c13(Arena *arena, String8 raw_debug_s); internal CV_DebugS cv_parse_debug_s_c13(Arena *arena, String8 raw_debug_s);
internal CV_DebugS cv_parse_debug_s_c13_list(Arena *arena, String8List raw_debug_s); internal CV_DebugS cv_parse_debug_s_c13_list(Arena *arena, String8List raw_debug_s);
internal CV_Signature cv_signature_from_debug_s(String8 raw_debug_s);
internal CV_DebugS cv_parse_debug_s(Arena *arena, String8 raw_debug_s); internal CV_DebugS cv_parse_debug_s(Arena *arena, String8 raw_debug_s);
internal void cv_debug_s_concat_in_place(CV_DebugS *dst, CV_DebugS *src); internal void cv_debug_s_concat_in_place(CV_DebugS *dst, CV_DebugS *src);
internal String8List cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig); internal String8List cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig);
+10 -7
View File
@@ -1635,9 +1635,10 @@ lnk_link_inputs(TP_Context *tp,
LNK_Lib *lib = member_ref->lib; LNK_Lib *lib = member_ref->lib;
LNK_Symbol *link_symbol = member_ref->link_symbol; LNK_Symbol *link_symbol = member_ref->link_symbol;
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_ref->member_idx]); U32 member_offset = memory_read32(lib->member_offsets + member_ref->member_idx);
COFF_DataType member_type = coff_data_type_from_data(member_info.data); COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, member_offset);
String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name); COFF_DataType member_type = coff_data_type_from_data(member_info.data);
String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name);
U64 refs_count = 0; U64 refs_count = 0;
LNK_ObjSymbolRef **refs = lnk_ref_from_symbol_many(temp.arena, link_symbol, &refs_count); LNK_ObjSymbolRef **refs = lnk_ref_from_symbol_many(temp.arena, link_symbol, &refs_count);
@@ -1656,9 +1657,10 @@ lnk_link_inputs(TP_Context *tp,
U64 member_idx = member_ref->member_idx; U64 member_idx = member_ref->member_idx;
// parse member info // parse member info
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_idx]); U32 member_offset = memory_read32(lib->member_offsets + member_idx);
COFF_DataType member_type = coff_data_type_from_data(member_info.data); COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, member_offset);
String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name); COFF_DataType member_type = coff_data_type_from_data(member_info.data);
String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name);
switch (member_type) { switch (member_type) {
case COFF_DataType_Import: { case COFF_DataType_Import: {
@@ -1809,7 +1811,8 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
LNK_LibMemberInfo *member_infos = hash_table_search_raw_raw(link->lib_member_infos_ht, lib); LNK_LibMemberInfo *member_infos = hash_table_search_raw_raw(link->lib_member_infos_ht, lib);
LNK_Symbol *link_symbol = member_infos[member_idx].link; LNK_Symbol *link_symbol = member_infos[member_idx].link;
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_idx]); U32 member_offset = memory_read32(lib->member_offsets + member_idx);
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, member_offset);
COFF_DataType member_type = coff_data_type_from_data(member_info.data); COFF_DataType member_type = coff_data_type_from_data(member_info.data);
String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name); String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name);
COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(member_info.data); COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(member_info.data);
+44 -38
View File
@@ -80,8 +80,8 @@ THREAD_POOL_TASK_FUNC(lnk_check_debug_t_sig_and_get_data_task)
lnk_error_obj(LNK_Error_IllData, obj, ".debug$T must have at least 4 bytes for CodeView signature"); lnk_error_obj(LNK_Error_IllData, obj, ".debug$T must have at least 4 bytes for CodeView signature");
} }
CV_Signature *sig_ptr = (CV_Signature *)data_ptr->str; CV_Signature sig = cv_signature_from_debug_s(*data_ptr);
switch (*sig_ptr) { switch (sig) {
default: { default: {
lnk_error_obj(LNK_Warning_IllData, obj, "unknown CodeView type signature in section (TODO: print section index)"); lnk_error_obj(LNK_Warning_IllData, obj, "unknown CodeView type signature in section (TODO: print section index)");
*data_ptr = str8(0,0); *data_ptr = str8(0,0);
@@ -1172,7 +1172,7 @@ lnk_hash_cv_leaf(Arena *arena,
// mix-in sub leaf hashes // mix-in sub leaf hashes
for (CV_TypeIndexInfo *ti_n = ti_info_list.first; ti_n != 0; ti_n = ti_n->next) { for (CV_TypeIndexInfo *ti_n = ti_info_list.first; ti_n != 0; ti_n = ti_n->next) {
CV_TypeIndex sub_ti = *(CV_TypeIndex *) (leaf.data.str + ti_n->offset); CV_TypeIndex sub_ti = memory_read32(leaf.data.str + ti_n->offset);
// is type index complex? // is type index complex?
if (sub_ti >= ti_ranges[ti_n->source].min) { if (sub_ti >= ti_ranges[ti_n->source].min) {
@@ -1278,12 +1278,13 @@ lnk_hash_cv_leaf_deep(Arena *arena,
// get type index info // get type index info
CV_TypeIndex *ti_ptr = (CV_TypeIndex *) (stack->data.str + curr_ti_info->offset); CV_TypeIndex *ti_ptr = (CV_TypeIndex *) (stack->data.str + curr_ti_info->offset);
CV_TypeIndex ti = memory_read32(ti_ptr);
// is index complex? // is index complex?
if (*ti_ptr >= ti_ranges[curr_ti_info->source].min) { if (ti >= ti_ranges[curr_ti_info->source].min) {
// TODO: handle malformed index // TODO: handle malformed index
AssertAlways(*ti_ptr < ti_ranges[curr_ti_info->source].max); AssertAlways(ti < ti_ranges[curr_ti_info->source].max);
U64 ti_idx = (*ti_ptr - ti_ranges[curr_ti_info->source].min); U64 ti_idx = (ti - ti_ranges[curr_ti_info->source].min);
// was leaf hashed? // was leaf hashed?
if (curr_hashes[curr_ti_info->source][ti_idx] == 0) { // :zero_hash_array if (curr_hashes[curr_ti_info->source][ti_idx] == 0) { // :zero_hash_array
@@ -1301,7 +1302,7 @@ lnk_hash_cv_leaf_deep(Arena *arena,
frame->ti_info = sub_ti_info_list.first; frame->ti_info = sub_ti_info_list.first;
frame->leaf = leaf; frame->leaf = leaf;
frame->data = leaf.data; frame->data = leaf.data;
frame->ti = *ti_ptr; frame->ti = ti;
frame->ti_source = curr_ti_info->source; frame->ti_source = curr_ti_info->source;
// recurse to sub leaf // recurse to sub leaf
@@ -1443,7 +1444,8 @@ THREAD_POOL_TASK_FUNC(lnk_count_per_source_leaf_task)
CV_DebugT debug_t = *leaf_range->debug_t; CV_DebugT debug_t = *leaf_range->debug_t;
for EachInRange(leaf_idx, leaf_range->range) { for EachInRange(leaf_idx, leaf_range->range) {
CV_LeafHeader *leaf_header = cv_debug_t_get_leaf_header(debug_t, leaf_idx); CV_LeafHeader *leaf_header = cv_debug_t_get_leaf_header(debug_t, leaf_idx);
CV_TypeIndexSource leaf_source = cv_type_index_source_from_leaf_kind(leaf_header->kind); CV_LeafKind kind = memory_read16(MemberFromPtr(CV_LeafHeader, leaf_header, kind));
CV_TypeIndexSource leaf_source = cv_type_index_source_from_leaf_kind(kind);
counts[leaf_source] += 1; counts[leaf_source] += 1;
} }
} }
@@ -1550,7 +1552,8 @@ THREAD_POOL_TASK_FUNC(lnk_leaf_dedup_internal_task)
LNK_LeafRef *bucket = 0; LNK_LeafRef *bucket = 0;
for EachIndex(leaf_idx, debug_t.count) { for EachIndex(leaf_idx, debug_t.count) {
CV_LeafHeader *leaf_header = cv_debug_t_get_leaf_header(debug_t, leaf_idx); CV_LeafHeader *leaf_header = cv_debug_t_get_leaf_header(debug_t, leaf_idx);
CV_TypeIndexSource ti_source = cv_type_index_source_from_leaf_kind(leaf_header->kind); CV_LeafKind leaf_kind = memory_read16(MemberFromPtr(CV_LeafHeader, leaf_header, kind));
CV_TypeIndexSource ti_source = cv_type_index_source_from_leaf_kind(leaf_kind);
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr[ti_source]; LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr[ti_source];
LNK_LeafRef leaf_ref = lnk_obj_leaf_ref(obj_idx, leaf_idx); LNK_LeafRef leaf_ref = lnk_obj_leaf_ref(obj_idx, leaf_idx);
@@ -1974,25 +1977,26 @@ THREAD_POOL_TASK_FUNC(lnk_cv_patcher_symbols_task)
// overwrite type indices in symbol // overwrite type indices in symbol
for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) { for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) {
CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(symbol_n->data.data.str + ti_info->offset); CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(symbol_n->data.data.str + ti_info->offset);
CV_TypeIndex ti = memory_read32(ti_ptr);
// skip simple type indices // skip simple type indices
if (*ti_ptr < ti_lo_arr[ti_info->source]) { continue; } if (ti < ti_lo_arr[ti_info->source]) { continue; }
U64 assigned_types_cap = task->assigned_type_caps[ti_info->source]; U64 assigned_types_cap = task->assigned_type_caps [ti_info->source];
CV_TypeIndex *assigned_types_ht = task->assigned_type_hts[ti_info->source]; CV_TypeIndex *assigned_types_ht = task->assigned_type_hts [ti_info->source];
CV_TypeIndex min_type_index = task->min_type_indices[ti_info->source]; CV_TypeIndex min_type_index = task->min_type_indices [ti_info->source];
LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source]; LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source];
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr [ti_info->source];
// find unique leaf refernece // find unique leaf refernece
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr[ti_info->source]; LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, ti);
LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, *ti_ptr);
LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref); LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref);
U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique)); U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique));
CV_TypeIndex type_index = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash); CV_TypeIndex final_ti = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash);
// we overwrite section memory directly // we overwrite section memory directly
*ti_ptr = type_index; memory_write32(ti_ptr, final_ti);
} }
temp_end(temp); temp_end(temp);
@@ -2022,26 +2026,27 @@ THREAD_POOL_TASK_FUNC(lnk_cv_patcher_inlines_task)
for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) { for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) {
CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(inline_data_node->string.str + ti_info->offset); CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(inline_data_node->string.str + ti_info->offset);
CV_TypeIndex ti_lo = lnk_ti_lo_from_loc(task->input, loc_type, loc_idx, ti_info->source); CV_TypeIndex ti = memory_read32(ti_ptr);
// skip simple type indices // skip simple type indices
if (*ti_ptr < ti_lo) { continue; } CV_TypeIndex ti_lo = lnk_ti_lo_from_loc(task->input, loc_type, loc_idx, ti_info->source);
if (ti < ti_lo) { continue; }
U64 assigned_types_cap = task->assigned_type_caps[ti_info->source]; U64 assigned_types_cap = task->assigned_type_caps [ti_info->source];
CV_TypeIndex *assigned_types_ht = task->assigned_type_hts[ti_info->source]; CV_TypeIndex *assigned_types_ht = task->assigned_type_hts [ti_info->source];
CV_TypeIndex min_type_index = task->min_type_indices[ti_info->source]; CV_TypeIndex min_type_index = task->min_type_indices [ti_info->source];
LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source]; LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source];
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr [ti_info->source];
// find unique leaf refernece // find unique leaf refernece
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr[ti_info->source]; LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, ti);
LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, *ti_ptr);
LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref); LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref);
U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique)); U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique));
CV_TypeIndex type_index = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash); CV_TypeIndex final_ti = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash);
// patch index // patch index
*ti_ptr = type_index; memory_write32(ti_ptr, final_ti);
} }
temp_end(temp); temp_end(temp);
@@ -2074,25 +2079,26 @@ THREAD_POOL_TASK_FUNC(lnk_cv_patcher_leaves_task)
for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) { for EachNode(ti_info, CV_TypeIndexInfo, ti_info_list.first) {
CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(leaf.data.str + ti_info->offset); CV_TypeIndex *ti_ptr = (CV_TypeIndex *)(leaf.data.str + ti_info->offset);
CV_TypeIndex ti = memory_read32(ti_ptr);
// skip simple type indices // skip simple type indices
if (*ti_ptr < ti_lo) { continue; } if (ti < ti_lo) { continue; }
U64 assigned_types_cap = task->assigned_type_caps[ti_info->source]; U64 assigned_types_cap = task->assigned_type_caps [ti_info->source];
CV_TypeIndex *assigned_types_ht = task->assigned_type_hts[ti_info->source]; CV_TypeIndex *assigned_types_ht = task->assigned_type_hts [ti_info->source];
CV_TypeIndex min_type_index = task->min_type_indices[ti_info->source]; CV_TypeIndex min_type_index = task->min_type_indices [ti_info->source];
LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source]; LNK_LeafRefArray unique_leaf_refs = task->unique_leaf_refs_arr[ti_info->source];
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr [ti_info->source];
// find unique leaf refernece // find unique leaf ref
LNK_LeafHashTable *leaf_ht = &task->leaf_ht_arr[ti_info->source]; LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, ti);
LNK_LeafRef leaf_ref = lnk_leaf_ref_from_loc_idx_and_ti(task->input, loc_type, ti_info->source, loc_idx, *ti_ptr);
LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref); LNK_LeafRef *leaf_ref_unique = lnk_leaf_hash_table_search(leaf_ht, task->input, task->hashes, leaf_ref);
U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique)); U64 leaf_ref_unique_hash = u64_hash_from_str8(str8_struct(&leaf_ref_unique));
CV_TypeIndex type_index = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash); CV_TypeIndex final_ti = lnk_assigned_type_ht_search(assigned_types_cap, assigned_types_ht, min_type_index, unique_leaf_refs, leaf_ref_unique, leaf_ref_unique_hash);
// patch index // patch index
*ti_ptr = type_index; memory_write32(ti_ptr, final_ti);
} }
temp_end(temp); temp_end(temp);
+2 -2
View File
@@ -69,8 +69,8 @@ typedef enum
LNK_LeafLocType_Count LNK_LeafLocType_Count
} LNK_LeafLocType; } LNK_LeafLocType;
#define LNK_LeafRefFlag_LocIdxExternal (1 << 31) #define LNK_LeafRefFlag_LocIdxExternal (1u << 31)
#define LNK_LeafRefFlag_LeafIdxIPI (1 << 31) #define LNK_LeafRefFlag_LeafIdxIPI (1u << 31)
typedef struct typedef struct
{ {
U32 enc_loc_idx; U32 enc_loc_idx;
+1 -1
View File
@@ -66,5 +66,5 @@ internal LNK_Lib ** lnk_array_from_lib_list(Arena *arena, LNK_LibList list
internal void lnk_lib_list_push_node(LNK_LibList *list, LNK_LibNode *node); internal void lnk_lib_list_push_node(LNK_LibList *list, LNK_LibNode *node);
internal LNK_LibNodeArray lnk_lib_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_LibList *list, U64 inputs_count, struct LNK_Input **inputs); internal LNK_LibNodeArray lnk_lib_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_LibList *list, U64 inputs_count, struct LNK_Input **inputs);
internal B32 lnk_search_lib(LNK_Lib *lib, String8 symbol_name, U32 *member_idx_out); internal force_inline B32 lnk_search_lib(LNK_Lib *lib, String8 symbol_name, U32 *member_idx_out);
+1 -1
View File
@@ -2384,7 +2384,7 @@ gsi_build_ex(TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 symbol_data_
if (bucket_list.count) { if (bucket_list.count) {
U64 word_idx = bucket_idx / gsi->word_size; U64 word_idx = bucket_idx / gsi->word_size;
Assert(word_idx < bitmap_count); Assert(word_idx < bitmap_count);
bitmap[word_idx] |= 1 << (bucket_idx % gsi->word_size); bitmap[word_idx] |= 1u << (bucket_idx % gsi->word_size);
compressed_offset_arr[compressed_offset_count] = hash_idx * sizeof(PDB_GsiHashRecordOffsetCalc); // store in-memory offset for first bucket compressed_offset_arr[compressed_offset_count] = hash_idx * sizeof(PDB_GsiHashRecordOffsetCalc); // store in-memory offset for first bucket
compressed_offset_count += 1; compressed_offset_count += 1;
} }
+4 -4
View File
@@ -290,9 +290,9 @@ CheckNil(nil,p) ? \
#if COMPILER_MSVC #if COMPILER_MSVC
# if defined(__SANITIZE_ADDRESS__) # if defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1 # define ASAN_ENABLED 1
# define NO_ASAN __declspec(no_sanitize_address) # define ASAN_NO_ADDR __declspec(no_sanitize_address)
# else # else
# define NO_ASAN # define ASAN_NO_ADDR
# endif # endif
#elif COMPILER_CLANG #elif COMPILER_CLANG
# if defined(__has_feature) # if defined(__has_feature)
@@ -300,9 +300,9 @@ CheckNil(nil,p) ? \
# define ASAN_ENABLED 1 # define ASAN_ENABLED 1
# endif # endif
# endif # endif
# define NO_ASAN __attribute__((no_sanitize("address"))) # define ASAN_NO_ADDR __attribute__((no_sanitize("address")))
#else #else
# define NO_ASAN # define ASAN_NO_ADDR
#endif #endif
#if ASAN_ENABLED #if ASAN_ENABLED
+6 -7
View File
@@ -6,18 +6,17 @@ pdb_hash_v1(String8 string)
{ {
U32 result = 0; U32 result = 0;
U8 *ptr = string.str; U8 *ptr = string.str;
U8 *opl = ptr + (string.size&(~3)); for(U8 *opl = ptr + (string.size & (~3)); ptr < opl; ptr += 4)
for(; ptr < opl; ptr += 4)
{ {
result ^= *(U32*)ptr; result ^= memory_read32(ptr);
} }
if((string.size&2) != 0) if((string.size & 2) != 0)
{ {
result ^= *(U16*)ptr; ptr += 2; result ^= memory_read16(ptr); ptr += 2;
} }
if((string.size&1) != 0) if((string.size & 1) != 0)
{ {
result ^= *ptr; result ^= memory_read8(ptr);
} }
result |= 0x20202020; result |= 0x20202020;
result ^= (result >> 11); result ^= (result >> 11);
+1 -1
View File
@@ -436,7 +436,7 @@ cl = lg; \
} else } else
#endif #endif
{ {
*(stbsp__uint32 *)bf = v; memory_write32(bf, v);
} }
bf += 4; bf += 4;
f += 4; f += 4;