From db35e09629d98d5ba983a43f42e25ad8f82adb17 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 Feb 2024 15:36:06 -0800 Subject: [PATCH] raddbgic -> rdim (rad debug info make) --- src/lib_raddbgi_cons/raddbgi_cons.c | 3673 ----------------- src/lib_raddbgi_cons/raddbgi_cons.h | 1303 ------ src/lib_raddbgi_make/raddbgi_make.c | 3673 +++++++++++++++++ src/lib_raddbgi_make/raddbgi_make.h | 1303 ++++++ src/raddbg/raddbg.c | 2 +- src/raddbg/raddbg_main.cpp | 4 +- src/raddbgi_cons_local/raddbgi_cons_local.h | 46 - src/raddbgi_from_pdb/raddbgi_from_pdb.c | 416 +- src/raddbgi_from_pdb/raddbgi_from_pdb.h | 54 +- src/raddbgi_from_pdb/raddbgi_from_pdb_main.c | 2 +- .../raddbgi_make_local.c} | 2 +- src/raddbgi_make_local/raddbgi_make_local.h | 46 + 12 files changed, 5262 insertions(+), 5262 deletions(-) delete mode 100644 src/lib_raddbgi_cons/raddbgi_cons.c delete mode 100644 src/lib_raddbgi_cons/raddbgi_cons.h create mode 100644 src/lib_raddbgi_make/raddbgi_make.c create mode 100644 src/lib_raddbgi_make/raddbgi_make.h delete mode 100644 src/raddbgi_cons_local/raddbgi_cons_local.h rename src/{raddbgi_cons_local/raddbgi_cons_local.c => raddbgi_make_local/raddbgi_make_local.c} (72%) create mode 100644 src/raddbgi_make_local/raddbgi_make_local.h diff --git a/src/lib_raddbgi_cons/raddbgi_cons.c b/src/lib_raddbgi_cons/raddbgi_cons.c deleted file mode 100644 index 51fddf42..00000000 --- a/src/lib_raddbgi_cons/raddbgi_cons.c +++ /dev/null @@ -1,3673 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: API Implementation Helper Macros - -#define raddbgic_require(root, b32, else_code, error_msg) do { if(!(b32)) {raddbgic_push_error((root), (error_msg)); else_code;} }while(0) -#define raddbgic_requiref(root, b32, else_code, fmt, ...) do { if(!(b32)) {raddbgic_push_errorf((root), (fmt), __VA_ARGS__); else_code;} }while(0) - -//////////////////////////////// -//~ rjf: Basic Helpers - -//- rjf: memory set - -#if !defined(RADDBGIC_MEMSET_OVERRIDE) -RADDBGI_PROC void * -raddbgic_memset_fallback(void *dst, RADDBGI_U8 c, RADDBGI_U64 size) -{ - for(RADDBGI_U64 idx = 0; idx < size; idx += 1) - { - ((RADDBGI_U8 *)dst)[idx] = c; - } - return dst; -} -#endif - -#if !defined(RADDBGIC_MEMCPY_OVERRIDE) -RADDBGI_PROC void * -raddbgic_memcpy_fallback(void *dst, void *src, RADDBGI_U64 size) -{ - for(RADDBGI_U64 idx = 0; idx < size; idx += 1) - { - ((RADDBGI_U8 *)dst)[idx] = ((RADDBGI_U8 *)src)[idx]; - } - return dst; -} -#endif - -//- rjf: arenas - -#if !defined (RADDBGIC_ARENA_OVERRIDE) - -RADDBGI_PROC RADDBGIC_Arena * -raddbgic_arena_alloc_fallback(void) -{ - RADDBGIC_Arena *arena = 0; - return arena; -} - -RADDBGI_PROC void -raddbgic_arena_release_fallback(RADDBGIC_Arena *arena) -{ - -} - -RADDBGI_PROC RADDBGI_U64 -raddbgic_arena_pos_fallback(RADDBGIC_Arena *arena) -{ - return 0; -} - -RADDBGI_PROC void * -raddbgic_arena_push_fallback(RADDBGIC_Arena *arena, RADDBGI_U64 size) -{ - return 0; -} - -RADDBGI_PROC void -raddbgic_arena_pop_to_fallback(RADDBGIC_Arena *arena, RADDBGI_U64 pos) -{ - -} - -#endif - -//- rjf: thread-local scratch arenas - -#if !defined (RADDBGIC_SCRATCH_OVERRIDE) -static RADDBGIC_THREAD_LOCAL RADDBGIC_Arena *raddbgic_thread_scratches[2]; - -RADDBGI_PROC RADDBGIC_Temp -raddbgic_scratch_begin_fallback(RADDBGIC_Arena **conflicts, RADDBGI_U64 conflicts_count) -{ - if(raddbgic_thread_scratches[0] == 0) - { - raddbgic_thread_scratches[0] = raddbgic_arena_alloc(); - raddbgic_thread_scratches[1] = raddbgic_arena_alloc(); - } - RADDBGIC_Arena *arena = 0; - for(RADDBGI_U64 scratch_idx = 0; - scratch_idx < sizeof(raddbgic_thread_scratches)/sizeof(raddbgic_thread_scratches[0]); - scratch_idx += 1) - { - RADDBGI_S32 scratch_conflicts = 0; - for(RADDBGI_U64 conflict_idx = 0; conflict_idx < conflicts_count; conflict_idx += 1) - { - if(conflicts[conflict_idx] == raddbgic_thread_scratches[scratch_idx]) - { - scratch_conflicts = 1; - break; - } - } - if(!scratch_conflicts) - { - arena = raddbgic_thread_scratches[scratch_idx]; - } - } - RADDBGIC_Temp temp; - temp.arena = arena; - temp.pos = raddbgic_arena_pos(arena); - return temp; -} - -RADDBGI_PROC void -raddbgic_scratch_end_fallback(RADDBGIC_Temp temp) -{ - raddbgic_arena_pop_to(temp.arena, temp.pos); -} - -#endif - -//- rjf: strings - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_str8(RADDBGI_U8 *str, RADDBGI_U64 size) -{ - RADDBGIC_String8 result; - result.RADDBGIC_String8_BaseMember = str; - result.RADDBGIC_String8_SizeMember = size; - return result; -} - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_str8_copy(RADDBGIC_Arena *arena, RADDBGIC_String8 src) -{ - RADDBGIC_String8 dst; - dst.RADDBGIC_String8_SizeMember = src.RADDBGIC_String8_SizeMember; - dst.RADDBGIC_String8_BaseMember = raddbgic_push_array_no_zero(arena, RADDBGI_U8, dst.RADDBGIC_String8_SizeMember+1); - raddbgic_memcpy(dst.RADDBGIC_String8_BaseMember, src.RADDBGIC_String8_BaseMember, src.RADDBGIC_String8_SizeMember); - dst.RADDBGIC_String8_BaseMember[dst.RADDBGIC_String8_SizeMember] = 0; - return dst; -} - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_str8f(RADDBGIC_Arena *arena, char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - RADDBGIC_String8 result = raddbgic_str8fv(arena, fmt, args); - va_end(args); - return(result); -} - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_str8fv(RADDBGIC_Arena *arena, char *fmt, va_list args) -{ - va_list args2; - va_copy(args2, args); - RADDBGI_U32 needed_bytes = raddbgic_vsnprintf(0, 0, fmt, args) + 1; - RADDBGIC_String8 result = {0}; - result.RADDBGIC_String8_BaseMember = raddbgic_push_array_no_zero(arena, RADDBGI_U8, needed_bytes); - result.RADDBGIC_String8_SizeMember = raddbgic_vsnprintf((char*)result.str, needed_bytes, fmt, args2); - result.RADDBGIC_String8_BaseMember[result.RADDBGIC_String8_SizeMember] = 0; - va_end(args2); - return(result); -} - -RADDBGI_PROC RADDBGI_S32 -raddbgic_str8_match(RADDBGIC_String8 a, RADDBGIC_String8 b, RADDBGIC_StringMatchFlags flags) -{ - RADDBGI_S32 result = 0; - if(a.RADDBGIC_String8_SizeMember == b.RADDBGIC_String8_SizeMember) - { - RADDBGI_S32 case_insensitive = (flags & RADDBGIC_StringMatchFlag_CaseInsensitive); - RADDBGI_U64 size = a.RADDBGIC_String8_SizeMember; - result = 1; - for(RADDBGI_U64 idx = 0; idx < size; idx += 1) - { - RADDBGI_U8 at = a.RADDBGIC_String8_BaseMember[idx]; - RADDBGI_U8 bt = b.RADDBGIC_String8_BaseMember[idx]; - if(case_insensitive) - { - at = ('a' <= at && at <= 'z') ? at-('a'-'A') : at; - bt = ('a' <= bt && bt <= 'z') ? bt-('a'-'A') : bt; - } - if(at != bt) - { - result = 0; - break; - } - } - } - return result; -} - -//- rjf: string lists - -RADDBGI_PROC void -raddbgic_str8_list_push(RADDBGIC_Arena *arena, RADDBGIC_String8List *list, RADDBGIC_String8 string) -{ - RADDBGIC_String8Node *n = raddbgic_push_array(arena, RADDBGIC_String8Node, 1); - n->RADDBGIC_String8Node_StringMember = string; - RADDBGIC_SLLQueuePush_N(list->RADDBGIC_String8List_FirstMember, list->RADDBGIC_String8List_LastMember, n, RADDBGIC_String8Node_NextPtrMember); - list->RADDBGIC_String8List_NodeCountMember += 1; - list->RADDBGIC_String8List_TotalSizeMember += string.RADDBGIC_String8_SizeMember; -} - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_str8_list_join(RADDBGIC_Arena *arena, RADDBGIC_String8List *list, RADDBGIC_String8 sep) -{ - RADDBGIC_String8 result; - raddbgic_memzero_struct(&result); - RADDBGI_U64 sep_count = (list->RADDBGIC_String8List_NodeCountMember > 1) ? (list->RADDBGIC_String8List_NodeCountMember-1) : 0; - result.RADDBGIC_String8_SizeMember = list->RADDBGIC_String8List_TotalSizeMember+sep_count*sep.RADDBGIC_String8_SizeMember; - result.RADDBGIC_String8_BaseMember = raddbgic_push_array_no_zero(arena, RADDBGI_U8, result.RADDBGIC_String8_SizeMember+1); - RADDBGI_U64 off = 0; - for(RADDBGIC_String8Node *node = list->RADDBGIC_String8List_FirstMember; - node != 0; - node = node->RADDBGIC_String8Node_NextPtrMember) - { - raddbgic_memcpy((RADDBGI_U8*)result.RADDBGIC_String8_BaseMember+off, - node->RADDBGIC_String8Node_StringMember.RADDBGIC_String8_BaseMember, - node->RADDBGIC_String8Node_StringMember.RADDBGIC_String8_SizeMember); - off += node->RADDBGIC_String8Node_StringMember.RADDBGIC_String8_SizeMember; - if(sep.RADDBGIC_String8_SizeMember != 0 && node->RADDBGIC_String8Node_NextPtrMember != 0) - { - raddbgic_memcpy((RADDBGI_U8*)result.RADDBGIC_String8_BaseMember+off, - sep.RADDBGIC_String8_BaseMember, - sep.RADDBGIC_String8_SizeMember); - off += sep.RADDBGIC_String8_SizeMember; - } - } - result.RADDBGIC_String8_BaseMember[off] = 0; - return result; -} - -//- rjf: type lists - -RADDBGI_PROC void -raddbgic_type_list_push(RADDBGIC_Arena *arena, RADDBGIC_TypeList *list, RADDBGIC_Type *type) -{ - RADDBGIC_TypeNode *node = raddbgic_push_array(arena, RADDBGIC_TypeNode, 1); - RADDBGIC_SLLQueuePush(list->first, list->last, node); - list->count += 1; - node->type = type; -} - -//- rjf: bytecode lists - -RADDBGI_PROC void -raddbgic_bytecode_push_op(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_EvalOp op, RADDBGI_U64 p) -{ - RADDBGI_U8 ctrlbits = raddbgi_eval_opcode_ctrlbits[op]; - RADDBGI_U32 p_size = RADDBGI_DECODEN_FROM_CTRLBITS(ctrlbits); - - RADDBGIC_EvalBytecodeOp *node = raddbgic_push_array(arena, RADDBGIC_EvalBytecodeOp, 1); - node->op = op; - node->p_size = p_size; - node->p = p; - - RADDBGIC_SLLQueuePush(bytecode->first_op, bytecode->last_op, node); - bytecode->op_count += 1; - bytecode->encoded_size += 1 + p_size; -} - -RADDBGI_PROC void -raddbgic_bytecode_push_uconst(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_U64 x) -{ - if(x <= 0xFF) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU8, x); - } - else if(x <= 0xFFFF) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU16, x); - } - else if(x <= 0xFFFFFFFF) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU32, x); - } - else - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU64, x); - } -} - -RADDBGI_PROC void -raddbgic_bytecode_push_sconst(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_S64 x) -{ - if(-0x80 <= x && x <= 0x7F) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU8, (RADDBGI_U64)x); - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 8); - } - else if(-0x8000 <= x && x <= 0x7FFF) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU16, (RADDBGI_U64)x); - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 16); - } - else if(-0x80000000ll <= x && x <= 0x7FFFFFFFll) - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU32, (RADDBGI_U64)x); - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 32); - } - else - { - raddbgic_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU64, (RADDBGI_U64)x); - } -} - -RADDBGI_PROC void -raddbgic_bytecode_concat_in_place(RADDBGIC_EvalBytecode *left_dst, RADDBGIC_EvalBytecode *right_destroyed) -{ - if(right_destroyed->first_op != 0) - { - if(left_dst->first_op == 0) - { - raddbgic_memcpy_struct(left_dst, right_destroyed); - } - else - { - left_dst->last_op = right_destroyed->last_op; - left_dst->op_count += right_destroyed->op_count; - left_dst->encoded_size += right_destroyed->encoded_size; - } - raddbgic_memzero_struct(right_destroyed); - } -} - -//- rjf: sortable range sorting - -RADDBGI_PROC RADDBGIC_SortKey* -raddbgic_sort_key_array(RADDBGIC_Arena *arena, RADDBGIC_SortKey *keys, RADDBGI_U64 count) -{ - // This sort is designed to take advantage of lots of pre-existing sorted ranges. - // Most line info is already sorted or close to already sorted. - // Similarly most vmap data has lots of pre-sorted ranges. etc. etc. - // Also - this sort should be a "stable" sort. In the use case of sorting vmap - // ranges, we want to be able to rely on order, so it needs to be preserved here. - - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - RADDBGIC_SortKey *result = 0; - - if(count <= 1) - { - result = keys; - } - else - { - RADDBGIC_OrderedRange *ranges_first = 0; - RADDBGIC_OrderedRange *ranges_last = 0; - RADDBGI_U64 range_count = 0; - { - RADDBGI_U64 pos = 0; - for(;pos < count;) - { - // identify ordered range - RADDBGI_U64 first = pos; - RADDBGI_U64 opl = pos + 1; - for(; opl < count && keys[opl - 1].key <= keys[opl].key; opl += 1); - - // generate an ordered range node - RADDBGIC_OrderedRange *new_range = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGIC_OrderedRange, 1); - SLLQueuePush(ranges_first, ranges_last, new_range); - range_count += 1; - new_range->first = first; - new_range->opl = opl; - - // update pos - pos = opl; - } - } - - if(range_count == 1) - { - result = keys; - } - else - { - RADDBGIC_SortKey *keys_swap = raddbgic_push_array_no_zero(arena, RADDBGIC_SortKey, count); - RADDBGIC_SortKey *src = keys; - RADDBGIC_SortKey *dst = keys_swap; - RADDBGIC_OrderedRange *src_ranges = ranges_first; - RADDBGIC_OrderedRange *dst_ranges = 0; - RADDBGIC_OrderedRange *dst_ranges_last = 0; - - for(;;) - { - // begin a pass - for(;;) - { - // end pass when out of ranges - if(src_ranges == 0) - { - break; - } - - // get first range - RADDBGIC_OrderedRange *range1 = src_ranges; - SLLStackPop(src_ranges); - - // if this range is the whole array, we are done - if(range1->first == 0 && range1->opl == count) - { - result = src; - goto sort_done; - } - - // if there is not a second range, save this range for next time and end this pass - if(src_ranges == 0) - { - RADDBGI_U64 first = range1->first; - raddbgic_memcpy(dst + first, src + first, sizeof(*src)*(range1->opl - first)); - SLLQueuePush(dst_ranges, dst_ranges_last, range1); - break; - } - - // get second range - RADDBGIC_OrderedRange *range2 = src_ranges; - SLLStackPop(src_ranges); - - raddbgic_assert(range1->opl == range2->first); - - // merge these ranges - RADDBGI_U64 jd = range1->first; - RADDBGI_U64 j1 = range1->first; - RADDBGI_U64 j1_opl = range1->opl; - RADDBGI_U64 j2 = range2->first; - RADDBGI_U64 j2_opl = range2->opl; - for(;;) - { - if(src[j1].key <= src[j2].key) - { - raddbgic_memcpy(dst + jd, src + j1, sizeof(*src)); - j1 += 1; - jd += 1; - if(j1 >= j1_opl) - { - break; - } - } - else - { - raddbgic_memcpy(dst + jd, src + j2, sizeof(*src)); - j2 += 1; - jd += 1; - if(j2 >= j2_opl) - { - break; - } - } - } - if(j1 < j1_opl) - { - raddbgic_memcpy(dst + jd, src + j1, sizeof(*src)*(j1_opl - j1)); - } - else - { - raddbgic_memcpy(dst + jd, src + j2, sizeof(*src)*(j2_opl - j2)); - } - - // save this as one range - range1->opl = range2->opl; - SLLQueuePush(dst_ranges, dst_ranges_last, range1); - } - - // end pass by swapping buffers and range nodes - { - RADDBGIC_SortKey *temp = src; - src = dst; - dst = temp; - } - src_ranges = dst_ranges; - dst_ranges = 0; - dst_ranges_last = 0; - } - } - } - sort_done:; - -#if 0 - // assert sortedness - for(RADDBGI_U64 i = 1; i < count; i += 1){ - raddbgic_assert(result[i - 1].key <= result[i].key); - } -#endif - - scratch_end(scratch); - return result; -} - -//////////////////////////////// -//~ rjf: Auxiliary Data Structure Functions - -//- rjf: u64 -> ptr map - -RADDBGI_PROC void -raddbgic_u64toptr_map_init(RADDBGIC_Arena *arena, RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 bucket_count) -{ - raddbgic_assert(IsPow2OrZero(bucket_count) && bucket_count > 0); - map->buckets = raddbgic_push_array(arena, RADDBGIC_U64ToPtrNode*, bucket_count); - map->buckets_count = bucket_count; -} - -RADDBGI_PROC void -raddbgic_u64toptr_map_lookup(RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RADDBGIC_U64ToPtrLookup *lookup_out) -{ - RADDBGI_U64 bucket_idx = hash&(map->buckets_count - 1); - RADDBGIC_U64ToPtrNode *check_node = map->buckets[bucket_idx]; - for(;check_node != 0; check_node = check_node->next){ - for(RADDBGI_U32 k = 0; k < ArrayCount(check_node->key); k += 1){ - if(check_node->ptr[k] == 0){ - lookup_out->fill_node = check_node; - lookup_out->fill_k = k; - break; - } - else if(check_node->key[k] == key){ - lookup_out->match = check_node->ptr[k]; - break; - } - } - } -} - -RADDBGI_PROC void -raddbgic_u64toptr_map_insert(RADDBGIC_Arena *arena, RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RADDBGIC_U64ToPtrLookup *lookup, void *ptr) -{ - if(lookup->fill_node != 0) - { - RADDBGIC_U64ToPtrNode *node = lookup->fill_node; - RADDBGI_U32 k = lookup->fill_k; - node->key[k] = key; - node->ptr[k] = ptr; - } - else - { - RADDBGI_U64 bucket_idx = hash&(map->buckets_count - 1); - - RADDBGIC_U64ToPtrNode *node = raddbgic_push_array(arena, RADDBGIC_U64ToPtrNode, 1); - SLLStackPush(map->buckets[bucket_idx], node); - node->key[0] = key; - node->ptr[0] = ptr; - - lookup->fill_node = node; - lookup->fill_k = 0; - - map->pair_count += 1; - map->bucket_collision_count += (node->next != 0); - } -} - -//- rjf: string8 -> ptr map - -RADDBGI_PROC void -raddbgic_str8toptr_map_init(RADDBGIC_Arena *arena, RADDBGIC_Str8ToPtrMap *map, RADDBGI_U64 bucket_count) -{ - map->buckets_count = bucket_count; - map->buckets = raddbgic_push_array(arena, RADDBGIC_Str8ToPtrNode*, map->buckets_count); -} - -RADDBGI_PROC void* -raddbgic_str8toptr_map_lookup(RADDBGIC_Str8ToPtrMap *map, RADDBGIC_String8 key, RADDBGI_U64 hash) -{ - void *result = 0; - RADDBGI_U64 bucket_idx = hash%map->buckets_count; - for(RADDBGIC_Str8ToPtrNode *node = map->buckets[bucket_idx]; - node != 0; - node = node->next) - { - if(node->hash == hash && raddbgic_str8_match(node->key, key, 0)) - { - result = node->ptr; - break; - } - } - return result; -} - -RADDBGI_PROC void -raddbgic_str8toptr_map_insert(RADDBGIC_Arena *arena, RADDBGIC_Str8ToPtrMap *map, RADDBGIC_String8 key, RADDBGI_U64 hash, void *ptr) -{ - RADDBGI_U64 bucket_idx = hash%map->buckets_count; - RADDBGIC_Str8ToPtrNode *node = raddbgic_push_array(arena, RADDBGIC_Str8ToPtrNode, 1); - SLLStackPush(map->buckets[bucket_idx], node); - - node->key = raddbgic_str8_copy(arena, key); - node->hash = hash; - node->ptr = ptr; - map->bucket_collision_count += (node->next != 0); - map->pair_count += 1; -} - -//////////////////////////////// -//~ rjf: Loose Debug Info Construction (Anything -> Loose) Functions - -//- rjf: root creation - -RADDBGI_PROC RADDBGIC_Root* -raddbgic_root_alloc(RADDBGIC_RootParams *params) -{ - RADDBGIC_Arena *arena = raddbgic_arena_alloc(); - RADDBGIC_Root *result = raddbgic_push_array(arena, RADDBGIC_Root, 1); - result->arena = arena; - - // fill in root parameters - { - result->addr_size = params->addr_size; - } - - // setup singular types - { - result->nil_type = raddbgic_type_new(result); - result->variadic_type = raddbgic_type_new(result); - result->variadic_type->kind = RADDBGI_TypeKind_Variadic; - - // references to "handled nil type" should be emitted as - // references to nil - but should not generate error - // messages when they are detected - they are expected! - raddbgic_assert(result->nil_type->idx == result->handled_nil_type.idx); - } - - // setup a null scope - { - RADDBGIC_Scope *scope = raddbgic_push_array(result->arena, RADDBGIC_Scope, 1); - RADDBGIC_SLLQueuePush_N(result->first_scope, result->last_scope, scope, next_order); - result->scope_count += 1; - } - - // rjf: setup null UDT - { - raddbgic_type_udt_from_any_type(result, result->nil_type); - } - - // initialize maps - { -#define BKTCOUNT(x) ((x)?(u64_up_to_pow2(x)):(128)) - - raddbgic_u64toptr_map_init(arena, &result->unit_map, BKTCOUNT(params->bucket_count_units)); - raddbgic_u64toptr_map_init(arena, &result->symbol_map, BKTCOUNT(params->bucket_count_symbols)); - raddbgic_u64toptr_map_init(arena, &result->scope_map, BKTCOUNT(params->bucket_count_scopes)); - raddbgic_u64toptr_map_init(arena, &result->local_map, BKTCOUNT(params->bucket_count_locals)); - raddbgic_u64toptr_map_init(arena, &result->type_from_id_map, BKTCOUNT(params->bucket_count_types)); - raddbgic_str8toptr_map_init(arena, &result->construct_map, BKTCOUNT(params->bucket_count_type_constructs)); - -#undef BKTCOUNT - } - - return result; -} - -RADDBGI_PROC void -raddbgic_root_release(RADDBGIC_Root *root) -{ - arena_release(root->arena); -} - -//- rjf: error accumulation - -RADDBGI_PROC void -raddbgic_push_error(RADDBGIC_Root *root, RADDBGIC_String8 string) -{ - RADDBGIC_Error *error = raddbgic_push_array(root->arena, RADDBGIC_Error, 1); - SLLQueuePush(root->errors.first, root->errors.last, error); - root->errors.count += 1; - error->msg = string; -} - -RADDBGI_PROC void -raddbgic_push_errorf(RADDBGIC_Root *root, char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - RADDBGIC_String8 str = raddbgic_str8fv(root->arena, fmt, args); - raddbgic_push_error(root, str); - va_end(args); -} - -RADDBGI_PROC RADDBGIC_Error* -raddbgic_first_error_from_root(RADDBGIC_Root *root) -{ - return root->errors.first; -} - -//- rjf: top-level info specification - -RADDBGI_PROC void -raddbgic_set_top_level_info(RADDBGIC_Root *root, RADDBGIC_TopLevelInfo *tli) -{ - raddbgic_requiref(root, !root->top_level_info_is_set, return, "Top level information set multiple times."); - raddbgic_memcpy_struct(&root->top_level_info, tli); - root->top_level_info_is_set = 1; -} - -//- rjf: binary section building - -RADDBGI_PROC void -raddbgic_add_binary_section(RADDBGIC_Root *root, RADDBGIC_String8 name, RADDBGI_BinarySectionFlags flags, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGI_U64 foff_first, RADDBGI_U64 foff_opl) -{ - RADDBGIC_BinarySection *sec = raddbgic_push_array(root->arena, RADDBGIC_BinarySection, 1); - SLLQueuePush(root->binary_section_first, root->binary_section_last, sec); - root->binary_section_count += 1; - sec->name = name; - sec->flags = flags; - sec->voff_first = voff_first; - sec->voff_opl = voff_opl; - sec->foff_first = foff_first; - sec->foff_opl = foff_opl; -} - -//- rjf: unit info building - -RADDBGI_PROC RADDBGIC_Unit* -raddbgic_unit_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 unit_user_id, RADDBGI_U64 unit_user_id_hash) -{ - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->unit_map, unit_user_id, unit_user_id_hash, &lookup); - RADDBGIC_Unit *result = 0; - if(lookup.match != 0) - { - result = (RADDBGIC_Unit*)lookup.match; - } - else - { - result = raddbgic_push_array(root->arena, RADDBGIC_Unit, 1); - result->idx = root->unit_count; - RADDBGIC_SLLQueuePush_N(root->unit_first, root->unit_last, result, next_order); - root->unit_count += 1; - raddbgic_u64toptr_map_insert(root->arena, &root->unit_map, unit_user_id, unit_user_id, &lookup, result); - } - return result; -} - -RADDBGI_PROC void -raddbgic_unit_set_info(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGIC_UnitInfo *info) -{ - raddbgic_requiref(root, !unit->info_is_set, return, "Unit information set multiple times."); - unit->info_is_set = 1; - unit->unit_name = raddbgic_str8_copy(root->arena, info->unit_name); - unit->compiler_name = raddbgic_str8_copy(root->arena, info->compiler_name); - unit->source_file = raddbgic_str8_copy(root->arena, info->source_file); - unit->object_file = raddbgic_str8_copy(root->arena, info->object_file); - unit->archive_file = raddbgic_str8_copy(root->arena, info->archive_file); - unit->build_path = raddbgic_str8_copy(root->arena, info->build_path); - unit->language = info->language; -} - -RADDBGI_PROC void -raddbgic_unit_add_line_sequence(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGIC_LineSequence *line_sequence) -{ - RADDBGIC_LineSequenceNode *node = raddbgic_push_array(root->arena, RADDBGIC_LineSequenceNode, 1); - SLLQueuePush(unit->line_seq_first, unit->line_seq_last, node); - unit->line_seq_count += 1; - - node->line_seq.file_name = raddbgic_str8_copy(root->arena, line_sequence->file_name); - - node->line_seq.voffs = raddbgic_push_array(root->arena, RADDBGI_U64, line_sequence->line_count + 1); - raddbgic_memcpy(node->line_seq.voffs, line_sequence->voffs, sizeof(RADDBGI_U64)*(line_sequence->line_count + 1)); - - node->line_seq.line_nums = raddbgic_push_array(root->arena, RADDBGI_U32, line_sequence->line_count); - raddbgic_memcpy(node->line_seq.line_nums, line_sequence->line_nums, sizeof(RADDBGI_U32)*line_sequence->line_count); - - if(line_sequence->col_nums != 0) - { - node->line_seq.col_nums = raddbgic_push_array(root->arena, RADDBGI_U16, line_sequence->line_count); - raddbgic_memcpy(node->line_seq.col_nums, line_sequence->col_nums, sizeof(RADDBGI_U16)*line_sequence->line_count); - } - - node->line_seq.line_count = line_sequence->line_count; -} - -RADDBGI_PROC void -raddbgic_unit_vmap_add_range(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGI_U64 first, RADDBGI_U64 opl) -{ - RADDBGIC_UnitVMapRange *node = raddbgic_push_array(root->arena, RADDBGIC_UnitVMapRange, 1); - SLLQueuePush(root->unit_vmap_range_first, root->unit_vmap_range_last, node); - root->unit_vmap_range_count += 1; - node->unit = unit; - node->first = first; - node->opl = opl; -} - -//- rjf: type info lookups/reservations - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_from_id(RADDBGIC_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash) -{ - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->type_from_id_map, type_user_id, type_user_id_hash, &lookup); - RADDBGIC_Type *result = (RADDBGIC_Type*)lookup.match; - return result; -} - -RADDBGI_PROC RADDBGIC_Reservation* -raddbgic_type_reserve_id(RADDBGIC_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash) -{ - RADDBGIC_Reservation *result = 0; - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->type_from_id_map, type_user_id, type_user_id_hash, &lookup); - if(lookup.match == 0) - { - raddbgic_u64toptr_map_insert(root->arena, &root->type_from_id_map, type_user_id, type_user_id_hash, &lookup, root->nil_type); - void **slot = &lookup.fill_node->ptr[lookup.fill_k]; - result = (RADDBGIC_Reservation*)slot; - } - return result; -} - -RADDBGI_PROC void -raddbgic_type_fill_id(RADDBGIC_Root *root, RADDBGIC_Reservation *res, RADDBGIC_Type *type) -{ - if(res != 0 && type != 0) - { - *(void**)res = type; - } -} - -//- rjf: nil/singleton types - -RADDBGI_PROC RADDBGI_S32 -raddbgic_type_is_unhandled_nil(RADDBGIC_Root *root, RADDBGIC_Type *type) -{ - RADDBGI_S32 result = (type->kind == RADDBGI_TypeKind_NULL && type != &root->handled_nil_type); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_handled_nil(RADDBGIC_Root *root) -{ - return &root->handled_nil_type; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_nil(RADDBGIC_Root *root) -{ - return root->nil_type; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_variadic(RADDBGIC_Root *root) -{ - return root->variadic_type; -} - -//- rjf: base type info constructors - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_new(RADDBGIC_Root *root) -{ - RADDBGIC_Type *result = raddbgic_push_array(root->arena, RADDBGIC_Type, 1); - result->idx = root->type_count; - RADDBGIC_SLLQueuePush_N(root->first_type, root->last_type, result, next_order); - root->type_count += 1; - return result; -} - -RADDBGI_PROC RADDBGIC_TypeUDT* -raddbgic_type_udt_from_any_type(RADDBGIC_Root *root, RADDBGIC_Type *type) -{ - if(type->udt == 0) - { - RADDBGIC_TypeUDT *new_udt = raddbgic_push_array(root->arena, RADDBGIC_TypeUDT, 1); - new_udt->idx = root->type_udt_count; - RADDBGIC_SLLQueuePush_N(root->first_udt, root->last_udt, new_udt, next_order); - root->type_udt_count += 1; - new_udt->self_type = type; - type->udt = new_udt; - } - RADDBGIC_TypeUDT *result = type->udt; - return result; -} - -RADDBGI_PROC RADDBGIC_TypeUDT* -raddbgic_type_udt_from_record_type(RADDBGIC_Root *root, RADDBGIC_Type *type) -{ - raddbgic_requiref(root, (type->kind == RADDBGI_TypeKind_Struct || - type->kind == RADDBGI_TypeKind_Class || - type->kind == RADDBGI_TypeKind_Union), - return 0, - "Tried to use non-user-defined-type-kind to create user-defined-type."); - RADDBGIC_TypeUDT *result = 0; - result = raddbgic_type_udt_from_any_type(root, type); - return result; -} - -//- rjf: basic/operator type construction helpers - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_basic(RADDBGIC_Root *root, RADDBGI_TypeKind type_kind, RADDBGIC_String8 name) -{ - raddbgic_requiref(root, (RADDBGI_TypeKind_FirstBuiltIn <= type_kind && type_kind <= RADDBGI_TypeKind_LastBuiltIn), return root->nil_type, "Non-basic type kind passed to construct basic type."); - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = sizeof(RADDBGIC_TypeConstructKind) + sizeof(type_kind) + name.size; - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "basic" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Basic; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // type_kind - raddbgic_memcpy(ptr, &type_kind, sizeof(type_kind)); - ptr += sizeof(type_kind); - // name - raddbgic_memcpy(ptr, name.str, name.size); - ptr += name.size; - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // calculate size - RADDBGI_U32 byte_size = raddbgi_size_from_basic_type_kind(type_kind); - if(byte_size == 0xFFFFFFFF) - { - byte_size = root->addr_size; - } - - // setup new node - result = raddbgic_type_new(root); - result->kind = type_kind; - result->name = raddbgic_str8_copy(root->arena, name); - result->byte_size = byte_size; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - - // save in name map - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Types); - raddbgic_name_map_add_pair(root, map, result->name, result->idx); - } - } - - scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_modifier(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_TypeModifierFlags flags) -{ - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = sizeof(RADDBGIC_TypeConstructKind) + sizeof(flags) + sizeof(direct_type->idx); - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "modifier" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Modifier; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // flags - raddbgic_memcpy(ptr, &flags, sizeof(flags)); - ptr += sizeof(flags); - // direct_type->idx - raddbgic_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); - ptr += sizeof(direct_type->idx); - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0){ - - // setup new node - result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Modifier; - result->flags = flags; - result->byte_size = direct_type->byte_size; - result->direct_type = direct_type; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - raddbgic_scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_bitfield(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_U32 bit_off, RADDBGI_U32 bit_count) -{ - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = sizeof(RADDBGIC_TypeConstructKind) + sizeof(direct_type->idx) + sizeof(RADDBGI_U32)*2; - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "bitfield" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Bitfield; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // direct_type->idx - raddbgic_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); - ptr += sizeof(direct_type->idx); - // bit_off - raddbgic_memcpy(ptr, &bit_off, sizeof(bit_off)); - ptr += sizeof(bit_off); - // bit_count - raddbgic_memcpy(ptr, &bit_count, sizeof(bit_count)); - ptr += sizeof(bit_count); - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // setup new node - result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Bitfield; - result->byte_size = direct_type->byte_size; - result->off = bit_off; - result->count = bit_count; - result->direct_type = direct_type; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - raddbgic_scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_pointer(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_TypeKind ptr_type_kind) -{ - raddbgic_requiref(root, (ptr_type_kind == RADDBGI_TypeKind_Ptr || - ptr_type_kind == RADDBGI_TypeKind_LRef || - ptr_type_kind == RADDBGI_TypeKind_RRef), - return root->nil_type, - "Non-pointer type kind used to construct pointer type."); - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = sizeof(RADDBGIC_TypeConstructKind) + sizeof(ptr_type_kind) + sizeof(direct_type->idx); - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "pointer" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Pointer; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // type_kind - raddbgic_memcpy(ptr, &ptr_type_kind, sizeof(ptr_type_kind)); - ptr += sizeof(ptr_type_kind); - // direct_type->idx - raddbgic_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); - ptr += sizeof(direct_type->idx); - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // setup new node - result = raddbgic_type_new(root); - result->kind = ptr_type_kind; - result->byte_size = root->addr_size; - result->direct_type = direct_type; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - raddbgic_scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_array(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_U64 count) -{ - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = - sizeof(RADDBGIC_TypeConstructKind) + sizeof(direct_type->idx) + sizeof(count); - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "array" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Array; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // direct_type->idx - raddbgic_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); - ptr += sizeof(direct_type->idx); - // count - raddbgic_memcpy(ptr, &count, sizeof(count)); - ptr += sizeof(count); - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // setup new node - result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Array; - result->count = count; - result->direct_type = direct_type; - result->byte_size = direct_type->byte_size*count; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_proc(RADDBGIC_Root *root, RADDBGIC_Type *return_type, struct RADDBGIC_TypeList *params) -{ - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = sizeof(RADDBGIC_TypeConstructKind) + sizeof(return_type->idx)*(1 + params->count); - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "procedure" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Procedure; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // ret_type->idx - raddbgic_memcpy(ptr, &return_type->idx, sizeof(return_type->idx)); - ptr += sizeof(return_type->idx); - // (params ...)->idx - for(RADDBGIC_TypeNode *node = params->first; - node != 0; - node = node->next) - { - raddbgic_memcpy(ptr, &node->type->idx, sizeof(node->type->idx)); - ptr += sizeof(node->type->idx); - } - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // setup param buffer - RADDBGIC_Type **param_types = raddbgic_push_array(root->arena, RADDBGIC_Type*, params->count); - { - RADDBGIC_Type **ptr = param_types; - for(RADDBGIC_TypeNode *node = params->first; - node != 0; - node = node->next) - { - *ptr = node->type; - ptr += 1; - } - } - - // setup new node - result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Function; - result->byte_size = root->addr_size; - result->count = params->count; - result->direct_type = return_type; - result->param_types = param_types; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - raddbgic_scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_method(RADDBGIC_Root *root, RADDBGIC_Type *this_type, RADDBGIC_Type *return_type, struct RADDBGIC_TypeList *params) -{ - RADDBGIC_Type *result = root->nil_type; - RADDBGIC_Temp scratch = raddbgic_scratch_begin(0, 0); - - // setup construct buffer - RADDBGI_U64 buf_size = - sizeof(RADDBGIC_TypeConstructKind) + sizeof(return_type->idx)*(2 + params->count); - RADDBGI_U8 *buf = raddbgic_push_array(raddbgic_temp_arena(scratch), RADDBGI_U8, buf_size); - { - RADDBGI_U8 *ptr = buf; - // "method" - *(RADDBGIC_TypeConstructKind*)ptr = RADDBGIC_TypeConstructKind_Method; - ptr += sizeof(RADDBGIC_TypeConstructKind); - // ret_type->idx - raddbgic_memcpy(ptr, &return_type->idx, sizeof(return_type->idx)); - ptr += sizeof(return_type->idx); - // this_type->idx - raddbgic_memcpy(ptr, &this_type->idx, sizeof(this_type->idx)); - ptr += sizeof(this_type->idx); - // (params ...)->idx - for(RADDBGIC_TypeNode *node = params->first; - node != 0; - node = node->next) - { - raddbgic_memcpy(ptr, &node->type->idx, sizeof(node->type->idx)); - ptr += sizeof(node->type->idx); - } - } - - // check for duplicate construct - RADDBGIC_String8 blob = raddbgic_str8(buf, buf_size); - RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); - void *lookup_ptr = raddbgic_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); - result = (RADDBGIC_Type*)lookup_ptr; - if(result == 0) - { - // setup param buffer - RADDBGIC_Type **param_types = raddbgic_push_array(root->arena, RADDBGIC_Type*, params->count + 1); - { - RADDBGIC_Type **ptr = param_types; - { - *ptr = this_type; - ptr += 1; - } - for(RADDBGIC_TypeNode *node = params->first; - node != 0; - node = node->next) - { - *ptr = node->type; - ptr += 1; - } - } - - // setup new node - result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Method; - result->byte_size = root->addr_size; - result->count = params->count; - result->direct_type = return_type; - result->param_types = param_types; - - // save in construct map - raddbgic_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); - } - - raddbgic_scratch_end(scratch); - raddbgic_assert(result != 0); - return result; -} - -//- rjf: udt type constructors - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_udt(RADDBGIC_Root *root, RADDBGI_TypeKind record_type_kind, RADDBGIC_String8 name, RADDBGI_U64 size) -{ - raddbgic_requiref(root, (record_type_kind == RADDBGI_TypeKind_Struct || - record_type_kind == RADDBGI_TypeKind_Class || - record_type_kind == RADDBGI_TypeKind_Union), - return root->nil_type, - "Non-user-defined-type-kind used to create user-defined type."); - - // rjf: make type - RADDBGIC_Type *result = raddbgic_type_new(root); - result->kind = record_type_kind; - result->byte_size = size; - result->name = raddbgic_str8_copy(root->arena, name); - - // rjf: save in name map - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Types); - raddbgic_name_map_add_pair(root, map, result->name, result->idx); - } - - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_enum(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGIC_String8 name) -{ - // rjf: make type - RADDBGIC_Type *result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Enum; - result->byte_size = direct_type->byte_size; - result->name = raddbgic_str8_copy(root->arena, name); - result->direct_type = direct_type; - - // rjf: save in name map - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Types); - raddbgic_name_map_add_pair(root, map, result->name, result->idx); - } - - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_alias(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGIC_String8 name) -{ - // rjf: make type - RADDBGIC_Type *result = raddbgic_type_new(root); - result->kind = RADDBGI_TypeKind_Alias; - result->byte_size = direct_type->byte_size; - result->name = raddbgic_str8_copy(root->arena, name); - result->direct_type = direct_type; - - // rjf: save in name map - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Types); - raddbgic_name_map_add_pair(root, map, result->name, result->idx); - } - - return result; -} - -RADDBGI_PROC RADDBGIC_Type* -raddbgic_type_incomplete(RADDBGIC_Root *root, RADDBGI_TypeKind type_kind, RADDBGIC_String8 name) -{ - raddbgic_requiref(root, (type_kind == RADDBGI_TypeKind_IncompleteStruct || - type_kind == RADDBGI_TypeKind_IncompleteClass || - type_kind == RADDBGI_TypeKind_IncompleteUnion || - type_kind == RADDBGI_TypeKind_IncompleteEnum), - return root->nil_type, - "Non-incomplete-type-kind used to create incomplete type."); - - // rjf: make type - RADDBGIC_Type *result = raddbgic_type_new(root); - result->kind = type_kind; - result->name = raddbgic_str8_copy(root->arena, name); - - // save in name map - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Types); - raddbgic_name_map_add_pair(root, map, result->name, result->idx); - } - - return result; -} - -//- rjf: type member building - -RADDBGI_PROC void -raddbgic_type_add_member_data_field(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type, RADDBGI_U32 off) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_DataField; - member->name = raddbgic_str8_copy(root->arena, name); - member->type = mem_type; - member->off = off; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_static_data(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_StaticData; - member->name = raddbgic_str8_copy(root->arena, name); - member->type = mem_type; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_Method; - member->name = raddbgic_str8_copy(root->arena, name); - member->type = mem_type; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_static_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - - root->total_member_count += 1; - - member->kind = RADDBGI_MemberKind_StaticMethod; - member->name = raddbgic_str8_copy(root->arena, name); - member->type = mem_type; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_virtual_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_VirtualMethod; - member->name = raddbgic_str8_copy(root->arena, name); - member->type = mem_type; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_base(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *base_type, RADDBGI_U32 off) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_Base; - member->type = base_type; - member->off = off; - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_virtual_base(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *base_type, RADDBGI_U32 vptr_off, RADDBGI_U32 vtable_off) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_VirtualBase; - member->type = base_type; - // TODO(allen): what to do with the two offsets in this case? - } -} - -RADDBGI_PROC void -raddbgic_type_add_member_nested_type(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *nested_type) -{ - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_record_type(root, record_type); - if(udt != 0) - { - RADDBGIC_TypeMember *member = raddbgic_push_array(root->arena, RADDBGIC_TypeMember, 1); - SLLQueuePush(udt->first_member, udt->last_member, member); - udt->member_count += 1; - root->total_member_count += 1; - member->kind = RADDBGI_MemberKind_NestedType; - member->type = nested_type; - } -} - -RADDBGI_PROC void -raddbgic_type_add_enum_val(RADDBGIC_Root *root, RADDBGIC_Type *enum_type, RADDBGIC_String8 name, RADDBGI_U64 val) -{ - raddbgic_requiref(root, (enum_type->kind == RADDBGI_TypeKind_Enum), return, "Tried to add enum value to non-enum type."); - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_any_type(root, enum_type); - if(udt != 0) - { - RADDBGIC_TypeEnumVal *enum_val = raddbgic_push_array(root->arena, RADDBGIC_TypeEnumVal, 1); - SLLQueuePush(udt->first_enum_val, udt->last_enum_val, enum_val); - udt->enum_val_count += 1; - root->total_enum_val_count += 1; - enum_val->name = raddbgic_str8_copy(root->arena, name); - enum_val->val = val; - } -} - -//- rjf: type source coordinate specifications -RADDBGI_PROC void -raddbgic_type_set_source_coordinates(RADDBGIC_Root *root, RADDBGIC_Type *defined_type, RADDBGIC_String8 source_path, RADDBGI_U32 line, RADDBGI_U32 col) -{ - raddbgic_requiref(root, (RADDBGI_TypeKind_FirstUserDefined <= defined_type->kind && defined_type->kind <= RADDBGI_TypeKind_LastUserDefined), - return, "Tried to add source coordinates to non-user-defined type."); - RADDBGIC_TypeUDT *udt = raddbgic_type_udt_from_any_type(root, defined_type); - if(udt != 0) - { - udt->source_path = raddbgic_str8_copy(root->arena, source_path); - udt->line = line; - udt->col = col; - } -} - -//- rjf: symbol info building - -RADDBGI_PROC RADDBGIC_Symbol* -raddbgic_symbol_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 symbol_user_id, RADDBGI_U64 symbol_user_id_hash) -{ - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->symbol_map, symbol_user_id, symbol_user_id_hash, &lookup); - RADDBGIC_Symbol *result = 0; - if(lookup.match != 0) - { - result = (RADDBGIC_Symbol*)lookup.match; - } - else - { - result = raddbgic_push_array(root->arena, RADDBGIC_Symbol, 1); - RADDBGIC_SLLQueuePush_N(root->first_symbol, root->last_symbol, result, next_order); - root->symbol_count += 1; - raddbgic_u64toptr_map_insert(root->arena, &root->symbol_map, symbol_user_id, symbol_user_id_hash, &lookup, result); - } - return result; -} - -RADDBGI_PROC void -raddbgic_symbol_set_info(RADDBGIC_Root *root, RADDBGIC_Symbol *symbol, RADDBGIC_SymbolInfo *info) -{ - // rjf: unpack - RADDBGIC_SymbolKind kind = info->kind; - RADDBGIC_Symbol *container_symbol = info->container_symbol; - RADDBGIC_Type *container_type = info->container_type; - - // rjf: requirements - raddbgic_requiref(root, RADDBGIC_SymbolKind_NULL == symbol->kind, return, "Symbol information set multiple times."); - raddbgic_requiref(root, RADDBGIC_SymbolKind_NULL < info->kind && info->kind < RADDBGIC_SymbolKind_COUNT, return, "Invalid symbol kind used to initialize symbol."); - raddbgic_requiref(root, info->type != 0, return, "Invalid type used to initialize symbol."); - raddbgic_requiref(root, info->container_symbol == 0 || info->container_type == 0, container_type = 0, "Symbol initialized with both a containing symbol and containing type, when only one is allowed."); - - // rjf: fill - root->symbol_kind_counts[kind] += 1; - symbol->idx = root->symbol_kind_counts[kind]; - symbol->kind = kind; - symbol->name = raddbgic_str8_copy(root->arena, info->name); - symbol->link_name = raddbgic_str8_copy(root->arena, info->link_name); - symbol->type = info->type; - symbol->is_extern = info->is_extern; - symbol->offset = info->offset; - symbol->container_symbol = container_symbol; - symbol->container_type = container_type; - - // rjf: set root scope - switch(kind) - { - default:{}break; - case RADDBGIC_SymbolKind_GlobalVariable: - case RADDBGIC_SymbolKind_ThreadVariable: - { - raddbgic_requiref(root, info->root_scope == 0, raddbgic_noop, "Global or thread variable initialized with root scope."); - }break; - case RADDBGIC_SymbolKind_Procedure: - { - raddbgic_requiref(root, info->root_scope != 0, raddbgic_noop, "Procedure symbol initialized without root scope."); - symbol->root_scope = info->root_scope; - raddbgic_scope_recursive_set_symbol(info->root_scope, symbol); - }break; - } - - // save name map - { - RADDBGIC_NameMap *map = 0; - switch(kind) - { - default:{}break; - case RADDBGIC_SymbolKind_GlobalVariable: - { - map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_GlobalVariables); - }break; - case RADDBGIC_SymbolKind_ThreadVariable: - { - map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_ThreadVariables); - }break; - case RADDBGIC_SymbolKind_Procedure: - { - map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_Procedures); - }break; - } - if(map != 0) - { - raddbgic_name_map_add_pair(root, map, symbol->name, symbol->idx); - } - } - - // save link name map - if(kind == RADDBGIC_SymbolKind_Procedure && symbol->link_name.size > 0) - { - RADDBGIC_NameMap *map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_LinkNameProcedures); - raddbgic_name_map_add_pair(root, map, symbol->link_name, symbol->idx); - } -} - -//- rjf: scope info building - -RADDBGI_PROC RADDBGIC_Scope * -raddbgic_scope_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 scope_user_id, RADDBGI_U64 scope_user_id_hash) -{ - RADDBGIC_Scope *result = 0; - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->scope_map, scope_user_id, scope_user_id_hash, &lookup); - if(lookup.match != 0) - { - result = (RADDBGIC_Scope*)lookup.match; - } - else - { - result = raddbgic_push_array(root->arena, RADDBGIC_Scope, 1); - result->idx = root->scope_count; - RADDBGIC_SLLQueuePush_N(root->first_scope, root->last_scope, result, next_order); - root->scope_count += 1; - raddbgic_u64toptr_map_insert(root->arena, &root->scope_map, scope_user_id, scope_user_id_hash, &lookup, result); - } - return result; -} - -RADDBGI_PROC void -raddbgic_scope_set_parent(RADDBGIC_Root *root, RADDBGIC_Scope *scope, RADDBGIC_Scope *parent) -{ - raddbgic_requiref(root, scope->parent_scope == 0, return, "Scope parent set multiple times."); - raddbgic_requiref(root, parent != 0, return, "Tried to set invalid parent as scope parent."); - scope->symbol = parent->symbol; - scope->parent_scope = parent; - RADDBGIC_SLLQueuePush_N(parent->first_child, parent->last_child, scope, next_sibling); -} - -RADDBGI_PROC void -raddbgic_scope_add_voff_range(RADDBGIC_Root *root, RADDBGIC_Scope *scope, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl) -{ - RADDBGIC_VOffRange *range = raddbgic_push_array(root->arena, RADDBGIC_VOffRange, 1); - SLLQueuePush(scope->first_range, scope->last_range, range); - scope->range_count += 1; - range->voff_first = voff_first; - range->voff_opl = voff_opl; - scope->voff_base = Min(scope->voff_base, voff_first); - root->scope_voff_count += 2; -} - -RADDBGI_PROC void -raddbgic_scope_recursive_set_symbol(RADDBGIC_Scope *scope, RADDBGIC_Symbol *symbol) -{ - scope->symbol = symbol; - for(RADDBGIC_Scope *node = scope->first_child; - node != 0; - node = node->next_sibling) - { - raddbgic_scope_recursive_set_symbol(node, symbol); - } -} - -//- rjf: local info building - -RADDBGI_PROC RADDBGIC_Local* -raddbgic_local_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 local_user_id, RADDBGI_U64 local_user_id_hash) -{ - RADDBGIC_Local *result = 0; - RADDBGIC_U64ToPtrLookup lookup = {0}; - raddbgic_u64toptr_map_lookup(&root->local_map, local_user_id, local_user_id_hash, &lookup); - if(lookup.match != 0) - { - result = (RADDBGIC_Local*)lookup.match; - } - else - { - result = raddbgic_push_array(root->arena, RADDBGIC_Local, 1); - raddbgic_u64toptr_map_insert(root->arena, &root->local_map, local_user_id, local_user_id_hash, &lookup, result); - } - return result; -} - -RADDBGI_PROC void -raddbgic_local_set_basic_info(RADDBGIC_Root *root, RADDBGIC_Local *local, RADDBGIC_LocalInfo *info) -{ - raddbgic_requiref(root, local->kind == RADDBGI_LocalKind_NULL, return, "Local information set multiple times."); - raddbgic_requiref(root, info->scope != 0, return, "Tried to set invalid scope as local's containing scope."); - raddbgic_requiref(root, RADDBGI_LocalKind_NULL < info->kind && info->kind < RADDBGI_LocalKind_COUNT, return, "Invalid local kind."); - raddbgic_requiref(root, info->type != 0, return, "Tried to set invalid type as local's type."); - RADDBGIC_Scope *scope = info->scope; - SLLQueuePush(scope->first_local, scope->last_local, local); - scope->local_count += 1; - root->local_count += 1; - local->kind = info->kind; - local->name = raddbgic_str8_copy(root->arena, info->name); - local->type = info->type; -} - -RADDBGI_PROC RADDBGIC_LocationSet* -raddbgic_location_set_from_local(RADDBGIC_Root *root, RADDBGIC_Local *local) -{ - RADDBGIC_LocationSet *result = local->locset; - if(result == 0) - { - local->locset = raddbgic_push_array(root->arena, RADDBGIC_LocationSet, 1); - result = local->locset; - } - return result; -} - -//- rjf: location info building - -RADDBGI_PROC void -raddbgic_location_set_add_case(RADDBGIC_Root *root, RADDBGIC_LocationSet *locset, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGIC_Location *location) -{ - RADDBGIC_LocationCase *location_case = raddbgic_push_array(root->arena, RADDBGIC_LocationCase, 1); - SLLQueuePush(locset->first_location_case, locset->last_location_case, location_case); - locset->location_case_count += 1; - root->location_count += 1; - location_case->voff_first = voff_first; - location_case->voff_opl = voff_opl; - location_case->location = location; -} - -RADDBGI_PROC RADDBGIC_Location* -raddbgic_location_addr_bytecode_stream(RADDBGIC_Root *root, struct RADDBGIC_EvalBytecode *bytecode) -{ - RADDBGIC_Location *result = raddbgic_push_array(root->arena, RADDBGIC_Location, 1); - result->kind = RADDBGI_LocationKind_AddrBytecodeStream; - result->bytecode = *bytecode; - return result; -} - -RADDBGI_PROC RADDBGIC_Location* -raddbgic_location_val_bytecode_stream(RADDBGIC_Root *root, struct RADDBGIC_EvalBytecode *bytecode) -{ - RADDBGIC_Location *result = raddbgic_push_array(root->arena, RADDBGIC_Location, 1); - result->kind = RADDBGI_LocationKind_ValBytecodeStream; - result->bytecode = *bytecode; - return result; -} - -RADDBGI_PROC RADDBGIC_Location* -raddbgic_location_addr_reg_plus_u16(RADDBGIC_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset) -{ - RADDBGIC_Location *result = raddbgic_push_array(root->arena, RADDBGIC_Location, 1); - result->kind = RADDBGI_LocationKind_AddrRegisterPlusU16; - result->register_code = reg_code; - result->offset = offset; - return result; -} - -RADDBGI_PROC RADDBGIC_Location* -raddbgic_location_addr_addr_reg_plus_u16(RADDBGIC_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset) -{ - RADDBGIC_Location *result = raddbgic_push_array(root->arena, RADDBGIC_Location, 1); - result->kind = RADDBGI_LocationKind_AddrAddrRegisterPlusU16; - result->register_code = reg_code; - result->offset = offset; - return result; -} - -RADDBGI_PROC RADDBGIC_Location* -raddbgic_location_val_reg(RADDBGIC_Root *root, RADDBGI_U8 reg_code) -{ - RADDBGIC_Location *result = raddbgic_push_array(root->arena, RADDBGIC_Location, 1); - result->kind = RADDBGI_LocationKind_ValRegister; - result->register_code = reg_code; - return result; -} - -//- rjf: name map building - -RADDBGI_PROC RADDBGIC_NameMap* -raddbgic_name_map_for_kind(RADDBGIC_Root *root, RADDBGI_NameMapKind kind) -{ - RADDBGIC_NameMap *result = 0; - if(kind < RADDBGI_NameMapKind_COUNT) - { - if(root->name_maps[kind] == 0) - { - root->name_maps[kind] = raddbgic_push_array(root->arena, RADDBGIC_NameMap, 1); - root->name_maps[kind]->buckets_count = 16384; - root->name_maps[kind]->buckets = raddbgic_push_array(root->arena, RADDBGIC_NameMapNode *, root->name_maps[kind]->buckets_count); - } - result = root->name_maps[kind]; - } - return result; -} - -RADDBGI_PROC void -raddbgic_name_map_add_pair(RADDBGIC_Root *root, RADDBGIC_NameMap *map, RADDBGIC_String8 string, RADDBGI_U32 idx) -{ - // hash - RADDBGI_U64 hash = raddbgi_hash(string.str, string.size); - RADDBGI_U64 bucket_idx = hash%map->buckets_count; - - // find existing name node - RADDBGIC_NameMapNode *match = 0; - for(RADDBGIC_NameMapNode *node = map->buckets[bucket_idx]; - node != 0; - node = node->bucket_next) - { - if(raddbgic_str8_match(string, node->string, 0)) - { - match = node; - break; - } - } - - // make name node if necessary - if(match == 0) - { - match = raddbgic_push_array(root->arena, RADDBGIC_NameMapNode, 1); - match->string = raddbgic_str8_copy(root->arena, string); - RADDBGIC_SLLStackPush_N(map->buckets[bucket_idx], match, bucket_next); - RADDBGIC_SLLQueuePush_N(map->first, map->last, match, order_next); - map->name_count += 1; - map->bucket_collision_count += (match->bucket_next != 0); - } - - // find existing idx - RADDBGI_S32 existing_idx = 0; - for(RADDBGIC_NameMapIdxNode *node = match->idx_first; - node != 0; - node = node->next) - { - for(RADDBGI_U32 i = 0; i < ArrayCount(node->idx); i += 1) - { - if(node->idx[i] == 0) - { - break; - } - if(node->idx[i] == idx) - { - existing_idx = 1; - break; - } - } - } - - // insert new idx if necessary - if(!existing_idx) - { - RADDBGIC_NameMapIdxNode *idx_node = match->idx_last; - RADDBGI_U32 insert_i = match->idx_count%ArrayCount(idx_node->idx); - if(insert_i == 0) - { - idx_node = raddbgic_push_array(root->arena, RADDBGIC_NameMapIdxNode, 1); - SLLQueuePush(match->idx_first, match->idx_last, idx_node); - } - - idx_node->idx[insert_i] = idx; - match->idx_count += 1; - } -} - -//////////////////////////////// -//~ rjf: Debug Info Baking (Loose -> Tight) Functions - -//- rjf: bake context construction - -RADDBGI_PROC RADDBGIC_BakeCtx* -raddbgic_bake_ctx_begin(RADDBGIC_BakeParams *params) -{ - RADDBGIC_Arena *arena = raddbgic_arena_alloc(); - RADDBGIC_BakeCtx *result = raddbgic_push_array(arena, RADDBGIC_BakeCtx, 1); - result->arena = arena; -#define BKTCOUNT(x) ((x)?(u64_up_to_pow2(x)):(16384)) - result->strs.buckets_count = BKTCOUNT(params->strings_bucket_count); - result->idxs.buckets_count = BKTCOUNT(params->idx_runs_bucket_count); -#undef BKTCOUNT - result->strs.buckets = raddbgic_push_array(arena, RADDBGIC_StringNode *, result->strs.buckets_count); - result->idxs.buckets = raddbgic_push_array(arena, RADDBGIC_IdxRunNode *, result->idxs.buckets_count); - - raddbgic_string(result, raddbgic_str8_lit("")); - raddbgic_idx_run(result, 0, 0); - - result->tree = raddbgic_push_array(arena, RADDBGIC_PathTree, 1); - { - RADDBGIC_PathNode *nil_path_node = raddbgic_paths_new_node(result); - nil_path_node->name = raddbgic_str8_lit(""); - RADDBGIC_SrcNode *nil_src_node = raddbgic_paths_new_src_node(result); - nil_src_node->path_node = nil_path_node; - nil_src_node->normal_full_path = raddbgic_str8_lit(""); - nil_path_node->src_file = nil_src_node; - } - - return result; -} - -RADDBGI_PROC void -raddbgic_bake_ctx_release(RADDBGIC_BakeCtx *bake_ctx) -{ - arena_release(bake_ctx->arena); -} - -//- rjf: string baking - -RADDBGI_PROC RADDBGI_U32 -raddbgic_string(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 str) -{ - RADDBGIC_Arena *arena = bctx->arena; - RADDBGIC_Strings *strs = &bctx->strs; - RADDBGI_U64 hash = raddbgi_hash(str.str, str.size); - RADDBGI_U64 bucket_idx = hash%strs->buckets_count; - - // look for a match - RADDBGIC_StringNode *match = 0; - for(RADDBGIC_StringNode *node = strs->buckets[bucket_idx]; - node != 0; - node = node->bucket_next) - { - if(node->hash == hash && raddbgic_str8_match(node->str, str, 0)) - { - match = node; - break; - } - } - - // insert new node if no match - if(match == 0) - { - RADDBGIC_StringNode *node = raddbgic_push_array_no_zero(arena, RADDBGIC_StringNode, 1); - node->str = raddbgic_str8_copy(arena, str); - node->hash = hash; - node->idx = strs->count; - strs->count += 1; - RADDBGIC_SLLQueuePush_N(strs->order_first, strs->order_last, node, order_next); - RADDBGIC_SLLStackPush_N(strs->buckets[bucket_idx], node, bucket_next); - match = node; - strs->bucket_collision_count += (node->bucket_next != 0); - } - - // extract idx to return - raddbgic_assert(match != 0); - RADDBGI_U32 result = match->idx; - return result; -} - -//- rjf: idx run baking - -RADDBGI_PROC RADDBGI_U64 -raddbgic_idx_run_hash(RADDBGI_U32 *idx_run, RADDBGI_U32 count) -{ - RADDBGI_U64 hash = 5381; - RADDBGI_U32 *ptr = idx_run; - RADDBGI_U32 *opl = idx_run + count; - for(;ptr < opl; ptr += 1) - { - hash = ((hash << 5) + hash) + (*ptr); - } - return(hash); -} - -RADDBGI_PROC RADDBGI_U32 -raddbgic_idx_run(RADDBGIC_BakeCtx *bctx, RADDBGI_U32 *idx_run, RADDBGI_U32 count) -{ - RADDBGIC_Arena *arena = bctx->arena; - RADDBGIC_IdxRuns *idxs = &bctx->idxs; - - RADDBGI_U64 hash = raddbgic_idx_run_hash(idx_run, count); - RADDBGI_U64 bucket_idx = hash%idxs->buckets_count; - - // look for a match - RADDBGIC_IdxRunNode *match = 0; - for(RADDBGIC_IdxRunNode *node = idxs->buckets[bucket_idx]; - node != 0; - node = node->bucket_next) - { - if(node->hash == hash) - { - RADDBGI_S32 is_match = 1; - RADDBGI_U32 *node_idx = node->idx_run; - for(RADDBGI_U32 i = 0; i < count; i += 1) - { - if(node_idx[i] != idx_run[i]) - { - is_match = 0; - break; - } - } - if(is_match) - { - match = node; - break; - } - } - } - - // insert new node if no match - if(match == 0) - { - RADDBGIC_IdxRunNode *node = raddbgic_push_array_no_zero(arena, RADDBGIC_IdxRunNode, 1); - RADDBGI_U32 *idx_run_copy = raddbgic_push_array_no_zero(arena, RADDBGI_U32, count); - for(RADDBGI_U32 i = 0; i < count; i += 1) - { - idx_run_copy[i] = idx_run[i]; - } - node->idx_run = idx_run_copy; - node->hash = hash; - node->count = count; - node->first_idx = idxs->idx_count; - idxs->count += 1; - idxs->idx_count += count; - RADDBGIC_SLLQueuePush_N(idxs->order_first, idxs->order_last, node, order_next); - RADDBGIC_SLLStackPush_N(idxs->buckets[bucket_idx], node, bucket_next); - match = node; - idxs->bucket_collision_count += (node->bucket_next != 0); - } - - // extract idx to return - raddbgic_assert(match != 0); - RADDBGI_U32 result = match->first_idx; - return result; -} - -//- rjf: data section baking - -RADDBGI_PROC RADDBGI_U32 -raddbgic_dsection(RADDBGIC_Arena *arena, RADDBGIC_DSections *dss, void *data, RADDBGI_U64 size, RADDBGI_DataSectionTag tag) -{ - RADDBGI_U32 result = dss->count; - RADDBGIC_DSectionNode *node = raddbgic_push_array(arena, RADDBGIC_DSectionNode, 1); - SLLQueuePush(dss->first, dss->last, node); - node->data = data; - node->size = size; - node->tag = tag; - dss->count += 1; - return result; -} - -//- rjf: paths baking - -RADDBGI_PROC RADDBGIC_String8 -raddbgic_normal_string_from_path_node(RADDBGIC_Arena *arena, RADDBGIC_PathNode *node) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - RADDBGIC_String8List list = {0}; - if(node != 0) - { - raddbgic_normal_string_from_path_node_build(scratch.arena, node, &list); - } - RADDBGIC_String8 result = raddbgic_str8_list_join(arena, &list, raddbgic_str8_lit("/")); - { - RADDBGI_U8 *ptr = result.str; - RADDBGI_U8 *opl = result.str + result.size; - for(; ptr < opl; ptr += 1) - { - RADDBGI_U8 c = *ptr; - if('A' <= c && c <= 'Z') { c += 'a' - 'A'; } - *ptr = c; - } - } - scratch_end(scratch); - return result; -} - -RADDBGI_PROC void -raddbgic_normal_string_from_path_node_build(RADDBGIC_Arena *arena, RADDBGIC_PathNode *node, RADDBGIC_String8List *out) -{ - // TODO(rjf): why is this recursive... - if(node->parent != 0) - { - raddbgic_normal_string_from_path_node_build(arena, node->parent, out); - } - if(node->name.size > 0) - { - raddbgic_str8_list_push(arena, out, node->name); - } -} - -RADDBGI_PROC RADDBGIC_PathNode* -raddbgic_paths_new_node(RADDBGIC_BakeCtx *bctx) -{ - RADDBGIC_PathTree *tree = bctx->tree; - RADDBGIC_PathNode *result = raddbgic_push_array(bctx->arena, RADDBGIC_PathNode, 1); - RADDBGIC_SLLQueuePush_N(tree->first, tree->last, result, next_order); - result->idx = tree->count; - tree->count += 1; - return result; -} - -RADDBGI_PROC RADDBGIC_PathNode* -raddbgic_paths_sub_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_PathNode *dir, RADDBGIC_String8 sub_dir) -{ - // look for existing match - RADDBGIC_PathNode *match = 0; - for(RADDBGIC_PathNode *node = dir->first_child; - node != 0; - node = node->next_sibling) - { - if(raddbgic_str8_match(node->name, sub_dir, RADDBGIC_StringMatchFlag_CaseInsensitive)) - { - match = node; - break; - } - } - - // construct new node if no match - RADDBGIC_PathNode *new_node = 0; - if(match == 0){ - new_node = raddbgic_paths_new_node(bctx); - new_node->parent = dir; - RADDBGIC_SLLQueuePush_N(dir->first_child, dir->last_child, new_node, next_sibling); - new_node->name = raddbgic_str8_copy(bctx->arena, sub_dir); - } - - // select result from the two paths - RADDBGIC_PathNode *result = match; - if(match == 0){ - result = new_node; - } - - return result; -} - -RADDBGI_PROC RADDBGIC_PathNode* -raddbgic_paths_node_from_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 path) -{ - RADDBGIC_PathNode *node_cursor = &bctx->tree->root; - - RADDBGI_U8 *ptr = path.str; - RADDBGI_U8 *opl = path.str + path.size; - for(;ptr < opl;){ - // skip past slashes - for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1); - - // save beginning of non-slash range - RADDBGI_U8 *range_first = ptr; - - // skip past non-slashes - for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1); - - // if range is non-empty advance the node cursor - if(range_first < ptr){ - RADDBGIC_String8 sub_dir = raddbgic_str8(range_first, (RADDBGI_U64)(ptr-range_first)); - node_cursor = raddbgic_paths_sub_path(bctx, node_cursor, sub_dir); - } - } - - RADDBGIC_PathNode *result = node_cursor; - return result; -} - -RADDBGI_PROC RADDBGI_U32 -raddbgic_paths_idx_from_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 path) -{ - RADDBGIC_PathNode *node = raddbgic_paths_node_from_path(bctx, path); - RADDBGI_U32 result = node->idx; - return result; -} - -RADDBGI_PROC RADDBGIC_SrcNode* -raddbgic_paths_new_src_node(RADDBGIC_BakeCtx *bctx) -{ - RADDBGIC_PathTree *tree = bctx->tree; - RADDBGIC_SrcNode *result = raddbgic_push_array(bctx->arena, RADDBGIC_SrcNode, 1); - SLLQueuePush(tree->src_first, tree->src_last, result); - result->idx = tree->src_count; - tree->src_count += 1; - return result; -} - -RADDBGI_PROC RADDBGIC_SrcNode* -raddbgic_paths_src_node_from_path_node(RADDBGIC_BakeCtx *bctx, RADDBGIC_PathNode *path_node) -{ - RADDBGIC_SrcNode *result = path_node->src_file; - if(result == 0) - { - RADDBGIC_SrcNode *new_node = raddbgic_paths_new_src_node(bctx); - new_node->path_node = path_node; - new_node->normal_full_path = raddbgic_normal_string_from_path_node(bctx->arena, path_node); - result = path_node->src_file = new_node; - } - return result; -} - -//- rjf: per-unit line info baking - -RADDBGI_PROC RADDBGIC_UnitLinesCombined* -raddbgic_unit_combine_lines(RADDBGIC_Arena *arena, RADDBGIC_BakeCtx *bctx, RADDBGIC_LineSequenceNode *first_seq) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // gather up all line info into two arrays - // keys: sortable array; pairs voffs with line info records; null records are sequence enders - // recs: contains all the source coordinates for a range of voffs - RADDBGI_U64 line_count = 0; - RADDBGI_U64 seq_count = 0; - for(RADDBGIC_LineSequenceNode *node = first_seq; - node != 0; - node = node->next) - { - seq_count += 1; - line_count += node->line_seq.line_count; - } - - RADDBGI_U64 key_count = line_count + seq_count; - RADDBGIC_SortKey *line_keys = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_SortKey, key_count); - RADDBGIC_LineRec *line_recs = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_LineRec, line_count); - - { - RADDBGIC_SortKey *key_ptr = line_keys; - RADDBGIC_LineRec *rec_ptr = line_recs; - - for(RADDBGIC_LineSequenceNode *node = first_seq; - node != 0; - node = node->next) - { - RADDBGIC_PathNode *src_path = - raddbgic_paths_node_from_path(bctx, node->line_seq.file_name); - RADDBGIC_SrcNode *src_file = raddbgic_paths_src_node_from_path_node(bctx, src_path); - RADDBGI_U32 file_id = src_file->idx; - - RADDBGI_U64 node_line_count = node->line_seq.line_count; - for(RADDBGI_U64 i = 0; i < node_line_count; i += 1){ - key_ptr->key = node->line_seq.voffs[i]; - key_ptr->val = rec_ptr; - key_ptr += 1; - - rec_ptr->file_id = file_id; - rec_ptr->line_num = node->line_seq.line_nums[i]; - if(node->line_seq.col_nums != 0){ - rec_ptr->col_first = node->line_seq.col_nums[i*2]; - rec_ptr->col_opl = node->line_seq.col_nums[i*2 + 1]; - } - rec_ptr += 1; - } - - key_ptr->key = node->line_seq.voffs[node_line_count]; - key_ptr->val = 0; - key_ptr += 1; - - RADDBGIC_LineMapFragment *fragment = raddbgic_push_array(arena, RADDBGIC_LineMapFragment, 1); - RADDBGIC_SLLQueuePush(src_file->first_fragment, src_file->last_fragment, fragment); - fragment->sequence = node; - } - } - - // sort - RADDBGIC_SortKey *sorted_line_keys = raddbgic_sort_key_array(scratch.arena, line_keys, key_count); - - // TODO(allen): do a pass over sorted keys to make sure duplicate keys are sorted with - // null record first, and no more than one null record and one non-null record - - // arrange output - RADDBGI_U64 *arranged_voffs = raddbgic_push_array_no_zero(arena, RADDBGI_U64, key_count + 1); - RADDBGI_Line *arranged_lines = raddbgic_push_array_no_zero(arena, RADDBGI_Line, key_count); - - for(RADDBGI_U64 i = 0; i < key_count; i += 1){ - arranged_voffs[i] = sorted_line_keys[i].key; - } - arranged_voffs[key_count] = ~0ull; - for(RADDBGI_U64 i = 0; i < key_count; i += 1){ - RADDBGIC_LineRec *rec = (RADDBGIC_LineRec*)sorted_line_keys[i].val; - if(rec != 0){ - arranged_lines[i].file_idx = rec->file_id; - arranged_lines[i].line_num = rec->line_num; - } - else{ - arranged_lines[i].file_idx = 0; - arranged_lines[i].line_num = 0; - } - } - - RADDBGIC_UnitLinesCombined *result = raddbgic_push_array(arena, RADDBGIC_UnitLinesCombined, 1); - result->voffs = arranged_voffs; - result->lines = arranged_lines; - result->cols = 0; - result->line_count = key_count; - - scratch_end(scratch); - return result; -} - -//- rjf: per-src line info baking - -RADDBGI_PROC RADDBGIC_SrcLinesCombined* -raddbgic_source_combine_lines(RADDBGIC_Arena *arena, RADDBGIC_LineMapFragment *first) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // gather line number map - RADDBGIC_SrcLineMapBucket *first_bucket = 0; - RADDBGIC_SrcLineMapBucket *last_bucket = 0; - RADDBGI_U64 line_hash_slots_count = 1024; - RADDBGIC_SrcLineMapBucket **line_hash_slots = raddbgic_push_array(scratch.arena, RADDBGIC_SrcLineMapBucket *, line_hash_slots_count); - RADDBGI_U64 line_count = 0; - RADDBGI_U64 voff_count = 0; - RADDBGI_U64 max_line_num = 0; - { - for(RADDBGIC_LineMapFragment *map_fragment = first; - map_fragment != 0; - map_fragment = map_fragment->next) - { - RADDBGIC_LineSequence *sequence = &map_fragment->sequence->line_seq; - - RADDBGI_U64 *seq_voffs = sequence->voffs; - RADDBGI_U32 *seq_line_nums = sequence->line_nums; - RADDBGI_U64 seq_line_count = sequence->line_count; - for(RADDBGI_U64 i = 0; i < seq_line_count; i += 1){ - RADDBGI_U32 line_num = seq_line_nums[i]; - RADDBGI_U64 voff = seq_voffs[i]; - RADDBGI_U64 line_hash_slot_idx = line_num%line_hash_slots_count; - - // update unique voff counter & max line number - voff_count += 1; - max_line_num = Max(max_line_num, line_num); - - // find match - RADDBGIC_SrcLineMapBucket *match = 0; - { - for(RADDBGIC_SrcLineMapBucket *node = line_hash_slots[line_hash_slot_idx]; - node != 0; - node = node->hash_next){ - if(node->line_num == line_num){ - match = node; - break; - } - } - } - - // introduce new line if no match - if(match == 0){ - match = raddbgic_push_array(scratch.arena, RADDBGIC_SrcLineMapBucket, 1); - RADDBGIC_SLLQueuePush_N(first_bucket, last_bucket, match, order_next); - RADDBGIC_SLLStackPush_N(line_hash_slots[line_hash_slot_idx], match, hash_next); - match->line_num = line_num; - line_count += 1; - } - - // insert new voff - { - RADDBGIC_SrcLineMapVoffBlock *block = raddbgic_push_array(scratch.arena, RADDBGIC_SrcLineMapVoffBlock, 1); - RADDBGIC_SLLQueuePush(match->first_voff_block, match->last_voff_block, block); - match->voff_count += 1; - block->voff = voff; - } - } - } - } - - // bake sortable keys array - RADDBGIC_SortKey *keys = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_SortKey, line_count); - { - RADDBGIC_SortKey *key_ptr = keys; - for(RADDBGIC_SrcLineMapBucket *node = first_bucket; - node != 0; - node = node->order_next, key_ptr += 1){ - key_ptr->key = node->line_num; - key_ptr->val = node; - } - } - - // sort - RADDBGIC_SortKey *sorted_keys = raddbgic_sort_key_array(scratch.arena, keys, line_count); - - // bake result - RADDBGI_U32 *line_nums = raddbgic_push_array_no_zero(arena, RADDBGI_U32, line_count); - RADDBGI_U32 *line_ranges = raddbgic_push_array_no_zero(arena, RADDBGI_U32, line_count + 1); - RADDBGI_U64 *voffs = raddbgic_push_array_no_zero(arena, RADDBGI_U64, voff_count); - { - RADDBGI_U64 *voff_ptr = voffs; - for(RADDBGI_U32 i = 0; i < line_count; i += 1){ - line_nums[i] = sorted_keys[i].key; - line_ranges[i] = (RADDBGI_U32)(voff_ptr - voffs); - RADDBGIC_SrcLineMapBucket *bucket = (RADDBGIC_SrcLineMapBucket*)sorted_keys[i].val; - for(RADDBGIC_SrcLineMapVoffBlock *node = bucket->first_voff_block; - node != 0; - node = node->next){ - *voff_ptr = node->voff; - voff_ptr += 1; - } - } - line_ranges[line_count] = voff_count; - } - - RADDBGIC_SrcLinesCombined *result = raddbgic_push_array(arena, RADDBGIC_SrcLinesCombined, 1); - result->line_nums = line_nums; - result->line_ranges = line_ranges; - result->line_count = line_count; - result->voffs = voffs; - result->voff_count = voff_count; - - scratch_end(scratch); - return result; -} - -//- rjf: vmap baking -RADDBGI_PROC RADDBGIC_VMap* -raddbgic_vmap_from_markers(RADDBGIC_Arena *arena, RADDBGIC_VMapMarker *markers, RADDBGIC_SortKey *keys, RADDBGI_U64 marker_count) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // sort markers - RADDBGIC_SortKey *sorted_keys = raddbgic_sort_key_array(scratch.arena, keys, marker_count); - - // determine if an extra vmap entry for zero is needed - RADDBGI_U32 extra_vmap_entry = 0; - if(marker_count > 0 && sorted_keys[0].key != 0){ - extra_vmap_entry = 1; - } - - // fill output vmap entries - RADDBGI_U32 vmap_count_raw = marker_count - 1 + extra_vmap_entry; - RADDBGI_VMapEntry *vmap = raddbgic_push_array_no_zero(arena, RADDBGI_VMapEntry, vmap_count_raw + 1); - RADDBGI_U32 vmap_entry_count_pass_1 = 0; - - { - RADDBGI_VMapEntry *vmap_ptr = vmap; - - if(extra_vmap_entry){ - vmap_ptr->voff = 0; - vmap_ptr->idx = 0; - vmap_ptr += 1; - } - - RADDBGIC_VMapRangeTracker *tracker_stack = 0; - RADDBGIC_VMapRangeTracker *tracker_free = 0; - - RADDBGIC_SortKey *key_ptr = sorted_keys; - RADDBGIC_SortKey *key_opl = sorted_keys + marker_count; - for(;key_ptr < key_opl;){ - // get initial map state from tracker stack - RADDBGI_U32 initial_idx = (RADDBGI_U32)0xffffffff; - if(tracker_stack != 0){ - initial_idx = tracker_stack->idx; - } - - // update tracker stack - // * we must process _all_ of the changes that apply at this voff before moving on - RADDBGI_U64 voff = key_ptr->key; - - for(;key_ptr < key_opl && key_ptr->key == voff; key_ptr += 1){ - RADDBGIC_VMapMarker *marker = (RADDBGIC_VMapMarker*)key_ptr->val; - RADDBGI_U32 idx = marker->idx; - - // push to stack - if(marker->begin_range){ - RADDBGIC_VMapRangeTracker *new_tracker = tracker_free; - if(new_tracker != 0){ - RADDBGIC_SLLStackPop(tracker_free); - } - else{ - new_tracker = raddbgic_push_array(scratch.arena, RADDBGIC_VMapRangeTracker, 1); - } - RADDBGIC_SLLStackPush(tracker_stack, new_tracker); - new_tracker->idx = idx; - } - - // pop matching node from stack (not always the top) - else{ - RADDBGIC_VMapRangeTracker **ptr_in = &tracker_stack; - RADDBGIC_VMapRangeTracker *match = 0; - for(RADDBGIC_VMapRangeTracker *node = tracker_stack; - node != 0;){ - if(node->idx == idx){ - match = node; - break; - } - ptr_in = &node->next; - node = node->next; - } - if(match != 0){ - *ptr_in = match->next; - RADDBGIC_SLLStackPush(tracker_free, match); - } - } - } - - // get final map state from tracker stack - RADDBGI_U32 final_idx = 0; - if(tracker_stack != 0){ - final_idx = tracker_stack->idx; - } - - // if final is different from initial - emit new vmap entry - if(final_idx != initial_idx){ - vmap_ptr->voff = voff; - vmap_ptr->idx = final_idx; - vmap_ptr += 1; - } - } - - vmap_entry_count_pass_1 = (RADDBGI_U32)(vmap_ptr - vmap); - } - - // replace zero unit indexes that follow a non-zero - // TODO(rjf): 0 *is* a real unit index right now - if(0) - { - // (the last entry is not replaced because it acts as a terminator) - RADDBGI_U32 last = vmap_entry_count_pass_1 - 1; - - RADDBGI_VMapEntry *vmap_ptr = vmap; - RADDBGI_U64 real_idx = 0; - - for(RADDBGI_U32 i = 0; i < last; i += 1, vmap_ptr += 1){ - // is this a zero after a real index? - if(vmap_ptr->idx == 0){ - vmap_ptr->idx = real_idx; - } - - // remember a real index - else{ - real_idx = vmap_ptr->idx; - } - } - } - - // combine duplicate neighbors - RADDBGI_U32 vmap_entry_count = 0; - { - RADDBGI_VMapEntry *vmap_ptr = vmap; - RADDBGI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; - RADDBGI_VMapEntry *vmap_out = vmap; - - for(;vmap_ptr < vmap_opl;){ - RADDBGI_VMapEntry *vmap_range_first = vmap_ptr; - RADDBGI_U64 idx = vmap_ptr->idx; - vmap_ptr += 1; - for(;vmap_ptr < vmap_opl && vmap_ptr->idx == idx;) vmap_ptr += 1; - raddbgic_memcpy_struct(vmap_out, vmap_range_first); - vmap_out += 1; - } - - vmap_entry_count = (RADDBGI_U32)(vmap_out - vmap); - } - - // fill result - RADDBGIC_VMap *result = raddbgic_push_array(arena, RADDBGIC_VMap, 1); - result->vmap = vmap; - result->count = vmap_entry_count - 1; - - raddbgic_scratch_end(scratch); - - return result; -} - -RADDBGI_PROC RADDBGIC_VMap* -raddbgic_vmap_from_unit_ranges(RADDBGIC_Arena *arena, RADDBGIC_UnitVMapRange *first, RADDBGI_U64 count) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // count necessary markers - RADDBGI_U64 marker_count = count*2; - - // fill markers - RADDBGIC_SortKey *keys = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_SortKey, marker_count); - RADDBGIC_VMapMarker *markers = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_VMapMarker, marker_count); - - { - RADDBGIC_SortKey *key_ptr = keys; - RADDBGIC_VMapMarker *marker_ptr = markers; - for(RADDBGIC_UnitVMapRange *range = first; - range != 0; - range = range->next){ - if(range->first < range->opl){ - RADDBGI_U32 unit_idx = range->unit->idx; - - key_ptr->key = range->first; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = range->opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - } - - // construct vmap - RADDBGIC_VMap *result = raddbgic_vmap_from_markers(arena, markers, keys, marker_count); - raddbgic_scratch_end(scratch); - return result; -} - -//- rjf: type info baking - -RADDBGI_PROC RADDBGI_U32* -raddbgic_idx_run_from_types(RADDBGIC_Arena *arena, RADDBGIC_Type **types, RADDBGI_U32 count) -{ - RADDBGI_U32 *result = raddbgic_push_array(arena, RADDBGI_U32, count); - for(RADDBGI_U32 i = 0; i < count; i += 1){ - result[i] = types[i]->idx; - } - return result; -} - -RADDBGI_PROC RADDBGIC_TypeData* -raddbgic_type_data_combine(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // fill type nodes - RADDBGI_U32 type_count = root->type_count; - RADDBGI_TypeNode *type_nodes = raddbgic_push_array_no_zero(arena, RADDBGI_TypeNode, type_count); - - { - RADDBGI_TypeNode *ptr = type_nodes; - RADDBGI_TypeNode *opl = ptr + type_count; - RADDBGIC_Type *loose_type = root->first_type; - for(;loose_type != 0 && ptr < opl; - loose_type = loose_type->next_order, ptr += 1){ - - RADDBGI_TypeKind kind = loose_type->kind; - - // shared - ptr->kind = kind; - ptr->flags = loose_type->flags; - ptr->byte_size = loose_type->byte_size; - - // built-in - if(RADDBGI_TypeKind_FirstBuiltIn <= kind && kind <= RADDBGI_TypeKind_LastBuiltIn){ - ptr->built_in.name_string_idx = raddbgic_string(bctx, loose_type->name); - } - - // constructed - else if(RADDBGI_TypeKind_FirstConstructed <= kind && kind <= RADDBGI_TypeKind_LastConstructed){ - ptr->constructed.direct_type_idx = loose_type->direct_type->idx; - - switch (kind){ - case RADDBGI_TypeKind_Array: - { - ptr->constructed.count = loose_type->count; - }break; - - case RADDBGI_TypeKind_Function: - { - // parameters - RADDBGI_U32 count = loose_type->count; - RADDBGI_U32 *idx_run = raddbgic_idx_run_from_types(scratch.arena, loose_type->param_types, count); - ptr->constructed.param_idx_run_first = raddbgic_idx_run(bctx, idx_run, count); - ptr->constructed.count = count; - }break; - - case RADDBGI_TypeKind_Method: - { - // parameters - RADDBGI_U32 count = loose_type->count; - RADDBGI_U32 *idx_run = raddbgic_idx_run_from_types(scratch.arena, loose_type->param_types, count); - ptr->constructed.param_idx_run_first = raddbgic_idx_run(bctx, idx_run, count); - ptr->constructed.count = count; - }break; - } - } - - // user-defined - else if(RADDBGI_TypeKind_FirstUserDefined <= kind && kind <= RADDBGI_TypeKind_LastUserDefined){ - ptr->user_defined.name_string_idx = raddbgic_string(bctx, loose_type->name); - if(loose_type->udt != 0){ - ptr->user_defined.udt_idx = loose_type->udt->idx; - } - if(loose_type->direct_type != 0){ - ptr->user_defined.direct_type_idx = loose_type->direct_type->idx; - } - } - - // bitfield - else if(kind == RADDBGI_TypeKind_Bitfield){ - ptr->bitfield.off = loose_type->off; - ptr->bitfield.size = loose_type->count; - } - - raddbgic_scratch_end(scratch); - } - - // both iterators should end at the same time - raddbgic_assert(loose_type == 0); - raddbgic_assert(ptr == opl); - } - - - // fill udts - RADDBGI_U32 udt_count = root->type_udt_count; - RADDBGI_UDT *udts = raddbgic_push_array_no_zero(arena, RADDBGI_UDT, udt_count); - - RADDBGI_U32 member_count = root->total_member_count; - RADDBGI_Member *members = raddbgic_push_array_no_zero(arena, RADDBGI_Member, member_count); - - RADDBGI_U32 enum_member_count = root->total_enum_val_count; - RADDBGI_EnumMember *enum_members = raddbgic_push_array_no_zero(arena, RADDBGI_EnumMember, enum_member_count); - - { - RADDBGI_UDT *ptr = udts; - RADDBGI_UDT *opl = ptr + udt_count; - - RADDBGI_Member *member_ptr = members; - RADDBGI_Member *member_opl = members + member_count; - - RADDBGI_EnumMember *enum_member_ptr = enum_members; - RADDBGI_EnumMember *enum_member_opl = enum_members + enum_member_count; - - RADDBGIC_TypeUDT *loose_udt = root->first_udt; - for(;loose_udt != 0 && ptr < opl; - loose_udt = loose_udt->next_order, ptr += 1){ - ptr->self_type_idx = loose_udt->self_type->idx; - - raddbgic_assert(loose_udt->member_count == 0 || - loose_udt->enum_val_count == 0); - - // enum members - if(loose_udt->enum_val_count != 0){ - ptr->flags |= RADDBGI_UserDefinedTypeFlag_EnumMembers; - - ptr->member_first = (RADDBGI_U32)(enum_member_ptr - enum_members); - ptr->member_count = loose_udt->enum_val_count; - - RADDBGI_U32 local_enum_val_count = loose_udt->enum_val_count; - RADDBGIC_TypeEnumVal *loose_enum_val = loose_udt->first_enum_val; - for(RADDBGI_U32 i = 0; - i < local_enum_val_count; - i += 1, enum_member_ptr += 1, loose_enum_val = loose_enum_val->next){ - enum_member_ptr->name_string_idx = raddbgic_string(bctx, loose_enum_val->name); - enum_member_ptr->val = loose_enum_val->val; - } - } - - // struct/class/union members - else{ - ptr->member_first = (RADDBGI_U32)(member_ptr - members); - ptr->member_count = loose_udt->member_count; - - RADDBGI_U32 local_member_count = loose_udt->member_count; - RADDBGIC_TypeMember *loose_member = loose_udt->first_member; - for(RADDBGI_U32 i = 0; - i < local_member_count; - i += 1, member_ptr += 1, loose_member = loose_member->next){ - member_ptr->kind = loose_member->kind; - // TODO(allen): member_ptr->visibility = ; - member_ptr->name_string_idx = raddbgic_string(bctx, loose_member->name); - member_ptr->off = loose_member->off; - member_ptr->type_idx = loose_member->type->idx; - - // TODO(allen): - if(loose_member->kind == RADDBGI_MemberKind_Method){ - //loose_member_ptr->unit_idx = ; - //loose_member_ptr->proc_symbol_idx = ; - } - } - - } - - RADDBGI_U32 file_idx = 0; - if(loose_udt->source_path.size > 0){ - RADDBGIC_PathNode *path_node = raddbgic_paths_node_from_path(bctx, loose_udt->source_path); - RADDBGIC_SrcNode *src_node = raddbgic_paths_src_node_from_path_node(bctx, path_node); - file_idx = src_node->idx; - } - - ptr->file_idx = file_idx; - ptr->line = loose_udt->line; - ptr->col = loose_udt->col; - } - - // all iterators should end at the same time - raddbgic_assert(loose_udt == 0); - raddbgic_assert(ptr == opl); - raddbgic_assert(member_ptr == member_opl); - raddbgic_assert(enum_member_ptr == enum_member_opl); - } - - - // fill result - RADDBGIC_TypeData *result = raddbgic_push_array(arena, RADDBGIC_TypeData, 1); - result->type_nodes = type_nodes; - result->type_node_count = type_count; - result->udts = udts; - result->udt_count = udt_count; - result->members = members; - result->member_count = member_count; - result->enum_members = enum_members; - result->enum_member_count = enum_member_count; - - raddbgic_scratch_end(scratch); - return result; -} - -//- rjf: symbol data baking - -RADDBGI_PROC RADDBGIC_SymbolData* -raddbgic_symbol_data_combine(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - // count symbol kinds - RADDBGI_U32 globalvar_count = 1 + root->symbol_kind_counts[RADDBGIC_SymbolKind_GlobalVariable]; - RADDBGI_U32 threadvar_count = 1 + root->symbol_kind_counts[RADDBGIC_SymbolKind_ThreadVariable]; - RADDBGI_U32 procedure_count = 1 + root->symbol_kind_counts[RADDBGIC_SymbolKind_Procedure]; - - // allocate symbol arrays - RADDBGI_GlobalVariable *global_variables = - raddbgic_push_array(arena, RADDBGI_GlobalVariable, globalvar_count); - - RADDBGI_ThreadVariable *thread_variables = - raddbgic_push_array(arena, RADDBGI_ThreadVariable, threadvar_count); - - RADDBGI_Procedure *procedures = raddbgic_push_array(arena, RADDBGI_Procedure, procedure_count); - - // fill symbol arrays - { - RADDBGI_GlobalVariable *global_ptr = global_variables; - RADDBGI_ThreadVariable *thread_local_ptr = thread_variables; - RADDBGI_Procedure *procedure_ptr = procedures; - - // nils - global_ptr += 1; - thread_local_ptr += 1; - procedure_ptr += 1; - - // symbol nodes - for(RADDBGIC_Symbol *node = root->first_symbol; - node != 0; - node = node->next_order){ - RADDBGI_U32 name_string_idx = raddbgic_string(bctx, node->name); - RADDBGI_U32 link_name_string_idx = raddbgic_string(bctx, node->link_name); - RADDBGI_U32 type_idx = node->type->idx; - - RADDBGI_LinkFlags link_flags = 0; - RADDBGI_U32 container_idx = 0; - { - if(node->is_extern){ - link_flags |= RADDBGI_LinkFlag_External; - } - if(node->container_symbol != 0){ - container_idx = node->container_symbol->idx; - link_flags |= RADDBGI_LinkFlag_ProcScoped; - } - else if(node->container_type != 0 && node->container_type->udt != 0){ - container_idx = node->container_type->udt->idx; - link_flags |= RADDBGI_LinkFlag_TypeScoped; - } - } - - switch (node->kind){ - default:{}break; - - case RADDBGIC_SymbolKind_GlobalVariable: - { - global_ptr->name_string_idx = name_string_idx; - global_ptr->link_flags = link_flags; - global_ptr->voff = node->offset; - global_ptr->type_idx = type_idx; - global_ptr->container_idx = container_idx; - global_ptr += 1; - }break; - - case RADDBGIC_SymbolKind_ThreadVariable: - { - thread_local_ptr->name_string_idx = name_string_idx; - thread_local_ptr->link_flags = link_flags; - thread_local_ptr->tls_off = (RADDBGI_U32)node->offset; - thread_local_ptr->type_idx = type_idx; - thread_local_ptr->container_idx = container_idx; - thread_local_ptr += 1; - }break; - - case RADDBGIC_SymbolKind_Procedure: - { - procedure_ptr->name_string_idx = name_string_idx; - procedure_ptr->link_name_string_idx = link_name_string_idx; - procedure_ptr->link_flags = link_flags; - procedure_ptr->type_idx = type_idx; - procedure_ptr->root_scope_idx = node->root_scope->idx; - procedure_ptr->container_idx = container_idx; - procedure_ptr += 1; - }break; - } - } - - raddbgic_assert(global_ptr - global_variables == globalvar_count); - raddbgic_assert(thread_local_ptr - thread_variables == threadvar_count); - raddbgic_assert(procedure_ptr - procedures == procedure_count); - } - - // global vmap - RADDBGIC_VMap *global_vmap = 0; - { - // count necessary markers - RADDBGI_U32 marker_count = globalvar_count*2; - - // fill markers - RADDBGIC_SortKey *keys = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_SortKey, marker_count); - RADDBGIC_VMapMarker *markers = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_VMapMarker, marker_count); - - RADDBGIC_SortKey *key_ptr = keys; - RADDBGIC_VMapMarker *marker_ptr = markers; - - // real globals - for(RADDBGIC_Symbol *node = root->first_symbol; - node != 0; - node = node->next_order){ - if(node->kind == RADDBGIC_SymbolKind_GlobalVariable){ - RADDBGI_U32 global_idx = node->idx; - - RADDBGI_U64 first = node->offset; - RADDBGI_U64 opl = first + node->type->byte_size; - - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - // nil global - { - RADDBGI_U32 global_idx = 0; - - RADDBGI_U64 first = 0; - RADDBGI_U64 opl = (RADDBGI_U64)0xffffffffffffffffull; - - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - - // assert we filled all the markers - raddbgic_assert(key_ptr - keys == marker_count && - marker_ptr - markers == marker_count); - - // construct vmap - global_vmap = raddbgic_vmap_from_markers(arena, markers, keys, marker_count); - } - - // allocate scope array - - // (assert there is a nil scope) - raddbgic_assert(root->first_scope != 0 && - root->first_scope->symbol == 0 && - root->first_scope->first_child == 0 && - root->first_scope->next_sibling == 0 && - root->first_scope->range_count == 0); - - RADDBGI_U32 scope_count = root->scope_count; - RADDBGI_Scope *scopes = raddbgic_push_array(arena, RADDBGI_Scope, scope_count); - - RADDBGI_U32 scope_voff_count = root->scope_voff_count; - RADDBGI_U64 *scope_voffs = raddbgic_push_array(arena, RADDBGI_U64, scope_voff_count); - - RADDBGI_U32 local_count = root->local_count; - RADDBGI_Local *locals = raddbgic_push_array(arena, RADDBGI_Local, local_count); - - RADDBGI_U32 location_block_count = root->location_count; - RADDBGI_LocationBlock *location_blocks = - raddbgic_push_array(arena, RADDBGI_LocationBlock, location_block_count); - - RADDBGIC_String8List location_data = {0}; - - // iterate scopes, locals, and locations - // fill scope voffs, locals, and location information - { - RADDBGI_Scope *scope_ptr = scopes; - RADDBGI_U64 *scope_voff_ptr = scope_voffs; - RADDBGI_Local *local_ptr = locals; - RADDBGI_LocationBlock *location_block_ptr = location_blocks; - - for(RADDBGIC_Scope *node = root->first_scope; - node != 0; - node = node->next_order, scope_ptr += 1){ - - // emit voffs - RADDBGI_U32 voff_first = (RADDBGI_U32)(scope_voff_ptr - scope_voffs); - for(RADDBGIC_VOffRange *range = node->first_range; - range != 0; - range = range->next){ - *scope_voff_ptr = range->voff_first; - scope_voff_ptr += 1; - *scope_voff_ptr = range->voff_opl; - scope_voff_ptr += 1; - } - RADDBGI_U32 voff_opl = (RADDBGI_U32)(scope_voff_ptr - scope_voffs); - - // emit locals - RADDBGI_U32 scope_local_count = node->local_count; - RADDBGI_U32 scope_local_first = (RADDBGI_U32)(local_ptr - locals); - for(RADDBGIC_Local *slocal = node->first_local; - slocal != 0; - slocal = slocal->next, local_ptr += 1){ - local_ptr->kind = slocal->kind; - local_ptr->name_string_idx = raddbgic_string(bctx, slocal->name); - local_ptr->type_idx = slocal->type->idx; - - RADDBGIC_LocationSet *locset = slocal->locset; - if(locset != 0){ - RADDBGI_U32 location_first = (RADDBGI_U32)(location_block_ptr - location_blocks); - RADDBGI_U32 location_opl = location_first + locset->location_case_count; - local_ptr->location_first = location_first; - local_ptr->location_opl = location_opl; - - for(RADDBGIC_LocationCase *location_case = locset->first_location_case; - location_case != 0; - location_case = location_case->next){ - location_block_ptr->scope_off_first = location_case->voff_first; - location_block_ptr->scope_off_opl = location_case->voff_opl; - location_block_ptr->location_data_off = location_data.total_size; - location_block_ptr += 1; - - RADDBGIC_Location *location = location_case->location; - if(location == 0){ - RADDBGI_U64 data = 0; - str8_serial_push_align(scratch.arena, &location_data, 8); - str8_serial_push_data(scratch.arena, &location_data, &data, 1); - } - else{ - switch (location->kind){ - default: - { - RADDBGI_U64 data = 0; - str8_serial_push_align(scratch.arena, &location_data, 8); - str8_serial_push_data(scratch.arena, &location_data, &data, 1); - }break; - - case RADDBGI_LocationKind_AddrBytecodeStream: - case RADDBGI_LocationKind_ValBytecodeStream: - { - raddbgic_str8_list_push(scratch.arena, &location_data, raddbgic_str8_copy(scratch.arena, raddbgic_str8_struct(&location->kind))); - for(RADDBGIC_EvalBytecodeOp *op_node = location->bytecode.first_op; - op_node != 0; - op_node = op_node->next){ - RADDBGI_U8 op_data[9]; - op_data[0] = op_node->op; - raddbgic_memcpy(op_data + 1, &op_node->p, op_node->p_size); - RADDBGIC_String8 op_data_str = raddbgic_str8(op_data, 1 + op_node->p_size); - raddbgic_str8_list_push(scratch.arena, &location_data, raddbgic_str8_copy(scratch.arena, op_data_str)); - } - { - RADDBGI_U64 data = 0; - RADDBGIC_String8 data_str = raddbgic_str8((RADDBGI_U8 *)&data, 1); - raddbgic_str8_list_push(scratch.arena, &location_data, raddbgic_str8_copy(scratch.arena, data_str)); - } - }break; - - case RADDBGI_LocationKind_AddrRegisterPlusU16: - case RADDBGI_LocationKind_AddrAddrRegisterPlusU16: - { - RADDBGI_LocationRegisterPlusU16 loc = {0}; - loc.kind = location->kind; - loc.register_code = location->register_code; - loc.offset = location->offset; - raddbgic_str8_list_push(scratch.arena, &location_data, raddbgic_str8_copy(scratch.arena, raddbgic_str8_struct(&loc))); - }break; - - case RADDBGI_LocationKind_ValRegister: - { - RADDBGI_LocationRegister loc = {0}; - loc.kind = location->kind; - loc.register_code = location->register_code; - raddbgic_str8_list_push(scratch.arena, &location_data, raddbgic_str8_copy(scratch.arena, raddbgic_str8_struct(&loc))); - }break; - } - } - } - - raddbgic_assert(location_block_ptr - location_blocks == location_opl); - } - } - - raddbgic_assert(local_ptr - locals == scope_local_first + scope_local_count); - - // emit scope - scope_ptr->proc_idx = (node->symbol == 0)?0:node->symbol->idx; - scope_ptr->parent_scope_idx = (node->parent_scope == 0)?0:node->parent_scope->idx; - scope_ptr->first_child_scope_idx = (node->first_child == 0)?0:node->first_child->idx; - scope_ptr->next_sibling_scope_idx = (node->next_sibling == 0)?0:node->next_sibling->idx; - scope_ptr->voff_range_first = voff_first; - scope_ptr->voff_range_opl = voff_opl; - scope_ptr->local_first = scope_local_first; - scope_ptr->local_count = scope_local_count; - - // TODO(allen): - //scope_ptr->static_local_idx_run_first = ; - //scope_ptr->static_local_count = ; - } - - raddbgic_assert(scope_ptr - scopes == scope_count); - raddbgic_assert(local_ptr - locals == local_count); - } - - // flatten location data - RADDBGIC_String8 location_data_str = raddbgic_str8_list_join(arena, &location_data, raddbgic_str8_lit("")); - - // scope vmap - RADDBGIC_VMap *scope_vmap = 0; - { - // count necessary markers - RADDBGI_U32 marker_count = scope_voff_count; - - // fill markers - RADDBGIC_SortKey *keys = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_SortKey, marker_count); - RADDBGIC_VMapMarker *markers = raddbgic_push_array_no_zero(scratch.arena, RADDBGIC_VMapMarker, marker_count); - - RADDBGIC_SortKey *key_ptr = keys; - RADDBGIC_VMapMarker *marker_ptr = markers; - - for(RADDBGIC_Scope *node = root->first_scope; - node != 0; - node = node->next_order){ - RADDBGI_U32 scope_idx = node->idx; - - for(RADDBGIC_VOffRange *range = node->first_range; - range != 0; - range = range->next){ - key_ptr->key = range->voff_first; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = range->voff_opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - scope_vmap = raddbgic_vmap_from_markers(arena, markers, keys, marker_count); - } - - // fill result - RADDBGIC_SymbolData *result = raddbgic_push_array(arena, RADDBGIC_SymbolData, 1); - result->global_variables = global_variables; - result->global_variable_count = globalvar_count; - result->global_vmap = global_vmap; - result->thread_variables = thread_variables; - result->thread_variable_count = threadvar_count; - result->procedures = procedures; - result->procedure_count = procedure_count; - result->scopes = scopes; - result->scope_count = scope_count; - result->scope_voffs = scope_voffs; - result->scope_voff_count = scope_voff_count; - result->scope_vmap = scope_vmap; - result->locals = locals; - result->local_count = local_count; - result->location_blocks = location_blocks; - result->location_block_count = location_block_count; - result->location_data = location_data_str.str; - result->location_data_size = location_data_str.size; - - raddbgic_scratch_end(scratch); - return result; -} - -//- rjf: name map baking - -RADDBGI_PROC RADDBGIC_NameMapBaked* -raddbgic_name_map_bake(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx, RADDBGIC_NameMap *map) -{ - RADDBGIC_Temp scratch = raddbgic_scratch_begin(&arena, 1); - - RADDBGI_U32 bucket_count = map->name_count; - RADDBGI_U32 node_count = map->name_count; - - // setup the final bucket layouts - RADDBGIC_NameMapSemiBucket *sbuckets = raddbgic_push_array(scratch.arena, RADDBGIC_NameMapSemiBucket, bucket_count); - for(RADDBGIC_NameMapNode *node = map->first; - node != 0; - node = node->order_next){ - RADDBGI_U64 hash = raddbgi_hash(node->string.str, node->string.size); - RADDBGI_U64 bi = hash%bucket_count; - RADDBGIC_NameMapSemiNode *snode = raddbgic_push_array(scratch.arena, RADDBGIC_NameMapSemiNode, 1); - SLLQueuePush(sbuckets[bi].first, sbuckets[bi].last, snode); - snode->node = node; - sbuckets[bi].count += 1; - } - - // allocate tables - RADDBGI_NameMapBucket *buckets = raddbgic_push_array(arena, RADDBGI_NameMapBucket, bucket_count); - RADDBGI_NameMapNode *nodes = raddbgic_push_array_no_zero(arena, RADDBGI_NameMapNode, node_count); - - // convert to serialized buckets & nodes - { - RADDBGI_NameMapBucket *bucket_ptr = buckets; - RADDBGI_NameMapNode *node_ptr = nodes; - for(RADDBGI_U32 i = 0; i < bucket_count; i += 1, bucket_ptr += 1){ - bucket_ptr->first_node = (RADDBGI_U32)(node_ptr - nodes); - bucket_ptr->node_count = sbuckets[i].count; - - for(RADDBGIC_NameMapSemiNode *snode = sbuckets[i].first; - snode != 0; - snode = snode->next){ - RADDBGIC_NameMapNode *node = snode->node; - - // cons name and index(es) - RADDBGI_U32 string_idx = raddbgic_string(bctx, node->string); - RADDBGI_U32 match_count = node->idx_count; - RADDBGI_U32 idx = 0; - if(match_count == 1){ - idx = node->idx_first->idx[0]; - } - else{ - RADDBGI_U64 temp_pos = raddbgic_arena_pos(scratch.arena); - RADDBGI_U32 *idx_run = raddbgic_push_array_no_zero(scratch.arena, RADDBGI_U32, match_count); - RADDBGI_U32 *idx_ptr = idx_run; - for(RADDBGIC_NameMapIdxNode *idxnode = node->idx_first; - idxnode != 0; - idxnode = idxnode->next){ - for(RADDBGI_U32 i = 0; i < ArrayCount(idxnode->idx); i += 1){ - if(idxnode->idx[i] == 0){ - goto dblbreak; - } - *idx_ptr = idxnode->idx[i]; - idx_ptr += 1; - } - } - dblbreak:; - raddbgic_assert(idx_ptr == idx_run + match_count); - idx = raddbgic_idx_run(bctx, idx_run, match_count); - raddbgic_arena_pop_to(scratch.arena, temp_pos); - } - - // write to node - node_ptr->string_idx = string_idx; - node_ptr->match_count = match_count; - node_ptr->match_idx_or_idx_run_first = idx; - node_ptr += 1; - } - } - raddbgic_assert(node_ptr - nodes == node_count); - } - - raddbgic_scratch_end(scratch); - - RADDBGIC_NameMapBaked *result = raddbgic_push_array(arena, RADDBGIC_NameMapBaked, 1); - result->buckets = buckets; - result->nodes = nodes; - result->bucket_count = bucket_count; - result->node_count = node_count; - return result; -} - -//- rjf: top-level baking entry point - -RADDBGI_PROC void -raddbgic_bake_file(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_String8List *out) -{ - str8_serial_begin(arena, out); - - // setup cons helpers - RADDBGIC_DSections dss = {0}; - raddbgic_dsection(arena, &dss, 0, 0, RADDBGI_DataSectionTag_NULL); - - RADDBGIC_BakeParams bctx_params = {0}; - { - bctx_params.strings_bucket_count = u64_up_to_pow2(root->symbol_map.pair_count*8); - bctx_params.idx_runs_bucket_count = u64_up_to_pow2(root->symbol_map.pair_count*8); - } - RADDBGIC_BakeCtx *bctx = raddbgic_bake_ctx_begin(&bctx_params); - - //////////////////////////////// - // MAIN PART: allocating and filling out sections of the file - - // top level info - RADDBGI_TopLevelInfo *tli = raddbgic_push_array(arena, RADDBGI_TopLevelInfo, 1); - { - RADDBGIC_TopLevelInfo *raddbgic_tli = &root->top_level_info; - tli->architecture = raddbgic_tli->architecture; - tli->exe_name_string_idx = raddbgic_string(bctx, raddbgic_tli->exe_name); - tli->exe_hash = raddbgic_tli->exe_hash; - tli->voff_max = raddbgic_tli->voff_max; - } - raddbgic_dsection(arena, &dss, tli, sizeof(*tli), RADDBGI_DataSectionTag_TopLevelInfo); - - // binary sections array - { - RADDBGI_U32 count = root->binary_section_count; - RADDBGI_BinarySection *sections = raddbgic_push_array(arena, RADDBGI_BinarySection, count); - RADDBGI_BinarySection *dsec = sections; - for(RADDBGIC_BinarySection *ssec = root->binary_section_first; - ssec != 0; - ssec = ssec->next, dsec += 1){ - dsec->name_string_idx = raddbgic_string(bctx, ssec->name); - dsec->flags = ssec->flags; - dsec->voff_first = ssec->voff_first; - dsec->voff_opl = ssec->voff_opl; - dsec->foff_first = ssec->foff_first; - dsec->foff_opl = ssec->foff_opl; - } - raddbgic_dsection(arena, &dss, sections, sizeof(*sections)*count, RADDBGI_DataSectionTag_BinarySections); - } - - // units array - // * pass for per-unit information including: - // * top-level unit information - // * combining line info for whole unit - { - RADDBGI_U32 count = root->unit_count; - RADDBGI_Unit *units = raddbgic_push_array(arena, RADDBGI_Unit, count); - RADDBGI_Unit *dunit = units; - for(RADDBGIC_Unit *sunit = root->unit_first; - sunit != 0; - sunit = sunit->next_order, dunit += 1){ - // strings & paths - RADDBGI_U32 unit_name = raddbgic_string(bctx, sunit->unit_name); - RADDBGI_U32 cmp_name = raddbgic_string(bctx, sunit->compiler_name); - - RADDBGI_U32 src_path = raddbgic_paths_idx_from_path(bctx, sunit->source_file); - RADDBGI_U32 obj_path = raddbgic_paths_idx_from_path(bctx, sunit->object_file); - RADDBGI_U32 archive_path = raddbgic_paths_idx_from_path(bctx, sunit->archive_file); - RADDBGI_U32 build_path = raddbgic_paths_idx_from_path(bctx, sunit->build_path); - - dunit->unit_name_string_idx = unit_name; - dunit->compiler_name_string_idx = cmp_name; - dunit->source_file_path_node = src_path; - dunit->object_file_path_node = obj_path; - dunit->archive_file_path_node = archive_path; - dunit->build_path_node = build_path; - dunit->language = sunit->language; - - // line info (voff -> file*line*col) - RADDBGIC_LineSequenceNode *first_seq = sunit->line_seq_first; - RADDBGIC_UnitLinesCombined *lines = raddbgic_unit_combine_lines(arena, bctx, first_seq); - - RADDBGI_U32 line_count = lines->line_count; - if(line_count > 0){ - dunit->line_info_voffs_data_idx = - raddbgic_dsection(arena, &dss, lines->voffs, sizeof(RADDBGI_U64)*(line_count + 1), - RADDBGI_DataSectionTag_LineInfoVoffs); - dunit->line_info_data_idx = - raddbgic_dsection(arena, &dss, lines->lines, sizeof(RADDBGI_Line)*line_count, - RADDBGI_DataSectionTag_LineInfoData); - if(lines->cols != 0){ - dunit->line_info_col_data_idx = - raddbgic_dsection(arena, &dss, lines->cols, sizeof(RADDBGI_Column)*line_count, - RADDBGI_DataSectionTag_LineInfoColumns); - } - dunit->line_info_count = line_count; - } - } - - raddbgic_dsection(arena, &dss, units, sizeof(*units)*count, RADDBGI_DataSectionTag_Units); - } - - // source file line info baking - // * pass for "source_combine_line" for each source file - - // * can only be run after a pass that does "unit_combine_lines" for each unit. - for(RADDBGIC_SrcNode *src_node = bctx->tree->src_first; - src_node != 0; - src_node = src_node->next){ - RADDBGIC_LineMapFragment *first_fragment = src_node->first_fragment; - RADDBGIC_SrcLinesCombined *lines = raddbgic_source_combine_lines(arena, first_fragment); - RADDBGI_U32 line_count = lines->line_count; - - if(line_count > 0){ - src_node->line_map_count = line_count; - - src_node->line_map_nums_data_idx = - raddbgic_dsection(arena, &dss, lines->line_nums, sizeof(*lines->line_nums)*line_count, - RADDBGI_DataSectionTag_LineMapNumbers); - - src_node->line_map_range_data_idx = - raddbgic_dsection(arena, &dss, lines->line_ranges, sizeof(*lines->line_ranges)*(line_count + 1), - RADDBGI_DataSectionTag_LineMapRanges); - - src_node->line_map_voff_data_idx = - raddbgic_dsection(arena, &dss, lines->voffs, sizeof(*lines->voffs)*lines->voff_count, - RADDBGI_DataSectionTag_LineMapVoffs); - } - } - - // source file name mapping - { - RADDBGIC_NameMap* map = raddbgic_name_map_for_kind(root, RADDBGI_NameMapKind_NormalSourcePaths); - for(RADDBGIC_SrcNode *src_node = bctx->tree->src_first; - src_node != 0; - src_node = src_node->next){ - if(src_node->idx != 0){ - raddbgic_name_map_add_pair(root, map, src_node->normal_full_path, src_node->idx); - } - } - } - - // unit vmap baking - { - RADDBGIC_VMap *vmap = raddbgic_vmap_from_unit_ranges(arena, - root->unit_vmap_range_first, - root->unit_vmap_range_count); - - RADDBGI_U64 vmap_size = sizeof(*vmap->vmap)*(vmap->count + 1); - raddbgic_dsection(arena, &dss, vmap->vmap, vmap_size, RADDBGI_DataSectionTag_UnitVmap); - } - - // type info baking - { - RADDBGIC_TypeData *types = raddbgic_type_data_combine(arena, root, bctx); - - RADDBGI_U64 type_nodes_size = sizeof(*types->type_nodes)*types->type_node_count; - raddbgic_dsection(arena, &dss, types->type_nodes, type_nodes_size, RADDBGI_DataSectionTag_TypeNodes); - - RADDBGI_U64 udt_size = sizeof(*types->udts)*types->udt_count; - raddbgic_dsection(arena, &dss, types->udts, udt_size, RADDBGI_DataSectionTag_UDTs); - - RADDBGI_U64 member_size = sizeof(*types->members)*types->member_count; - raddbgic_dsection(arena, &dss, types->members, member_size, RADDBGI_DataSectionTag_Members); - - RADDBGI_U64 enum_member_size = sizeof(*types->enum_members)*types->enum_member_count; - raddbgic_dsection(arena, &dss, types->enum_members, enum_member_size, RADDBGI_DataSectionTag_EnumMembers); - } - - // symbol info baking - { - RADDBGIC_SymbolData *symbol_data = raddbgic_symbol_data_combine(arena, root, bctx); - - RADDBGI_U64 global_variables_size = - sizeof(*symbol_data->global_variables)*symbol_data->global_variable_count; - raddbgic_dsection(arena, &dss, symbol_data->global_variables, global_variables_size, - RADDBGI_DataSectionTag_GlobalVariables); - - RADDBGIC_VMap *global_vmap = symbol_data->global_vmap; - RADDBGI_U64 global_vmap_size = sizeof(*global_vmap->vmap)*(global_vmap->count + 1); - raddbgic_dsection(arena, &dss, global_vmap->vmap, global_vmap_size, - RADDBGI_DataSectionTag_GlobalVmap); - - RADDBGI_U64 thread_variables_size = - sizeof(*symbol_data->thread_variables)*symbol_data->thread_variable_count; - raddbgic_dsection(arena, &dss, symbol_data->thread_variables, thread_variables_size, - RADDBGI_DataSectionTag_ThreadVariables); - - RADDBGI_U64 procedures_size = sizeof(*symbol_data->procedures)*symbol_data->procedure_count; - raddbgic_dsection(arena, &dss, symbol_data->procedures, procedures_size, - RADDBGI_DataSectionTag_Procedures); - - RADDBGI_U64 scopes_size = sizeof(*symbol_data->scopes)*symbol_data->scope_count; - raddbgic_dsection(arena, &dss, symbol_data->scopes, scopes_size, RADDBGI_DataSectionTag_Scopes); - - RADDBGI_U64 scope_voffs_size = sizeof(*symbol_data->scope_voffs)*symbol_data->scope_voff_count; - raddbgic_dsection(arena, &dss, symbol_data->scope_voffs, scope_voffs_size, - RADDBGI_DataSectionTag_ScopeVoffData); - - RADDBGIC_VMap *scope_vmap = symbol_data->scope_vmap; - RADDBGI_U64 scope_vmap_size = sizeof(*scope_vmap->vmap)*(scope_vmap->count + 1); - raddbgic_dsection(arena, &dss, scope_vmap->vmap, scope_vmap_size, RADDBGI_DataSectionTag_ScopeVmap); - - RADDBGI_U64 local_size = sizeof(*symbol_data->locals)*symbol_data->local_count; - raddbgic_dsection(arena, &dss, symbol_data->locals, local_size, RADDBGI_DataSectionTag_Locals); - - RADDBGI_U64 location_blocks_size = - sizeof(*symbol_data->location_blocks)*symbol_data->location_block_count; - raddbgic_dsection(arena, &dss, symbol_data->location_blocks, location_blocks_size, - RADDBGI_DataSectionTag_LocationBlocks); - - RADDBGI_U64 location_data_size = symbol_data->location_data_size; - raddbgic_dsection(arena, &dss, symbol_data->location_data, location_data_size, - RADDBGI_DataSectionTag_LocationData); - } - - // name map baking - { - RADDBGI_U32 name_map_count = 0; - for(RADDBGI_U32 i = 0; i < RADDBGI_NameMapKind_COUNT; i += 1){ - if(root->name_maps[i] != 0){ - name_map_count += 1; - } - } - - RADDBGI_NameMap *name_maps = raddbgic_push_array(arena, RADDBGI_NameMap, name_map_count); - - RADDBGI_NameMap *name_map_ptr = name_maps; - for(RADDBGI_U32 i = 0; i < RADDBGI_NameMapKind_COUNT; i += 1){ - RADDBGIC_NameMap *map = root->name_maps[i]; - if(map != 0){ - RADDBGIC_NameMapBaked *baked = raddbgic_name_map_bake(arena, root, bctx, map); - - name_map_ptr->kind = i; - name_map_ptr->bucket_data_idx = - raddbgic_dsection(arena, &dss, baked->buckets, sizeof(*baked->buckets)*baked->bucket_count, - RADDBGI_DataSectionTag_NameMapBuckets); - name_map_ptr->node_data_idx = - raddbgic_dsection(arena, &dss, baked->nodes, sizeof(*baked->nodes)*baked->node_count, - RADDBGI_DataSectionTag_NameMapNodes); - name_map_ptr += 1; - } - } - - raddbgic_dsection(arena, &dss, name_maps, sizeof(*name_maps)*name_map_count, - RADDBGI_DataSectionTag_NameMaps); - } - - //////////////////////////////// - // LATE PART: baking loose structures and creating final layout - - // generate data sections for file paths - { - RADDBGI_U32 count = bctx->tree->count; - RADDBGI_FilePathNode *nodes = raddbgic_push_array(arena, RADDBGI_FilePathNode, count); - - RADDBGI_FilePathNode *out_node = nodes; - for(RADDBGIC_PathNode *node = bctx->tree->first; - node != 0; - node = node->next_order, out_node += 1){ - out_node->name_string_idx = raddbgic_string(bctx, node->name); - if(node->parent != 0){ - out_node->parent_path_node = node->parent->idx; - } - if(node->first_child != 0){ - out_node->first_child = node->first_child->idx; - } - if(node->next_sibling != 0){ - out_node->next_sibling = node->next_sibling->idx; - } - if(node->src_file != 0){ - out_node->source_file_idx = node->src_file->idx; - } - } - - raddbgic_dsection(arena, &dss, nodes, sizeof(*nodes)*count, RADDBGI_DataSectionTag_FilePathNodes); - } - - // generate data sections for files - { - RADDBGI_U32 count = bctx->tree->src_count; - RADDBGI_SourceFile *src_files = raddbgic_push_array(arena, RADDBGI_SourceFile, count); - - RADDBGI_SourceFile *out_src_file = src_files; - for(RADDBGIC_SrcNode *node = bctx->tree->src_first; - node != 0; - node = node->next, out_src_file += 1){ - out_src_file->file_path_node_idx = node->path_node->idx; - out_src_file->normal_full_path_string_idx = raddbgic_string(bctx, node->normal_full_path); - out_src_file->line_map_nums_data_idx = node->line_map_nums_data_idx; - out_src_file->line_map_range_data_idx = node->line_map_range_data_idx; - out_src_file->line_map_count = node->line_map_count; - out_src_file->line_map_voff_data_idx = node->line_map_voff_data_idx; - } - - raddbgic_dsection(arena, &dss, src_files, sizeof(*src_files)*count, RADDBGI_DataSectionTag_SourceFiles); - } - - // generate data sections for strings - { - RADDBGI_U32 *str_offs = raddbgic_push_array_no_zero(arena, RADDBGI_U32, bctx->strs.count + 1); - - RADDBGI_U32 off_cursor = 0; - { - RADDBGI_U32 *off_ptr = str_offs; - *off_ptr = 0; - off_ptr += 1; - for(RADDBGIC_StringNode *node = bctx->strs.order_first; - node != 0; - node = node->order_next){ - off_cursor += node->str.size; - *off_ptr = off_cursor; - off_ptr += 1; - } - } - - RADDBGI_U8 *buf = raddbgic_push_array(arena, RADDBGI_U8, off_cursor); - { - RADDBGI_U8 *ptr = buf; - for(RADDBGIC_StringNode *node = bctx->strs.order_first; - node != 0; - node = node->order_next){ - raddbgic_memcpy(ptr, node->str.str, node->str.size); - ptr += node->str.size; - } - } - - raddbgic_dsection(arena, &dss, str_offs, sizeof(*str_offs)*(bctx->strs.count + 1), - RADDBGI_DataSectionTag_StringTable); - raddbgic_dsection(arena, &dss, buf, off_cursor, RADDBGI_DataSectionTag_StringData); - } - - // generate data sections for index runs - { - RADDBGI_U32 *idx_data = raddbgic_push_array_no_zero(arena, RADDBGI_U32, bctx->idxs.idx_count); - - { - RADDBGI_U32 *out_ptr = idx_data; - RADDBGI_U32 *opl = out_ptr + bctx->idxs.idx_count; - RADDBGIC_IdxRunNode *node = bctx->idxs.order_first; - for(;node != 0 && out_ptr < opl; - node = node->order_next){ - raddbgic_memcpy(out_ptr, node->idx_run, sizeof(*node->idx_run)*node->count); - out_ptr += node->count; - } - raddbgic_assert(out_ptr == opl); - } - - raddbgic_dsection(arena, &dss, idx_data, sizeof(*idx_data)*bctx->idxs.idx_count, - RADDBGI_DataSectionTag_IndexRuns); - } - - // layout - // * the header and data section table have to be initialized "out of order" - // * so that the rest of the system can avoid this tricky order-layout interdependence stuff - RADDBGI_Header *header = raddbgic_push_array(arena, RADDBGI_Header, 1); - RADDBGI_DataSection *dstable = raddbgic_push_array(arena, RADDBGI_DataSection, dss.count); - str8_serial_push_align(arena, out, 8); - RADDBGI_U64 header_off = out->total_size; - str8_list_push(arena, out, str8_struct(header)); - str8_serial_push_align(arena, out, 8); - RADDBGI_U64 data_section_off = out->total_size; - str8_list_push(arena, out, str8((RADDBGI_U8 *)dstable, sizeof(*dstable)*dss.count)); - { - header->magic = RADDBGI_MAGIC_CONSTANT; - header->encoding_version = RADDBGI_ENCODING_VERSION; - header->data_section_off = data_section_off; - header->data_section_count = dss.count; - } - { - RADDBGI_U64 test_dss_count = 0; - for(RADDBGIC_DSectionNode *node = dss.first; - node != 0; - node = node->next){ - test_dss_count += 1; - } - raddbgic_assert(test_dss_count == dss.count); - - RADDBGI_DataSection *ptr = dstable; - for(RADDBGIC_DSectionNode *node = dss.first; - node != 0; - node = node->next, ptr += 1){ - RADDBGI_U64 data_section_offset = 0; - if(node->size != 0) - { - str8_serial_push_align(arena, out, 8); - data_section_offset = out->total_size; - str8_list_push(arena, out, str8((RADDBGI_U8 *)node->data, node->size)); - } - ptr->tag = node->tag; - ptr->encoding = RADDBGI_DataSectionEncoding_Unpacked; - ptr->off = data_section_offset; - ptr->encoded_size = node->size; - ptr->unpacked_size = node->size; - } - raddbgic_assert(ptr == dstable + dss.count); - } - - raddbgic_bake_ctx_release(bctx); -} diff --git a/src/lib_raddbgi_cons/raddbgi_cons.h b/src/lib_raddbgi_cons/raddbgi_cons.h deleted file mode 100644 index 5c35fe62..00000000 --- a/src/lib_raddbgi_cons/raddbgi_cons.h +++ /dev/null @@ -1,1303 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RADDBGI_CONS_H -#define RADDBGI_CONS_H - -//////////////////////////////// -//~ rjf: Overrideable Memory Operations - -// To override the slow/default memset implementation used by the library, -// do the following: -// -// #define RADDBGIC_MEMSET_OVERRIDE -// #define raddbgic_memset - -#if !defined(raddbgic_memset) -# define raddbgic_memset raddbgic_memset_fallback -#endif - -// To override the slow/default memcpy implementation used by the library, -// do the following: -// -// #define RADDBGIC_MEMCPY_OVERRIDE -// #define raddbgic_memcpy - -#if !defined(raddbgic_memset) -# define raddbgic_memset raddbgic_memset_fallback -#endif - -#if !defined(raddbgic_memcpy) -# define raddbgic_memcpy raddbgic_memcpy_fallback -#endif - -//////////////////////////////// -//~ rjf: Overrideable sprintf Functions - -#if !defined(raddbgic_vsnprintf) -# include -# define raddbgic_vsnprintf vsnprintf -#endif - -//////////////////////////////// -//~ rjf: Overrideable String View Types - -// To override the string view type used by the library, do the following: -// -// #define RADDBGIC_STRING8_OVERRIDE -// #define RADDBGIC_String8 -// #define RADDBGIC_String8_BaseMember -// #define RADDBGIC_String8_SizeMember - -// To override the string view list type used by the library, do the following: -// -// #define RADDBGIC_STRING8LIST_OVERRIDE -// #define RADDBGIC_String8Node -// #define RADDBGIC_String8_NextPtrMember -// #define RADDBGIC_String8_StringMember -// #define RADDBGIC_String8List -// #define RADDBGIC_String8_FirstMember -// #define RADDBGIC_String8_LastMember -// #define RADDBGIC_String8_NodeCount -// #define RADDBGIC_String8_TotalSizeMember - -#if !defined(RADDBGIC_String8) -#define RADDBGIC_String8 RADDBGIC_String8 -#define RADDBGIC_String8_BaseMember str -#define RADDBGIC_String8_SizeMember size -typedef struct RADDBGIC_String8 RADDBGIC_String8; -struct RADDBGIC_String8 -{ - RADDBGI_U8 *str; - RADDBGI_U64 size; -}; -#endif - -#if !defined(RADDBGIC_String8Node) -#define RADDBGIC_String8Node RADDBGIC_String8Node -#define RADDBGIC_String8Node_NextPtrMember next -#define RADDBGIC_String8Node_StringMember string -typedef struct RADDBGIC_String8Node RADDBGIC_String8Node; -struct RADDBGIC_String8Node -{ - RADDBGIC_String8Node *next; - RADDBGIC_String8 string; -}; -#endif - -#if !defined(RADDBGIC_String8List) -#define RADDBGIC_String8List RADDBGIC_String8List -#define RADDBGIC_String8List_FirstMember first -#define RADDBGIC_String8List_LastMember last -#define RADDBGIC_String8List_NodeCountMember node_count -#define RADDBGIC_String8List_TotalSizeMember total_size -typedef struct RADDBGIC_String8List RADDBGIC_String8List; -struct RADDBGIC_String8List -{ - RADDBGIC_String8Node *first; - RADDBGIC_String8Node *last; - RADDBGI_U64 node_count; - RADDBGI_U64 total_size; -}; -#endif - -typedef RADDBGI_U32 RADDBGIC_StringMatchFlags; -enum -{ - RADDBGIC_StringMatchFlag_CaseInsensitive = (1<<0), -}; - -//////////////////////////////// -//~ rjf: Overrideable Arena Allocator Types - -// To override the arena allocator type used by the library, do the following: -// -// #define RADDBGIC_ARENA_OVERRIDE -// #define RADDBGIC_Arena -// #define raddbgic_arena_alloc Arena*> -// #define raddbgic_arena_release void> -// #define raddbgic_arena_pos U64> -// #define raddbgic_arena_push void*> -// #define raddbgic_arena_pop_to void> - -#if !defined(RADDBGIC_Arena) -# define RADDBGIC_Arena RADDBGIC_Arena -typedef struct RADDBGIC_Arena RADDBGIC_Arena; -struct RADDBGIC_Arena -{ - RADDBGIC_Arena *prev; - RADDBGIC_Arena *current; - RADDBGI_U64 base_pos; - RADDBGI_U64 pos; - RADDBGI_U64 cmt; - RADDBGI_U64 res; - RADDBGI_U64 align; - RADDBGI_S8 grow; -}; -#endif - -#if !defined(raddbgic_arena_alloc) -# define raddbgic_arena_alloc raddbgic_arena_alloc_fallback -#endif -#if !defined(raddbgic_arena_release) -# define raddbgic_arena_release raddbgic_arena_release_fallback -#endif -#if !defined(raddbgic_arena_pos) -# define raddbgic_arena_pos raddbgic_arena_pos_fallback -#endif -#if !defined(raddbgic_arena_push) -# define raddbgic_arena_push raddbgic_arena_push_fallback -#endif - -//////////////////////////////// -//~ rjf: Overrideable Thread-Local Scratch Arenas - -// To override the default thread-local scratch arenas used b yhe library, -// do the following: -// -// #define RADDBGIC_SCRATCH_OVERRIDE -// #define RADDBGIC_Temp arena implementation - must be (Temp) -> (Arena*)> -// #define raddbgic_scratch_begin Temp> -// #define raddbgic_scratch_end void - -#if !defined(RADDBGIC_Temp) -# define RADDBGIC_Temp RADDBGIC_Temp -typedef struct RADDBGIC_Temp RADDBGIC_Temp; -struct RADDBGIC_Temp -{ - RADDBGIC_Arena *arena; - RADDBGI_U64 pos; -}; -#define raddbgic_temp_arena(t) ((t).arena) -#endif - -#if !defined(raddbgic_scratch_begin) -# define raddbgic_scratch_begin raddbgic_scratch_begin_fallback -#endif -#if !defined(raddbgic_scratch_end) -# define raddbgic_scratch_end raddbgic_scratch_end_fallback -#endif - -//////////////////////////////// -//~ rjf: Linked List Helpers - -#define RADDBGIC_CheckNil(nil,p) ((p) == 0 || (p) == nil) -#define RADDBGIC_SetNil(nil,p) ((p) = nil) - -//- rjf: Base Doubly-Linked-List Macros -#define RADDBGIC_DLLInsert_NPZ(nil,f,l,p,n,next,prev) (RADDBGIC_CheckNil(nil,f) ? \ -((f) = (l) = (n), RADDBGIC_SetNil(nil,(n)->next), RADDBGIC_SetNil(nil,(n)->prev)) :\ -RADDBGIC_CheckNil(nil,p) ? \ -((n)->next = (f), (f)->prev = (n), (f) = (n), RADDBGIC_SetNil(nil,(n)->prev)) :\ -((p)==(l)) ? \ -((l)->next = (n), (n)->prev = (l), (l) = (n), RADDBGIC_SetNil(nil, (n)->next)) :\ -(((!RADDBGIC_CheckNil(nil,p) && RADDBGIC_CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) -#define RADDBGIC_DLLPushBack_NPZ(nil,f,l,n,next,prev) RADDBGIC_DLLInsert_NPZ(nil,f,l,l,n,next,prev) -#define RADDBGIC_DLLPushFront_NPZ(nil,f,l,n,next,prev) RADDBGIC_DLLInsert_NPZ(nil,l,f,f,n,prev,next) -#define RADDBGIC_DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\ -((n) == (l) ? (l) = (l)->prev : (0)),\ -(RADDBGIC_CheckNil(nil,(n)->prev) ? (0) :\ -((n)->prev->next = (n)->next)),\ -(RADDBGIC_CheckNil(nil,(n)->next) ? (0) :\ -((n)->next->prev = (n)->prev))) - -//- rjf: Base Singly-Linked-List Queue Macros -#define RADDBGIC_SLLQueuePush_NZ(nil,f,l,n,next) (RADDBGIC_CheckNil(nil,f)?\ -((f)=(l)=(n),RADDBGIC_SetNil(nil,(n)->next)):\ -((l)->next=(n),(l)=(n),RADDBGIC_SetNil(nil,(n)->next))) -#define RADDBGIC_SLLQueuePushFront_NZ(nil,f,l,n,next) (RADDBGIC_CheckNil(nil,f)?\ -((f)=(l)=(n),RADDBGIC_SetNil(nil,(n)->next)):\ -((n)->next=(f),(f)=(n))) -#define RADDBGIC_SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\ -(RADDBGIC_SetNil(nil,f), RADDBGIC_SetNil(nil,l)):\ -((f)=(f)->next)) - -//- rjf: Base Singly-Linked-List Stack Macros -#define RADDBGIC_SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n)) -#define RADDBGIC_SLLStackPop_N(f,next) ((f)=(f)->next) - -//////////////////////////////// -//~ rjf: Convenience Wrappers - -//- rjf: Doubly-Linked-List Wrappers -#define RADDBGIC_DLLInsert_NP(f,l,p,n,next,prev) RADDBGIC_DLLInsert_NPZ(0,f,l,p,n,next,prev) -#define RADDBGIC_DLLPushBack_NP(f,l,n,next,prev) RADDBGIC_DLLPushBack_NPZ(0,f,l,n,next,prev) -#define RADDBGIC_DLLPushFront_NP(f,l,n,next,prev) RADDBGIC_DLLPushFront_NPZ(0,f,l,n,next,prev) -#define RADDBGIC_DLLRemove_NP(f,l,n,next,prev) RADDBGIC_DLLRemove_NPZ(0,f,l,n,next,prev) -#define RADDBGIC_DLLInsert(f,l,p,n) RADDBGIC_DLLInsert_NPZ(0,f,l,p,n,next,prev) -#define RADDBGIC_DLLPushBack(f,l,n) RADDBGIC_DLLPushBack_NPZ(0,f,l,n,next,prev) -#define RADDBGIC_DLLPushFront(f,l,n) RADDBGIC_DLLPushFront_NPZ(0,f,l,n,next,prev) -#define RADDBGIC_DLLRemove(f,l,n) RADDBGIC_DLLRemove_NPZ(0,f,l,n,next,prev) - -//- rjf: Singly-Linked-List Queue Wrappers -#define RADDBGIC_SLLQueuePush_N(f,l,n,next) RADDBGIC_SLLQueuePush_NZ(0,f,l,n,next) -#define RADDBGIC_SLLQueuePushFront_N(f,l,n,next) RADDBGIC_SLLQueuePushFront_NZ(0,f,l,n,next) -#define RADDBGIC_SLLQueuePop_N(f,l,next) RADDBGIC_SLLQueuePop_NZ(0,f,l,next) -#define RADDBGIC_SLLQueuePush(f,l,n) RADDBGIC_SLLQueuePush_NZ(0,f,l,n,next) -#define RADDBGIC_SLLQueuePushFront(f,l,n) RADDBGIC_SLLQueuePushFront_NZ(0,f,l,n,next) -#define RADDBGIC_SLLQueuePop(f,l) RADDBGIC_SLLQueuePop_NZ(0,f,l,next) - -//- rjf: Singly-Linked-List Stack Wrappers -#define RADDBGIC_SLLStackPush(f,n) RADDBGIC_SLLStackPush_N(f,n,next) -#define RADDBGIC_SLLStackPop(f) RADDBGIC_SLLStackPop_N(f,next) - -//////////////////////////////// -//~ rjf: Helper Macros - -#if defined(_MSC_VER) -# define RADDBGIC_THREAD_LOCAL __declspec(thread) -#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) -# define RADDBGIC_THREAD_LOCAL __thread -#else -# error RADDBGIC_THREAD_LOCAL not defined for this compiler. -#endif - -#if defined(_MSC_VER) -# define raddbgic_trap() __debugbreak() -#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) -# define raddbgic_trap() __builtin_trap() -#else -# error "raddbgic_trap not defined for this compiler." -#endif - -#define raddbgic_assert_always(x) do{if(!(x)) {raddbgic_trap();}}while(0) -#if !defined(NDEBUG) -# define raddbgic_assert(x) raddbgic_assert_always(x) -#else -# define raddbgic_assert(x) (void)(x) -#endif -#define raddbgic_noop ((void)0) - -//////////////////////////////// -//~ rjf: Error Types - -typedef struct RADDBGIC_Error RADDBGIC_Error; -struct RADDBGIC_Error -{ - RADDBGIC_Error *next; - RADDBGIC_String8 msg; -}; - -typedef struct RADDBGIC_ErrorList RADDBGIC_ErrorList; -struct RADDBGIC_ErrorList -{ - RADDBGIC_Error *first; - RADDBGIC_Error *last; - RADDBGI_U64 count; -}; - -//////////////////////////////// -//~ rjf: Auxiliary Data Structure Types - -//- rjf: u64 -> pointer map - -typedef struct RADDBGIC_U64ToPtrNode RADDBGIC_U64ToPtrNode; -struct RADDBGIC_U64ToPtrNode -{ - RADDBGIC_U64ToPtrNode *next; - RADDBGI_U64 _padding_; - RADDBGI_U64 key[1]; - void *ptr[1]; -}; - -typedef struct RADDBGIC_U64ToPtrMap RADDBGIC_U64ToPtrMap; -struct RADDBGIC_U64ToPtrMap -{ - RADDBGIC_U64ToPtrNode **buckets; - RADDBGI_U64 buckets_count; - RADDBGI_U64 bucket_collision_count; - RADDBGI_U64 pair_count; -}; - -typedef struct RADDBGIC_U64ToPtrLookup RADDBGIC_U64ToPtrLookup; -struct RADDBGIC_U64ToPtrLookup -{ - void *match; - RADDBGIC_U64ToPtrNode *fill_node; - RADDBGI_U32 fill_k; -}; - -//- rjf: string8 -> pointer map - -typedef struct RADDBGIC_Str8ToPtrNode RADDBGIC_Str8ToPtrNode; -struct RADDBGIC_Str8ToPtrNode -{ - struct RADDBGIC_Str8ToPtrNode *next; - RADDBGIC_String8 key; - RADDBGI_U64 hash; - void *ptr; -}; - -typedef struct RADDBGIC_Str8ToPtrMap RADDBGIC_Str8ToPtrMap; -struct RADDBGIC_Str8ToPtrMap -{ - RADDBGIC_Str8ToPtrNode **buckets; - RADDBGI_U64 buckets_count; - RADDBGI_U64 bucket_collision_count; - RADDBGI_U64 pair_count; -}; - -//- rjf: sortable range data structure - -typedef struct RADDBGIC_SortKey RADDBGIC_SortKey; -struct RADDBGIC_SortKey -{ - RADDBGI_U64 key; - void *val; -}; - -typedef struct RADDBGIC_OrderedRange RADDBGIC_OrderedRange; -struct RADDBGIC_OrderedRange -{ - RADDBGIC_OrderedRange *next; - RADDBGI_U64 first; - RADDBGI_U64 opl; -}; - -//////////////////////////////// -//~ rjf: Binary Section Types - -typedef struct RADDBGIC_BinarySection RADDBGIC_BinarySection; -struct RADDBGIC_BinarySection -{ - RADDBGIC_BinarySection *next; - RADDBGIC_String8 name; - RADDBGI_BinarySectionFlags flags; - RADDBGI_U64 voff_first; - RADDBGI_U64 voff_opl; - RADDBGI_U64 foff_first; - RADDBGI_U64 foff_opl; -}; - -//////////////////////////////// -//~ rjf: Per-Compilation-Unit Info Types - -typedef struct RADDBGIC_LineSequence RADDBGIC_LineSequence; -struct RADDBGIC_LineSequence -{ - RADDBGIC_String8 file_name; - RADDBGI_U64 *voffs; // [line_count + 1] (sorted) - RADDBGI_U32 *line_nums; // [line_count] - RADDBGI_U16 *col_nums; // [2*line_count] - RADDBGI_U64 line_count; -}; - -typedef struct RADDBGIC_LineSequenceNode RADDBGIC_LineSequenceNode; -struct RADDBGIC_LineSequenceNode -{ - RADDBGIC_LineSequenceNode *next; - RADDBGIC_LineSequence line_seq; -}; - -typedef struct RADDBGIC_UnitInfo RADDBGIC_UnitInfo; -struct RADDBGIC_UnitInfo -{ - RADDBGIC_String8 unit_name; - RADDBGIC_String8 compiler_name; - RADDBGIC_String8 source_file; - RADDBGIC_String8 object_file; - RADDBGIC_String8 archive_file; - RADDBGIC_String8 build_path; - RADDBGI_Language language; -}; - -typedef struct RADDBGIC_Unit RADDBGIC_Unit; -struct RADDBGIC_Unit -{ - RADDBGIC_Unit *next_order; - RADDBGI_U32 idx; - RADDBGI_S32 info_is_set; - RADDBGIC_String8 unit_name; - RADDBGIC_String8 compiler_name; - RADDBGIC_String8 source_file; - RADDBGIC_String8 object_file; - RADDBGIC_String8 archive_file; - RADDBGIC_String8 build_path; - RADDBGI_Language language; - RADDBGIC_LineSequenceNode *line_seq_first; - RADDBGIC_LineSequenceNode *line_seq_last; - RADDBGI_U64 line_seq_count; -}; - -typedef struct RADDBGIC_UnitVMapRange RADDBGIC_UnitVMapRange; -struct RADDBGIC_UnitVMapRange -{ - RADDBGIC_UnitVMapRange *next; - RADDBGIC_Unit *unit; - RADDBGI_U64 first; - RADDBGI_U64 opl; -}; - -//////////////////////////////// -//~ rjf: Type Info Types - -typedef RADDBGI_U8 RADDBGIC_TypeConstructKind; -enum -{ - RADDBGIC_TypeConstructKind_Basic, - RADDBGIC_TypeConstructKind_Modifier, - RADDBGIC_TypeConstructKind_Bitfield, - RADDBGIC_TypeConstructKind_Pointer, - RADDBGIC_TypeConstructKind_Array, - RADDBGIC_TypeConstructKind_Procedure, - RADDBGIC_TypeConstructKind_Method, -}; - -typedef struct RADDBGIC_Reservation RADDBGIC_Reservation; - -typedef struct RADDBGIC_TypeMember RADDBGIC_TypeMember; -struct RADDBGIC_TypeMember -{ - RADDBGIC_TypeMember *next; - RADDBGI_MemberKind kind; - RADDBGIC_String8 name; - struct RADDBGIC_Type *type; - RADDBGI_U32 off; -}; - -typedef struct RADDBGIC_TypeEnumVal RADDBGIC_TypeEnumVal; -struct RADDBGIC_TypeEnumVal -{ - RADDBGIC_TypeEnumVal *next; - RADDBGIC_String8 name; - RADDBGI_U64 val; -}; - -typedef struct RADDBGIC_Type RADDBGIC_Type; -struct RADDBGIC_Type -{ - RADDBGIC_Type *next_order; - RADDBGI_TypeKind kind; - RADDBGI_U32 idx; - RADDBGI_U32 byte_size; - RADDBGI_U32 flags; - RADDBGI_U32 off; - RADDBGI_U32 count; - RADDBGIC_String8 name; - RADDBGIC_Type *direct_type; - RADDBGIC_Type **param_types; - struct RADDBGIC_TypeUDT *udt; -}; - -typedef struct RADDBGIC_TypeUDT RADDBGIC_TypeUDT; -struct RADDBGIC_TypeUDT -{ - RADDBGIC_TypeUDT *next_order; - RADDBGI_U32 idx; - RADDBGIC_Type *self_type; - RADDBGIC_TypeMember *first_member; - RADDBGIC_TypeMember *last_member; - RADDBGI_U64 member_count; - RADDBGIC_TypeEnumVal *first_enum_val; - RADDBGIC_TypeEnumVal *last_enum_val; - RADDBGI_U64 enum_val_count; - RADDBGIC_String8 source_path; - RADDBGI_U32 line; - RADDBGI_U32 col; -}; - -typedef struct RADDBGIC_TypeNode RADDBGIC_TypeNode; -struct RADDBGIC_TypeNode -{ - RADDBGIC_TypeNode *next; - RADDBGIC_Type *type; -}; - -typedef struct RADDBGIC_TypeList RADDBGIC_TypeList; -struct RADDBGIC_TypeList -{ - RADDBGIC_TypeNode *first; - RADDBGIC_TypeNode *last; - RADDBGI_U64 count; -}; - -//////////////////////////////// -//~ rjf: Symbol Info Types - -typedef enum RADDBGIC_SymbolKind -{ - RADDBGIC_SymbolKind_NULL, - RADDBGIC_SymbolKind_GlobalVariable, - RADDBGIC_SymbolKind_ThreadVariable, - RADDBGIC_SymbolKind_Procedure, - RADDBGIC_SymbolKind_COUNT -} -RADDBGIC_SymbolKind; - -typedef struct RADDBGIC_SymbolInfo RADDBGIC_SymbolInfo; -struct RADDBGIC_SymbolInfo -{ - RADDBGIC_SymbolKind kind; - RADDBGIC_String8 name; - RADDBGIC_String8 link_name; - RADDBGIC_Type *type; - RADDBGI_S32 is_extern; - RADDBGI_U64 offset; - // TODO(allen): should this actually be "container scope"? - struct RADDBGIC_Symbol *container_symbol; - RADDBGIC_Type *container_type; - struct RADDBGIC_Scope *root_scope; -}; - -typedef struct RADDBGIC_Symbol RADDBGIC_Symbol; -struct RADDBGIC_Symbol -{ - RADDBGIC_Symbol *next_order; - RADDBGI_U32 idx; - RADDBGIC_SymbolKind kind; - RADDBGIC_String8 name; - RADDBGIC_String8 link_name; - RADDBGIC_Type *type; - RADDBGI_S32 is_extern; - RADDBGI_S8 offset_is_set; - RADDBGI_U64 offset; - RADDBGIC_Symbol *container_symbol; - RADDBGIC_Type *container_type; - struct RADDBGIC_Scope *root_scope; -}; - -//////////////////////////////// -//~ rjf: Scope Info Types - -typedef struct RADDBGIC_LocalInfo RADDBGIC_LocalInfo; -struct RADDBGIC_LocalInfo -{ - RADDBGI_LocalKind kind; - struct RADDBGIC_Scope *scope; - RADDBGIC_String8 name; - RADDBGIC_Type *type; -}; - -typedef struct RADDBGIC_Local RADDBGIC_Local; -struct RADDBGIC_Local -{ - RADDBGIC_Local *next; - RADDBGI_LocalKind kind; - RADDBGIC_String8 name; - RADDBGIC_Type *type; - struct RADDBGIC_LocationSet *locset; -}; - -typedef struct RADDBGIC_VOffRange RADDBGIC_VOffRange; -struct RADDBGIC_VOffRange -{ - RADDBGIC_VOffRange *next; - RADDBGI_U64 voff_first; - RADDBGI_U64 voff_opl; -}; - -typedef struct RADDBGIC_Scope RADDBGIC_Scope; -struct RADDBGIC_Scope -{ - RADDBGIC_Scope *next_order; - RADDBGIC_Symbol *symbol; - RADDBGIC_Scope *parent_scope; - RADDBGIC_Scope *first_child; - RADDBGIC_Scope *last_child; - RADDBGIC_Scope *next_sibling; - RADDBGI_U64 voff_base; - RADDBGIC_VOffRange *first_range; - RADDBGIC_VOffRange *last_range; - RADDBGI_U32 range_count; - RADDBGI_U32 idx; - RADDBGIC_Local *first_local; - RADDBGIC_Local *last_local; - RADDBGI_U32 local_count; -}; - -//////////////////////////////// -//~ rjf: Location Info Types - -typedef struct RADDBGIC_EvalBytecodeOp RADDBGIC_EvalBytecodeOp; -struct RADDBGIC_EvalBytecodeOp -{ - RADDBGIC_EvalBytecodeOp *next; - RADDBGI_EvalOp op; - RADDBGI_U32 p_size; - RADDBGI_U64 p; -}; - -typedef struct RADDBGIC_EvalBytecode RADDBGIC_EvalBytecode; -struct RADDBGIC_EvalBytecode -{ - RADDBGIC_EvalBytecodeOp *first_op; - RADDBGIC_EvalBytecodeOp *last_op; - RADDBGI_U32 op_count; - RADDBGI_U32 encoded_size; -}; - -typedef struct RADDBGIC_Location RADDBGIC_Location; -struct RADDBGIC_Location -{ - RADDBGI_LocationKind kind; - RADDBGI_U8 register_code; - RADDBGI_U16 offset; - RADDBGIC_EvalBytecode bytecode; -}; - -typedef struct RADDBGIC_LocationCase RADDBGIC_LocationCase; -struct RADDBGIC_LocationCase -{ - RADDBGIC_LocationCase *next; - RADDBGI_U64 voff_first; - RADDBGI_U64 voff_opl; - RADDBGIC_Location *location; -}; - -typedef struct RADDBGIC_LocationSet RADDBGIC_LocationSet; -struct RADDBGIC_LocationSet -{ - RADDBGIC_LocationCase *first_location_case; - RADDBGIC_LocationCase *last_location_case; - RADDBGI_U64 location_case_count; -}; - -//////////////////////////////// -//~ rjf: Name Map Types - -typedef struct RADDBGIC_NameMapIdxNode RADDBGIC_NameMapIdxNode; -struct RADDBGIC_NameMapIdxNode -{ - RADDBGIC_NameMapIdxNode *next; - RADDBGI_U32 idx[8]; -}; - -typedef struct RADDBGIC_NameMapNode RADDBGIC_NameMapNode; -struct RADDBGIC_NameMapNode -{ - RADDBGIC_NameMapNode *bucket_next; - RADDBGIC_NameMapNode *order_next; - RADDBGIC_String8 string; - RADDBGIC_NameMapIdxNode *idx_first; - RADDBGIC_NameMapIdxNode *idx_last; - RADDBGI_U64 idx_count; -}; - -typedef struct RADDBGIC_NameMap RADDBGIC_NameMap; -struct RADDBGIC_NameMap -{ - RADDBGIC_NameMapNode **buckets; - RADDBGI_U64 buckets_count; - RADDBGI_U64 bucket_collision_count; - RADDBGIC_NameMapNode *first; - RADDBGIC_NameMapNode *last; - RADDBGI_U64 name_count; -}; - -//////////////////////////////// -//~ rjf: Top-Level Debug Info Types - -typedef struct RADDBGIC_TopLevelInfo RADDBGIC_TopLevelInfo; -struct RADDBGIC_TopLevelInfo -{ - RADDBGI_Arch architecture; - RADDBGIC_String8 exe_name; - RADDBGI_U64 exe_hash; - RADDBGI_U64 voff_max; -}; - -//////////////////////////////// -//~ rjf: Root Construction Bundle Types - -typedef struct RADDBGIC_RootParams RADDBGIC_RootParams; -struct RADDBGIC_RootParams -{ - RADDBGI_U64 addr_size; - RADDBGI_U32 bucket_count_units; // optional; default chosen if 0 - RADDBGI_U32 bucket_count_symbols; // optional; default chosen if 0 - RADDBGI_U32 bucket_count_scopes; // optional; default chosen if 0 - RADDBGI_U32 bucket_count_locals; // optional; default chosen if 0 - RADDBGI_U32 bucket_count_types; // optional; default chosen if 0 - RADDBGI_U64 bucket_count_type_constructs; // optional; default chosen if 0 -}; - -typedef struct RADDBGIC_Root RADDBGIC_Root; -struct RADDBGIC_Root -{ - RADDBGIC_Arena *arena; - RADDBGIC_ErrorList errors; - - //////// Contextual Information - - RADDBGI_U64 addr_size; - - //////// Info Declared By User - - // top level info - RADDBGI_S32 top_level_info_is_set; - RADDBGIC_TopLevelInfo top_level_info; - - // binary layout - RADDBGIC_BinarySection *binary_section_first; - RADDBGIC_BinarySection *binary_section_last; - RADDBGI_U64 binary_section_count; - - // compilation units - RADDBGIC_Unit *unit_first; - RADDBGIC_Unit *unit_last; - RADDBGI_U64 unit_count; - - RADDBGIC_UnitVMapRange *unit_vmap_range_first; - RADDBGIC_UnitVMapRange *unit_vmap_range_last; - RADDBGI_U64 unit_vmap_range_count; - - // types - RADDBGIC_Type *first_type; - RADDBGIC_Type *last_type; - RADDBGI_U64 type_count; - - RADDBGIC_Type *nil_type; - RADDBGIC_Type *variadic_type; - - RADDBGIC_Type handled_nil_type; - - RADDBGIC_TypeUDT *first_udt; - RADDBGIC_TypeUDT *last_udt; - RADDBGI_U64 type_udt_count; - - RADDBGI_U64 total_member_count; - RADDBGI_U64 total_enum_val_count; - - // symbols - RADDBGIC_Symbol *first_symbol; - RADDBGIC_Symbol *last_symbol; - union - { - RADDBGI_U64 symbol_count; - RADDBGI_U64 symbol_kind_counts[RADDBGIC_SymbolKind_COUNT]; - }; - - RADDBGIC_Scope *first_scope; - RADDBGIC_Scope *last_scope; - RADDBGI_U64 scope_count; - RADDBGI_U64 scope_voff_count; - - RADDBGIC_Local *first_local; - RADDBGIC_Local *last_local; - RADDBGI_U64 local_count; - RADDBGI_U64 location_count; - - // name maps - RADDBGIC_NameMap *name_maps[RADDBGI_NameMapKind_COUNT]; - - //////// Handle Relationship Maps - - RADDBGIC_U64ToPtrMap unit_map; - RADDBGIC_U64ToPtrMap symbol_map; - RADDBGIC_U64ToPtrMap scope_map; - RADDBGIC_U64ToPtrMap local_map; - RADDBGIC_U64ToPtrMap type_from_id_map; - RADDBGIC_Str8ToPtrMap construct_map; -}; - -//////////////////////////////// -//~ rjf: Baking Phase Types - -//- rjf: bake data section data structure - -typedef struct RADDBGIC_DSectionNode RADDBGIC_DSectionNode; -struct RADDBGIC_DSectionNode -{ - RADDBGIC_DSectionNode *next; - void *data; - RADDBGI_U64 size; - RADDBGI_DataSectionTag tag; -}; - -typedef struct RADDBGIC_DSections RADDBGIC_DSections; -struct RADDBGIC_DSections -{ - RADDBGIC_DSectionNode *first; - RADDBGIC_DSectionNode *last; - RADDBGI_U32 count; -}; - -//- rjf: bake string data structure - -typedef struct RADDBGIC_StringNode RADDBGIC_StringNode; -struct RADDBGIC_StringNode -{ - RADDBGIC_StringNode *order_next; - RADDBGIC_StringNode *bucket_next; - RADDBGIC_String8 str; - RADDBGI_U64 hash; - RADDBGI_U32 idx; -}; - -typedef struct RADDBGIC_Strings RADDBGIC_Strings; -struct RADDBGIC_Strings -{ - RADDBGIC_StringNode *order_first; - RADDBGIC_StringNode *order_last; - RADDBGIC_StringNode **buckets; - RADDBGI_U64 buckets_count; - RADDBGI_U64 bucket_collision_count; - RADDBGI_U32 count; -}; - -//- rjf: index run baking data structure - -typedef struct RADDBGIC_IdxRunNode RADDBGIC_IdxRunNode; -struct RADDBGIC_IdxRunNode -{ - RADDBGIC_IdxRunNode *order_next; - RADDBGIC_IdxRunNode *bucket_next; - RADDBGI_U32 *idx_run; - RADDBGI_U64 hash; - RADDBGI_U32 count; - RADDBGI_U32 first_idx; -}; - -typedef struct RADDBGIC_IdxRuns RADDBGIC_IdxRuns; -struct RADDBGIC_IdxRuns -{ - RADDBGIC_IdxRunNode *order_first; - RADDBGIC_IdxRunNode *order_last; - RADDBGIC_IdxRunNode **buckets; - RADDBGI_U64 buckets_count; - RADDBGI_U64 bucket_collision_count; - RADDBGI_U32 count; - RADDBGI_U32 idx_count; -}; - -//- rjf: source file & file path baking data structures - -typedef struct RADDBGIC_PathNode RADDBGIC_PathNode; -struct RADDBGIC_PathNode -{ - RADDBGIC_PathNode *next_order; - RADDBGIC_PathNode *parent; - RADDBGIC_PathNode *first_child; - RADDBGIC_PathNode *last_child; - RADDBGIC_PathNode *next_sibling; - RADDBGIC_String8 name; - struct RADDBGIC_SrcNode *src_file; - RADDBGI_U32 idx; -}; - -typedef struct RADDBGIC_LineMapFragment RADDBGIC_LineMapFragment; -struct RADDBGIC_LineMapFragment -{ - RADDBGIC_LineMapFragment *next; - RADDBGIC_LineSequenceNode *sequence; -}; - -typedef struct RADDBGIC_SrcNode RADDBGIC_SrcNode; -struct RADDBGIC_SrcNode -{ - RADDBGIC_SrcNode *next; - RADDBGIC_PathNode *path_node; - RADDBGI_U32 idx; - - RADDBGIC_String8 normal_full_path; - - // place to gather the line info attached to this src file - RADDBGIC_LineMapFragment *first_fragment; - RADDBGIC_LineMapFragment *last_fragment; - - // place to put the final baked version of this file's line map - RADDBGI_U32 line_map_nums_data_idx; - RADDBGI_U32 line_map_range_data_idx; - RADDBGI_U32 line_map_count; - RADDBGI_U32 line_map_voff_data_idx; -}; - -typedef struct RADDBGIC_PathTree RADDBGIC_PathTree; -struct RADDBGIC_PathTree -{ - RADDBGIC_PathNode *first; - RADDBGIC_PathNode *last; - RADDBGI_U32 count; - RADDBGIC_PathNode root; - RADDBGIC_SrcNode *src_first; - RADDBGIC_SrcNode *src_last; - RADDBGI_U32 src_count; -}; - -//- rjf: line info baking data structures - -typedef struct RADDBGIC_LineRec RADDBGIC_LineRec; -struct RADDBGIC_LineRec -{ - RADDBGI_U32 file_id; - RADDBGI_U32 line_num; - RADDBGI_U16 col_first; - RADDBGI_U16 col_opl; -}; - -typedef struct RADDBGIC_UnitLinesCombined RADDBGIC_UnitLinesCombined; -struct RADDBGIC_UnitLinesCombined -{ - RADDBGI_U64 *voffs; - RADDBGI_Line *lines; - RADDBGI_U16 *cols; - RADDBGI_U32 line_count; -}; - -typedef struct RADDBGIC_SrcLinesCombined RADDBGIC_SrcLinesCombined; -struct RADDBGIC_SrcLinesCombined -{ - RADDBGI_U32 *line_nums; - RADDBGI_U32 *line_ranges; - RADDBGI_U64 *voffs; - RADDBGI_U32 line_count; - RADDBGI_U32 voff_count; -}; - -typedef struct RADDBGIC_SrcLineMapVoffBlock RADDBGIC_SrcLineMapVoffBlock; -struct RADDBGIC_SrcLineMapVoffBlock -{ - RADDBGIC_SrcLineMapVoffBlock *next; - RADDBGI_U64 voff; -}; - -typedef struct RADDBGIC_SrcLineMapBucket RADDBGIC_SrcLineMapBucket; -struct RADDBGIC_SrcLineMapBucket -{ - RADDBGIC_SrcLineMapBucket *order_next; - RADDBGIC_SrcLineMapBucket *hash_next; - RADDBGI_U32 line_num; - RADDBGIC_SrcLineMapVoffBlock *first_voff_block; - RADDBGIC_SrcLineMapVoffBlock *last_voff_block; - RADDBGI_U64 voff_count; -}; - -//- rjf: vmap baking data structure - -typedef struct RADDBGIC_VMap RADDBGIC_VMap; -struct RADDBGIC_VMap -{ - RADDBGI_VMapEntry *vmap; // [count + 1] - RADDBGI_U32 count; -}; - -typedef struct RADDBGIC_VMapMarker RADDBGIC_VMapMarker; -struct RADDBGIC_VMapMarker -{ - RADDBGI_U32 idx; - RADDBGI_U32 begin_range; -}; - -typedef struct RADDBGIC_VMapRangeTracker RADDBGIC_VMapRangeTracker; -struct RADDBGIC_VMapRangeTracker -{ - RADDBGIC_VMapRangeTracker *next; - RADDBGI_U32 idx; -}; - -//- rjf: type data baking types - -typedef struct RADDBGIC_TypeData RADDBGIC_TypeData; -struct RADDBGIC_TypeData -{ - RADDBGI_TypeNode *type_nodes; - RADDBGI_U32 type_node_count; - - RADDBGI_UDT *udts; - RADDBGI_U32 udt_count; - - RADDBGI_Member *members; - RADDBGI_U32 member_count; - - RADDBGI_EnumMember *enum_members; - RADDBGI_U32 enum_member_count; -}; - -//- rjf: symbol data baking types - -typedef struct RADDBGIC_SymbolData RADDBGIC_SymbolData; -struct RADDBGIC_SymbolData -{ - RADDBGI_GlobalVariable *global_variables; - RADDBGI_U32 global_variable_count; - - RADDBGIC_VMap *global_vmap; - - RADDBGI_ThreadVariable *thread_variables; - RADDBGI_U32 thread_variable_count; - - RADDBGI_Procedure *procedures; - RADDBGI_U32 procedure_count; - - RADDBGI_Scope *scopes; - RADDBGI_U32 scope_count; - - RADDBGI_U64 *scope_voffs; - RADDBGI_U32 scope_voff_count; - - RADDBGIC_VMap *scope_vmap; - - RADDBGI_Local *locals; - RADDBGI_U32 local_count; - - RADDBGI_LocationBlock *location_blocks; - RADDBGI_U32 location_block_count; - - void *location_data; - RADDBGI_U32 location_data_size; -}; - -//- rjf: name map baking types - -typedef struct RADDBGIC_NameMapSemiNode RADDBGIC_NameMapSemiNode; -struct RADDBGIC_NameMapSemiNode -{ - RADDBGIC_NameMapSemiNode *next; - RADDBGIC_NameMapNode *node; -}; - -typedef struct RADDBGIC_NameMapSemiBucket RADDBGIC_NameMapSemiBucket; -struct RADDBGIC_NameMapSemiBucket -{ - RADDBGIC_NameMapSemiNode *first; - RADDBGIC_NameMapSemiNode *last; - RADDBGI_U64 count; -}; - -typedef struct RADDBGIC_NameMapBaked RADDBGIC_NameMapBaked; -struct RADDBGIC_NameMapBaked -{ - RADDBGI_NameMapBucket *buckets; - RADDBGI_NameMapNode *nodes; - RADDBGI_U32 bucket_count; - RADDBGI_U32 node_count; -}; - -//- rjf: bundle baking context type - -typedef struct RADDBGIC_BakeParams RADDBGIC_BakeParams; -struct RADDBGIC_BakeParams -{ - RADDBGI_U64 strings_bucket_count; - RADDBGI_U64 idx_runs_bucket_count; -}; - -typedef struct RADDBGIC_BakeCtx RADDBGIC_BakeCtx; -struct RADDBGIC_BakeCtx -{ - RADDBGIC_Arena *arena; - RADDBGIC_Strings strs; - RADDBGIC_IdxRuns idxs; - RADDBGIC_PathTree *tree; -}; - -//////////////////////////////// -//~ rjf: Basic Helpers - -//- rjf: memory operations -#if !defined(RADDBGIC_MEMSET_OVERRIDE) -RADDBGI_PROC void *raddbgic_memset_fallback(void *dst, RADDBGI_U8 c, RADDBGI_U64 size); -#endif -#if !defined(RADDBGIC_MEMCPY_OVERRIDE) -RADDBGI_PROC void *raddbgic_memcpy_fallback(void *dst, void *src, RADDBGI_U64 size); -#endif -#define raddbgic_memzero(ptr, size) raddbgic_memset((ptr), 0, (size)) -#define raddbgic_memzero_struct(ptr) raddbgic_memset((ptr), 0, sizeof(*(ptr))) -#define raddbgic_memcpy_struct(dst, src) raddbgic_memcpy((dst), (src), sizeof(*(dst))) - -//- rjf: arenas -#if !defined (RADDBGIC_ARENA_OVERRIDE) -RADDBGI_PROC RADDBGIC_Arena *raddbgic_arena_alloc_fallback(void); -RADDBGI_PROC void raddbgic_arena_release_fallback(RADDBGIC_Arena *arena); -RADDBGI_PROC RADDBGI_U64 raddbgic_arena_pos_fallback(RADDBGIC_Arena *arena); -RADDBGI_PROC void *raddbgic_arena_push_fallback(RADDBGIC_Arena *arena, RADDBGI_U64 size); -RADDBGI_PROC void raddbgic_arena_pop_to_fallback(RADDBGIC_Arena *arena, RADDBGI_U64 pos); -#endif -#define raddbgic_push_array_no_zero(a,T,c) (T*)raddbgic_arena_push((a), sizeof(T)*(c)) -#define raddbgic_push_array(a,T,c) (T*)raddbgic_memzero(raddbgic_push_array_no_zero(a,T,c), sizeof(T)*(c)) - -//- rjf: thread-local scratch arenas -#if !defined (RADDBGIC_SCRATCH_OVERRIDE) -RADDBGI_PROC RADDBGIC_Temp raddbgic_scratch_begin_fallback(RADDBGIC_Arena **conflicts, RADDBGI_U64 conflicts_count); -RADDBGI_PROC void raddbgic_scratch_end_fallback(RADDBGIC_Temp temp); -#endif - -//- rjf: strings -RADDBGI_PROC RADDBGIC_String8 raddbgic_str8(RADDBGI_U8 *str, RADDBGI_U64 size); -RADDBGI_PROC RADDBGIC_String8 raddbgic_str8_copy(RADDBGIC_Arena *arena, RADDBGIC_String8 src); -RADDBGI_PROC RADDBGIC_String8 raddbgic_str8f(RADDBGIC_Arena *arena, char *fmt, ...); -RADDBGI_PROC RADDBGIC_String8 raddbgic_str8fv(RADDBGIC_Arena *arena, char *fmt, va_list args); -RADDBGI_PROC RADDBGI_S32 raddbgic_str8_match(RADDBGIC_String8 a, RADDBGIC_String8 b, RADDBGIC_StringMatchFlags flags); -#define raddbgic_str8_lit(S) raddbgic_str8((RADDBGI_U8*)(S), sizeof(S) - 1) -#define raddbgic_str8_struct(S) raddbgic_str8((RADDBGI_U8*)(S), sizeof(*(S))) - -//- rjf: string lists -RADDBGI_PROC void raddbgic_str8_list_push(RADDBGIC_Arena *arena, RADDBGIC_String8List *list, RADDBGIC_String8 string); -RADDBGI_PROC RADDBGIC_String8 raddbgic_str8_list_join(RADDBGIC_Arena *arena, RADDBGIC_String8List *list, RADDBGIC_String8 sep); - -//- rjf: type lists -RADDBGI_PROC void raddbgic_type_list_push(RADDBGIC_Arena *arena, RADDBGIC_TypeList *list, RADDBGIC_Type *type); - -//- rjf: bytecode lists -RADDBGI_PROC void raddbgic_bytecode_push_op(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_EvalOp op, RADDBGI_U64 p); -RADDBGI_PROC void raddbgic_bytecode_push_uconst(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_U64 x); -RADDBGI_PROC void raddbgic_bytecode_push_sconst(RADDBGIC_Arena *arena, RADDBGIC_EvalBytecode *bytecode, RADDBGI_S64 x); -RADDBGI_PROC void raddbgic_bytecode_concat_in_place(RADDBGIC_EvalBytecode *left_dst, RADDBGIC_EvalBytecode *right_destroyed); - -//- rjf: sortable range sorting -RADDBGI_PROC RADDBGIC_SortKey* raddbgic_sort_key_array(RADDBGIC_Arena *arena, RADDBGIC_SortKey *keys, RADDBGI_U64 count); - -//////////////////////////////// -//~ rjf: Auxiliary Data Structure Functions - -//- rjf: u64 -> ptr map -RADDBGI_PROC void raddbgic_u64toptr_map_init(RADDBGIC_Arena *arena, RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 bucket_count); -RADDBGI_PROC void raddbgic_u64toptr_map_lookup(RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RADDBGIC_U64ToPtrLookup *lookup_out); -RADDBGI_PROC void raddbgic_u64toptr_map_insert(RADDBGIC_Arena *arena, RADDBGIC_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RADDBGIC_U64ToPtrLookup *lookup, void *ptr); - -//- rjf: string8 -> ptr map -RADDBGI_PROC void raddbgic_str8toptr_map_init(RADDBGIC_Arena *arena, RADDBGIC_Str8ToPtrMap *map, RADDBGI_U64 bucket_count); -RADDBGI_PROC void*raddbgic_str8toptr_map_lookup(RADDBGIC_Str8ToPtrMap *map, RADDBGIC_String8 key, RADDBGI_U64 hash); -RADDBGI_PROC void raddbgic_str8toptr_map_insert(RADDBGIC_Arena *arena, RADDBGIC_Str8ToPtrMap *map, RADDBGIC_String8 key, RADDBGI_U64 hash, void *ptr); - -//////////////////////////////// -//~ rjf: Loose Debug Info Construction (Anything -> Loose) Functions - -//- rjf: root creation -RADDBGI_PROC RADDBGIC_Root* raddbgic_root_alloc(RADDBGIC_RootParams *params); -RADDBGI_PROC void raddbgic_root_release(RADDBGIC_Root *root); - -//- rjf: error accumulation -RADDBGI_PROC void raddbgic_push_error(RADDBGIC_Root *root, RADDBGIC_String8 string); -RADDBGI_PROC void raddbgic_push_errorf(RADDBGIC_Root *root, char *fmt, ...); -RADDBGI_PROC RADDBGIC_Error* raddbgic_first_error_from_root(RADDBGIC_Root *root); - -//- rjf: top-level info specification -RADDBGI_PROC void raddbgic_set_top_level_info(RADDBGIC_Root *root, RADDBGIC_TopLevelInfo *tli); - -//- rjf: binary section building -RADDBGI_PROC void raddbgic_add_binary_section(RADDBGIC_Root *root, - RADDBGIC_String8 name, RADDBGI_BinarySectionFlags flags, - RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGI_U64 foff_first, - RADDBGI_U64 foff_opl); - -//- rjf: unit info building -RADDBGI_PROC RADDBGIC_Unit* raddbgic_unit_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 unit_user_id, RADDBGI_U64 unit_user_id_hash); -RADDBGI_PROC void raddbgic_unit_set_info(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGIC_UnitInfo *info); -RADDBGI_PROC void raddbgic_unit_add_line_sequence(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGIC_LineSequence *line_sequence); -RADDBGI_PROC void raddbgic_unit_vmap_add_range(RADDBGIC_Root *root, RADDBGIC_Unit *unit, RADDBGI_U64 first, RADDBGI_U64 opl); - -//- rjf: type info lookups/reservations -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_from_id(RADDBGIC_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash); -RADDBGI_PROC RADDBGIC_Reservation* raddbgic_type_reserve_id(RADDBGIC_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash); -RADDBGI_PROC void raddbgic_type_fill_id(RADDBGIC_Root *root, RADDBGIC_Reservation *res, RADDBGIC_Type *type); - -//- rjf: nil/singleton types -RADDBGI_PROC RADDBGI_S32 raddbgic_type_is_unhandled_nil(RADDBGIC_Root *root, RADDBGIC_Type *type); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_handled_nil(RADDBGIC_Root *root); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_nil(RADDBGIC_Root *root); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_variadic(RADDBGIC_Root *root); - -//- rjf: base type info constructors -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_new(RADDBGIC_Root *root); -RADDBGI_PROC RADDBGIC_TypeUDT* raddbgic_type_udt_from_any_type(RADDBGIC_Root *root, RADDBGIC_Type *type); -RADDBGI_PROC RADDBGIC_TypeUDT* raddbgic_type_udt_from_record_type(RADDBGIC_Root *root, RADDBGIC_Type *type); - -//- rjf: basic/operator type construction helpers -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_basic(RADDBGIC_Root *root, RADDBGI_TypeKind type_kind, RADDBGIC_String8 name); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_modifier(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_TypeModifierFlags flags); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_bitfield(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_U32 bit_off, RADDBGI_U32 bit_count); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_pointer(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_TypeKind ptr_type_kind); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_array(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGI_U64 count); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_proc(RADDBGIC_Root *root, RADDBGIC_Type *return_type, struct RADDBGIC_TypeList *params); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_method(RADDBGIC_Root *root, RADDBGIC_Type *this_type, RADDBGIC_Type *return_type, struct RADDBGIC_TypeList *params); - -//- rjf: udt type constructors -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_udt(RADDBGIC_Root *root, RADDBGI_TypeKind record_type_kind, RADDBGIC_String8 name, RADDBGI_U64 size); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_enum(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGIC_String8 name); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_alias(RADDBGIC_Root *root, RADDBGIC_Type *direct_type, RADDBGIC_String8 name); -RADDBGI_PROC RADDBGIC_Type* raddbgic_type_incomplete(RADDBGIC_Root *root, RADDBGI_TypeKind type_kind, RADDBGIC_String8 name); - -//- rjf: type member building -RADDBGI_PROC void raddbgic_type_add_member_data_field(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type, RADDBGI_U32 off); -RADDBGI_PROC void raddbgic_type_add_member_static_data(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type); -RADDBGI_PROC void raddbgic_type_add_member_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type); -RADDBGI_PROC void raddbgic_type_add_member_static_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type); -RADDBGI_PROC void raddbgic_type_add_member_virtual_method(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_String8 name, RADDBGIC_Type *mem_type); -RADDBGI_PROC void raddbgic_type_add_member_base(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *base_type, RADDBGI_U32 off); -RADDBGI_PROC void raddbgic_type_add_member_virtual_base(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *base_type, RADDBGI_U32 vptr_off, RADDBGI_U32 vtable_off); -RADDBGI_PROC void raddbgic_type_add_member_nested_type(RADDBGIC_Root *root, RADDBGIC_Type *record_type, RADDBGIC_Type *nested_type); -RADDBGI_PROC void raddbgic_type_add_enum_val(RADDBGIC_Root *root, RADDBGIC_Type *enum_type, RADDBGIC_String8 name, RADDBGI_U64 val); - -//- rjf: type source coordinate specifications -RADDBGI_PROC void raddbgic_type_set_source_coordinates(RADDBGIC_Root *root, RADDBGIC_Type *defined_type, RADDBGIC_String8 source_path, RADDBGI_U32 line, RADDBGI_U32 col); - -//- rjf: symbol info building -RADDBGI_PROC RADDBGIC_Symbol* raddbgic_symbol_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 symbol_user_id, RADDBGI_U64 symbol_user_id_hash); -RADDBGI_PROC void raddbgic_symbol_set_info(RADDBGIC_Root *root, RADDBGIC_Symbol *symbol, RADDBGIC_SymbolInfo *info); - -//- rjf: scope info building -RADDBGI_PROC RADDBGIC_Scope *raddbgic_scope_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 scope_user_id, RADDBGI_U64 scope_user_id_hash); -RADDBGI_PROC void raddbgic_scope_set_parent(RADDBGIC_Root *root, RADDBGIC_Scope *scope, RADDBGIC_Scope *parent); -RADDBGI_PROC void raddbgic_scope_add_voff_range(RADDBGIC_Root *root, RADDBGIC_Scope *scope, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl); -RADDBGI_PROC void raddbgic_scope_recursive_set_symbol(RADDBGIC_Scope *scope, RADDBGIC_Symbol *symbol); - -//- rjf: local info building -RADDBGI_PROC RADDBGIC_Local* raddbgic_local_handle_from_user_id(RADDBGIC_Root *root, RADDBGI_U64 local_user_id, RADDBGI_U64 local_user_id_hash); -RADDBGI_PROC void raddbgic_local_set_basic_info(RADDBGIC_Root *root, RADDBGIC_Local *local, RADDBGIC_LocalInfo *info); -RADDBGI_PROC RADDBGIC_LocationSet* raddbgic_location_set_from_local(RADDBGIC_Root *root, RADDBGIC_Local *local); - -//- rjf: location info building -RADDBGI_PROC void raddbgic_location_set_add_case(RADDBGIC_Root *root, RADDBGIC_LocationSet *locset, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGIC_Location *location); -RADDBGI_PROC RADDBGIC_Location* raddbgic_location_addr_bytecode_stream(RADDBGIC_Root *root, struct RADDBGIC_EvalBytecode *bytecode); -RADDBGI_PROC RADDBGIC_Location* raddbgic_location_val_bytecode_stream(RADDBGIC_Root *root, struct RADDBGIC_EvalBytecode *bytecode); -RADDBGI_PROC RADDBGIC_Location* raddbgic_location_addr_reg_plus_u16(RADDBGIC_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset); -RADDBGI_PROC RADDBGIC_Location* raddbgic_location_addr_addr_reg_plus_u16(RADDBGIC_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset); -RADDBGI_PROC RADDBGIC_Location* raddbgic_location_val_reg(RADDBGIC_Root *root, RADDBGI_U8 reg_code); - -//- rjf: name map building -RADDBGI_PROC RADDBGIC_NameMap* raddbgic_name_map_for_kind(RADDBGIC_Root *root, RADDBGI_NameMapKind kind); -RADDBGI_PROC void raddbgic_name_map_add_pair(RADDBGIC_Root *root, RADDBGIC_NameMap *map, RADDBGIC_String8 name, RADDBGI_U32 idx); - -//////////////////////////////// -//~ rjf: Debug Info Baking (Loose -> Tight) Functions - -//- rjf: bake context construction -RADDBGI_PROC RADDBGIC_BakeCtx* raddbgic_bake_ctx_begin(RADDBGIC_BakeParams *params); -RADDBGI_PROC void raddbgic_bake_ctx_release(RADDBGIC_BakeCtx *bake_ctx); - -//- rjf: string baking -RADDBGI_PROC RADDBGI_U32 raddbgic_string(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 str); - -//- rjf: idx run baking -RADDBGI_PROC RADDBGI_U64 raddbgic_idx_run_hash(RADDBGI_U32 *idx_run, RADDBGI_U32 count); -RADDBGI_PROC RADDBGI_U32 raddbgic_idx_run(RADDBGIC_BakeCtx *bctx, RADDBGI_U32 *idx_run, RADDBGI_U32 count); - -//- rjf: data section baking -RADDBGI_PROC RADDBGI_U32 raddbgic_dsection(RADDBGIC_Arena *arena, RADDBGIC_DSections *dss, void *data, RADDBGI_U64 size, RADDBGI_DataSectionTag tag); - -//- rjf: paths baking -RADDBGI_PROC RADDBGIC_String8 raddbgic_normal_string_from_path_node(RADDBGIC_Arena *arena, RADDBGIC_PathNode *node); -RADDBGI_PROC void raddbgic_normal_string_from_path_node_build(RADDBGIC_Arena *arena, RADDBGIC_PathNode *node, RADDBGIC_String8List *out); -RADDBGI_PROC RADDBGIC_PathNode* raddbgic_paths_new_node(RADDBGIC_BakeCtx *bctx); -RADDBGI_PROC RADDBGIC_PathNode* raddbgic_paths_sub_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_PathNode *dir, RADDBGIC_String8 sub_dir); -RADDBGI_PROC RADDBGIC_PathNode* raddbgic_paths_node_from_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 path); -RADDBGI_PROC RADDBGI_U32 raddbgic_paths_idx_from_path(RADDBGIC_BakeCtx *bctx, RADDBGIC_String8 path); -RADDBGI_PROC RADDBGIC_SrcNode* raddbgic_paths_new_src_node(RADDBGIC_BakeCtx *bctx); -RADDBGI_PROC RADDBGIC_SrcNode* raddbgic_paths_src_node_from_path_node(RADDBGIC_BakeCtx *bctx, RADDBGIC_PathNode *path_node); - -//- rjf: per-unit line info baking -RADDBGI_PROC RADDBGIC_UnitLinesCombined* raddbgic_unit_combine_lines(RADDBGIC_Arena *arena, RADDBGIC_BakeCtx *bctx, RADDBGIC_LineSequenceNode *first_seq); - -//- rjf: per-src line info baking -RADDBGI_PROC RADDBGIC_SrcLinesCombined* raddbgic_source_combine_lines(RADDBGIC_Arena *arena, RADDBGIC_LineMapFragment *first); - -//- rjf: vmap baking -RADDBGI_PROC RADDBGIC_VMap* raddbgic_vmap_from_markers(RADDBGIC_Arena *arena, RADDBGIC_VMapMarker *markers, RADDBGIC_SortKey *keys, RADDBGI_U64 marker_count); -RADDBGI_PROC RADDBGIC_VMap* raddbgic_vmap_from_unit_ranges(RADDBGIC_Arena *arena, RADDBGIC_UnitVMapRange *first, RADDBGI_U64 count); - -//- rjf: type info baking -RADDBGI_PROC RADDBGI_U32* raddbgic_idx_run_from_types(RADDBGIC_Arena *arena, RADDBGIC_Type **types, RADDBGI_U32 count); -RADDBGI_PROC RADDBGIC_TypeData* raddbgic_type_data_combine(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx); - -//- rjf: symbol data baking -RADDBGI_PROC RADDBGIC_SymbolData* raddbgic_symbol_data_combine(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx); - -//- rjf: name map baking -RADDBGI_PROC RADDBGIC_NameMapBaked* raddbgic_name_map_bake(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_BakeCtx *bctx, RADDBGIC_NameMap *map); - -//- rjf: top-level baking entry point -RADDBGI_PROC void raddbgic_bake_file(RADDBGIC_Arena *arena, RADDBGIC_Root *root, RADDBGIC_String8List *out); - -#endif // RADDBGI_CONS_H diff --git a/src/lib_raddbgi_make/raddbgi_make.c b/src/lib_raddbgi_make/raddbgi_make.c new file mode 100644 index 00000000..e55f79b3 --- /dev/null +++ b/src/lib_raddbgi_make/raddbgi_make.c @@ -0,0 +1,3673 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: API Implementation Helper Macros + +#define rdim_require(root, b32, else_code, error_msg) do { if(!(b32)) {rdim_push_error((root), (error_msg)); else_code;} }while(0) +#define rdim_requiref(root, b32, else_code, fmt, ...) do { if(!(b32)) {rdim_push_errorf((root), (fmt), __VA_ARGS__); else_code;} }while(0) + +//////////////////////////////// +//~ rjf: Basic Helpers + +//- rjf: memory set + +#if !defined(RDIM_MEMSET_OVERRIDE) +RADDBGI_PROC void * +rdim_memset_fallback(void *dst, RADDBGI_U8 c, RADDBGI_U64 size) +{ + for(RADDBGI_U64 idx = 0; idx < size; idx += 1) + { + ((RADDBGI_U8 *)dst)[idx] = c; + } + return dst; +} +#endif + +#if !defined(RDIM_MEMCPY_OVERRIDE) +RADDBGI_PROC void * +rdim_memcpy_fallback(void *dst, void *src, RADDBGI_U64 size) +{ + for(RADDBGI_U64 idx = 0; idx < size; idx += 1) + { + ((RADDBGI_U8 *)dst)[idx] = ((RADDBGI_U8 *)src)[idx]; + } + return dst; +} +#endif + +//- rjf: arenas + +#if !defined (RDIM_ARENA_OVERRIDE) + +RADDBGI_PROC RDIM_Arena * +rdim_arena_alloc_fallback(void) +{ + RDIM_Arena *arena = 0; + return arena; +} + +RADDBGI_PROC void +rdim_arena_release_fallback(RDIM_Arena *arena) +{ + +} + +RADDBGI_PROC RADDBGI_U64 +rdim_arena_pos_fallback(RDIM_Arena *arena) +{ + return 0; +} + +RADDBGI_PROC void * +rdim_arena_push_fallback(RDIM_Arena *arena, RADDBGI_U64 size) +{ + return 0; +} + +RADDBGI_PROC void +rdim_arena_pop_to_fallback(RDIM_Arena *arena, RADDBGI_U64 pos) +{ + +} + +#endif + +//- rjf: thread-local scratch arenas + +#if !defined (RDIM_SCRATCH_OVERRIDE) +static RDIM_THREAD_LOCAL RDIM_Arena *rdim_thread_scratches[2]; + +RADDBGI_PROC RDIM_Temp +rdim_scratch_begin_fallback(RDIM_Arena **conflicts, RADDBGI_U64 conflicts_count) +{ + if(rdim_thread_scratches[0] == 0) + { + rdim_thread_scratches[0] = rdim_arena_alloc(); + rdim_thread_scratches[1] = rdim_arena_alloc(); + } + RDIM_Arena *arena = 0; + for(RADDBGI_U64 scratch_idx = 0; + scratch_idx < sizeof(rdim_thread_scratches)/sizeof(rdim_thread_scratches[0]); + scratch_idx += 1) + { + RADDBGI_S32 scratch_conflicts = 0; + for(RADDBGI_U64 conflict_idx = 0; conflict_idx < conflicts_count; conflict_idx += 1) + { + if(conflicts[conflict_idx] == rdim_thread_scratches[scratch_idx]) + { + scratch_conflicts = 1; + break; + } + } + if(!scratch_conflicts) + { + arena = rdim_thread_scratches[scratch_idx]; + } + } + RDIM_Temp temp; + temp.arena = arena; + temp.pos = rdim_arena_pos(arena); + return temp; +} + +RADDBGI_PROC void +rdim_scratch_end_fallback(RDIM_Temp temp) +{ + rdim_arena_pop_to(temp.arena, temp.pos); +} + +#endif + +//- rjf: strings + +RADDBGI_PROC RDIM_String8 +rdim_str8(RADDBGI_U8 *str, RADDBGI_U64 size) +{ + RDIM_String8 result; + result.RDIM_String8_BaseMember = str; + result.RDIM_String8_SizeMember = size; + return result; +} + +RADDBGI_PROC RDIM_String8 +rdim_str8_copy(RDIM_Arena *arena, RDIM_String8 src) +{ + RDIM_String8 dst; + dst.RDIM_String8_SizeMember = src.RDIM_String8_SizeMember; + dst.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RADDBGI_U8, dst.RDIM_String8_SizeMember+1); + rdim_memcpy(dst.RDIM_String8_BaseMember, src.RDIM_String8_BaseMember, src.RDIM_String8_SizeMember); + dst.RDIM_String8_BaseMember[dst.RDIM_String8_SizeMember] = 0; + return dst; +} + +RADDBGI_PROC RDIM_String8 +rdim_str8f(RDIM_Arena *arena, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + RDIM_String8 result = rdim_str8fv(arena, fmt, args); + va_end(args); + return(result); +} + +RADDBGI_PROC RDIM_String8 +rdim_str8fv(RDIM_Arena *arena, char *fmt, va_list args) +{ + va_list args2; + va_copy(args2, args); + RADDBGI_U32 needed_bytes = rdim_vsnprintf(0, 0, fmt, args) + 1; + RDIM_String8 result = {0}; + result.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RADDBGI_U8, needed_bytes); + result.RDIM_String8_SizeMember = rdim_vsnprintf((char*)result.str, needed_bytes, fmt, args2); + result.RDIM_String8_BaseMember[result.RDIM_String8_SizeMember] = 0; + va_end(args2); + return(result); +} + +RADDBGI_PROC RADDBGI_S32 +rdim_str8_match(RDIM_String8 a, RDIM_String8 b, RDIM_StringMatchFlags flags) +{ + RADDBGI_S32 result = 0; + if(a.RDIM_String8_SizeMember == b.RDIM_String8_SizeMember) + { + RADDBGI_S32 case_insensitive = (flags & RDIM_StringMatchFlag_CaseInsensitive); + RADDBGI_U64 size = a.RDIM_String8_SizeMember; + result = 1; + for(RADDBGI_U64 idx = 0; idx < size; idx += 1) + { + RADDBGI_U8 at = a.RDIM_String8_BaseMember[idx]; + RADDBGI_U8 bt = b.RDIM_String8_BaseMember[idx]; + if(case_insensitive) + { + at = ('a' <= at && at <= 'z') ? at-('a'-'A') : at; + bt = ('a' <= bt && bt <= 'z') ? bt-('a'-'A') : bt; + } + if(at != bt) + { + result = 0; + break; + } + } + } + return result; +} + +//- rjf: string lists + +RADDBGI_PROC void +rdim_str8_list_push(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 string) +{ + RDIM_String8Node *n = rdim_push_array(arena, RDIM_String8Node, 1); + n->RDIM_String8Node_StringMember = string; + RDIM_SLLQueuePush_N(list->RDIM_String8List_FirstMember, list->RDIM_String8List_LastMember, n, RDIM_String8Node_NextPtrMember); + list->RDIM_String8List_NodeCountMember += 1; + list->RDIM_String8List_TotalSizeMember += string.RDIM_String8_SizeMember; +} + +RADDBGI_PROC RDIM_String8 +rdim_str8_list_join(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 sep) +{ + RDIM_String8 result; + rdim_memzero_struct(&result); + RADDBGI_U64 sep_count = (list->RDIM_String8List_NodeCountMember > 1) ? (list->RDIM_String8List_NodeCountMember-1) : 0; + result.RDIM_String8_SizeMember = list->RDIM_String8List_TotalSizeMember+sep_count*sep.RDIM_String8_SizeMember; + result.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RADDBGI_U8, result.RDIM_String8_SizeMember+1); + RADDBGI_U64 off = 0; + for(RDIM_String8Node *node = list->RDIM_String8List_FirstMember; + node != 0; + node = node->RDIM_String8Node_NextPtrMember) + { + rdim_memcpy((RADDBGI_U8*)result.RDIM_String8_BaseMember+off, + node->RDIM_String8Node_StringMember.RDIM_String8_BaseMember, + node->RDIM_String8Node_StringMember.RDIM_String8_SizeMember); + off += node->RDIM_String8Node_StringMember.RDIM_String8_SizeMember; + if(sep.RDIM_String8_SizeMember != 0 && node->RDIM_String8Node_NextPtrMember != 0) + { + rdim_memcpy((RADDBGI_U8*)result.RDIM_String8_BaseMember+off, + sep.RDIM_String8_BaseMember, + sep.RDIM_String8_SizeMember); + off += sep.RDIM_String8_SizeMember; + } + } + result.RDIM_String8_BaseMember[off] = 0; + return result; +} + +//- rjf: type lists + +RADDBGI_PROC void +rdim_type_list_push(RDIM_Arena *arena, RDIM_TypeList *list, RDIM_Type *type) +{ + RDIM_TypeNode *node = rdim_push_array(arena, RDIM_TypeNode, 1); + RDIM_SLLQueuePush(list->first, list->last, node); + list->count += 1; + node->type = type; +} + +//- rjf: bytecode lists + +RADDBGI_PROC void +rdim_bytecode_push_op(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_EvalOp op, RADDBGI_U64 p) +{ + RADDBGI_U8 ctrlbits = raddbgi_eval_opcode_ctrlbits[op]; + RADDBGI_U32 p_size = RADDBGI_DECODEN_FROM_CTRLBITS(ctrlbits); + + RDIM_EvalBytecodeOp *node = rdim_push_array(arena, RDIM_EvalBytecodeOp, 1); + node->op = op; + node->p_size = p_size; + node->p = p; + + RDIM_SLLQueuePush(bytecode->first_op, bytecode->last_op, node); + bytecode->op_count += 1; + bytecode->encoded_size += 1 + p_size; +} + +RADDBGI_PROC void +rdim_bytecode_push_uconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_U64 x) +{ + if(x <= 0xFF) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU8, x); + } + else if(x <= 0xFFFF) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU16, x); + } + else if(x <= 0xFFFFFFFF) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU32, x); + } + else + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU64, x); + } +} + +RADDBGI_PROC void +rdim_bytecode_push_sconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_S64 x) +{ + if(-0x80 <= x && x <= 0x7F) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU8, (RADDBGI_U64)x); + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 8); + } + else if(-0x8000 <= x && x <= 0x7FFF) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU16, (RADDBGI_U64)x); + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 16); + } + else if(-0x80000000ll <= x && x <= 0x7FFFFFFFll) + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU32, (RADDBGI_U64)x); + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_TruncSigned, 32); + } + else + { + rdim_bytecode_push_op(arena, bytecode, RADDBGI_EvalOp_ConstU64, (RADDBGI_U64)x); + } +} + +RADDBGI_PROC void +rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *right_destroyed) +{ + if(right_destroyed->first_op != 0) + { + if(left_dst->first_op == 0) + { + rdim_memcpy_struct(left_dst, right_destroyed); + } + else + { + left_dst->last_op = right_destroyed->last_op; + left_dst->op_count += right_destroyed->op_count; + left_dst->encoded_size += right_destroyed->encoded_size; + } + rdim_memzero_struct(right_destroyed); + } +} + +//- rjf: sortable range sorting + +RADDBGI_PROC RDIM_SortKey* +rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RADDBGI_U64 count) +{ + // This sort is designed to take advantage of lots of pre-existing sorted ranges. + // Most line info is already sorted or close to already sorted. + // Similarly most vmap data has lots of pre-sorted ranges. etc. etc. + // Also - this sort should be a "stable" sort. In the use case of sorting vmap + // ranges, we want to be able to rely on order, so it needs to be preserved here. + + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + RDIM_SortKey *result = 0; + + if(count <= 1) + { + result = keys; + } + else + { + RDIM_OrderedRange *ranges_first = 0; + RDIM_OrderedRange *ranges_last = 0; + RADDBGI_U64 range_count = 0; + { + RADDBGI_U64 pos = 0; + for(;pos < count;) + { + // identify ordered range + RADDBGI_U64 first = pos; + RADDBGI_U64 opl = pos + 1; + for(; opl < count && keys[opl - 1].key <= keys[opl].key; opl += 1); + + // generate an ordered range node + RDIM_OrderedRange *new_range = rdim_push_array(rdim_temp_arena(scratch), RDIM_OrderedRange, 1); + SLLQueuePush(ranges_first, ranges_last, new_range); + range_count += 1; + new_range->first = first; + new_range->opl = opl; + + // update pos + pos = opl; + } + } + + if(range_count == 1) + { + result = keys; + } + else + { + RDIM_SortKey *keys_swap = rdim_push_array_no_zero(arena, RDIM_SortKey, count); + RDIM_SortKey *src = keys; + RDIM_SortKey *dst = keys_swap; + RDIM_OrderedRange *src_ranges = ranges_first; + RDIM_OrderedRange *dst_ranges = 0; + RDIM_OrderedRange *dst_ranges_last = 0; + + for(;;) + { + // begin a pass + for(;;) + { + // end pass when out of ranges + if(src_ranges == 0) + { + break; + } + + // get first range + RDIM_OrderedRange *range1 = src_ranges; + SLLStackPop(src_ranges); + + // if this range is the whole array, we are done + if(range1->first == 0 && range1->opl == count) + { + result = src; + goto sort_done; + } + + // if there is not a second range, save this range for next time and end this pass + if(src_ranges == 0) + { + RADDBGI_U64 first = range1->first; + rdim_memcpy(dst + first, src + first, sizeof(*src)*(range1->opl - first)); + SLLQueuePush(dst_ranges, dst_ranges_last, range1); + break; + } + + // get second range + RDIM_OrderedRange *range2 = src_ranges; + SLLStackPop(src_ranges); + + rdim_assert(range1->opl == range2->first); + + // merge these ranges + RADDBGI_U64 jd = range1->first; + RADDBGI_U64 j1 = range1->first; + RADDBGI_U64 j1_opl = range1->opl; + RADDBGI_U64 j2 = range2->first; + RADDBGI_U64 j2_opl = range2->opl; + for(;;) + { + if(src[j1].key <= src[j2].key) + { + rdim_memcpy(dst + jd, src + j1, sizeof(*src)); + j1 += 1; + jd += 1; + if(j1 >= j1_opl) + { + break; + } + } + else + { + rdim_memcpy(dst + jd, src + j2, sizeof(*src)); + j2 += 1; + jd += 1; + if(j2 >= j2_opl) + { + break; + } + } + } + if(j1 < j1_opl) + { + rdim_memcpy(dst + jd, src + j1, sizeof(*src)*(j1_opl - j1)); + } + else + { + rdim_memcpy(dst + jd, src + j2, sizeof(*src)*(j2_opl - j2)); + } + + // save this as one range + range1->opl = range2->opl; + SLLQueuePush(dst_ranges, dst_ranges_last, range1); + } + + // end pass by swapping buffers and range nodes + { + RDIM_SortKey *temp = src; + src = dst; + dst = temp; + } + src_ranges = dst_ranges; + dst_ranges = 0; + dst_ranges_last = 0; + } + } + } + sort_done:; + +#if 0 + // assert sortedness + for(RADDBGI_U64 i = 1; i < count; i += 1){ + rdim_assert(result[i - 1].key <= result[i].key); + } +#endif + + scratch_end(scratch); + return result; +} + +//////////////////////////////// +//~ rjf: Auxiliary Data Structure Functions + +//- rjf: u64 -> ptr map + +RADDBGI_PROC void +rdim_u64toptr_map_init(RDIM_Arena *arena, RDIM_U64ToPtrMap *map, RADDBGI_U64 bucket_count) +{ + rdim_assert(IsPow2OrZero(bucket_count) && bucket_count > 0); + map->buckets = rdim_push_array(arena, RDIM_U64ToPtrNode*, bucket_count); + map->buckets_count = bucket_count; +} + +RADDBGI_PROC void +rdim_u64toptr_map_lookup(RDIM_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RDIM_U64ToPtrLookup *lookup_out) +{ + RADDBGI_U64 bucket_idx = hash&(map->buckets_count - 1); + RDIM_U64ToPtrNode *check_node = map->buckets[bucket_idx]; + for(;check_node != 0; check_node = check_node->next){ + for(RADDBGI_U32 k = 0; k < ArrayCount(check_node->key); k += 1){ + if(check_node->ptr[k] == 0){ + lookup_out->fill_node = check_node; + lookup_out->fill_k = k; + break; + } + else if(check_node->key[k] == key){ + lookup_out->match = check_node->ptr[k]; + break; + } + } + } +} + +RADDBGI_PROC void +rdim_u64toptr_map_insert(RDIM_Arena *arena, RDIM_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RDIM_U64ToPtrLookup *lookup, void *ptr) +{ + if(lookup->fill_node != 0) + { + RDIM_U64ToPtrNode *node = lookup->fill_node; + RADDBGI_U32 k = lookup->fill_k; + node->key[k] = key; + node->ptr[k] = ptr; + } + else + { + RADDBGI_U64 bucket_idx = hash&(map->buckets_count - 1); + + RDIM_U64ToPtrNode *node = rdim_push_array(arena, RDIM_U64ToPtrNode, 1); + SLLStackPush(map->buckets[bucket_idx], node); + node->key[0] = key; + node->ptr[0] = ptr; + + lookup->fill_node = node; + lookup->fill_k = 0; + + map->pair_count += 1; + map->bucket_collision_count += (node->next != 0); + } +} + +//- rjf: string8 -> ptr map + +RADDBGI_PROC void +rdim_str8toptr_map_init(RDIM_Arena *arena, RDIM_Str8ToPtrMap *map, RADDBGI_U64 bucket_count) +{ + map->buckets_count = bucket_count; + map->buckets = rdim_push_array(arena, RDIM_Str8ToPtrNode*, map->buckets_count); +} + +RADDBGI_PROC void* +rdim_str8toptr_map_lookup(RDIM_Str8ToPtrMap *map, RDIM_String8 key, RADDBGI_U64 hash) +{ + void *result = 0; + RADDBGI_U64 bucket_idx = hash%map->buckets_count; + for(RDIM_Str8ToPtrNode *node = map->buckets[bucket_idx]; + node != 0; + node = node->next) + { + if(node->hash == hash && rdim_str8_match(node->key, key, 0)) + { + result = node->ptr; + break; + } + } + return result; +} + +RADDBGI_PROC void +rdim_str8toptr_map_insert(RDIM_Arena *arena, RDIM_Str8ToPtrMap *map, RDIM_String8 key, RADDBGI_U64 hash, void *ptr) +{ + RADDBGI_U64 bucket_idx = hash%map->buckets_count; + RDIM_Str8ToPtrNode *node = rdim_push_array(arena, RDIM_Str8ToPtrNode, 1); + SLLStackPush(map->buckets[bucket_idx], node); + + node->key = rdim_str8_copy(arena, key); + node->hash = hash; + node->ptr = ptr; + map->bucket_collision_count += (node->next != 0); + map->pair_count += 1; +} + +//////////////////////////////// +//~ rjf: Loose Debug Info Construction (Anything -> Loose) Functions + +//- rjf: root creation + +RADDBGI_PROC RDIM_Root* +rdim_root_alloc(RDIM_RootParams *params) +{ + RDIM_Arena *arena = rdim_arena_alloc(); + RDIM_Root *result = rdim_push_array(arena, RDIM_Root, 1); + result->arena = arena; + + // fill in root parameters + { + result->addr_size = params->addr_size; + } + + // setup singular types + { + result->nil_type = rdim_type_new(result); + result->variadic_type = rdim_type_new(result); + result->variadic_type->kind = RADDBGI_TypeKind_Variadic; + + // references to "handled nil type" should be emitted as + // references to nil - but should not generate error + // messages when they are detected - they are expected! + rdim_assert(result->nil_type->idx == result->handled_nil_type.idx); + } + + // setup a null scope + { + RDIM_Scope *scope = rdim_push_array(result->arena, RDIM_Scope, 1); + RDIM_SLLQueuePush_N(result->first_scope, result->last_scope, scope, next_order); + result->scope_count += 1; + } + + // rjf: setup null UDT + { + rdim_type_udt_from_any_type(result, result->nil_type); + } + + // initialize maps + { +#define BKTCOUNT(x) ((x)?(u64_up_to_pow2(x)):(128)) + + rdim_u64toptr_map_init(arena, &result->unit_map, BKTCOUNT(params->bucket_count_units)); + rdim_u64toptr_map_init(arena, &result->symbol_map, BKTCOUNT(params->bucket_count_symbols)); + rdim_u64toptr_map_init(arena, &result->scope_map, BKTCOUNT(params->bucket_count_scopes)); + rdim_u64toptr_map_init(arena, &result->local_map, BKTCOUNT(params->bucket_count_locals)); + rdim_u64toptr_map_init(arena, &result->type_from_id_map, BKTCOUNT(params->bucket_count_types)); + rdim_str8toptr_map_init(arena, &result->construct_map, BKTCOUNT(params->bucket_count_type_constructs)); + +#undef BKTCOUNT + } + + return result; +} + +RADDBGI_PROC void +rdim_root_release(RDIM_Root *root) +{ + arena_release(root->arena); +} + +//- rjf: error accumulation + +RADDBGI_PROC void +rdim_push_error(RDIM_Root *root, RDIM_String8 string) +{ + RDIM_Error *error = rdim_push_array(root->arena, RDIM_Error, 1); + SLLQueuePush(root->errors.first, root->errors.last, error); + root->errors.count += 1; + error->msg = string; +} + +RADDBGI_PROC void +rdim_push_errorf(RDIM_Root *root, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + RDIM_String8 str = rdim_str8fv(root->arena, fmt, args); + rdim_push_error(root, str); + va_end(args); +} + +RADDBGI_PROC RDIM_Error* +rdim_first_error_from_root(RDIM_Root *root) +{ + return root->errors.first; +} + +//- rjf: top-level info specification + +RADDBGI_PROC void +rdim_set_top_level_info(RDIM_Root *root, RDIM_TopLevelInfo *tli) +{ + rdim_requiref(root, !root->top_level_info_is_set, return, "Top level information set multiple times."); + rdim_memcpy_struct(&root->top_level_info, tli); + root->top_level_info_is_set = 1; +} + +//- rjf: binary section building + +RADDBGI_PROC void +rdim_add_binary_section(RDIM_Root *root, RDIM_String8 name, RADDBGI_BinarySectionFlags flags, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGI_U64 foff_first, RADDBGI_U64 foff_opl) +{ + RDIM_BinarySection *sec = rdim_push_array(root->arena, RDIM_BinarySection, 1); + SLLQueuePush(root->binary_section_first, root->binary_section_last, sec); + root->binary_section_count += 1; + sec->name = name; + sec->flags = flags; + sec->voff_first = voff_first; + sec->voff_opl = voff_opl; + sec->foff_first = foff_first; + sec->foff_opl = foff_opl; +} + +//- rjf: unit info building + +RADDBGI_PROC RDIM_Unit* +rdim_unit_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 unit_user_id, RADDBGI_U64 unit_user_id_hash) +{ + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->unit_map, unit_user_id, unit_user_id_hash, &lookup); + RDIM_Unit *result = 0; + if(lookup.match != 0) + { + result = (RDIM_Unit*)lookup.match; + } + else + { + result = rdim_push_array(root->arena, RDIM_Unit, 1); + result->idx = root->unit_count; + RDIM_SLLQueuePush_N(root->unit_first, root->unit_last, result, next_order); + root->unit_count += 1; + rdim_u64toptr_map_insert(root->arena, &root->unit_map, unit_user_id, unit_user_id, &lookup, result); + } + return result; +} + +RADDBGI_PROC void +rdim_unit_set_info(RDIM_Root *root, RDIM_Unit *unit, RDIM_UnitInfo *info) +{ + rdim_requiref(root, !unit->info_is_set, return, "Unit information set multiple times."); + unit->info_is_set = 1; + unit->unit_name = rdim_str8_copy(root->arena, info->unit_name); + unit->compiler_name = rdim_str8_copy(root->arena, info->compiler_name); + unit->source_file = rdim_str8_copy(root->arena, info->source_file); + unit->object_file = rdim_str8_copy(root->arena, info->object_file); + unit->archive_file = rdim_str8_copy(root->arena, info->archive_file); + unit->build_path = rdim_str8_copy(root->arena, info->build_path); + unit->language = info->language; +} + +RADDBGI_PROC void +rdim_unit_add_line_sequence(RDIM_Root *root, RDIM_Unit *unit, RDIM_LineSequence *line_sequence) +{ + RDIM_LineSequenceNode *node = rdim_push_array(root->arena, RDIM_LineSequenceNode, 1); + SLLQueuePush(unit->line_seq_first, unit->line_seq_last, node); + unit->line_seq_count += 1; + + node->line_seq.file_name = rdim_str8_copy(root->arena, line_sequence->file_name); + + node->line_seq.voffs = rdim_push_array(root->arena, RADDBGI_U64, line_sequence->line_count + 1); + rdim_memcpy(node->line_seq.voffs, line_sequence->voffs, sizeof(RADDBGI_U64)*(line_sequence->line_count + 1)); + + node->line_seq.line_nums = rdim_push_array(root->arena, RADDBGI_U32, line_sequence->line_count); + rdim_memcpy(node->line_seq.line_nums, line_sequence->line_nums, sizeof(RADDBGI_U32)*line_sequence->line_count); + + if(line_sequence->col_nums != 0) + { + node->line_seq.col_nums = rdim_push_array(root->arena, RADDBGI_U16, line_sequence->line_count); + rdim_memcpy(node->line_seq.col_nums, line_sequence->col_nums, sizeof(RADDBGI_U16)*line_sequence->line_count); + } + + node->line_seq.line_count = line_sequence->line_count; +} + +RADDBGI_PROC void +rdim_unit_vmap_add_range(RDIM_Root *root, RDIM_Unit *unit, RADDBGI_U64 first, RADDBGI_U64 opl) +{ + RDIM_UnitVMapRange *node = rdim_push_array(root->arena, RDIM_UnitVMapRange, 1); + SLLQueuePush(root->unit_vmap_range_first, root->unit_vmap_range_last, node); + root->unit_vmap_range_count += 1; + node->unit = unit; + node->first = first; + node->opl = opl; +} + +//- rjf: type info lookups/reservations + +RADDBGI_PROC RDIM_Type* +rdim_type_from_id(RDIM_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash) +{ + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->type_from_id_map, type_user_id, type_user_id_hash, &lookup); + RDIM_Type *result = (RDIM_Type*)lookup.match; + return result; +} + +RADDBGI_PROC RDIM_Reservation* +rdim_type_reserve_id(RDIM_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash) +{ + RDIM_Reservation *result = 0; + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->type_from_id_map, type_user_id, type_user_id_hash, &lookup); + if(lookup.match == 0) + { + rdim_u64toptr_map_insert(root->arena, &root->type_from_id_map, type_user_id, type_user_id_hash, &lookup, root->nil_type); + void **slot = &lookup.fill_node->ptr[lookup.fill_k]; + result = (RDIM_Reservation*)slot; + } + return result; +} + +RADDBGI_PROC void +rdim_type_fill_id(RDIM_Root *root, RDIM_Reservation *res, RDIM_Type *type) +{ + if(res != 0 && type != 0) + { + *(void**)res = type; + } +} + +//- rjf: nil/singleton types + +RADDBGI_PROC RADDBGI_S32 +rdim_type_is_unhandled_nil(RDIM_Root *root, RDIM_Type *type) +{ + RADDBGI_S32 result = (type->kind == RADDBGI_TypeKind_NULL && type != &root->handled_nil_type); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_handled_nil(RDIM_Root *root) +{ + return &root->handled_nil_type; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_nil(RDIM_Root *root) +{ + return root->nil_type; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_variadic(RDIM_Root *root) +{ + return root->variadic_type; +} + +//- rjf: base type info constructors + +RADDBGI_PROC RDIM_Type* +rdim_type_new(RDIM_Root *root) +{ + RDIM_Type *result = rdim_push_array(root->arena, RDIM_Type, 1); + result->idx = root->type_count; + RDIM_SLLQueuePush_N(root->first_type, root->last_type, result, next_order); + root->type_count += 1; + return result; +} + +RADDBGI_PROC RDIM_TypeUDT* +rdim_type_udt_from_any_type(RDIM_Root *root, RDIM_Type *type) +{ + if(type->udt == 0) + { + RDIM_TypeUDT *new_udt = rdim_push_array(root->arena, RDIM_TypeUDT, 1); + new_udt->idx = root->type_udt_count; + RDIM_SLLQueuePush_N(root->first_udt, root->last_udt, new_udt, next_order); + root->type_udt_count += 1; + new_udt->self_type = type; + type->udt = new_udt; + } + RDIM_TypeUDT *result = type->udt; + return result; +} + +RADDBGI_PROC RDIM_TypeUDT* +rdim_type_udt_from_record_type(RDIM_Root *root, RDIM_Type *type) +{ + rdim_requiref(root, (type->kind == RADDBGI_TypeKind_Struct || + type->kind == RADDBGI_TypeKind_Class || + type->kind == RADDBGI_TypeKind_Union), + return 0, + "Tried to use non-user-defined-type-kind to create user-defined-type."); + RDIM_TypeUDT *result = 0; + result = rdim_type_udt_from_any_type(root, type); + return result; +} + +//- rjf: basic/operator type construction helpers + +RADDBGI_PROC RDIM_Type* +rdim_type_basic(RDIM_Root *root, RADDBGI_TypeKind type_kind, RDIM_String8 name) +{ + rdim_requiref(root, (RADDBGI_TypeKind_FirstBuiltIn <= type_kind && type_kind <= RADDBGI_TypeKind_LastBuiltIn), return root->nil_type, "Non-basic type kind passed to construct basic type."); + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = sizeof(RDIM_TypeConstructKind) + sizeof(type_kind) + name.size; + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "basic" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Basic; + ptr += sizeof(RDIM_TypeConstructKind); + // type_kind + rdim_memcpy(ptr, &type_kind, sizeof(type_kind)); + ptr += sizeof(type_kind); + // name + rdim_memcpy(ptr, name.str, name.size); + ptr += name.size; + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // calculate size + RADDBGI_U32 byte_size = raddbgi_size_from_basic_type_kind(type_kind); + if(byte_size == 0xFFFFFFFF) + { + byte_size = root->addr_size; + } + + // setup new node + result = rdim_type_new(root); + result->kind = type_kind; + result->name = rdim_str8_copy(root->arena, name); + result->byte_size = byte_size; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + + // save in name map + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Types); + rdim_name_map_add_pair(root, map, result->name, result->idx); + } + } + + scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_modifier(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_TypeModifierFlags flags) +{ + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = sizeof(RDIM_TypeConstructKind) + sizeof(flags) + sizeof(direct_type->idx); + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "modifier" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Modifier; + ptr += sizeof(RDIM_TypeConstructKind); + // flags + rdim_memcpy(ptr, &flags, sizeof(flags)); + ptr += sizeof(flags); + // direct_type->idx + rdim_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); + ptr += sizeof(direct_type->idx); + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0){ + + // setup new node + result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Modifier; + result->flags = flags; + result->byte_size = direct_type->byte_size; + result->direct_type = direct_type; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + rdim_scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_bitfield(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_U32 bit_off, RADDBGI_U32 bit_count) +{ + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = sizeof(RDIM_TypeConstructKind) + sizeof(direct_type->idx) + sizeof(RADDBGI_U32)*2; + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "bitfield" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Bitfield; + ptr += sizeof(RDIM_TypeConstructKind); + // direct_type->idx + rdim_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); + ptr += sizeof(direct_type->idx); + // bit_off + rdim_memcpy(ptr, &bit_off, sizeof(bit_off)); + ptr += sizeof(bit_off); + // bit_count + rdim_memcpy(ptr, &bit_count, sizeof(bit_count)); + ptr += sizeof(bit_count); + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // setup new node + result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Bitfield; + result->byte_size = direct_type->byte_size; + result->off = bit_off; + result->count = bit_count; + result->direct_type = direct_type; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + rdim_scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_pointer(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_TypeKind ptr_type_kind) +{ + rdim_requiref(root, (ptr_type_kind == RADDBGI_TypeKind_Ptr || + ptr_type_kind == RADDBGI_TypeKind_LRef || + ptr_type_kind == RADDBGI_TypeKind_RRef), + return root->nil_type, + "Non-pointer type kind used to construct pointer type."); + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = sizeof(RDIM_TypeConstructKind) + sizeof(ptr_type_kind) + sizeof(direct_type->idx); + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "pointer" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Pointer; + ptr += sizeof(RDIM_TypeConstructKind); + // type_kind + rdim_memcpy(ptr, &ptr_type_kind, sizeof(ptr_type_kind)); + ptr += sizeof(ptr_type_kind); + // direct_type->idx + rdim_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); + ptr += sizeof(direct_type->idx); + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // setup new node + result = rdim_type_new(root); + result->kind = ptr_type_kind; + result->byte_size = root->addr_size; + result->direct_type = direct_type; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + rdim_scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_array(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_U64 count) +{ + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = + sizeof(RDIM_TypeConstructKind) + sizeof(direct_type->idx) + sizeof(count); + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "array" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Array; + ptr += sizeof(RDIM_TypeConstructKind); + // direct_type->idx + rdim_memcpy(ptr, &direct_type->idx, sizeof(direct_type->idx)); + ptr += sizeof(direct_type->idx); + // count + rdim_memcpy(ptr, &count, sizeof(count)); + ptr += sizeof(count); + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // setup new node + result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Array; + result->count = count; + result->direct_type = direct_type; + result->byte_size = direct_type->byte_size*count; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_proc(RDIM_Root *root, RDIM_Type *return_type, struct RDIM_TypeList *params) +{ + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = sizeof(RDIM_TypeConstructKind) + sizeof(return_type->idx)*(1 + params->count); + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "procedure" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Procedure; + ptr += sizeof(RDIM_TypeConstructKind); + // ret_type->idx + rdim_memcpy(ptr, &return_type->idx, sizeof(return_type->idx)); + ptr += sizeof(return_type->idx); + // (params ...)->idx + for(RDIM_TypeNode *node = params->first; + node != 0; + node = node->next) + { + rdim_memcpy(ptr, &node->type->idx, sizeof(node->type->idx)); + ptr += sizeof(node->type->idx); + } + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // setup param buffer + RDIM_Type **param_types = rdim_push_array(root->arena, RDIM_Type*, params->count); + { + RDIM_Type **ptr = param_types; + for(RDIM_TypeNode *node = params->first; + node != 0; + node = node->next) + { + *ptr = node->type; + ptr += 1; + } + } + + // setup new node + result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Function; + result->byte_size = root->addr_size; + result->count = params->count; + result->direct_type = return_type; + result->param_types = param_types; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + rdim_scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_method(RDIM_Root *root, RDIM_Type *this_type, RDIM_Type *return_type, struct RDIM_TypeList *params) +{ + RDIM_Type *result = root->nil_type; + RDIM_Temp scratch = rdim_scratch_begin(0, 0); + + // setup construct buffer + RADDBGI_U64 buf_size = + sizeof(RDIM_TypeConstructKind) + sizeof(return_type->idx)*(2 + params->count); + RADDBGI_U8 *buf = rdim_push_array(rdim_temp_arena(scratch), RADDBGI_U8, buf_size); + { + RADDBGI_U8 *ptr = buf; + // "method" + *(RDIM_TypeConstructKind*)ptr = RDIM_TypeConstructKind_Method; + ptr += sizeof(RDIM_TypeConstructKind); + // ret_type->idx + rdim_memcpy(ptr, &return_type->idx, sizeof(return_type->idx)); + ptr += sizeof(return_type->idx); + // this_type->idx + rdim_memcpy(ptr, &this_type->idx, sizeof(this_type->idx)); + ptr += sizeof(this_type->idx); + // (params ...)->idx + for(RDIM_TypeNode *node = params->first; + node != 0; + node = node->next) + { + rdim_memcpy(ptr, &node->type->idx, sizeof(node->type->idx)); + ptr += sizeof(node->type->idx); + } + } + + // check for duplicate construct + RDIM_String8 blob = rdim_str8(buf, buf_size); + RADDBGI_U64 blob_hash = raddbgi_hash(buf, buf_size); + void *lookup_ptr = rdim_str8toptr_map_lookup(&root->construct_map, blob, blob_hash); + result = (RDIM_Type*)lookup_ptr; + if(result == 0) + { + // setup param buffer + RDIM_Type **param_types = rdim_push_array(root->arena, RDIM_Type*, params->count + 1); + { + RDIM_Type **ptr = param_types; + { + *ptr = this_type; + ptr += 1; + } + for(RDIM_TypeNode *node = params->first; + node != 0; + node = node->next) + { + *ptr = node->type; + ptr += 1; + } + } + + // setup new node + result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Method; + result->byte_size = root->addr_size; + result->count = params->count; + result->direct_type = return_type; + result->param_types = param_types; + + // save in construct map + rdim_str8toptr_map_insert(root->arena, &root->construct_map, blob, blob_hash, result); + } + + rdim_scratch_end(scratch); + rdim_assert(result != 0); + return result; +} + +//- rjf: udt type constructors + +RADDBGI_PROC RDIM_Type* +rdim_type_udt(RDIM_Root *root, RADDBGI_TypeKind record_type_kind, RDIM_String8 name, RADDBGI_U64 size) +{ + rdim_requiref(root, (record_type_kind == RADDBGI_TypeKind_Struct || + record_type_kind == RADDBGI_TypeKind_Class || + record_type_kind == RADDBGI_TypeKind_Union), + return root->nil_type, + "Non-user-defined-type-kind used to create user-defined type."); + + // rjf: make type + RDIM_Type *result = rdim_type_new(root); + result->kind = record_type_kind; + result->byte_size = size; + result->name = rdim_str8_copy(root->arena, name); + + // rjf: save in name map + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Types); + rdim_name_map_add_pair(root, map, result->name, result->idx); + } + + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_enum(RDIM_Root *root, RDIM_Type *direct_type, RDIM_String8 name) +{ + // rjf: make type + RDIM_Type *result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Enum; + result->byte_size = direct_type->byte_size; + result->name = rdim_str8_copy(root->arena, name); + result->direct_type = direct_type; + + // rjf: save in name map + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Types); + rdim_name_map_add_pair(root, map, result->name, result->idx); + } + + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_alias(RDIM_Root *root, RDIM_Type *direct_type, RDIM_String8 name) +{ + // rjf: make type + RDIM_Type *result = rdim_type_new(root); + result->kind = RADDBGI_TypeKind_Alias; + result->byte_size = direct_type->byte_size; + result->name = rdim_str8_copy(root->arena, name); + result->direct_type = direct_type; + + // rjf: save in name map + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Types); + rdim_name_map_add_pair(root, map, result->name, result->idx); + } + + return result; +} + +RADDBGI_PROC RDIM_Type* +rdim_type_incomplete(RDIM_Root *root, RADDBGI_TypeKind type_kind, RDIM_String8 name) +{ + rdim_requiref(root, (type_kind == RADDBGI_TypeKind_IncompleteStruct || + type_kind == RADDBGI_TypeKind_IncompleteClass || + type_kind == RADDBGI_TypeKind_IncompleteUnion || + type_kind == RADDBGI_TypeKind_IncompleteEnum), + return root->nil_type, + "Non-incomplete-type-kind used to create incomplete type."); + + // rjf: make type + RDIM_Type *result = rdim_type_new(root); + result->kind = type_kind; + result->name = rdim_str8_copy(root->arena, name); + + // save in name map + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Types); + rdim_name_map_add_pair(root, map, result->name, result->idx); + } + + return result; +} + +//- rjf: type member building + +RADDBGI_PROC void +rdim_type_add_member_data_field(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type, RADDBGI_U32 off) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_DataField; + member->name = rdim_str8_copy(root->arena, name); + member->type = mem_type; + member->off = off; + } +} + +RADDBGI_PROC void +rdim_type_add_member_static_data(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_StaticData; + member->name = rdim_str8_copy(root->arena, name); + member->type = mem_type; + } +} + +RADDBGI_PROC void +rdim_type_add_member_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_Method; + member->name = rdim_str8_copy(root->arena, name); + member->type = mem_type; + } +} + +RADDBGI_PROC void +rdim_type_add_member_static_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + + root->total_member_count += 1; + + member->kind = RADDBGI_MemberKind_StaticMethod; + member->name = rdim_str8_copy(root->arena, name); + member->type = mem_type; + } +} + +RADDBGI_PROC void +rdim_type_add_member_virtual_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_VirtualMethod; + member->name = rdim_str8_copy(root->arena, name); + member->type = mem_type; + } +} + +RADDBGI_PROC void +rdim_type_add_member_base(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *base_type, RADDBGI_U32 off) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_Base; + member->type = base_type; + member->off = off; + } +} + +RADDBGI_PROC void +rdim_type_add_member_virtual_base(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *base_type, RADDBGI_U32 vptr_off, RADDBGI_U32 vtable_off) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_VirtualBase; + member->type = base_type; + // TODO(allen): what to do with the two offsets in this case? + } +} + +RADDBGI_PROC void +rdim_type_add_member_nested_type(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *nested_type) +{ + RDIM_TypeUDT *udt = rdim_type_udt_from_record_type(root, record_type); + if(udt != 0) + { + RDIM_TypeMember *member = rdim_push_array(root->arena, RDIM_TypeMember, 1); + SLLQueuePush(udt->first_member, udt->last_member, member); + udt->member_count += 1; + root->total_member_count += 1; + member->kind = RADDBGI_MemberKind_NestedType; + member->type = nested_type; + } +} + +RADDBGI_PROC void +rdim_type_add_enum_val(RDIM_Root *root, RDIM_Type *enum_type, RDIM_String8 name, RADDBGI_U64 val) +{ + rdim_requiref(root, (enum_type->kind == RADDBGI_TypeKind_Enum), return, "Tried to add enum value to non-enum type."); + RDIM_TypeUDT *udt = rdim_type_udt_from_any_type(root, enum_type); + if(udt != 0) + { + RDIM_TypeEnumVal *enum_val = rdim_push_array(root->arena, RDIM_TypeEnumVal, 1); + SLLQueuePush(udt->first_enum_val, udt->last_enum_val, enum_val); + udt->enum_val_count += 1; + root->total_enum_val_count += 1; + enum_val->name = rdim_str8_copy(root->arena, name); + enum_val->val = val; + } +} + +//- rjf: type source coordinate specifications +RADDBGI_PROC void +rdim_type_set_source_coordinates(RDIM_Root *root, RDIM_Type *defined_type, RDIM_String8 source_path, RADDBGI_U32 line, RADDBGI_U32 col) +{ + rdim_requiref(root, (RADDBGI_TypeKind_FirstUserDefined <= defined_type->kind && defined_type->kind <= RADDBGI_TypeKind_LastUserDefined), + return, "Tried to add source coordinates to non-user-defined type."); + RDIM_TypeUDT *udt = rdim_type_udt_from_any_type(root, defined_type); + if(udt != 0) + { + udt->source_path = rdim_str8_copy(root->arena, source_path); + udt->line = line; + udt->col = col; + } +} + +//- rjf: symbol info building + +RADDBGI_PROC RDIM_Symbol* +rdim_symbol_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 symbol_user_id, RADDBGI_U64 symbol_user_id_hash) +{ + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->symbol_map, symbol_user_id, symbol_user_id_hash, &lookup); + RDIM_Symbol *result = 0; + if(lookup.match != 0) + { + result = (RDIM_Symbol*)lookup.match; + } + else + { + result = rdim_push_array(root->arena, RDIM_Symbol, 1); + RDIM_SLLQueuePush_N(root->first_symbol, root->last_symbol, result, next_order); + root->symbol_count += 1; + rdim_u64toptr_map_insert(root->arena, &root->symbol_map, symbol_user_id, symbol_user_id_hash, &lookup, result); + } + return result; +} + +RADDBGI_PROC void +rdim_symbol_set_info(RDIM_Root *root, RDIM_Symbol *symbol, RDIM_SymbolInfo *info) +{ + // rjf: unpack + RDIM_SymbolKind kind = info->kind; + RDIM_Symbol *container_symbol = info->container_symbol; + RDIM_Type *container_type = info->container_type; + + // rjf: requirements + rdim_requiref(root, RDIM_SymbolKind_NULL == symbol->kind, return, "Symbol information set multiple times."); + rdim_requiref(root, RDIM_SymbolKind_NULL < info->kind && info->kind < RDIM_SymbolKind_COUNT, return, "Invalid symbol kind used to initialize symbol."); + rdim_requiref(root, info->type != 0, return, "Invalid type used to initialize symbol."); + rdim_requiref(root, info->container_symbol == 0 || info->container_type == 0, container_type = 0, "Symbol initialized with both a containing symbol and containing type, when only one is allowed."); + + // rjf: fill + root->symbol_kind_counts[kind] += 1; + symbol->idx = root->symbol_kind_counts[kind]; + symbol->kind = kind; + symbol->name = rdim_str8_copy(root->arena, info->name); + symbol->link_name = rdim_str8_copy(root->arena, info->link_name); + symbol->type = info->type; + symbol->is_extern = info->is_extern; + symbol->offset = info->offset; + symbol->container_symbol = container_symbol; + symbol->container_type = container_type; + + // rjf: set root scope + switch(kind) + { + default:{}break; + case RDIM_SymbolKind_GlobalVariable: + case RDIM_SymbolKind_ThreadVariable: + { + rdim_requiref(root, info->root_scope == 0, rdim_noop, "Global or thread variable initialized with root scope."); + }break; + case RDIM_SymbolKind_Procedure: + { + rdim_requiref(root, info->root_scope != 0, rdim_noop, "Procedure symbol initialized without root scope."); + symbol->root_scope = info->root_scope; + rdim_scope_recursive_set_symbol(info->root_scope, symbol); + }break; + } + + // save name map + { + RDIM_NameMap *map = 0; + switch(kind) + { + default:{}break; + case RDIM_SymbolKind_GlobalVariable: + { + map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_GlobalVariables); + }break; + case RDIM_SymbolKind_ThreadVariable: + { + map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_ThreadVariables); + }break; + case RDIM_SymbolKind_Procedure: + { + map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_Procedures); + }break; + } + if(map != 0) + { + rdim_name_map_add_pair(root, map, symbol->name, symbol->idx); + } + } + + // save link name map + if(kind == RDIM_SymbolKind_Procedure && symbol->link_name.size > 0) + { + RDIM_NameMap *map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_LinkNameProcedures); + rdim_name_map_add_pair(root, map, symbol->link_name, symbol->idx); + } +} + +//- rjf: scope info building + +RADDBGI_PROC RDIM_Scope * +rdim_scope_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 scope_user_id, RADDBGI_U64 scope_user_id_hash) +{ + RDIM_Scope *result = 0; + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->scope_map, scope_user_id, scope_user_id_hash, &lookup); + if(lookup.match != 0) + { + result = (RDIM_Scope*)lookup.match; + } + else + { + result = rdim_push_array(root->arena, RDIM_Scope, 1); + result->idx = root->scope_count; + RDIM_SLLQueuePush_N(root->first_scope, root->last_scope, result, next_order); + root->scope_count += 1; + rdim_u64toptr_map_insert(root->arena, &root->scope_map, scope_user_id, scope_user_id_hash, &lookup, result); + } + return result; +} + +RADDBGI_PROC void +rdim_scope_set_parent(RDIM_Root *root, RDIM_Scope *scope, RDIM_Scope *parent) +{ + rdim_requiref(root, scope->parent_scope == 0, return, "Scope parent set multiple times."); + rdim_requiref(root, parent != 0, return, "Tried to set invalid parent as scope parent."); + scope->symbol = parent->symbol; + scope->parent_scope = parent; + RDIM_SLLQueuePush_N(parent->first_child, parent->last_child, scope, next_sibling); +} + +RADDBGI_PROC void +rdim_scope_add_voff_range(RDIM_Root *root, RDIM_Scope *scope, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl) +{ + RDIM_VOffRange *range = rdim_push_array(root->arena, RDIM_VOffRange, 1); + SLLQueuePush(scope->first_range, scope->last_range, range); + scope->range_count += 1; + range->voff_first = voff_first; + range->voff_opl = voff_opl; + scope->voff_base = Min(scope->voff_base, voff_first); + root->scope_voff_count += 2; +} + +RADDBGI_PROC void +rdim_scope_recursive_set_symbol(RDIM_Scope *scope, RDIM_Symbol *symbol) +{ + scope->symbol = symbol; + for(RDIM_Scope *node = scope->first_child; + node != 0; + node = node->next_sibling) + { + rdim_scope_recursive_set_symbol(node, symbol); + } +} + +//- rjf: local info building + +RADDBGI_PROC RDIM_Local* +rdim_local_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 local_user_id, RADDBGI_U64 local_user_id_hash) +{ + RDIM_Local *result = 0; + RDIM_U64ToPtrLookup lookup = {0}; + rdim_u64toptr_map_lookup(&root->local_map, local_user_id, local_user_id_hash, &lookup); + if(lookup.match != 0) + { + result = (RDIM_Local*)lookup.match; + } + else + { + result = rdim_push_array(root->arena, RDIM_Local, 1); + rdim_u64toptr_map_insert(root->arena, &root->local_map, local_user_id, local_user_id_hash, &lookup, result); + } + return result; +} + +RADDBGI_PROC void +rdim_local_set_basic_info(RDIM_Root *root, RDIM_Local *local, RDIM_LocalInfo *info) +{ + rdim_requiref(root, local->kind == RADDBGI_LocalKind_NULL, return, "Local information set multiple times."); + rdim_requiref(root, info->scope != 0, return, "Tried to set invalid scope as local's containing scope."); + rdim_requiref(root, RADDBGI_LocalKind_NULL < info->kind && info->kind < RADDBGI_LocalKind_COUNT, return, "Invalid local kind."); + rdim_requiref(root, info->type != 0, return, "Tried to set invalid type as local's type."); + RDIM_Scope *scope = info->scope; + SLLQueuePush(scope->first_local, scope->last_local, local); + scope->local_count += 1; + root->local_count += 1; + local->kind = info->kind; + local->name = rdim_str8_copy(root->arena, info->name); + local->type = info->type; +} + +RADDBGI_PROC RDIM_LocationSet* +rdim_location_set_from_local(RDIM_Root *root, RDIM_Local *local) +{ + RDIM_LocationSet *result = local->locset; + if(result == 0) + { + local->locset = rdim_push_array(root->arena, RDIM_LocationSet, 1); + result = local->locset; + } + return result; +} + +//- rjf: location info building + +RADDBGI_PROC void +rdim_location_set_add_case(RDIM_Root *root, RDIM_LocationSet *locset, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RDIM_Location *location) +{ + RDIM_LocationCase *location_case = rdim_push_array(root->arena, RDIM_LocationCase, 1); + SLLQueuePush(locset->first_location_case, locset->last_location_case, location_case); + locset->location_case_count += 1; + root->location_count += 1; + location_case->voff_first = voff_first; + location_case->voff_opl = voff_opl; + location_case->location = location; +} + +RADDBGI_PROC RDIM_Location* +rdim_location_addr_bytecode_stream(RDIM_Root *root, struct RDIM_EvalBytecode *bytecode) +{ + RDIM_Location *result = rdim_push_array(root->arena, RDIM_Location, 1); + result->kind = RADDBGI_LocationKind_AddrBytecodeStream; + result->bytecode = *bytecode; + return result; +} + +RADDBGI_PROC RDIM_Location* +rdim_location_val_bytecode_stream(RDIM_Root *root, struct RDIM_EvalBytecode *bytecode) +{ + RDIM_Location *result = rdim_push_array(root->arena, RDIM_Location, 1); + result->kind = RADDBGI_LocationKind_ValBytecodeStream; + result->bytecode = *bytecode; + return result; +} + +RADDBGI_PROC RDIM_Location* +rdim_location_addr_reg_plus_u16(RDIM_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset) +{ + RDIM_Location *result = rdim_push_array(root->arena, RDIM_Location, 1); + result->kind = RADDBGI_LocationKind_AddrRegisterPlusU16; + result->register_code = reg_code; + result->offset = offset; + return result; +} + +RADDBGI_PROC RDIM_Location* +rdim_location_addr_addr_reg_plus_u16(RDIM_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset) +{ + RDIM_Location *result = rdim_push_array(root->arena, RDIM_Location, 1); + result->kind = RADDBGI_LocationKind_AddrAddrRegisterPlusU16; + result->register_code = reg_code; + result->offset = offset; + return result; +} + +RADDBGI_PROC RDIM_Location* +rdim_location_val_reg(RDIM_Root *root, RADDBGI_U8 reg_code) +{ + RDIM_Location *result = rdim_push_array(root->arena, RDIM_Location, 1); + result->kind = RADDBGI_LocationKind_ValRegister; + result->register_code = reg_code; + return result; +} + +//- rjf: name map building + +RADDBGI_PROC RDIM_NameMap* +rdim_name_map_for_kind(RDIM_Root *root, RADDBGI_NameMapKind kind) +{ + RDIM_NameMap *result = 0; + if(kind < RADDBGI_NameMapKind_COUNT) + { + if(root->name_maps[kind] == 0) + { + root->name_maps[kind] = rdim_push_array(root->arena, RDIM_NameMap, 1); + root->name_maps[kind]->buckets_count = 16384; + root->name_maps[kind]->buckets = rdim_push_array(root->arena, RDIM_NameMapNode *, root->name_maps[kind]->buckets_count); + } + result = root->name_maps[kind]; + } + return result; +} + +RADDBGI_PROC void +rdim_name_map_add_pair(RDIM_Root *root, RDIM_NameMap *map, RDIM_String8 string, RADDBGI_U32 idx) +{ + // hash + RADDBGI_U64 hash = raddbgi_hash(string.str, string.size); + RADDBGI_U64 bucket_idx = hash%map->buckets_count; + + // find existing name node + RDIM_NameMapNode *match = 0; + for(RDIM_NameMapNode *node = map->buckets[bucket_idx]; + node != 0; + node = node->bucket_next) + { + if(rdim_str8_match(string, node->string, 0)) + { + match = node; + break; + } + } + + // make name node if necessary + if(match == 0) + { + match = rdim_push_array(root->arena, RDIM_NameMapNode, 1); + match->string = rdim_str8_copy(root->arena, string); + RDIM_SLLStackPush_N(map->buckets[bucket_idx], match, bucket_next); + RDIM_SLLQueuePush_N(map->first, map->last, match, order_next); + map->name_count += 1; + map->bucket_collision_count += (match->bucket_next != 0); + } + + // find existing idx + RADDBGI_S32 existing_idx = 0; + for(RDIM_NameMapIdxNode *node = match->idx_first; + node != 0; + node = node->next) + { + for(RADDBGI_U32 i = 0; i < ArrayCount(node->idx); i += 1) + { + if(node->idx[i] == 0) + { + break; + } + if(node->idx[i] == idx) + { + existing_idx = 1; + break; + } + } + } + + // insert new idx if necessary + if(!existing_idx) + { + RDIM_NameMapIdxNode *idx_node = match->idx_last; + RADDBGI_U32 insert_i = match->idx_count%ArrayCount(idx_node->idx); + if(insert_i == 0) + { + idx_node = rdim_push_array(root->arena, RDIM_NameMapIdxNode, 1); + SLLQueuePush(match->idx_first, match->idx_last, idx_node); + } + + idx_node->idx[insert_i] = idx; + match->idx_count += 1; + } +} + +//////////////////////////////// +//~ rjf: Debug Info Baking (Loose -> Tight) Functions + +//- rjf: bake context construction + +RADDBGI_PROC RDIM_BakeCtx* +rdim_bake_ctx_begin(RDIM_BakeParams *params) +{ + RDIM_Arena *arena = rdim_arena_alloc(); + RDIM_BakeCtx *result = rdim_push_array(arena, RDIM_BakeCtx, 1); + result->arena = arena; +#define BKTCOUNT(x) ((x)?(u64_up_to_pow2(x)):(16384)) + result->strs.buckets_count = BKTCOUNT(params->strings_bucket_count); + result->idxs.buckets_count = BKTCOUNT(params->idx_runs_bucket_count); +#undef BKTCOUNT + result->strs.buckets = rdim_push_array(arena, RDIM_StringNode *, result->strs.buckets_count); + result->idxs.buckets = rdim_push_array(arena, RDIM_IdxRunNode *, result->idxs.buckets_count); + + rdim_string(result, rdim_str8_lit("")); + rdim_idx_run(result, 0, 0); + + result->tree = rdim_push_array(arena, RDIM_PathTree, 1); + { + RDIM_PathNode *nil_path_node = rdim_paths_new_node(result); + nil_path_node->name = rdim_str8_lit(""); + RDIM_SrcNode *nil_src_node = rdim_paths_new_src_node(result); + nil_src_node->path_node = nil_path_node; + nil_src_node->normal_full_path = rdim_str8_lit(""); + nil_path_node->src_file = nil_src_node; + } + + return result; +} + +RADDBGI_PROC void +rdim_bake_ctx_release(RDIM_BakeCtx *bake_ctx) +{ + arena_release(bake_ctx->arena); +} + +//- rjf: string baking + +RADDBGI_PROC RADDBGI_U32 +rdim_string(RDIM_BakeCtx *bctx, RDIM_String8 str) +{ + RDIM_Arena *arena = bctx->arena; + RDIM_Strings *strs = &bctx->strs; + RADDBGI_U64 hash = raddbgi_hash(str.str, str.size); + RADDBGI_U64 bucket_idx = hash%strs->buckets_count; + + // look for a match + RDIM_StringNode *match = 0; + for(RDIM_StringNode *node = strs->buckets[bucket_idx]; + node != 0; + node = node->bucket_next) + { + if(node->hash == hash && rdim_str8_match(node->str, str, 0)) + { + match = node; + break; + } + } + + // insert new node if no match + if(match == 0) + { + RDIM_StringNode *node = rdim_push_array_no_zero(arena, RDIM_StringNode, 1); + node->str = rdim_str8_copy(arena, str); + node->hash = hash; + node->idx = strs->count; + strs->count += 1; + RDIM_SLLQueuePush_N(strs->order_first, strs->order_last, node, order_next); + RDIM_SLLStackPush_N(strs->buckets[bucket_idx], node, bucket_next); + match = node; + strs->bucket_collision_count += (node->bucket_next != 0); + } + + // extract idx to return + rdim_assert(match != 0); + RADDBGI_U32 result = match->idx; + return result; +} + +//- rjf: idx run baking + +RADDBGI_PROC RADDBGI_U64 +rdim_idx_run_hash(RADDBGI_U32 *idx_run, RADDBGI_U32 count) +{ + RADDBGI_U64 hash = 5381; + RADDBGI_U32 *ptr = idx_run; + RADDBGI_U32 *opl = idx_run + count; + for(;ptr < opl; ptr += 1) + { + hash = ((hash << 5) + hash) + (*ptr); + } + return(hash); +} + +RADDBGI_PROC RADDBGI_U32 +rdim_idx_run(RDIM_BakeCtx *bctx, RADDBGI_U32 *idx_run, RADDBGI_U32 count) +{ + RDIM_Arena *arena = bctx->arena; + RDIM_IdxRuns *idxs = &bctx->idxs; + + RADDBGI_U64 hash = rdim_idx_run_hash(idx_run, count); + RADDBGI_U64 bucket_idx = hash%idxs->buckets_count; + + // look for a match + RDIM_IdxRunNode *match = 0; + for(RDIM_IdxRunNode *node = idxs->buckets[bucket_idx]; + node != 0; + node = node->bucket_next) + { + if(node->hash == hash) + { + RADDBGI_S32 is_match = 1; + RADDBGI_U32 *node_idx = node->idx_run; + for(RADDBGI_U32 i = 0; i < count; i += 1) + { + if(node_idx[i] != idx_run[i]) + { + is_match = 0; + break; + } + } + if(is_match) + { + match = node; + break; + } + } + } + + // insert new node if no match + if(match == 0) + { + RDIM_IdxRunNode *node = rdim_push_array_no_zero(arena, RDIM_IdxRunNode, 1); + RADDBGI_U32 *idx_run_copy = rdim_push_array_no_zero(arena, RADDBGI_U32, count); + for(RADDBGI_U32 i = 0; i < count; i += 1) + { + idx_run_copy[i] = idx_run[i]; + } + node->idx_run = idx_run_copy; + node->hash = hash; + node->count = count; + node->first_idx = idxs->idx_count; + idxs->count += 1; + idxs->idx_count += count; + RDIM_SLLQueuePush_N(idxs->order_first, idxs->order_last, node, order_next); + RDIM_SLLStackPush_N(idxs->buckets[bucket_idx], node, bucket_next); + match = node; + idxs->bucket_collision_count += (node->bucket_next != 0); + } + + // extract idx to return + rdim_assert(match != 0); + RADDBGI_U32 result = match->first_idx; + return result; +} + +//- rjf: data section baking + +RADDBGI_PROC RADDBGI_U32 +rdim_dsection(RDIM_Arena *arena, RDIM_DSections *dss, void *data, RADDBGI_U64 size, RADDBGI_DataSectionTag tag) +{ + RADDBGI_U32 result = dss->count; + RDIM_DSectionNode *node = rdim_push_array(arena, RDIM_DSectionNode, 1); + SLLQueuePush(dss->first, dss->last, node); + node->data = data; + node->size = size; + node->tag = tag; + dss->count += 1; + return result; +} + +//- rjf: paths baking + +RADDBGI_PROC RDIM_String8 +rdim_normal_string_from_path_node(RDIM_Arena *arena, RDIM_PathNode *node) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + RDIM_String8List list = {0}; + if(node != 0) + { + rdim_normal_string_from_path_node_build(scratch.arena, node, &list); + } + RDIM_String8 result = rdim_str8_list_join(arena, &list, rdim_str8_lit("/")); + { + RADDBGI_U8 *ptr = result.str; + RADDBGI_U8 *opl = result.str + result.size; + for(; ptr < opl; ptr += 1) + { + RADDBGI_U8 c = *ptr; + if('A' <= c && c <= 'Z') { c += 'a' - 'A'; } + *ptr = c; + } + } + scratch_end(scratch); + return result; +} + +RADDBGI_PROC void +rdim_normal_string_from_path_node_build(RDIM_Arena *arena, RDIM_PathNode *node, RDIM_String8List *out) +{ + // TODO(rjf): why is this recursive... + if(node->parent != 0) + { + rdim_normal_string_from_path_node_build(arena, node->parent, out); + } + if(node->name.size > 0) + { + rdim_str8_list_push(arena, out, node->name); + } +} + +RADDBGI_PROC RDIM_PathNode* +rdim_paths_new_node(RDIM_BakeCtx *bctx) +{ + RDIM_PathTree *tree = bctx->tree; + RDIM_PathNode *result = rdim_push_array(bctx->arena, RDIM_PathNode, 1); + RDIM_SLLQueuePush_N(tree->first, tree->last, result, next_order); + result->idx = tree->count; + tree->count += 1; + return result; +} + +RADDBGI_PROC RDIM_PathNode* +rdim_paths_sub_path(RDIM_BakeCtx *bctx, RDIM_PathNode *dir, RDIM_String8 sub_dir) +{ + // look for existing match + RDIM_PathNode *match = 0; + for(RDIM_PathNode *node = dir->first_child; + node != 0; + node = node->next_sibling) + { + if(rdim_str8_match(node->name, sub_dir, RDIM_StringMatchFlag_CaseInsensitive)) + { + match = node; + break; + } + } + + // construct new node if no match + RDIM_PathNode *new_node = 0; + if(match == 0){ + new_node = rdim_paths_new_node(bctx); + new_node->parent = dir; + RDIM_SLLQueuePush_N(dir->first_child, dir->last_child, new_node, next_sibling); + new_node->name = rdim_str8_copy(bctx->arena, sub_dir); + } + + // select result from the two paths + RDIM_PathNode *result = match; + if(match == 0){ + result = new_node; + } + + return result; +} + +RADDBGI_PROC RDIM_PathNode* +rdim_paths_node_from_path(RDIM_BakeCtx *bctx, RDIM_String8 path) +{ + RDIM_PathNode *node_cursor = &bctx->tree->root; + + RADDBGI_U8 *ptr = path.str; + RADDBGI_U8 *opl = path.str + path.size; + for(;ptr < opl;){ + // skip past slashes + for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1); + + // save beginning of non-slash range + RADDBGI_U8 *range_first = ptr; + + // skip past non-slashes + for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1); + + // if range is non-empty advance the node cursor + if(range_first < ptr){ + RDIM_String8 sub_dir = rdim_str8(range_first, (RADDBGI_U64)(ptr-range_first)); + node_cursor = rdim_paths_sub_path(bctx, node_cursor, sub_dir); + } + } + + RDIM_PathNode *result = node_cursor; + return result; +} + +RADDBGI_PROC RADDBGI_U32 +rdim_paths_idx_from_path(RDIM_BakeCtx *bctx, RDIM_String8 path) +{ + RDIM_PathNode *node = rdim_paths_node_from_path(bctx, path); + RADDBGI_U32 result = node->idx; + return result; +} + +RADDBGI_PROC RDIM_SrcNode* +rdim_paths_new_src_node(RDIM_BakeCtx *bctx) +{ + RDIM_PathTree *tree = bctx->tree; + RDIM_SrcNode *result = rdim_push_array(bctx->arena, RDIM_SrcNode, 1); + SLLQueuePush(tree->src_first, tree->src_last, result); + result->idx = tree->src_count; + tree->src_count += 1; + return result; +} + +RADDBGI_PROC RDIM_SrcNode* +rdim_paths_src_node_from_path_node(RDIM_BakeCtx *bctx, RDIM_PathNode *path_node) +{ + RDIM_SrcNode *result = path_node->src_file; + if(result == 0) + { + RDIM_SrcNode *new_node = rdim_paths_new_src_node(bctx); + new_node->path_node = path_node; + new_node->normal_full_path = rdim_normal_string_from_path_node(bctx->arena, path_node); + result = path_node->src_file = new_node; + } + return result; +} + +//- rjf: per-unit line info baking + +RADDBGI_PROC RDIM_UnitLinesCombined* +rdim_unit_combine_lines(RDIM_Arena *arena, RDIM_BakeCtx *bctx, RDIM_LineSequenceNode *first_seq) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // gather up all line info into two arrays + // keys: sortable array; pairs voffs with line info records; null records are sequence enders + // recs: contains all the source coordinates for a range of voffs + RADDBGI_U64 line_count = 0; + RADDBGI_U64 seq_count = 0; + for(RDIM_LineSequenceNode *node = first_seq; + node != 0; + node = node->next) + { + seq_count += 1; + line_count += node->line_seq.line_count; + } + + RADDBGI_U64 key_count = line_count + seq_count; + RDIM_SortKey *line_keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, key_count); + RDIM_LineRec *line_recs = rdim_push_array_no_zero(scratch.arena, RDIM_LineRec, line_count); + + { + RDIM_SortKey *key_ptr = line_keys; + RDIM_LineRec *rec_ptr = line_recs; + + for(RDIM_LineSequenceNode *node = first_seq; + node != 0; + node = node->next) + { + RDIM_PathNode *src_path = + rdim_paths_node_from_path(bctx, node->line_seq.file_name); + RDIM_SrcNode *src_file = rdim_paths_src_node_from_path_node(bctx, src_path); + RADDBGI_U32 file_id = src_file->idx; + + RADDBGI_U64 node_line_count = node->line_seq.line_count; + for(RADDBGI_U64 i = 0; i < node_line_count; i += 1){ + key_ptr->key = node->line_seq.voffs[i]; + key_ptr->val = rec_ptr; + key_ptr += 1; + + rec_ptr->file_id = file_id; + rec_ptr->line_num = node->line_seq.line_nums[i]; + if(node->line_seq.col_nums != 0){ + rec_ptr->col_first = node->line_seq.col_nums[i*2]; + rec_ptr->col_opl = node->line_seq.col_nums[i*2 + 1]; + } + rec_ptr += 1; + } + + key_ptr->key = node->line_seq.voffs[node_line_count]; + key_ptr->val = 0; + key_ptr += 1; + + RDIM_LineMapFragment *fragment = rdim_push_array(arena, RDIM_LineMapFragment, 1); + RDIM_SLLQueuePush(src_file->first_fragment, src_file->last_fragment, fragment); + fragment->sequence = node; + } + } + + // sort + RDIM_SortKey *sorted_line_keys = rdim_sort_key_array(scratch.arena, line_keys, key_count); + + // TODO(allen): do a pass over sorted keys to make sure duplicate keys are sorted with + // null record first, and no more than one null record and one non-null record + + // arrange output + RADDBGI_U64 *arranged_voffs = rdim_push_array_no_zero(arena, RADDBGI_U64, key_count + 1); + RADDBGI_Line *arranged_lines = rdim_push_array_no_zero(arena, RADDBGI_Line, key_count); + + for(RADDBGI_U64 i = 0; i < key_count; i += 1){ + arranged_voffs[i] = sorted_line_keys[i].key; + } + arranged_voffs[key_count] = ~0ull; + for(RADDBGI_U64 i = 0; i < key_count; i += 1){ + RDIM_LineRec *rec = (RDIM_LineRec*)sorted_line_keys[i].val; + if(rec != 0){ + arranged_lines[i].file_idx = rec->file_id; + arranged_lines[i].line_num = rec->line_num; + } + else{ + arranged_lines[i].file_idx = 0; + arranged_lines[i].line_num = 0; + } + } + + RDIM_UnitLinesCombined *result = rdim_push_array(arena, RDIM_UnitLinesCombined, 1); + result->voffs = arranged_voffs; + result->lines = arranged_lines; + result->cols = 0; + result->line_count = key_count; + + scratch_end(scratch); + return result; +} + +//- rjf: per-src line info baking + +RADDBGI_PROC RDIM_SrcLinesCombined* +rdim_source_combine_lines(RDIM_Arena *arena, RDIM_LineMapFragment *first) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // gather line number map + RDIM_SrcLineMapBucket *first_bucket = 0; + RDIM_SrcLineMapBucket *last_bucket = 0; + RADDBGI_U64 line_hash_slots_count = 1024; + RDIM_SrcLineMapBucket **line_hash_slots = rdim_push_array(scratch.arena, RDIM_SrcLineMapBucket *, line_hash_slots_count); + RADDBGI_U64 line_count = 0; + RADDBGI_U64 voff_count = 0; + RADDBGI_U64 max_line_num = 0; + { + for(RDIM_LineMapFragment *map_fragment = first; + map_fragment != 0; + map_fragment = map_fragment->next) + { + RDIM_LineSequence *sequence = &map_fragment->sequence->line_seq; + + RADDBGI_U64 *seq_voffs = sequence->voffs; + RADDBGI_U32 *seq_line_nums = sequence->line_nums; + RADDBGI_U64 seq_line_count = sequence->line_count; + for(RADDBGI_U64 i = 0; i < seq_line_count; i += 1){ + RADDBGI_U32 line_num = seq_line_nums[i]; + RADDBGI_U64 voff = seq_voffs[i]; + RADDBGI_U64 line_hash_slot_idx = line_num%line_hash_slots_count; + + // update unique voff counter & max line number + voff_count += 1; + max_line_num = Max(max_line_num, line_num); + + // find match + RDIM_SrcLineMapBucket *match = 0; + { + for(RDIM_SrcLineMapBucket *node = line_hash_slots[line_hash_slot_idx]; + node != 0; + node = node->hash_next){ + if(node->line_num == line_num){ + match = node; + break; + } + } + } + + // introduce new line if no match + if(match == 0){ + match = rdim_push_array(scratch.arena, RDIM_SrcLineMapBucket, 1); + RDIM_SLLQueuePush_N(first_bucket, last_bucket, match, order_next); + RDIM_SLLStackPush_N(line_hash_slots[line_hash_slot_idx], match, hash_next); + match->line_num = line_num; + line_count += 1; + } + + // insert new voff + { + RDIM_SrcLineMapVoffBlock *block = rdim_push_array(scratch.arena, RDIM_SrcLineMapVoffBlock, 1); + RDIM_SLLQueuePush(match->first_voff_block, match->last_voff_block, block); + match->voff_count += 1; + block->voff = voff; + } + } + } + } + + // bake sortable keys array + RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, line_count); + { + RDIM_SortKey *key_ptr = keys; + for(RDIM_SrcLineMapBucket *node = first_bucket; + node != 0; + node = node->order_next, key_ptr += 1){ + key_ptr->key = node->line_num; + key_ptr->val = node; + } + } + + // sort + RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, line_count); + + // bake result + RADDBGI_U32 *line_nums = rdim_push_array_no_zero(arena, RADDBGI_U32, line_count); + RADDBGI_U32 *line_ranges = rdim_push_array_no_zero(arena, RADDBGI_U32, line_count + 1); + RADDBGI_U64 *voffs = rdim_push_array_no_zero(arena, RADDBGI_U64, voff_count); + { + RADDBGI_U64 *voff_ptr = voffs; + for(RADDBGI_U32 i = 0; i < line_count; i += 1){ + line_nums[i] = sorted_keys[i].key; + line_ranges[i] = (RADDBGI_U32)(voff_ptr - voffs); + RDIM_SrcLineMapBucket *bucket = (RDIM_SrcLineMapBucket*)sorted_keys[i].val; + for(RDIM_SrcLineMapVoffBlock *node = bucket->first_voff_block; + node != 0; + node = node->next){ + *voff_ptr = node->voff; + voff_ptr += 1; + } + } + line_ranges[line_count] = voff_count; + } + + RDIM_SrcLinesCombined *result = rdim_push_array(arena, RDIM_SrcLinesCombined, 1); + result->line_nums = line_nums; + result->line_ranges = line_ranges; + result->line_count = line_count; + result->voffs = voffs; + result->voff_count = voff_count; + + scratch_end(scratch); + return result; +} + +//- rjf: vmap baking +RADDBGI_PROC RDIM_VMap* +rdim_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RADDBGI_U64 marker_count) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // sort markers + RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, marker_count); + + // determine if an extra vmap entry for zero is needed + RADDBGI_U32 extra_vmap_entry = 0; + if(marker_count > 0 && sorted_keys[0].key != 0){ + extra_vmap_entry = 1; + } + + // fill output vmap entries + RADDBGI_U32 vmap_count_raw = marker_count - 1 + extra_vmap_entry; + RADDBGI_VMapEntry *vmap = rdim_push_array_no_zero(arena, RADDBGI_VMapEntry, vmap_count_raw + 1); + RADDBGI_U32 vmap_entry_count_pass_1 = 0; + + { + RADDBGI_VMapEntry *vmap_ptr = vmap; + + if(extra_vmap_entry){ + vmap_ptr->voff = 0; + vmap_ptr->idx = 0; + vmap_ptr += 1; + } + + RDIM_VMapRangeTracker *tracker_stack = 0; + RDIM_VMapRangeTracker *tracker_free = 0; + + RDIM_SortKey *key_ptr = sorted_keys; + RDIM_SortKey *key_opl = sorted_keys + marker_count; + for(;key_ptr < key_opl;){ + // get initial map state from tracker stack + RADDBGI_U32 initial_idx = (RADDBGI_U32)0xffffffff; + if(tracker_stack != 0){ + initial_idx = tracker_stack->idx; + } + + // update tracker stack + // * we must process _all_ of the changes that apply at this voff before moving on + RADDBGI_U64 voff = key_ptr->key; + + for(;key_ptr < key_opl && key_ptr->key == voff; key_ptr += 1){ + RDIM_VMapMarker *marker = (RDIM_VMapMarker*)key_ptr->val; + RADDBGI_U32 idx = marker->idx; + + // push to stack + if(marker->begin_range){ + RDIM_VMapRangeTracker *new_tracker = tracker_free; + if(new_tracker != 0){ + RDIM_SLLStackPop(tracker_free); + } + else{ + new_tracker = rdim_push_array(scratch.arena, RDIM_VMapRangeTracker, 1); + } + RDIM_SLLStackPush(tracker_stack, new_tracker); + new_tracker->idx = idx; + } + + // pop matching node from stack (not always the top) + else{ + RDIM_VMapRangeTracker **ptr_in = &tracker_stack; + RDIM_VMapRangeTracker *match = 0; + for(RDIM_VMapRangeTracker *node = tracker_stack; + node != 0;){ + if(node->idx == idx){ + match = node; + break; + } + ptr_in = &node->next; + node = node->next; + } + if(match != 0){ + *ptr_in = match->next; + RDIM_SLLStackPush(tracker_free, match); + } + } + } + + // get final map state from tracker stack + RADDBGI_U32 final_idx = 0; + if(tracker_stack != 0){ + final_idx = tracker_stack->idx; + } + + // if final is different from initial - emit new vmap entry + if(final_idx != initial_idx){ + vmap_ptr->voff = voff; + vmap_ptr->idx = final_idx; + vmap_ptr += 1; + } + } + + vmap_entry_count_pass_1 = (RADDBGI_U32)(vmap_ptr - vmap); + } + + // replace zero unit indexes that follow a non-zero + // TODO(rjf): 0 *is* a real unit index right now + if(0) + { + // (the last entry is not replaced because it acts as a terminator) + RADDBGI_U32 last = vmap_entry_count_pass_1 - 1; + + RADDBGI_VMapEntry *vmap_ptr = vmap; + RADDBGI_U64 real_idx = 0; + + for(RADDBGI_U32 i = 0; i < last; i += 1, vmap_ptr += 1){ + // is this a zero after a real index? + if(vmap_ptr->idx == 0){ + vmap_ptr->idx = real_idx; + } + + // remember a real index + else{ + real_idx = vmap_ptr->idx; + } + } + } + + // combine duplicate neighbors + RADDBGI_U32 vmap_entry_count = 0; + { + RADDBGI_VMapEntry *vmap_ptr = vmap; + RADDBGI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; + RADDBGI_VMapEntry *vmap_out = vmap; + + for(;vmap_ptr < vmap_opl;){ + RADDBGI_VMapEntry *vmap_range_first = vmap_ptr; + RADDBGI_U64 idx = vmap_ptr->idx; + vmap_ptr += 1; + for(;vmap_ptr < vmap_opl && vmap_ptr->idx == idx;) vmap_ptr += 1; + rdim_memcpy_struct(vmap_out, vmap_range_first); + vmap_out += 1; + } + + vmap_entry_count = (RADDBGI_U32)(vmap_out - vmap); + } + + // fill result + RDIM_VMap *result = rdim_push_array(arena, RDIM_VMap, 1); + result->vmap = vmap; + result->count = vmap_entry_count - 1; + + rdim_scratch_end(scratch); + + return result; +} + +RADDBGI_PROC RDIM_VMap* +rdim_vmap_from_unit_ranges(RDIM_Arena *arena, RDIM_UnitVMapRange *first, RADDBGI_U64 count) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // count necessary markers + RADDBGI_U64 marker_count = count*2; + + // fill markers + RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); + RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); + + { + RDIM_SortKey *key_ptr = keys; + RDIM_VMapMarker *marker_ptr = markers; + for(RDIM_UnitVMapRange *range = first; + range != 0; + range = range->next){ + if(range->first < range->opl){ + RADDBGI_U32 unit_idx = range->unit->idx; + + key_ptr->key = range->first; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = range->opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + } + + // construct vmap + RDIM_VMap *result = rdim_vmap_from_markers(arena, markers, keys, marker_count); + rdim_scratch_end(scratch); + return result; +} + +//- rjf: type info baking + +RADDBGI_PROC RADDBGI_U32* +rdim_idx_run_from_types(RDIM_Arena *arena, RDIM_Type **types, RADDBGI_U32 count) +{ + RADDBGI_U32 *result = rdim_push_array(arena, RADDBGI_U32, count); + for(RADDBGI_U32 i = 0; i < count; i += 1){ + result[i] = types[i]->idx; + } + return result; +} + +RADDBGI_PROC RDIM_TypeData* +rdim_type_data_combine(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // fill type nodes + RADDBGI_U32 type_count = root->type_count; + RADDBGI_TypeNode *type_nodes = rdim_push_array_no_zero(arena, RADDBGI_TypeNode, type_count); + + { + RADDBGI_TypeNode *ptr = type_nodes; + RADDBGI_TypeNode *opl = ptr + type_count; + RDIM_Type *loose_type = root->first_type; + for(;loose_type != 0 && ptr < opl; + loose_type = loose_type->next_order, ptr += 1){ + + RADDBGI_TypeKind kind = loose_type->kind; + + // shared + ptr->kind = kind; + ptr->flags = loose_type->flags; + ptr->byte_size = loose_type->byte_size; + + // built-in + if(RADDBGI_TypeKind_FirstBuiltIn <= kind && kind <= RADDBGI_TypeKind_LastBuiltIn){ + ptr->built_in.name_string_idx = rdim_string(bctx, loose_type->name); + } + + // constructed + else if(RADDBGI_TypeKind_FirstConstructed <= kind && kind <= RADDBGI_TypeKind_LastConstructed){ + ptr->constructed.direct_type_idx = loose_type->direct_type->idx; + + switch (kind){ + case RADDBGI_TypeKind_Array: + { + ptr->constructed.count = loose_type->count; + }break; + + case RADDBGI_TypeKind_Function: + { + // parameters + RADDBGI_U32 count = loose_type->count; + RADDBGI_U32 *idx_run = rdim_idx_run_from_types(scratch.arena, loose_type->param_types, count); + ptr->constructed.param_idx_run_first = rdim_idx_run(bctx, idx_run, count); + ptr->constructed.count = count; + }break; + + case RADDBGI_TypeKind_Method: + { + // parameters + RADDBGI_U32 count = loose_type->count; + RADDBGI_U32 *idx_run = rdim_idx_run_from_types(scratch.arena, loose_type->param_types, count); + ptr->constructed.param_idx_run_first = rdim_idx_run(bctx, idx_run, count); + ptr->constructed.count = count; + }break; + } + } + + // user-defined + else if(RADDBGI_TypeKind_FirstUserDefined <= kind && kind <= RADDBGI_TypeKind_LastUserDefined){ + ptr->user_defined.name_string_idx = rdim_string(bctx, loose_type->name); + if(loose_type->udt != 0){ + ptr->user_defined.udt_idx = loose_type->udt->idx; + } + if(loose_type->direct_type != 0){ + ptr->user_defined.direct_type_idx = loose_type->direct_type->idx; + } + } + + // bitfield + else if(kind == RADDBGI_TypeKind_Bitfield){ + ptr->bitfield.off = loose_type->off; + ptr->bitfield.size = loose_type->count; + } + + rdim_scratch_end(scratch); + } + + // both iterators should end at the same time + rdim_assert(loose_type == 0); + rdim_assert(ptr == opl); + } + + + // fill udts + RADDBGI_U32 udt_count = root->type_udt_count; + RADDBGI_UDT *udts = rdim_push_array_no_zero(arena, RADDBGI_UDT, udt_count); + + RADDBGI_U32 member_count = root->total_member_count; + RADDBGI_Member *members = rdim_push_array_no_zero(arena, RADDBGI_Member, member_count); + + RADDBGI_U32 enum_member_count = root->total_enum_val_count; + RADDBGI_EnumMember *enum_members = rdim_push_array_no_zero(arena, RADDBGI_EnumMember, enum_member_count); + + { + RADDBGI_UDT *ptr = udts; + RADDBGI_UDT *opl = ptr + udt_count; + + RADDBGI_Member *member_ptr = members; + RADDBGI_Member *member_opl = members + member_count; + + RADDBGI_EnumMember *enum_member_ptr = enum_members; + RADDBGI_EnumMember *enum_member_opl = enum_members + enum_member_count; + + RDIM_TypeUDT *loose_udt = root->first_udt; + for(;loose_udt != 0 && ptr < opl; + loose_udt = loose_udt->next_order, ptr += 1){ + ptr->self_type_idx = loose_udt->self_type->idx; + + rdim_assert(loose_udt->member_count == 0 || + loose_udt->enum_val_count == 0); + + // enum members + if(loose_udt->enum_val_count != 0){ + ptr->flags |= RADDBGI_UserDefinedTypeFlag_EnumMembers; + + ptr->member_first = (RADDBGI_U32)(enum_member_ptr - enum_members); + ptr->member_count = loose_udt->enum_val_count; + + RADDBGI_U32 local_enum_val_count = loose_udt->enum_val_count; + RDIM_TypeEnumVal *loose_enum_val = loose_udt->first_enum_val; + for(RADDBGI_U32 i = 0; + i < local_enum_val_count; + i += 1, enum_member_ptr += 1, loose_enum_val = loose_enum_val->next){ + enum_member_ptr->name_string_idx = rdim_string(bctx, loose_enum_val->name); + enum_member_ptr->val = loose_enum_val->val; + } + } + + // struct/class/union members + else{ + ptr->member_first = (RADDBGI_U32)(member_ptr - members); + ptr->member_count = loose_udt->member_count; + + RADDBGI_U32 local_member_count = loose_udt->member_count; + RDIM_TypeMember *loose_member = loose_udt->first_member; + for(RADDBGI_U32 i = 0; + i < local_member_count; + i += 1, member_ptr += 1, loose_member = loose_member->next){ + member_ptr->kind = loose_member->kind; + // TODO(allen): member_ptr->visibility = ; + member_ptr->name_string_idx = rdim_string(bctx, loose_member->name); + member_ptr->off = loose_member->off; + member_ptr->type_idx = loose_member->type->idx; + + // TODO(allen): + if(loose_member->kind == RADDBGI_MemberKind_Method){ + //loose_member_ptr->unit_idx = ; + //loose_member_ptr->proc_symbol_idx = ; + } + } + + } + + RADDBGI_U32 file_idx = 0; + if(loose_udt->source_path.size > 0){ + RDIM_PathNode *path_node = rdim_paths_node_from_path(bctx, loose_udt->source_path); + RDIM_SrcNode *src_node = rdim_paths_src_node_from_path_node(bctx, path_node); + file_idx = src_node->idx; + } + + ptr->file_idx = file_idx; + ptr->line = loose_udt->line; + ptr->col = loose_udt->col; + } + + // all iterators should end at the same time + rdim_assert(loose_udt == 0); + rdim_assert(ptr == opl); + rdim_assert(member_ptr == member_opl); + rdim_assert(enum_member_ptr == enum_member_opl); + } + + + // fill result + RDIM_TypeData *result = rdim_push_array(arena, RDIM_TypeData, 1); + result->type_nodes = type_nodes; + result->type_node_count = type_count; + result->udts = udts; + result->udt_count = udt_count; + result->members = members; + result->member_count = member_count; + result->enum_members = enum_members; + result->enum_member_count = enum_member_count; + + rdim_scratch_end(scratch); + return result; +} + +//- rjf: symbol data baking + +RADDBGI_PROC RDIM_SymbolData* +rdim_symbol_data_combine(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // count symbol kinds + RADDBGI_U32 globalvar_count = 1 + root->symbol_kind_counts[RDIM_SymbolKind_GlobalVariable]; + RADDBGI_U32 threadvar_count = 1 + root->symbol_kind_counts[RDIM_SymbolKind_ThreadVariable]; + RADDBGI_U32 procedure_count = 1 + root->symbol_kind_counts[RDIM_SymbolKind_Procedure]; + + // allocate symbol arrays + RADDBGI_GlobalVariable *global_variables = + rdim_push_array(arena, RADDBGI_GlobalVariable, globalvar_count); + + RADDBGI_ThreadVariable *thread_variables = + rdim_push_array(arena, RADDBGI_ThreadVariable, threadvar_count); + + RADDBGI_Procedure *procedures = rdim_push_array(arena, RADDBGI_Procedure, procedure_count); + + // fill symbol arrays + { + RADDBGI_GlobalVariable *global_ptr = global_variables; + RADDBGI_ThreadVariable *thread_local_ptr = thread_variables; + RADDBGI_Procedure *procedure_ptr = procedures; + + // nils + global_ptr += 1; + thread_local_ptr += 1; + procedure_ptr += 1; + + // symbol nodes + for(RDIM_Symbol *node = root->first_symbol; + node != 0; + node = node->next_order){ + RADDBGI_U32 name_string_idx = rdim_string(bctx, node->name); + RADDBGI_U32 link_name_string_idx = rdim_string(bctx, node->link_name); + RADDBGI_U32 type_idx = node->type->idx; + + RADDBGI_LinkFlags link_flags = 0; + RADDBGI_U32 container_idx = 0; + { + if(node->is_extern){ + link_flags |= RADDBGI_LinkFlag_External; + } + if(node->container_symbol != 0){ + container_idx = node->container_symbol->idx; + link_flags |= RADDBGI_LinkFlag_ProcScoped; + } + else if(node->container_type != 0 && node->container_type->udt != 0){ + container_idx = node->container_type->udt->idx; + link_flags |= RADDBGI_LinkFlag_TypeScoped; + } + } + + switch (node->kind){ + default:{}break; + + case RDIM_SymbolKind_GlobalVariable: + { + global_ptr->name_string_idx = name_string_idx; + global_ptr->link_flags = link_flags; + global_ptr->voff = node->offset; + global_ptr->type_idx = type_idx; + global_ptr->container_idx = container_idx; + global_ptr += 1; + }break; + + case RDIM_SymbolKind_ThreadVariable: + { + thread_local_ptr->name_string_idx = name_string_idx; + thread_local_ptr->link_flags = link_flags; + thread_local_ptr->tls_off = (RADDBGI_U32)node->offset; + thread_local_ptr->type_idx = type_idx; + thread_local_ptr->container_idx = container_idx; + thread_local_ptr += 1; + }break; + + case RDIM_SymbolKind_Procedure: + { + procedure_ptr->name_string_idx = name_string_idx; + procedure_ptr->link_name_string_idx = link_name_string_idx; + procedure_ptr->link_flags = link_flags; + procedure_ptr->type_idx = type_idx; + procedure_ptr->root_scope_idx = node->root_scope->idx; + procedure_ptr->container_idx = container_idx; + procedure_ptr += 1; + }break; + } + } + + rdim_assert(global_ptr - global_variables == globalvar_count); + rdim_assert(thread_local_ptr - thread_variables == threadvar_count); + rdim_assert(procedure_ptr - procedures == procedure_count); + } + + // global vmap + RDIM_VMap *global_vmap = 0; + { + // count necessary markers + RADDBGI_U32 marker_count = globalvar_count*2; + + // fill markers + RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); + RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); + + RDIM_SortKey *key_ptr = keys; + RDIM_VMapMarker *marker_ptr = markers; + + // real globals + for(RDIM_Symbol *node = root->first_symbol; + node != 0; + node = node->next_order){ + if(node->kind == RDIM_SymbolKind_GlobalVariable){ + RADDBGI_U32 global_idx = node->idx; + + RADDBGI_U64 first = node->offset; + RADDBGI_U64 opl = first + node->type->byte_size; + + key_ptr->key = first; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + + // nil global + { + RADDBGI_U32 global_idx = 0; + + RADDBGI_U64 first = 0; + RADDBGI_U64 opl = (RADDBGI_U64)0xffffffffffffffffull; + + key_ptr->key = first; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + + // assert we filled all the markers + rdim_assert(key_ptr - keys == marker_count && + marker_ptr - markers == marker_count); + + // construct vmap + global_vmap = rdim_vmap_from_markers(arena, markers, keys, marker_count); + } + + // allocate scope array + + // (assert there is a nil scope) + rdim_assert(root->first_scope != 0 && + root->first_scope->symbol == 0 && + root->first_scope->first_child == 0 && + root->first_scope->next_sibling == 0 && + root->first_scope->range_count == 0); + + RADDBGI_U32 scope_count = root->scope_count; + RADDBGI_Scope *scopes = rdim_push_array(arena, RADDBGI_Scope, scope_count); + + RADDBGI_U32 scope_voff_count = root->scope_voff_count; + RADDBGI_U64 *scope_voffs = rdim_push_array(arena, RADDBGI_U64, scope_voff_count); + + RADDBGI_U32 local_count = root->local_count; + RADDBGI_Local *locals = rdim_push_array(arena, RADDBGI_Local, local_count); + + RADDBGI_U32 location_block_count = root->location_count; + RADDBGI_LocationBlock *location_blocks = + rdim_push_array(arena, RADDBGI_LocationBlock, location_block_count); + + RDIM_String8List location_data = {0}; + + // iterate scopes, locals, and locations + // fill scope voffs, locals, and location information + { + RADDBGI_Scope *scope_ptr = scopes; + RADDBGI_U64 *scope_voff_ptr = scope_voffs; + RADDBGI_Local *local_ptr = locals; + RADDBGI_LocationBlock *location_block_ptr = location_blocks; + + for(RDIM_Scope *node = root->first_scope; + node != 0; + node = node->next_order, scope_ptr += 1){ + + // emit voffs + RADDBGI_U32 voff_first = (RADDBGI_U32)(scope_voff_ptr - scope_voffs); + for(RDIM_VOffRange *range = node->first_range; + range != 0; + range = range->next){ + *scope_voff_ptr = range->voff_first; + scope_voff_ptr += 1; + *scope_voff_ptr = range->voff_opl; + scope_voff_ptr += 1; + } + RADDBGI_U32 voff_opl = (RADDBGI_U32)(scope_voff_ptr - scope_voffs); + + // emit locals + RADDBGI_U32 scope_local_count = node->local_count; + RADDBGI_U32 scope_local_first = (RADDBGI_U32)(local_ptr - locals); + for(RDIM_Local *slocal = node->first_local; + slocal != 0; + slocal = slocal->next, local_ptr += 1){ + local_ptr->kind = slocal->kind; + local_ptr->name_string_idx = rdim_string(bctx, slocal->name); + local_ptr->type_idx = slocal->type->idx; + + RDIM_LocationSet *locset = slocal->locset; + if(locset != 0){ + RADDBGI_U32 location_first = (RADDBGI_U32)(location_block_ptr - location_blocks); + RADDBGI_U32 location_opl = location_first + locset->location_case_count; + local_ptr->location_first = location_first; + local_ptr->location_opl = location_opl; + + for(RDIM_LocationCase *location_case = locset->first_location_case; + location_case != 0; + location_case = location_case->next){ + location_block_ptr->scope_off_first = location_case->voff_first; + location_block_ptr->scope_off_opl = location_case->voff_opl; + location_block_ptr->location_data_off = location_data.total_size; + location_block_ptr += 1; + + RDIM_Location *location = location_case->location; + if(location == 0){ + RADDBGI_U64 data = 0; + str8_serial_push_align(scratch.arena, &location_data, 8); + str8_serial_push_data(scratch.arena, &location_data, &data, 1); + } + else{ + switch (location->kind){ + default: + { + RADDBGI_U64 data = 0; + str8_serial_push_align(scratch.arena, &location_data, 8); + str8_serial_push_data(scratch.arena, &location_data, &data, 1); + }break; + + case RADDBGI_LocationKind_AddrBytecodeStream: + case RADDBGI_LocationKind_ValBytecodeStream: + { + rdim_str8_list_push(scratch.arena, &location_data, rdim_str8_copy(scratch.arena, rdim_str8_struct(&location->kind))); + for(RDIM_EvalBytecodeOp *op_node = location->bytecode.first_op; + op_node != 0; + op_node = op_node->next){ + RADDBGI_U8 op_data[9]; + op_data[0] = op_node->op; + rdim_memcpy(op_data + 1, &op_node->p, op_node->p_size); + RDIM_String8 op_data_str = rdim_str8(op_data, 1 + op_node->p_size); + rdim_str8_list_push(scratch.arena, &location_data, rdim_str8_copy(scratch.arena, op_data_str)); + } + { + RADDBGI_U64 data = 0; + RDIM_String8 data_str = rdim_str8((RADDBGI_U8 *)&data, 1); + rdim_str8_list_push(scratch.arena, &location_data, rdim_str8_copy(scratch.arena, data_str)); + } + }break; + + case RADDBGI_LocationKind_AddrRegisterPlusU16: + case RADDBGI_LocationKind_AddrAddrRegisterPlusU16: + { + RADDBGI_LocationRegisterPlusU16 loc = {0}; + loc.kind = location->kind; + loc.register_code = location->register_code; + loc.offset = location->offset; + rdim_str8_list_push(scratch.arena, &location_data, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); + }break; + + case RADDBGI_LocationKind_ValRegister: + { + RADDBGI_LocationRegister loc = {0}; + loc.kind = location->kind; + loc.register_code = location->register_code; + rdim_str8_list_push(scratch.arena, &location_data, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); + }break; + } + } + } + + rdim_assert(location_block_ptr - location_blocks == location_opl); + } + } + + rdim_assert(local_ptr - locals == scope_local_first + scope_local_count); + + // emit scope + scope_ptr->proc_idx = (node->symbol == 0)?0:node->symbol->idx; + scope_ptr->parent_scope_idx = (node->parent_scope == 0)?0:node->parent_scope->idx; + scope_ptr->first_child_scope_idx = (node->first_child == 0)?0:node->first_child->idx; + scope_ptr->next_sibling_scope_idx = (node->next_sibling == 0)?0:node->next_sibling->idx; + scope_ptr->voff_range_first = voff_first; + scope_ptr->voff_range_opl = voff_opl; + scope_ptr->local_first = scope_local_first; + scope_ptr->local_count = scope_local_count; + + // TODO(allen): + //scope_ptr->static_local_idx_run_first = ; + //scope_ptr->static_local_count = ; + } + + rdim_assert(scope_ptr - scopes == scope_count); + rdim_assert(local_ptr - locals == local_count); + } + + // flatten location data + RDIM_String8 location_data_str = rdim_str8_list_join(arena, &location_data, rdim_str8_lit("")); + + // scope vmap + RDIM_VMap *scope_vmap = 0; + { + // count necessary markers + RADDBGI_U32 marker_count = scope_voff_count; + + // fill markers + RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); + RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); + + RDIM_SortKey *key_ptr = keys; + RDIM_VMapMarker *marker_ptr = markers; + + for(RDIM_Scope *node = root->first_scope; + node != 0; + node = node->next_order){ + RADDBGI_U32 scope_idx = node->idx; + + for(RDIM_VOffRange *range = node->first_range; + range != 0; + range = range->next){ + key_ptr->key = range->voff_first; + key_ptr->val = marker_ptr; + marker_ptr->idx = scope_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = range->voff_opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = scope_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + + scope_vmap = rdim_vmap_from_markers(arena, markers, keys, marker_count); + } + + // fill result + RDIM_SymbolData *result = rdim_push_array(arena, RDIM_SymbolData, 1); + result->global_variables = global_variables; + result->global_variable_count = globalvar_count; + result->global_vmap = global_vmap; + result->thread_variables = thread_variables; + result->thread_variable_count = threadvar_count; + result->procedures = procedures; + result->procedure_count = procedure_count; + result->scopes = scopes; + result->scope_count = scope_count; + result->scope_voffs = scope_voffs; + result->scope_voff_count = scope_voff_count; + result->scope_vmap = scope_vmap; + result->locals = locals; + result->local_count = local_count; + result->location_blocks = location_blocks; + result->location_block_count = location_block_count; + result->location_data = location_data_str.str; + result->location_data_size = location_data_str.size; + + rdim_scratch_end(scratch); + return result; +} + +//- rjf: name map baking + +RADDBGI_PROC RDIM_NameMapBaked* +rdim_name_map_bake(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx, RDIM_NameMap *map) +{ + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + RADDBGI_U32 bucket_count = map->name_count; + RADDBGI_U32 node_count = map->name_count; + + // setup the final bucket layouts + RDIM_NameMapSemiBucket *sbuckets = rdim_push_array(scratch.arena, RDIM_NameMapSemiBucket, bucket_count); + for(RDIM_NameMapNode *node = map->first; + node != 0; + node = node->order_next){ + RADDBGI_U64 hash = raddbgi_hash(node->string.str, node->string.size); + RADDBGI_U64 bi = hash%bucket_count; + RDIM_NameMapSemiNode *snode = rdim_push_array(scratch.arena, RDIM_NameMapSemiNode, 1); + SLLQueuePush(sbuckets[bi].first, sbuckets[bi].last, snode); + snode->node = node; + sbuckets[bi].count += 1; + } + + // allocate tables + RADDBGI_NameMapBucket *buckets = rdim_push_array(arena, RADDBGI_NameMapBucket, bucket_count); + RADDBGI_NameMapNode *nodes = rdim_push_array_no_zero(arena, RADDBGI_NameMapNode, node_count); + + // convert to serialized buckets & nodes + { + RADDBGI_NameMapBucket *bucket_ptr = buckets; + RADDBGI_NameMapNode *node_ptr = nodes; + for(RADDBGI_U32 i = 0; i < bucket_count; i += 1, bucket_ptr += 1){ + bucket_ptr->first_node = (RADDBGI_U32)(node_ptr - nodes); + bucket_ptr->node_count = sbuckets[i].count; + + for(RDIM_NameMapSemiNode *snode = sbuckets[i].first; + snode != 0; + snode = snode->next){ + RDIM_NameMapNode *node = snode->node; + + // cons name and index(es) + RADDBGI_U32 string_idx = rdim_string(bctx, node->string); + RADDBGI_U32 match_count = node->idx_count; + RADDBGI_U32 idx = 0; + if(match_count == 1){ + idx = node->idx_first->idx[0]; + } + else{ + RADDBGI_U64 temp_pos = rdim_arena_pos(scratch.arena); + RADDBGI_U32 *idx_run = rdim_push_array_no_zero(scratch.arena, RADDBGI_U32, match_count); + RADDBGI_U32 *idx_ptr = idx_run; + for(RDIM_NameMapIdxNode *idxnode = node->idx_first; + idxnode != 0; + idxnode = idxnode->next){ + for(RADDBGI_U32 i = 0; i < ArrayCount(idxnode->idx); i += 1){ + if(idxnode->idx[i] == 0){ + goto dblbreak; + } + *idx_ptr = idxnode->idx[i]; + idx_ptr += 1; + } + } + dblbreak:; + rdim_assert(idx_ptr == idx_run + match_count); + idx = rdim_idx_run(bctx, idx_run, match_count); + rdim_arena_pop_to(scratch.arena, temp_pos); + } + + // write to node + node_ptr->string_idx = string_idx; + node_ptr->match_count = match_count; + node_ptr->match_idx_or_idx_run_first = idx; + node_ptr += 1; + } + } + rdim_assert(node_ptr - nodes == node_count); + } + + rdim_scratch_end(scratch); + + RDIM_NameMapBaked *result = rdim_push_array(arena, RDIM_NameMapBaked, 1); + result->buckets = buckets; + result->nodes = nodes; + result->bucket_count = bucket_count; + result->node_count = node_count; + return result; +} + +//- rjf: top-level baking entry point + +RADDBGI_PROC void +rdim_bake_file(RDIM_Arena *arena, RDIM_Root *root, RDIM_String8List *out) +{ + str8_serial_begin(arena, out); + + // setup cons helpers + RDIM_DSections dss = {0}; + rdim_dsection(arena, &dss, 0, 0, RADDBGI_DataSectionTag_NULL); + + RDIM_BakeParams bctx_params = {0}; + { + bctx_params.strings_bucket_count = u64_up_to_pow2(root->symbol_map.pair_count*8); + bctx_params.idx_runs_bucket_count = u64_up_to_pow2(root->symbol_map.pair_count*8); + } + RDIM_BakeCtx *bctx = rdim_bake_ctx_begin(&bctx_params); + + //////////////////////////////// + // MAIN PART: allocating and filling out sections of the file + + // top level info + RADDBGI_TopLevelInfo *tli = rdim_push_array(arena, RADDBGI_TopLevelInfo, 1); + { + RDIM_TopLevelInfo *rdim_tli = &root->top_level_info; + tli->architecture = rdim_tli->architecture; + tli->exe_name_string_idx = rdim_string(bctx, rdim_tli->exe_name); + tli->exe_hash = rdim_tli->exe_hash; + tli->voff_max = rdim_tli->voff_max; + } + rdim_dsection(arena, &dss, tli, sizeof(*tli), RADDBGI_DataSectionTag_TopLevelInfo); + + // binary sections array + { + RADDBGI_U32 count = root->binary_section_count; + RADDBGI_BinarySection *sections = rdim_push_array(arena, RADDBGI_BinarySection, count); + RADDBGI_BinarySection *dsec = sections; + for(RDIM_BinarySection *ssec = root->binary_section_first; + ssec != 0; + ssec = ssec->next, dsec += 1){ + dsec->name_string_idx = rdim_string(bctx, ssec->name); + dsec->flags = ssec->flags; + dsec->voff_first = ssec->voff_first; + dsec->voff_opl = ssec->voff_opl; + dsec->foff_first = ssec->foff_first; + dsec->foff_opl = ssec->foff_opl; + } + rdim_dsection(arena, &dss, sections, sizeof(*sections)*count, RADDBGI_DataSectionTag_BinarySections); + } + + // units array + // * pass for per-unit information including: + // * top-level unit information + // * combining line info for whole unit + { + RADDBGI_U32 count = root->unit_count; + RADDBGI_Unit *units = rdim_push_array(arena, RADDBGI_Unit, count); + RADDBGI_Unit *dunit = units; + for(RDIM_Unit *sunit = root->unit_first; + sunit != 0; + sunit = sunit->next_order, dunit += 1){ + // strings & paths + RADDBGI_U32 unit_name = rdim_string(bctx, sunit->unit_name); + RADDBGI_U32 cmp_name = rdim_string(bctx, sunit->compiler_name); + + RADDBGI_U32 src_path = rdim_paths_idx_from_path(bctx, sunit->source_file); + RADDBGI_U32 obj_path = rdim_paths_idx_from_path(bctx, sunit->object_file); + RADDBGI_U32 archive_path = rdim_paths_idx_from_path(bctx, sunit->archive_file); + RADDBGI_U32 build_path = rdim_paths_idx_from_path(bctx, sunit->build_path); + + dunit->unit_name_string_idx = unit_name; + dunit->compiler_name_string_idx = cmp_name; + dunit->source_file_path_node = src_path; + dunit->object_file_path_node = obj_path; + dunit->archive_file_path_node = archive_path; + dunit->build_path_node = build_path; + dunit->language = sunit->language; + + // line info (voff -> file*line*col) + RDIM_LineSequenceNode *first_seq = sunit->line_seq_first; + RDIM_UnitLinesCombined *lines = rdim_unit_combine_lines(arena, bctx, first_seq); + + RADDBGI_U32 line_count = lines->line_count; + if(line_count > 0){ + dunit->line_info_voffs_data_idx = + rdim_dsection(arena, &dss, lines->voffs, sizeof(RADDBGI_U64)*(line_count + 1), + RADDBGI_DataSectionTag_LineInfoVoffs); + dunit->line_info_data_idx = + rdim_dsection(arena, &dss, lines->lines, sizeof(RADDBGI_Line)*line_count, + RADDBGI_DataSectionTag_LineInfoData); + if(lines->cols != 0){ + dunit->line_info_col_data_idx = + rdim_dsection(arena, &dss, lines->cols, sizeof(RADDBGI_Column)*line_count, + RADDBGI_DataSectionTag_LineInfoColumns); + } + dunit->line_info_count = line_count; + } + } + + rdim_dsection(arena, &dss, units, sizeof(*units)*count, RADDBGI_DataSectionTag_Units); + } + + // source file line info baking + // * pass for "source_combine_line" for each source file - + // * can only be run after a pass that does "unit_combine_lines" for each unit. + for(RDIM_SrcNode *src_node = bctx->tree->src_first; + src_node != 0; + src_node = src_node->next){ + RDIM_LineMapFragment *first_fragment = src_node->first_fragment; + RDIM_SrcLinesCombined *lines = rdim_source_combine_lines(arena, first_fragment); + RADDBGI_U32 line_count = lines->line_count; + + if(line_count > 0){ + src_node->line_map_count = line_count; + + src_node->line_map_nums_data_idx = + rdim_dsection(arena, &dss, lines->line_nums, sizeof(*lines->line_nums)*line_count, + RADDBGI_DataSectionTag_LineMapNumbers); + + src_node->line_map_range_data_idx = + rdim_dsection(arena, &dss, lines->line_ranges, sizeof(*lines->line_ranges)*(line_count + 1), + RADDBGI_DataSectionTag_LineMapRanges); + + src_node->line_map_voff_data_idx = + rdim_dsection(arena, &dss, lines->voffs, sizeof(*lines->voffs)*lines->voff_count, + RADDBGI_DataSectionTag_LineMapVoffs); + } + } + + // source file name mapping + { + RDIM_NameMap* map = rdim_name_map_for_kind(root, RADDBGI_NameMapKind_NormalSourcePaths); + for(RDIM_SrcNode *src_node = bctx->tree->src_first; + src_node != 0; + src_node = src_node->next){ + if(src_node->idx != 0){ + rdim_name_map_add_pair(root, map, src_node->normal_full_path, src_node->idx); + } + } + } + + // unit vmap baking + { + RDIM_VMap *vmap = rdim_vmap_from_unit_ranges(arena, + root->unit_vmap_range_first, + root->unit_vmap_range_count); + + RADDBGI_U64 vmap_size = sizeof(*vmap->vmap)*(vmap->count + 1); + rdim_dsection(arena, &dss, vmap->vmap, vmap_size, RADDBGI_DataSectionTag_UnitVmap); + } + + // type info baking + { + RDIM_TypeData *types = rdim_type_data_combine(arena, root, bctx); + + RADDBGI_U64 type_nodes_size = sizeof(*types->type_nodes)*types->type_node_count; + rdim_dsection(arena, &dss, types->type_nodes, type_nodes_size, RADDBGI_DataSectionTag_TypeNodes); + + RADDBGI_U64 udt_size = sizeof(*types->udts)*types->udt_count; + rdim_dsection(arena, &dss, types->udts, udt_size, RADDBGI_DataSectionTag_UDTs); + + RADDBGI_U64 member_size = sizeof(*types->members)*types->member_count; + rdim_dsection(arena, &dss, types->members, member_size, RADDBGI_DataSectionTag_Members); + + RADDBGI_U64 enum_member_size = sizeof(*types->enum_members)*types->enum_member_count; + rdim_dsection(arena, &dss, types->enum_members, enum_member_size, RADDBGI_DataSectionTag_EnumMembers); + } + + // symbol info baking + { + RDIM_SymbolData *symbol_data = rdim_symbol_data_combine(arena, root, bctx); + + RADDBGI_U64 global_variables_size = + sizeof(*symbol_data->global_variables)*symbol_data->global_variable_count; + rdim_dsection(arena, &dss, symbol_data->global_variables, global_variables_size, + RADDBGI_DataSectionTag_GlobalVariables); + + RDIM_VMap *global_vmap = symbol_data->global_vmap; + RADDBGI_U64 global_vmap_size = sizeof(*global_vmap->vmap)*(global_vmap->count + 1); + rdim_dsection(arena, &dss, global_vmap->vmap, global_vmap_size, + RADDBGI_DataSectionTag_GlobalVmap); + + RADDBGI_U64 thread_variables_size = + sizeof(*symbol_data->thread_variables)*symbol_data->thread_variable_count; + rdim_dsection(arena, &dss, symbol_data->thread_variables, thread_variables_size, + RADDBGI_DataSectionTag_ThreadVariables); + + RADDBGI_U64 procedures_size = sizeof(*symbol_data->procedures)*symbol_data->procedure_count; + rdim_dsection(arena, &dss, symbol_data->procedures, procedures_size, + RADDBGI_DataSectionTag_Procedures); + + RADDBGI_U64 scopes_size = sizeof(*symbol_data->scopes)*symbol_data->scope_count; + rdim_dsection(arena, &dss, symbol_data->scopes, scopes_size, RADDBGI_DataSectionTag_Scopes); + + RADDBGI_U64 scope_voffs_size = sizeof(*symbol_data->scope_voffs)*symbol_data->scope_voff_count; + rdim_dsection(arena, &dss, symbol_data->scope_voffs, scope_voffs_size, + RADDBGI_DataSectionTag_ScopeVoffData); + + RDIM_VMap *scope_vmap = symbol_data->scope_vmap; + RADDBGI_U64 scope_vmap_size = sizeof(*scope_vmap->vmap)*(scope_vmap->count + 1); + rdim_dsection(arena, &dss, scope_vmap->vmap, scope_vmap_size, RADDBGI_DataSectionTag_ScopeVmap); + + RADDBGI_U64 local_size = sizeof(*symbol_data->locals)*symbol_data->local_count; + rdim_dsection(arena, &dss, symbol_data->locals, local_size, RADDBGI_DataSectionTag_Locals); + + RADDBGI_U64 location_blocks_size = + sizeof(*symbol_data->location_blocks)*symbol_data->location_block_count; + rdim_dsection(arena, &dss, symbol_data->location_blocks, location_blocks_size, + RADDBGI_DataSectionTag_LocationBlocks); + + RADDBGI_U64 location_data_size = symbol_data->location_data_size; + rdim_dsection(arena, &dss, symbol_data->location_data, location_data_size, + RADDBGI_DataSectionTag_LocationData); + } + + // name map baking + { + RADDBGI_U32 name_map_count = 0; + for(RADDBGI_U32 i = 0; i < RADDBGI_NameMapKind_COUNT; i += 1){ + if(root->name_maps[i] != 0){ + name_map_count += 1; + } + } + + RADDBGI_NameMap *name_maps = rdim_push_array(arena, RADDBGI_NameMap, name_map_count); + + RADDBGI_NameMap *name_map_ptr = name_maps; + for(RADDBGI_U32 i = 0; i < RADDBGI_NameMapKind_COUNT; i += 1){ + RDIM_NameMap *map = root->name_maps[i]; + if(map != 0){ + RDIM_NameMapBaked *baked = rdim_name_map_bake(arena, root, bctx, map); + + name_map_ptr->kind = i; + name_map_ptr->bucket_data_idx = + rdim_dsection(arena, &dss, baked->buckets, sizeof(*baked->buckets)*baked->bucket_count, + RADDBGI_DataSectionTag_NameMapBuckets); + name_map_ptr->node_data_idx = + rdim_dsection(arena, &dss, baked->nodes, sizeof(*baked->nodes)*baked->node_count, + RADDBGI_DataSectionTag_NameMapNodes); + name_map_ptr += 1; + } + } + + rdim_dsection(arena, &dss, name_maps, sizeof(*name_maps)*name_map_count, + RADDBGI_DataSectionTag_NameMaps); + } + + //////////////////////////////// + // LATE PART: baking loose structures and creating final layout + + // generate data sections for file paths + { + RADDBGI_U32 count = bctx->tree->count; + RADDBGI_FilePathNode *nodes = rdim_push_array(arena, RADDBGI_FilePathNode, count); + + RADDBGI_FilePathNode *out_node = nodes; + for(RDIM_PathNode *node = bctx->tree->first; + node != 0; + node = node->next_order, out_node += 1){ + out_node->name_string_idx = rdim_string(bctx, node->name); + if(node->parent != 0){ + out_node->parent_path_node = node->parent->idx; + } + if(node->first_child != 0){ + out_node->first_child = node->first_child->idx; + } + if(node->next_sibling != 0){ + out_node->next_sibling = node->next_sibling->idx; + } + if(node->src_file != 0){ + out_node->source_file_idx = node->src_file->idx; + } + } + + rdim_dsection(arena, &dss, nodes, sizeof(*nodes)*count, RADDBGI_DataSectionTag_FilePathNodes); + } + + // generate data sections for files + { + RADDBGI_U32 count = bctx->tree->src_count; + RADDBGI_SourceFile *src_files = rdim_push_array(arena, RADDBGI_SourceFile, count); + + RADDBGI_SourceFile *out_src_file = src_files; + for(RDIM_SrcNode *node = bctx->tree->src_first; + node != 0; + node = node->next, out_src_file += 1){ + out_src_file->file_path_node_idx = node->path_node->idx; + out_src_file->normal_full_path_string_idx = rdim_string(bctx, node->normal_full_path); + out_src_file->line_map_nums_data_idx = node->line_map_nums_data_idx; + out_src_file->line_map_range_data_idx = node->line_map_range_data_idx; + out_src_file->line_map_count = node->line_map_count; + out_src_file->line_map_voff_data_idx = node->line_map_voff_data_idx; + } + + rdim_dsection(arena, &dss, src_files, sizeof(*src_files)*count, RADDBGI_DataSectionTag_SourceFiles); + } + + // generate data sections for strings + { + RADDBGI_U32 *str_offs = rdim_push_array_no_zero(arena, RADDBGI_U32, bctx->strs.count + 1); + + RADDBGI_U32 off_cursor = 0; + { + RADDBGI_U32 *off_ptr = str_offs; + *off_ptr = 0; + off_ptr += 1; + for(RDIM_StringNode *node = bctx->strs.order_first; + node != 0; + node = node->order_next){ + off_cursor += node->str.size; + *off_ptr = off_cursor; + off_ptr += 1; + } + } + + RADDBGI_U8 *buf = rdim_push_array(arena, RADDBGI_U8, off_cursor); + { + RADDBGI_U8 *ptr = buf; + for(RDIM_StringNode *node = bctx->strs.order_first; + node != 0; + node = node->order_next){ + rdim_memcpy(ptr, node->str.str, node->str.size); + ptr += node->str.size; + } + } + + rdim_dsection(arena, &dss, str_offs, sizeof(*str_offs)*(bctx->strs.count + 1), + RADDBGI_DataSectionTag_StringTable); + rdim_dsection(arena, &dss, buf, off_cursor, RADDBGI_DataSectionTag_StringData); + } + + // generate data sections for index runs + { + RADDBGI_U32 *idx_data = rdim_push_array_no_zero(arena, RADDBGI_U32, bctx->idxs.idx_count); + + { + RADDBGI_U32 *out_ptr = idx_data; + RADDBGI_U32 *opl = out_ptr + bctx->idxs.idx_count; + RDIM_IdxRunNode *node = bctx->idxs.order_first; + for(;node != 0 && out_ptr < opl; + node = node->order_next){ + rdim_memcpy(out_ptr, node->idx_run, sizeof(*node->idx_run)*node->count); + out_ptr += node->count; + } + rdim_assert(out_ptr == opl); + } + + rdim_dsection(arena, &dss, idx_data, sizeof(*idx_data)*bctx->idxs.idx_count, + RADDBGI_DataSectionTag_IndexRuns); + } + + // layout + // * the header and data section table have to be initialized "out of order" + // * so that the rest of the system can avoid this tricky order-layout interdependence stuff + RADDBGI_Header *header = rdim_push_array(arena, RADDBGI_Header, 1); + RADDBGI_DataSection *dstable = rdim_push_array(arena, RADDBGI_DataSection, dss.count); + str8_serial_push_align(arena, out, 8); + RADDBGI_U64 header_off = out->total_size; + str8_list_push(arena, out, str8_struct(header)); + str8_serial_push_align(arena, out, 8); + RADDBGI_U64 data_section_off = out->total_size; + str8_list_push(arena, out, str8((RADDBGI_U8 *)dstable, sizeof(*dstable)*dss.count)); + { + header->magic = RADDBGI_MAGIC_CONSTANT; + header->encoding_version = RADDBGI_ENCODING_VERSION; + header->data_section_off = data_section_off; + header->data_section_count = dss.count; + } + { + RADDBGI_U64 test_dss_count = 0; + for(RDIM_DSectionNode *node = dss.first; + node != 0; + node = node->next){ + test_dss_count += 1; + } + rdim_assert(test_dss_count == dss.count); + + RADDBGI_DataSection *ptr = dstable; + for(RDIM_DSectionNode *node = dss.first; + node != 0; + node = node->next, ptr += 1){ + RADDBGI_U64 data_section_offset = 0; + if(node->size != 0) + { + str8_serial_push_align(arena, out, 8); + data_section_offset = out->total_size; + str8_list_push(arena, out, str8((RADDBGI_U8 *)node->data, node->size)); + } + ptr->tag = node->tag; + ptr->encoding = RADDBGI_DataSectionEncoding_Unpacked; + ptr->off = data_section_offset; + ptr->encoded_size = node->size; + ptr->unpacked_size = node->size; + } + rdim_assert(ptr == dstable + dss.count); + } + + rdim_bake_ctx_release(bctx); +} diff --git a/src/lib_raddbgi_make/raddbgi_make.h b/src/lib_raddbgi_make/raddbgi_make.h new file mode 100644 index 00000000..414aa237 --- /dev/null +++ b/src/lib_raddbgi_make/raddbgi_make.h @@ -0,0 +1,1303 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADDBGI_CONS_H +#define RADDBGI_CONS_H + +//////////////////////////////// +//~ rjf: Overrideable Memory Operations + +// To override the slow/default memset implementation used by the library, +// do the following: +// +// #define RDIM_MEMSET_OVERRIDE +// #define rdim_memset + +#if !defined(rdim_memset) +# define rdim_memset rdim_memset_fallback +#endif + +// To override the slow/default memcpy implementation used by the library, +// do the following: +// +// #define RDIM_MEMCPY_OVERRIDE +// #define rdim_memcpy + +#if !defined(rdim_memset) +# define rdim_memset rdim_memset_fallback +#endif + +#if !defined(rdim_memcpy) +# define rdim_memcpy rdim_memcpy_fallback +#endif + +//////////////////////////////// +//~ rjf: Overrideable sprintf Functions + +#if !defined(rdim_vsnprintf) +# include +# define rdim_vsnprintf vsnprintf +#endif + +//////////////////////////////// +//~ rjf: Overrideable String View Types + +// To override the string view type used by the library, do the following: +// +// #define RDIM_STRING8_OVERRIDE +// #define RDIM_String8 +// #define RDIM_String8_BaseMember +// #define RDIM_String8_SizeMember + +// To override the string view list type used by the library, do the following: +// +// #define RDIM_STRING8LIST_OVERRIDE +// #define RDIM_String8Node +// #define RDIM_String8_NextPtrMember +// #define RDIM_String8_StringMember +// #define RDIM_String8List +// #define RDIM_String8_FirstMember +// #define RDIM_String8_LastMember +// #define RDIM_String8_NodeCount +// #define RDIM_String8_TotalSizeMember + +#if !defined(RDIM_String8) +#define RDIM_String8 RDIM_String8 +#define RDIM_String8_BaseMember str +#define RDIM_String8_SizeMember size +typedef struct RDIM_String8 RDIM_String8; +struct RDIM_String8 +{ + RADDBGI_U8 *str; + RADDBGI_U64 size; +}; +#endif + +#if !defined(RDIM_String8Node) +#define RDIM_String8Node RDIM_String8Node +#define RDIM_String8Node_NextPtrMember next +#define RDIM_String8Node_StringMember string +typedef struct RDIM_String8Node RDIM_String8Node; +struct RDIM_String8Node +{ + RDIM_String8Node *next; + RDIM_String8 string; +}; +#endif + +#if !defined(RDIM_String8List) +#define RDIM_String8List RDIM_String8List +#define RDIM_String8List_FirstMember first +#define RDIM_String8List_LastMember last +#define RDIM_String8List_NodeCountMember node_count +#define RDIM_String8List_TotalSizeMember total_size +typedef struct RDIM_String8List RDIM_String8List; +struct RDIM_String8List +{ + RDIM_String8Node *first; + RDIM_String8Node *last; + RADDBGI_U64 node_count; + RADDBGI_U64 total_size; +}; +#endif + +typedef RADDBGI_U32 RDIM_StringMatchFlags; +enum +{ + RDIM_StringMatchFlag_CaseInsensitive = (1<<0), +}; + +//////////////////////////////// +//~ rjf: Overrideable Arena Allocator Types + +// To override the arena allocator type used by the library, do the following: +// +// #define RDIM_ARENA_OVERRIDE +// #define RDIM_Arena +// #define rdim_arena_alloc Arena*> +// #define rdim_arena_release void> +// #define rdim_arena_pos U64> +// #define rdim_arena_push void*> +// #define rdim_arena_pop_to void> + +#if !defined(RDIM_Arena) +# define RDIM_Arena RDIM_Arena +typedef struct RDIM_Arena RDIM_Arena; +struct RDIM_Arena +{ + RDIM_Arena *prev; + RDIM_Arena *current; + RADDBGI_U64 base_pos; + RADDBGI_U64 pos; + RADDBGI_U64 cmt; + RADDBGI_U64 res; + RADDBGI_U64 align; + RADDBGI_S8 grow; +}; +#endif + +#if !defined(rdim_arena_alloc) +# define rdim_arena_alloc rdim_arena_alloc_fallback +#endif +#if !defined(rdim_arena_release) +# define rdim_arena_release rdim_arena_release_fallback +#endif +#if !defined(rdim_arena_pos) +# define rdim_arena_pos rdim_arena_pos_fallback +#endif +#if !defined(rdim_arena_push) +# define rdim_arena_push rdim_arena_push_fallback +#endif + +//////////////////////////////// +//~ rjf: Overrideable Thread-Local Scratch Arenas + +// To override the default thread-local scratch arenas used b yhe library, +// do the following: +// +// #define RDIM_SCRATCH_OVERRIDE +// #define RDIM_Temp arena implementation - must be (Temp) -> (Arena*)> +// #define rdim_scratch_begin Temp> +// #define rdim_scratch_end void + +#if !defined(RDIM_Temp) +# define RDIM_Temp RDIM_Temp +typedef struct RDIM_Temp RDIM_Temp; +struct RDIM_Temp +{ + RDIM_Arena *arena; + RADDBGI_U64 pos; +}; +#define rdim_temp_arena(t) ((t).arena) +#endif + +#if !defined(rdim_scratch_begin) +# define rdim_scratch_begin rdim_scratch_begin_fallback +#endif +#if !defined(rdim_scratch_end) +# define rdim_scratch_end rdim_scratch_end_fallback +#endif + +//////////////////////////////// +//~ rjf: Linked List Helpers + +#define RDIM_CheckNil(nil,p) ((p) == 0 || (p) == nil) +#define RDIM_SetNil(nil,p) ((p) = nil) + +//- rjf: Base Doubly-Linked-List Macros +#define RDIM_DLLInsert_NPZ(nil,f,l,p,n,next,prev) (RDIM_CheckNil(nil,f) ? \ +((f) = (l) = (n), RDIM_SetNil(nil,(n)->next), RDIM_SetNil(nil,(n)->prev)) :\ +RDIM_CheckNil(nil,p) ? \ +((n)->next = (f), (f)->prev = (n), (f) = (n), RDIM_SetNil(nil,(n)->prev)) :\ +((p)==(l)) ? \ +((l)->next = (n), (n)->prev = (l), (l) = (n), RDIM_SetNil(nil, (n)->next)) :\ +(((!RDIM_CheckNil(nil,p) && RDIM_CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) +#define RDIM_DLLPushBack_NPZ(nil,f,l,n,next,prev) RDIM_DLLInsert_NPZ(nil,f,l,l,n,next,prev) +#define RDIM_DLLPushFront_NPZ(nil,f,l,n,next,prev) RDIM_DLLInsert_NPZ(nil,l,f,f,n,prev,next) +#define RDIM_DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\ +((n) == (l) ? (l) = (l)->prev : (0)),\ +(RDIM_CheckNil(nil,(n)->prev) ? (0) :\ +((n)->prev->next = (n)->next)),\ +(RDIM_CheckNil(nil,(n)->next) ? (0) :\ +((n)->next->prev = (n)->prev))) + +//- rjf: Base Singly-Linked-List Queue Macros +#define RDIM_SLLQueuePush_NZ(nil,f,l,n,next) (RDIM_CheckNil(nil,f)?\ +((f)=(l)=(n),RDIM_SetNil(nil,(n)->next)):\ +((l)->next=(n),(l)=(n),RDIM_SetNil(nil,(n)->next))) +#define RDIM_SLLQueuePushFront_NZ(nil,f,l,n,next) (RDIM_CheckNil(nil,f)?\ +((f)=(l)=(n),RDIM_SetNil(nil,(n)->next)):\ +((n)->next=(f),(f)=(n))) +#define RDIM_SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\ +(RDIM_SetNil(nil,f), RDIM_SetNil(nil,l)):\ +((f)=(f)->next)) + +//- rjf: Base Singly-Linked-List Stack Macros +#define RDIM_SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n)) +#define RDIM_SLLStackPop_N(f,next) ((f)=(f)->next) + +//////////////////////////////// +//~ rjf: Convenience Wrappers + +//- rjf: Doubly-Linked-List Wrappers +#define RDIM_DLLInsert_NP(f,l,p,n,next,prev) RDIM_DLLInsert_NPZ(0,f,l,p,n,next,prev) +#define RDIM_DLLPushBack_NP(f,l,n,next,prev) RDIM_DLLPushBack_NPZ(0,f,l,n,next,prev) +#define RDIM_DLLPushFront_NP(f,l,n,next,prev) RDIM_DLLPushFront_NPZ(0,f,l,n,next,prev) +#define RDIM_DLLRemove_NP(f,l,n,next,prev) RDIM_DLLRemove_NPZ(0,f,l,n,next,prev) +#define RDIM_DLLInsert(f,l,p,n) RDIM_DLLInsert_NPZ(0,f,l,p,n,next,prev) +#define RDIM_DLLPushBack(f,l,n) RDIM_DLLPushBack_NPZ(0,f,l,n,next,prev) +#define RDIM_DLLPushFront(f,l,n) RDIM_DLLPushFront_NPZ(0,f,l,n,next,prev) +#define RDIM_DLLRemove(f,l,n) RDIM_DLLRemove_NPZ(0,f,l,n,next,prev) + +//- rjf: Singly-Linked-List Queue Wrappers +#define RDIM_SLLQueuePush_N(f,l,n,next) RDIM_SLLQueuePush_NZ(0,f,l,n,next) +#define RDIM_SLLQueuePushFront_N(f,l,n,next) RDIM_SLLQueuePushFront_NZ(0,f,l,n,next) +#define RDIM_SLLQueuePop_N(f,l,next) RDIM_SLLQueuePop_NZ(0,f,l,next) +#define RDIM_SLLQueuePush(f,l,n) RDIM_SLLQueuePush_NZ(0,f,l,n,next) +#define RDIM_SLLQueuePushFront(f,l,n) RDIM_SLLQueuePushFront_NZ(0,f,l,n,next) +#define RDIM_SLLQueuePop(f,l) RDIM_SLLQueuePop_NZ(0,f,l,next) + +//- rjf: Singly-Linked-List Stack Wrappers +#define RDIM_SLLStackPush(f,n) RDIM_SLLStackPush_N(f,n,next) +#define RDIM_SLLStackPop(f) RDIM_SLLStackPop_N(f,next) + +//////////////////////////////// +//~ rjf: Helper Macros + +#if defined(_MSC_VER) +# define RDIM_THREAD_LOCAL __declspec(thread) +#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) +# define RDIM_THREAD_LOCAL __thread +#else +# error RDIM_THREAD_LOCAL not defined for this compiler. +#endif + +#if defined(_MSC_VER) +# define rdim_trap() __debugbreak() +#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) +# define rdim_trap() __builtin_trap() +#else +# error "rdim_trap not defined for this compiler." +#endif + +#define rdim_assert_always(x) do{if(!(x)) {rdim_trap();}}while(0) +#if !defined(NDEBUG) +# define rdim_assert(x) rdim_assert_always(x) +#else +# define rdim_assert(x) (void)(x) +#endif +#define rdim_noop ((void)0) + +//////////////////////////////// +//~ rjf: Error Types + +typedef struct RDIM_Error RDIM_Error; +struct RDIM_Error +{ + RDIM_Error *next; + RDIM_String8 msg; +}; + +typedef struct RDIM_ErrorList RDIM_ErrorList; +struct RDIM_ErrorList +{ + RDIM_Error *first; + RDIM_Error *last; + RADDBGI_U64 count; +}; + +//////////////////////////////// +//~ rjf: Auxiliary Data Structure Types + +//- rjf: u64 -> pointer map + +typedef struct RDIM_U64ToPtrNode RDIM_U64ToPtrNode; +struct RDIM_U64ToPtrNode +{ + RDIM_U64ToPtrNode *next; + RADDBGI_U64 _padding_; + RADDBGI_U64 key[1]; + void *ptr[1]; +}; + +typedef struct RDIM_U64ToPtrMap RDIM_U64ToPtrMap; +struct RDIM_U64ToPtrMap +{ + RDIM_U64ToPtrNode **buckets; + RADDBGI_U64 buckets_count; + RADDBGI_U64 bucket_collision_count; + RADDBGI_U64 pair_count; +}; + +typedef struct RDIM_U64ToPtrLookup RDIM_U64ToPtrLookup; +struct RDIM_U64ToPtrLookup +{ + void *match; + RDIM_U64ToPtrNode *fill_node; + RADDBGI_U32 fill_k; +}; + +//- rjf: string8 -> pointer map + +typedef struct RDIM_Str8ToPtrNode RDIM_Str8ToPtrNode; +struct RDIM_Str8ToPtrNode +{ + struct RDIM_Str8ToPtrNode *next; + RDIM_String8 key; + RADDBGI_U64 hash; + void *ptr; +}; + +typedef struct RDIM_Str8ToPtrMap RDIM_Str8ToPtrMap; +struct RDIM_Str8ToPtrMap +{ + RDIM_Str8ToPtrNode **buckets; + RADDBGI_U64 buckets_count; + RADDBGI_U64 bucket_collision_count; + RADDBGI_U64 pair_count; +}; + +//- rjf: sortable range data structure + +typedef struct RDIM_SortKey RDIM_SortKey; +struct RDIM_SortKey +{ + RADDBGI_U64 key; + void *val; +}; + +typedef struct RDIM_OrderedRange RDIM_OrderedRange; +struct RDIM_OrderedRange +{ + RDIM_OrderedRange *next; + RADDBGI_U64 first; + RADDBGI_U64 opl; +}; + +//////////////////////////////// +//~ rjf: Binary Section Types + +typedef struct RDIM_BinarySection RDIM_BinarySection; +struct RDIM_BinarySection +{ + RDIM_BinarySection *next; + RDIM_String8 name; + RADDBGI_BinarySectionFlags flags; + RADDBGI_U64 voff_first; + RADDBGI_U64 voff_opl; + RADDBGI_U64 foff_first; + RADDBGI_U64 foff_opl; +}; + +//////////////////////////////// +//~ rjf: Per-Compilation-Unit Info Types + +typedef struct RDIM_LineSequence RDIM_LineSequence; +struct RDIM_LineSequence +{ + RDIM_String8 file_name; + RADDBGI_U64 *voffs; // [line_count + 1] (sorted) + RADDBGI_U32 *line_nums; // [line_count] + RADDBGI_U16 *col_nums; // [2*line_count] + RADDBGI_U64 line_count; +}; + +typedef struct RDIM_LineSequenceNode RDIM_LineSequenceNode; +struct RDIM_LineSequenceNode +{ + RDIM_LineSequenceNode *next; + RDIM_LineSequence line_seq; +}; + +typedef struct RDIM_UnitInfo RDIM_UnitInfo; +struct RDIM_UnitInfo +{ + RDIM_String8 unit_name; + RDIM_String8 compiler_name; + RDIM_String8 source_file; + RDIM_String8 object_file; + RDIM_String8 archive_file; + RDIM_String8 build_path; + RADDBGI_Language language; +}; + +typedef struct RDIM_Unit RDIM_Unit; +struct RDIM_Unit +{ + RDIM_Unit *next_order; + RADDBGI_U32 idx; + RADDBGI_S32 info_is_set; + RDIM_String8 unit_name; + RDIM_String8 compiler_name; + RDIM_String8 source_file; + RDIM_String8 object_file; + RDIM_String8 archive_file; + RDIM_String8 build_path; + RADDBGI_Language language; + RDIM_LineSequenceNode *line_seq_first; + RDIM_LineSequenceNode *line_seq_last; + RADDBGI_U64 line_seq_count; +}; + +typedef struct RDIM_UnitVMapRange RDIM_UnitVMapRange; +struct RDIM_UnitVMapRange +{ + RDIM_UnitVMapRange *next; + RDIM_Unit *unit; + RADDBGI_U64 first; + RADDBGI_U64 opl; +}; + +//////////////////////////////// +//~ rjf: Type Info Types + +typedef RADDBGI_U8 RDIM_TypeConstructKind; +enum +{ + RDIM_TypeConstructKind_Basic, + RDIM_TypeConstructKind_Modifier, + RDIM_TypeConstructKind_Bitfield, + RDIM_TypeConstructKind_Pointer, + RDIM_TypeConstructKind_Array, + RDIM_TypeConstructKind_Procedure, + RDIM_TypeConstructKind_Method, +}; + +typedef struct RDIM_Reservation RDIM_Reservation; + +typedef struct RDIM_TypeMember RDIM_TypeMember; +struct RDIM_TypeMember +{ + RDIM_TypeMember *next; + RADDBGI_MemberKind kind; + RDIM_String8 name; + struct RDIM_Type *type; + RADDBGI_U32 off; +}; + +typedef struct RDIM_TypeEnumVal RDIM_TypeEnumVal; +struct RDIM_TypeEnumVal +{ + RDIM_TypeEnumVal *next; + RDIM_String8 name; + RADDBGI_U64 val; +}; + +typedef struct RDIM_Type RDIM_Type; +struct RDIM_Type +{ + RDIM_Type *next_order; + RADDBGI_TypeKind kind; + RADDBGI_U32 idx; + RADDBGI_U32 byte_size; + RADDBGI_U32 flags; + RADDBGI_U32 off; + RADDBGI_U32 count; + RDIM_String8 name; + RDIM_Type *direct_type; + RDIM_Type **param_types; + struct RDIM_TypeUDT *udt; +}; + +typedef struct RDIM_TypeUDT RDIM_TypeUDT; +struct RDIM_TypeUDT +{ + RDIM_TypeUDT *next_order; + RADDBGI_U32 idx; + RDIM_Type *self_type; + RDIM_TypeMember *first_member; + RDIM_TypeMember *last_member; + RADDBGI_U64 member_count; + RDIM_TypeEnumVal *first_enum_val; + RDIM_TypeEnumVal *last_enum_val; + RADDBGI_U64 enum_val_count; + RDIM_String8 source_path; + RADDBGI_U32 line; + RADDBGI_U32 col; +}; + +typedef struct RDIM_TypeNode RDIM_TypeNode; +struct RDIM_TypeNode +{ + RDIM_TypeNode *next; + RDIM_Type *type; +}; + +typedef struct RDIM_TypeList RDIM_TypeList; +struct RDIM_TypeList +{ + RDIM_TypeNode *first; + RDIM_TypeNode *last; + RADDBGI_U64 count; +}; + +//////////////////////////////// +//~ rjf: Symbol Info Types + +typedef enum RDIM_SymbolKind +{ + RDIM_SymbolKind_NULL, + RDIM_SymbolKind_GlobalVariable, + RDIM_SymbolKind_ThreadVariable, + RDIM_SymbolKind_Procedure, + RDIM_SymbolKind_COUNT +} +RDIM_SymbolKind; + +typedef struct RDIM_SymbolInfo RDIM_SymbolInfo; +struct RDIM_SymbolInfo +{ + RDIM_SymbolKind kind; + RDIM_String8 name; + RDIM_String8 link_name; + RDIM_Type *type; + RADDBGI_S32 is_extern; + RADDBGI_U64 offset; + // TODO(allen): should this actually be "container scope"? + struct RDIM_Symbol *container_symbol; + RDIM_Type *container_type; + struct RDIM_Scope *root_scope; +}; + +typedef struct RDIM_Symbol RDIM_Symbol; +struct RDIM_Symbol +{ + RDIM_Symbol *next_order; + RADDBGI_U32 idx; + RDIM_SymbolKind kind; + RDIM_String8 name; + RDIM_String8 link_name; + RDIM_Type *type; + RADDBGI_S32 is_extern; + RADDBGI_S8 offset_is_set; + RADDBGI_U64 offset; + RDIM_Symbol *container_symbol; + RDIM_Type *container_type; + struct RDIM_Scope *root_scope; +}; + +//////////////////////////////// +//~ rjf: Scope Info Types + +typedef struct RDIM_LocalInfo RDIM_LocalInfo; +struct RDIM_LocalInfo +{ + RADDBGI_LocalKind kind; + struct RDIM_Scope *scope; + RDIM_String8 name; + RDIM_Type *type; +}; + +typedef struct RDIM_Local RDIM_Local; +struct RDIM_Local +{ + RDIM_Local *next; + RADDBGI_LocalKind kind; + RDIM_String8 name; + RDIM_Type *type; + struct RDIM_LocationSet *locset; +}; + +typedef struct RDIM_VOffRange RDIM_VOffRange; +struct RDIM_VOffRange +{ + RDIM_VOffRange *next; + RADDBGI_U64 voff_first; + RADDBGI_U64 voff_opl; +}; + +typedef struct RDIM_Scope RDIM_Scope; +struct RDIM_Scope +{ + RDIM_Scope *next_order; + RDIM_Symbol *symbol; + RDIM_Scope *parent_scope; + RDIM_Scope *first_child; + RDIM_Scope *last_child; + RDIM_Scope *next_sibling; + RADDBGI_U64 voff_base; + RDIM_VOffRange *first_range; + RDIM_VOffRange *last_range; + RADDBGI_U32 range_count; + RADDBGI_U32 idx; + RDIM_Local *first_local; + RDIM_Local *last_local; + RADDBGI_U32 local_count; +}; + +//////////////////////////////// +//~ rjf: Location Info Types + +typedef struct RDIM_EvalBytecodeOp RDIM_EvalBytecodeOp; +struct RDIM_EvalBytecodeOp +{ + RDIM_EvalBytecodeOp *next; + RADDBGI_EvalOp op; + RADDBGI_U32 p_size; + RADDBGI_U64 p; +}; + +typedef struct RDIM_EvalBytecode RDIM_EvalBytecode; +struct RDIM_EvalBytecode +{ + RDIM_EvalBytecodeOp *first_op; + RDIM_EvalBytecodeOp *last_op; + RADDBGI_U32 op_count; + RADDBGI_U32 encoded_size; +}; + +typedef struct RDIM_Location RDIM_Location; +struct RDIM_Location +{ + RADDBGI_LocationKind kind; + RADDBGI_U8 register_code; + RADDBGI_U16 offset; + RDIM_EvalBytecode bytecode; +}; + +typedef struct RDIM_LocationCase RDIM_LocationCase; +struct RDIM_LocationCase +{ + RDIM_LocationCase *next; + RADDBGI_U64 voff_first; + RADDBGI_U64 voff_opl; + RDIM_Location *location; +}; + +typedef struct RDIM_LocationSet RDIM_LocationSet; +struct RDIM_LocationSet +{ + RDIM_LocationCase *first_location_case; + RDIM_LocationCase *last_location_case; + RADDBGI_U64 location_case_count; +}; + +//////////////////////////////// +//~ rjf: Name Map Types + +typedef struct RDIM_NameMapIdxNode RDIM_NameMapIdxNode; +struct RDIM_NameMapIdxNode +{ + RDIM_NameMapIdxNode *next; + RADDBGI_U32 idx[8]; +}; + +typedef struct RDIM_NameMapNode RDIM_NameMapNode; +struct RDIM_NameMapNode +{ + RDIM_NameMapNode *bucket_next; + RDIM_NameMapNode *order_next; + RDIM_String8 string; + RDIM_NameMapIdxNode *idx_first; + RDIM_NameMapIdxNode *idx_last; + RADDBGI_U64 idx_count; +}; + +typedef struct RDIM_NameMap RDIM_NameMap; +struct RDIM_NameMap +{ + RDIM_NameMapNode **buckets; + RADDBGI_U64 buckets_count; + RADDBGI_U64 bucket_collision_count; + RDIM_NameMapNode *first; + RDIM_NameMapNode *last; + RADDBGI_U64 name_count; +}; + +//////////////////////////////// +//~ rjf: Top-Level Debug Info Types + +typedef struct RDIM_TopLevelInfo RDIM_TopLevelInfo; +struct RDIM_TopLevelInfo +{ + RADDBGI_Arch architecture; + RDIM_String8 exe_name; + RADDBGI_U64 exe_hash; + RADDBGI_U64 voff_max; +}; + +//////////////////////////////// +//~ rjf: Root Construction Bundle Types + +typedef struct RDIM_RootParams RDIM_RootParams; +struct RDIM_RootParams +{ + RADDBGI_U64 addr_size; + RADDBGI_U32 bucket_count_units; // optional; default chosen if 0 + RADDBGI_U32 bucket_count_symbols; // optional; default chosen if 0 + RADDBGI_U32 bucket_count_scopes; // optional; default chosen if 0 + RADDBGI_U32 bucket_count_locals; // optional; default chosen if 0 + RADDBGI_U32 bucket_count_types; // optional; default chosen if 0 + RADDBGI_U64 bucket_count_type_constructs; // optional; default chosen if 0 +}; + +typedef struct RDIM_Root RDIM_Root; +struct RDIM_Root +{ + RDIM_Arena *arena; + RDIM_ErrorList errors; + + //////// Contextual Information + + RADDBGI_U64 addr_size; + + //////// Info Declared By User + + // top level info + RADDBGI_S32 top_level_info_is_set; + RDIM_TopLevelInfo top_level_info; + + // binary layout + RDIM_BinarySection *binary_section_first; + RDIM_BinarySection *binary_section_last; + RADDBGI_U64 binary_section_count; + + // compilation units + RDIM_Unit *unit_first; + RDIM_Unit *unit_last; + RADDBGI_U64 unit_count; + + RDIM_UnitVMapRange *unit_vmap_range_first; + RDIM_UnitVMapRange *unit_vmap_range_last; + RADDBGI_U64 unit_vmap_range_count; + + // types + RDIM_Type *first_type; + RDIM_Type *last_type; + RADDBGI_U64 type_count; + + RDIM_Type *nil_type; + RDIM_Type *variadic_type; + + RDIM_Type handled_nil_type; + + RDIM_TypeUDT *first_udt; + RDIM_TypeUDT *last_udt; + RADDBGI_U64 type_udt_count; + + RADDBGI_U64 total_member_count; + RADDBGI_U64 total_enum_val_count; + + // symbols + RDIM_Symbol *first_symbol; + RDIM_Symbol *last_symbol; + union + { + RADDBGI_U64 symbol_count; + RADDBGI_U64 symbol_kind_counts[RDIM_SymbolKind_COUNT]; + }; + + RDIM_Scope *first_scope; + RDIM_Scope *last_scope; + RADDBGI_U64 scope_count; + RADDBGI_U64 scope_voff_count; + + RDIM_Local *first_local; + RDIM_Local *last_local; + RADDBGI_U64 local_count; + RADDBGI_U64 location_count; + + // name maps + RDIM_NameMap *name_maps[RADDBGI_NameMapKind_COUNT]; + + //////// Handle Relationship Maps + + RDIM_U64ToPtrMap unit_map; + RDIM_U64ToPtrMap symbol_map; + RDIM_U64ToPtrMap scope_map; + RDIM_U64ToPtrMap local_map; + RDIM_U64ToPtrMap type_from_id_map; + RDIM_Str8ToPtrMap construct_map; +}; + +//////////////////////////////// +//~ rjf: Baking Phase Types + +//- rjf: bake data section data structure + +typedef struct RDIM_DSectionNode RDIM_DSectionNode; +struct RDIM_DSectionNode +{ + RDIM_DSectionNode *next; + void *data; + RADDBGI_U64 size; + RADDBGI_DataSectionTag tag; +}; + +typedef struct RDIM_DSections RDIM_DSections; +struct RDIM_DSections +{ + RDIM_DSectionNode *first; + RDIM_DSectionNode *last; + RADDBGI_U32 count; +}; + +//- rjf: bake string data structure + +typedef struct RDIM_StringNode RDIM_StringNode; +struct RDIM_StringNode +{ + RDIM_StringNode *order_next; + RDIM_StringNode *bucket_next; + RDIM_String8 str; + RADDBGI_U64 hash; + RADDBGI_U32 idx; +}; + +typedef struct RDIM_Strings RDIM_Strings; +struct RDIM_Strings +{ + RDIM_StringNode *order_first; + RDIM_StringNode *order_last; + RDIM_StringNode **buckets; + RADDBGI_U64 buckets_count; + RADDBGI_U64 bucket_collision_count; + RADDBGI_U32 count; +}; + +//- rjf: index run baking data structure + +typedef struct RDIM_IdxRunNode RDIM_IdxRunNode; +struct RDIM_IdxRunNode +{ + RDIM_IdxRunNode *order_next; + RDIM_IdxRunNode *bucket_next; + RADDBGI_U32 *idx_run; + RADDBGI_U64 hash; + RADDBGI_U32 count; + RADDBGI_U32 first_idx; +}; + +typedef struct RDIM_IdxRuns RDIM_IdxRuns; +struct RDIM_IdxRuns +{ + RDIM_IdxRunNode *order_first; + RDIM_IdxRunNode *order_last; + RDIM_IdxRunNode **buckets; + RADDBGI_U64 buckets_count; + RADDBGI_U64 bucket_collision_count; + RADDBGI_U32 count; + RADDBGI_U32 idx_count; +}; + +//- rjf: source file & file path baking data structures + +typedef struct RDIM_PathNode RDIM_PathNode; +struct RDIM_PathNode +{ + RDIM_PathNode *next_order; + RDIM_PathNode *parent; + RDIM_PathNode *first_child; + RDIM_PathNode *last_child; + RDIM_PathNode *next_sibling; + RDIM_String8 name; + struct RDIM_SrcNode *src_file; + RADDBGI_U32 idx; +}; + +typedef struct RDIM_LineMapFragment RDIM_LineMapFragment; +struct RDIM_LineMapFragment +{ + RDIM_LineMapFragment *next; + RDIM_LineSequenceNode *sequence; +}; + +typedef struct RDIM_SrcNode RDIM_SrcNode; +struct RDIM_SrcNode +{ + RDIM_SrcNode *next; + RDIM_PathNode *path_node; + RADDBGI_U32 idx; + + RDIM_String8 normal_full_path; + + // place to gather the line info attached to this src file + RDIM_LineMapFragment *first_fragment; + RDIM_LineMapFragment *last_fragment; + + // place to put the final baked version of this file's line map + RADDBGI_U32 line_map_nums_data_idx; + RADDBGI_U32 line_map_range_data_idx; + RADDBGI_U32 line_map_count; + RADDBGI_U32 line_map_voff_data_idx; +}; + +typedef struct RDIM_PathTree RDIM_PathTree; +struct RDIM_PathTree +{ + RDIM_PathNode *first; + RDIM_PathNode *last; + RADDBGI_U32 count; + RDIM_PathNode root; + RDIM_SrcNode *src_first; + RDIM_SrcNode *src_last; + RADDBGI_U32 src_count; +}; + +//- rjf: line info baking data structures + +typedef struct RDIM_LineRec RDIM_LineRec; +struct RDIM_LineRec +{ + RADDBGI_U32 file_id; + RADDBGI_U32 line_num; + RADDBGI_U16 col_first; + RADDBGI_U16 col_opl; +}; + +typedef struct RDIM_UnitLinesCombined RDIM_UnitLinesCombined; +struct RDIM_UnitLinesCombined +{ + RADDBGI_U64 *voffs; + RADDBGI_Line *lines; + RADDBGI_U16 *cols; + RADDBGI_U32 line_count; +}; + +typedef struct RDIM_SrcLinesCombined RDIM_SrcLinesCombined; +struct RDIM_SrcLinesCombined +{ + RADDBGI_U32 *line_nums; + RADDBGI_U32 *line_ranges; + RADDBGI_U64 *voffs; + RADDBGI_U32 line_count; + RADDBGI_U32 voff_count; +}; + +typedef struct RDIM_SrcLineMapVoffBlock RDIM_SrcLineMapVoffBlock; +struct RDIM_SrcLineMapVoffBlock +{ + RDIM_SrcLineMapVoffBlock *next; + RADDBGI_U64 voff; +}; + +typedef struct RDIM_SrcLineMapBucket RDIM_SrcLineMapBucket; +struct RDIM_SrcLineMapBucket +{ + RDIM_SrcLineMapBucket *order_next; + RDIM_SrcLineMapBucket *hash_next; + RADDBGI_U32 line_num; + RDIM_SrcLineMapVoffBlock *first_voff_block; + RDIM_SrcLineMapVoffBlock *last_voff_block; + RADDBGI_U64 voff_count; +}; + +//- rjf: vmap baking data structure + +typedef struct RDIM_VMap RDIM_VMap; +struct RDIM_VMap +{ + RADDBGI_VMapEntry *vmap; // [count + 1] + RADDBGI_U32 count; +}; + +typedef struct RDIM_VMapMarker RDIM_VMapMarker; +struct RDIM_VMapMarker +{ + RADDBGI_U32 idx; + RADDBGI_U32 begin_range; +}; + +typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker; +struct RDIM_VMapRangeTracker +{ + RDIM_VMapRangeTracker *next; + RADDBGI_U32 idx; +}; + +//- rjf: type data baking types + +typedef struct RDIM_TypeData RDIM_TypeData; +struct RDIM_TypeData +{ + RADDBGI_TypeNode *type_nodes; + RADDBGI_U32 type_node_count; + + RADDBGI_UDT *udts; + RADDBGI_U32 udt_count; + + RADDBGI_Member *members; + RADDBGI_U32 member_count; + + RADDBGI_EnumMember *enum_members; + RADDBGI_U32 enum_member_count; +}; + +//- rjf: symbol data baking types + +typedef struct RDIM_SymbolData RDIM_SymbolData; +struct RDIM_SymbolData +{ + RADDBGI_GlobalVariable *global_variables; + RADDBGI_U32 global_variable_count; + + RDIM_VMap *global_vmap; + + RADDBGI_ThreadVariable *thread_variables; + RADDBGI_U32 thread_variable_count; + + RADDBGI_Procedure *procedures; + RADDBGI_U32 procedure_count; + + RADDBGI_Scope *scopes; + RADDBGI_U32 scope_count; + + RADDBGI_U64 *scope_voffs; + RADDBGI_U32 scope_voff_count; + + RDIM_VMap *scope_vmap; + + RADDBGI_Local *locals; + RADDBGI_U32 local_count; + + RADDBGI_LocationBlock *location_blocks; + RADDBGI_U32 location_block_count; + + void *location_data; + RADDBGI_U32 location_data_size; +}; + +//- rjf: name map baking types + +typedef struct RDIM_NameMapSemiNode RDIM_NameMapSemiNode; +struct RDIM_NameMapSemiNode +{ + RDIM_NameMapSemiNode *next; + RDIM_NameMapNode *node; +}; + +typedef struct RDIM_NameMapSemiBucket RDIM_NameMapSemiBucket; +struct RDIM_NameMapSemiBucket +{ + RDIM_NameMapSemiNode *first; + RDIM_NameMapSemiNode *last; + RADDBGI_U64 count; +}; + +typedef struct RDIM_NameMapBaked RDIM_NameMapBaked; +struct RDIM_NameMapBaked +{ + RADDBGI_NameMapBucket *buckets; + RADDBGI_NameMapNode *nodes; + RADDBGI_U32 bucket_count; + RADDBGI_U32 node_count; +}; + +//- rjf: bundle baking context type + +typedef struct RDIM_BakeParams RDIM_BakeParams; +struct RDIM_BakeParams +{ + RADDBGI_U64 strings_bucket_count; + RADDBGI_U64 idx_runs_bucket_count; +}; + +typedef struct RDIM_BakeCtx RDIM_BakeCtx; +struct RDIM_BakeCtx +{ + RDIM_Arena *arena; + RDIM_Strings strs; + RDIM_IdxRuns idxs; + RDIM_PathTree *tree; +}; + +//////////////////////////////// +//~ rjf: Basic Helpers + +//- rjf: memory operations +#if !defined(RDIM_MEMSET_OVERRIDE) +RADDBGI_PROC void *rdim_memset_fallback(void *dst, RADDBGI_U8 c, RADDBGI_U64 size); +#endif +#if !defined(RDIM_MEMCPY_OVERRIDE) +RADDBGI_PROC void *rdim_memcpy_fallback(void *dst, void *src, RADDBGI_U64 size); +#endif +#define rdim_memzero(ptr, size) rdim_memset((ptr), 0, (size)) +#define rdim_memzero_struct(ptr) rdim_memset((ptr), 0, sizeof(*(ptr))) +#define rdim_memcpy_struct(dst, src) rdim_memcpy((dst), (src), sizeof(*(dst))) + +//- rjf: arenas +#if !defined (RDIM_ARENA_OVERRIDE) +RADDBGI_PROC RDIM_Arena *rdim_arena_alloc_fallback(void); +RADDBGI_PROC void rdim_arena_release_fallback(RDIM_Arena *arena); +RADDBGI_PROC RADDBGI_U64 rdim_arena_pos_fallback(RDIM_Arena *arena); +RADDBGI_PROC void *rdim_arena_push_fallback(RDIM_Arena *arena, RADDBGI_U64 size); +RADDBGI_PROC void rdim_arena_pop_to_fallback(RDIM_Arena *arena, RADDBGI_U64 pos); +#endif +#define rdim_push_array_no_zero(a,T,c) (T*)rdim_arena_push((a), sizeof(T)*(c)) +#define rdim_push_array(a,T,c) (T*)rdim_memzero(rdim_push_array_no_zero(a,T,c), sizeof(T)*(c)) + +//- rjf: thread-local scratch arenas +#if !defined (RDIM_SCRATCH_OVERRIDE) +RADDBGI_PROC RDIM_Temp rdim_scratch_begin_fallback(RDIM_Arena **conflicts, RADDBGI_U64 conflicts_count); +RADDBGI_PROC void rdim_scratch_end_fallback(RDIM_Temp temp); +#endif + +//- rjf: strings +RADDBGI_PROC RDIM_String8 rdim_str8(RADDBGI_U8 *str, RADDBGI_U64 size); +RADDBGI_PROC RDIM_String8 rdim_str8_copy(RDIM_Arena *arena, RDIM_String8 src); +RADDBGI_PROC RDIM_String8 rdim_str8f(RDIM_Arena *arena, char *fmt, ...); +RADDBGI_PROC RDIM_String8 rdim_str8fv(RDIM_Arena *arena, char *fmt, va_list args); +RADDBGI_PROC RADDBGI_S32 rdim_str8_match(RDIM_String8 a, RDIM_String8 b, RDIM_StringMatchFlags flags); +#define rdim_str8_lit(S) rdim_str8((RADDBGI_U8*)(S), sizeof(S) - 1) +#define rdim_str8_struct(S) rdim_str8((RADDBGI_U8*)(S), sizeof(*(S))) + +//- rjf: string lists +RADDBGI_PROC void rdim_str8_list_push(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 string); +RADDBGI_PROC RDIM_String8 rdim_str8_list_join(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 sep); + +//- rjf: type lists +RADDBGI_PROC void rdim_type_list_push(RDIM_Arena *arena, RDIM_TypeList *list, RDIM_Type *type); + +//- rjf: bytecode lists +RADDBGI_PROC void rdim_bytecode_push_op(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_EvalOp op, RADDBGI_U64 p); +RADDBGI_PROC void rdim_bytecode_push_uconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_U64 x); +RADDBGI_PROC void rdim_bytecode_push_sconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RADDBGI_S64 x); +RADDBGI_PROC void rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *right_destroyed); + +//- rjf: sortable range sorting +RADDBGI_PROC RDIM_SortKey* rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RADDBGI_U64 count); + +//////////////////////////////// +//~ rjf: Auxiliary Data Structure Functions + +//- rjf: u64 -> ptr map +RADDBGI_PROC void rdim_u64toptr_map_init(RDIM_Arena *arena, RDIM_U64ToPtrMap *map, RADDBGI_U64 bucket_count); +RADDBGI_PROC void rdim_u64toptr_map_lookup(RDIM_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RDIM_U64ToPtrLookup *lookup_out); +RADDBGI_PROC void rdim_u64toptr_map_insert(RDIM_Arena *arena, RDIM_U64ToPtrMap *map, RADDBGI_U64 key, RADDBGI_U64 hash, RDIM_U64ToPtrLookup *lookup, void *ptr); + +//- rjf: string8 -> ptr map +RADDBGI_PROC void rdim_str8toptr_map_init(RDIM_Arena *arena, RDIM_Str8ToPtrMap *map, RADDBGI_U64 bucket_count); +RADDBGI_PROC void*rdim_str8toptr_map_lookup(RDIM_Str8ToPtrMap *map, RDIM_String8 key, RADDBGI_U64 hash); +RADDBGI_PROC void rdim_str8toptr_map_insert(RDIM_Arena *arena, RDIM_Str8ToPtrMap *map, RDIM_String8 key, RADDBGI_U64 hash, void *ptr); + +//////////////////////////////// +//~ rjf: Loose Debug Info Construction (Anything -> Loose) Functions + +//- rjf: root creation +RADDBGI_PROC RDIM_Root* rdim_root_alloc(RDIM_RootParams *params); +RADDBGI_PROC void rdim_root_release(RDIM_Root *root); + +//- rjf: error accumulation +RADDBGI_PROC void rdim_push_error(RDIM_Root *root, RDIM_String8 string); +RADDBGI_PROC void rdim_push_errorf(RDIM_Root *root, char *fmt, ...); +RADDBGI_PROC RDIM_Error* rdim_first_error_from_root(RDIM_Root *root); + +//- rjf: top-level info specification +RADDBGI_PROC void rdim_set_top_level_info(RDIM_Root *root, RDIM_TopLevelInfo *tli); + +//- rjf: binary section building +RADDBGI_PROC void rdim_add_binary_section(RDIM_Root *root, + RDIM_String8 name, RADDBGI_BinarySectionFlags flags, + RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RADDBGI_U64 foff_first, + RADDBGI_U64 foff_opl); + +//- rjf: unit info building +RADDBGI_PROC RDIM_Unit* rdim_unit_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 unit_user_id, RADDBGI_U64 unit_user_id_hash); +RADDBGI_PROC void rdim_unit_set_info(RDIM_Root *root, RDIM_Unit *unit, RDIM_UnitInfo *info); +RADDBGI_PROC void rdim_unit_add_line_sequence(RDIM_Root *root, RDIM_Unit *unit, RDIM_LineSequence *line_sequence); +RADDBGI_PROC void rdim_unit_vmap_add_range(RDIM_Root *root, RDIM_Unit *unit, RADDBGI_U64 first, RADDBGI_U64 opl); + +//- rjf: type info lookups/reservations +RADDBGI_PROC RDIM_Type* rdim_type_from_id(RDIM_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash); +RADDBGI_PROC RDIM_Reservation* rdim_type_reserve_id(RDIM_Root *root, RADDBGI_U64 type_user_id, RADDBGI_U64 type_user_id_hash); +RADDBGI_PROC void rdim_type_fill_id(RDIM_Root *root, RDIM_Reservation *res, RDIM_Type *type); + +//- rjf: nil/singleton types +RADDBGI_PROC RADDBGI_S32 rdim_type_is_unhandled_nil(RDIM_Root *root, RDIM_Type *type); +RADDBGI_PROC RDIM_Type* rdim_type_handled_nil(RDIM_Root *root); +RADDBGI_PROC RDIM_Type* rdim_type_nil(RDIM_Root *root); +RADDBGI_PROC RDIM_Type* rdim_type_variadic(RDIM_Root *root); + +//- rjf: base type info constructors +RADDBGI_PROC RDIM_Type* rdim_type_new(RDIM_Root *root); +RADDBGI_PROC RDIM_TypeUDT* rdim_type_udt_from_any_type(RDIM_Root *root, RDIM_Type *type); +RADDBGI_PROC RDIM_TypeUDT* rdim_type_udt_from_record_type(RDIM_Root *root, RDIM_Type *type); + +//- rjf: basic/operator type construction helpers +RADDBGI_PROC RDIM_Type* rdim_type_basic(RDIM_Root *root, RADDBGI_TypeKind type_kind, RDIM_String8 name); +RADDBGI_PROC RDIM_Type* rdim_type_modifier(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_TypeModifierFlags flags); +RADDBGI_PROC RDIM_Type* rdim_type_bitfield(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_U32 bit_off, RADDBGI_U32 bit_count); +RADDBGI_PROC RDIM_Type* rdim_type_pointer(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_TypeKind ptr_type_kind); +RADDBGI_PROC RDIM_Type* rdim_type_array(RDIM_Root *root, RDIM_Type *direct_type, RADDBGI_U64 count); +RADDBGI_PROC RDIM_Type* rdim_type_proc(RDIM_Root *root, RDIM_Type *return_type, struct RDIM_TypeList *params); +RADDBGI_PROC RDIM_Type* rdim_type_method(RDIM_Root *root, RDIM_Type *this_type, RDIM_Type *return_type, struct RDIM_TypeList *params); + +//- rjf: udt type constructors +RADDBGI_PROC RDIM_Type* rdim_type_udt(RDIM_Root *root, RADDBGI_TypeKind record_type_kind, RDIM_String8 name, RADDBGI_U64 size); +RADDBGI_PROC RDIM_Type* rdim_type_enum(RDIM_Root *root, RDIM_Type *direct_type, RDIM_String8 name); +RADDBGI_PROC RDIM_Type* rdim_type_alias(RDIM_Root *root, RDIM_Type *direct_type, RDIM_String8 name); +RADDBGI_PROC RDIM_Type* rdim_type_incomplete(RDIM_Root *root, RADDBGI_TypeKind type_kind, RDIM_String8 name); + +//- rjf: type member building +RADDBGI_PROC void rdim_type_add_member_data_field(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type, RADDBGI_U32 off); +RADDBGI_PROC void rdim_type_add_member_static_data(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type); +RADDBGI_PROC void rdim_type_add_member_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type); +RADDBGI_PROC void rdim_type_add_member_static_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type); +RADDBGI_PROC void rdim_type_add_member_virtual_method(RDIM_Root *root, RDIM_Type *record_type, RDIM_String8 name, RDIM_Type *mem_type); +RADDBGI_PROC void rdim_type_add_member_base(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *base_type, RADDBGI_U32 off); +RADDBGI_PROC void rdim_type_add_member_virtual_base(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *base_type, RADDBGI_U32 vptr_off, RADDBGI_U32 vtable_off); +RADDBGI_PROC void rdim_type_add_member_nested_type(RDIM_Root *root, RDIM_Type *record_type, RDIM_Type *nested_type); +RADDBGI_PROC void rdim_type_add_enum_val(RDIM_Root *root, RDIM_Type *enum_type, RDIM_String8 name, RADDBGI_U64 val); + +//- rjf: type source coordinate specifications +RADDBGI_PROC void rdim_type_set_source_coordinates(RDIM_Root *root, RDIM_Type *defined_type, RDIM_String8 source_path, RADDBGI_U32 line, RADDBGI_U32 col); + +//- rjf: symbol info building +RADDBGI_PROC RDIM_Symbol* rdim_symbol_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 symbol_user_id, RADDBGI_U64 symbol_user_id_hash); +RADDBGI_PROC void rdim_symbol_set_info(RDIM_Root *root, RDIM_Symbol *symbol, RDIM_SymbolInfo *info); + +//- rjf: scope info building +RADDBGI_PROC RDIM_Scope *rdim_scope_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 scope_user_id, RADDBGI_U64 scope_user_id_hash); +RADDBGI_PROC void rdim_scope_set_parent(RDIM_Root *root, RDIM_Scope *scope, RDIM_Scope *parent); +RADDBGI_PROC void rdim_scope_add_voff_range(RDIM_Root *root, RDIM_Scope *scope, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl); +RADDBGI_PROC void rdim_scope_recursive_set_symbol(RDIM_Scope *scope, RDIM_Symbol *symbol); + +//- rjf: local info building +RADDBGI_PROC RDIM_Local* rdim_local_handle_from_user_id(RDIM_Root *root, RADDBGI_U64 local_user_id, RADDBGI_U64 local_user_id_hash); +RADDBGI_PROC void rdim_local_set_basic_info(RDIM_Root *root, RDIM_Local *local, RDIM_LocalInfo *info); +RADDBGI_PROC RDIM_LocationSet* rdim_location_set_from_local(RDIM_Root *root, RDIM_Local *local); + +//- rjf: location info building +RADDBGI_PROC void rdim_location_set_add_case(RDIM_Root *root, RDIM_LocationSet *locset, RADDBGI_U64 voff_first, RADDBGI_U64 voff_opl, RDIM_Location *location); +RADDBGI_PROC RDIM_Location* rdim_location_addr_bytecode_stream(RDIM_Root *root, struct RDIM_EvalBytecode *bytecode); +RADDBGI_PROC RDIM_Location* rdim_location_val_bytecode_stream(RDIM_Root *root, struct RDIM_EvalBytecode *bytecode); +RADDBGI_PROC RDIM_Location* rdim_location_addr_reg_plus_u16(RDIM_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset); +RADDBGI_PROC RDIM_Location* rdim_location_addr_addr_reg_plus_u16(RDIM_Root *root, RADDBGI_U8 reg_code, RADDBGI_U16 offset); +RADDBGI_PROC RDIM_Location* rdim_location_val_reg(RDIM_Root *root, RADDBGI_U8 reg_code); + +//- rjf: name map building +RADDBGI_PROC RDIM_NameMap* rdim_name_map_for_kind(RDIM_Root *root, RADDBGI_NameMapKind kind); +RADDBGI_PROC void rdim_name_map_add_pair(RDIM_Root *root, RDIM_NameMap *map, RDIM_String8 name, RADDBGI_U32 idx); + +//////////////////////////////// +//~ rjf: Debug Info Baking (Loose -> Tight) Functions + +//- rjf: bake context construction +RADDBGI_PROC RDIM_BakeCtx* rdim_bake_ctx_begin(RDIM_BakeParams *params); +RADDBGI_PROC void rdim_bake_ctx_release(RDIM_BakeCtx *bake_ctx); + +//- rjf: string baking +RADDBGI_PROC RADDBGI_U32 rdim_string(RDIM_BakeCtx *bctx, RDIM_String8 str); + +//- rjf: idx run baking +RADDBGI_PROC RADDBGI_U64 rdim_idx_run_hash(RADDBGI_U32 *idx_run, RADDBGI_U32 count); +RADDBGI_PROC RADDBGI_U32 rdim_idx_run(RDIM_BakeCtx *bctx, RADDBGI_U32 *idx_run, RADDBGI_U32 count); + +//- rjf: data section baking +RADDBGI_PROC RADDBGI_U32 rdim_dsection(RDIM_Arena *arena, RDIM_DSections *dss, void *data, RADDBGI_U64 size, RADDBGI_DataSectionTag tag); + +//- rjf: paths baking +RADDBGI_PROC RDIM_String8 rdim_normal_string_from_path_node(RDIM_Arena *arena, RDIM_PathNode *node); +RADDBGI_PROC void rdim_normal_string_from_path_node_build(RDIM_Arena *arena, RDIM_PathNode *node, RDIM_String8List *out); +RADDBGI_PROC RDIM_PathNode* rdim_paths_new_node(RDIM_BakeCtx *bctx); +RADDBGI_PROC RDIM_PathNode* rdim_paths_sub_path(RDIM_BakeCtx *bctx, RDIM_PathNode *dir, RDIM_String8 sub_dir); +RADDBGI_PROC RDIM_PathNode* rdim_paths_node_from_path(RDIM_BakeCtx *bctx, RDIM_String8 path); +RADDBGI_PROC RADDBGI_U32 rdim_paths_idx_from_path(RDIM_BakeCtx *bctx, RDIM_String8 path); +RADDBGI_PROC RDIM_SrcNode* rdim_paths_new_src_node(RDIM_BakeCtx *bctx); +RADDBGI_PROC RDIM_SrcNode* rdim_paths_src_node_from_path_node(RDIM_BakeCtx *bctx, RDIM_PathNode *path_node); + +//- rjf: per-unit line info baking +RADDBGI_PROC RDIM_UnitLinesCombined* rdim_unit_combine_lines(RDIM_Arena *arena, RDIM_BakeCtx *bctx, RDIM_LineSequenceNode *first_seq); + +//- rjf: per-src line info baking +RADDBGI_PROC RDIM_SrcLinesCombined* rdim_source_combine_lines(RDIM_Arena *arena, RDIM_LineMapFragment *first); + +//- rjf: vmap baking +RADDBGI_PROC RDIM_VMap* rdim_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RADDBGI_U64 marker_count); +RADDBGI_PROC RDIM_VMap* rdim_vmap_from_unit_ranges(RDIM_Arena *arena, RDIM_UnitVMapRange *first, RADDBGI_U64 count); + +//- rjf: type info baking +RADDBGI_PROC RADDBGI_U32* rdim_idx_run_from_types(RDIM_Arena *arena, RDIM_Type **types, RADDBGI_U32 count); +RADDBGI_PROC RDIM_TypeData* rdim_type_data_combine(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx); + +//- rjf: symbol data baking +RADDBGI_PROC RDIM_SymbolData* rdim_symbol_data_combine(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx); + +//- rjf: name map baking +RADDBGI_PROC RDIM_NameMapBaked* rdim_name_map_bake(RDIM_Arena *arena, RDIM_Root *root, RDIM_BakeCtx *bctx, RDIM_NameMap *map); + +//- rjf: top-level baking entry point +RADDBGI_PROC void rdim_bake_file(RDIM_Arena *arena, RDIM_Root *root, RDIM_String8List *out); + +#endif // RADDBGI_CONS_H diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index 3f5a43ee..2111864e 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -634,7 +634,7 @@ entry_point(int argc, char **argv) if(out != 0 && params->output_name.size > 0) { String8List baked = {0}; - raddbgic_bake_file(scratch.arena, out->root, &baked); + rdim_bake_file(scratch.arena, out->root, &baked); U64 off = 0; for(String8Node *node = baked.first; node != 0; node = node->next) { diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 4e72888d..6bb32ceb 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -13,7 +13,7 @@ //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" -#include "raddbgi_cons_local/raddbgi_cons_local.h" +#include "raddbgi_make_local/raddbgi_make_local.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" #include "file_stream/file_stream.h" @@ -50,7 +50,7 @@ //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" -#include "raddbgi_cons_local/raddbgi_cons_local.c" +#include "raddbgi_make_local/raddbgi_make_local.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" #include "file_stream/file_stream.c" diff --git a/src/raddbgi_cons_local/raddbgi_cons_local.h b/src/raddbgi_cons_local/raddbgi_cons_local.h deleted file mode 100644 index 3b37a7b7..00000000 --- a/src/raddbgi_cons_local/raddbgi_cons_local.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RADDBGI_CONS_LOCAL_H -#define RADDBGI_CONS_LOCAL_H - -// rjf: base layer memory ops -#define RADDBGIC_MEMSET_OVERRIDE -#define RADDBGIC_MEMCPY_OVERRIDE -#define raddbgic_memset MemorySet -#define raddbgic_memcpy MemoryCopy - -// rjf: base layer string overrides -#define RADDBGI_STRING8_OVERRIDE -#define RADDBGIC_String8 String8 -#define RADDBGIC_String8_BaseMember str -#define RADDBGIC_String8_SizeMember size -#define RADDBGI_STRING8LIST_OVERRIDE -#define RADDBGIC_String8Node String8Node -#define RADDBGIC_String8Node_NextPtrMember next -#define RADDBGIC_String8Node_StringMember string -#define RADDBGIC_String8List String8List -#define RADDBGIC_String8List_FirstMember first -#define RADDBGIC_String8List_LastMember last -#define RADDBGIC_String8List_NodeCountMember node_count -#define RADDBGIC_String8List_TotalSizeMember total_size - -// rjf: base layer arena overrides -#define RADDBGIC_ARENA_OVERRIDE -#define RADDBGIC_Arena Arena -#define raddbgic_arena_alloc arena_alloc -#define raddbgic_arena_release arena_release -#define raddbgic_arena_pos arena_pos -#define raddbgic_arena_push arena_push -#define raddbgic_arena_pop_to arena_pop_to - -// rjf: base layer scratch arena overrides -#define RADDBGIC_SCRATCH_OVERRIDE -#define RADDBGIC_Temp Temp -#define raddbgic_temp_arena(t) ((t).arena) -#define raddbgic_scratch_begin scratch_begin -#define raddbgic_scratch_end scratch_end - -#include "lib_raddbgi_cons/raddbgi_cons.h" - -#endif // RADDBGI_CONS_LOCAL_H diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.c b/src/raddbgi_from_pdb/raddbgi_from_pdb.c index bcfeecbb..643cd794 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.c @@ -304,7 +304,7 @@ raddbgi_language_from_cv_language(CV_Language cv_language) //- rjf: pdb conversion context creation internal P2R_Ctx * -p2r_ctx_alloc(P2R_CtxParams *params, RADDBGIC_Root *out_root) +p2r_ctx_alloc(P2R_CtxParams *params, RDIM_Root *out_root) { Arena *arena = arena_alloc(); P2R_Ctx *pdb_ctx = push_array(arena, P2R_Ctx, 1); @@ -362,7 +362,7 @@ p2r_u32_from_numeric(P2R_Ctx *ctx, CV_NumericParsed *num) U32 n_u32 = (U32)n_u64; if(n_u64 > 0xFFFFFFFF) { - raddbgic_push_errorf(ctx->root, "constant too large"); + rdim_push_errorf(ctx->root, "constant too large"); n_u32 = 0; } return(n_u32); @@ -391,9 +391,9 @@ p2r_type_cons_main_passes(P2R_Ctx *ctx) // setup variadic itype -> node ProfScope("setup variadic itype -> node") { - RADDBGIC_Type *variadic_type = raddbgic_type_variadic(ctx->root); - RADDBGIC_Reservation *res = raddbgic_type_reserve_id(ctx->root, CV_TypeId_Variadic, CV_TypeId_Variadic); - raddbgic_type_fill_id(ctx->root, res, variadic_type); + RDIM_Type *variadic_type = rdim_type_variadic(ctx->root); + RDIM_Reservation *res = rdim_type_reserve_id(ctx->root, CV_TypeId_Variadic, CV_TypeId_Variadic); + rdim_type_fill_id(ctx->root, res, variadic_type); } // resolve forward references @@ -610,7 +610,7 @@ p2r_type_resolve_fwd(P2R_Ctx *ctx, CV_TypeId itype) return(result); } -internal RADDBGIC_Type* +internal RDIM_Type* p2r_type_resolve_itype(P2R_Ctx *ctx, CV_TypeId itype) { B32 is_basic = (itype < 0x1000); @@ -626,7 +626,7 @@ p2r_type_resolve_itype(P2R_Ctx *ctx, CV_TypeId itype) } // type handle from id - RADDBGIC_Type *result = raddbgic_type_from_id(ctx->root, itype, itype); + RDIM_Type *result = rdim_type_from_id(ctx->root, itype, itype); // basic type if(result == 0 && is_basic) @@ -643,14 +643,14 @@ p2r_type_resolve_itype(P2R_Ctx *ctx, CV_TypeId itype) // never return null, return "nil" instead if(result == 0) { - result = raddbgic_type_nil(ctx->root); + result = rdim_type_nil(ctx->root); } return(result); } internal void -p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_itype) +p2r_type_equip_members(P2R_Ctx *ctx, RDIM_Type *owner_type, CV_TypeId field_itype) { Temp scratch = scratch_begin(0, 0); @@ -763,9 +763,9 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ list_item_opl_off = name_off + name.size + 1; // emit member - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, member->itype); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, member->itype); U32 offset_u32 = p2r_u32_from_numeric(ctx, &offset); - raddbgic_type_add_member_data_field(ctx->root, owner_type, name, mem_type, offset_u32); + rdim_type_add_member_data_field(ctx->root, owner_type, name, mem_type, offset_u32); } }break; @@ -785,8 +785,8 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit member - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, stmember->itype); - raddbgic_type_add_member_static_data(ctx->root, owner_type, name, mem_type); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, stmember->itype); + rdim_type_add_member_static_data(ctx->root, owner_type, name, mem_type); } }break; @@ -870,18 +870,18 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, method->itype); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, method->itype); switch (prop) { default: { - raddbgic_type_add_member_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_method(ctx->root, owner_type, name, mem_type); }break; case CV_MethodProp_Static: { - raddbgic_type_add_member_static_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_static_method(ctx->root, owner_type, name, mem_type); }break; case CV_MethodProp_Virtual: @@ -889,7 +889,7 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ case CV_MethodProp_Intro: case CV_MethodProp_PureIntro: { - raddbgic_type_add_member_virtual_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_virtual_method(ctx->root, owner_type, name, mem_type); }break; } } @@ -924,18 +924,18 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, one_method->itype); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, one_method->itype); switch (prop) { default: { - raddbgic_type_add_member_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_method(ctx->root, owner_type, name, mem_type); }break; case CV_MethodProp_Static: { - raddbgic_type_add_member_static_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_static_method(ctx->root, owner_type, name, mem_type); }break; case CV_MethodProp_Virtual: @@ -943,7 +943,7 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ case CV_MethodProp_Intro: case CV_MethodProp_PureIntro: { - raddbgic_type_add_member_virtual_method(ctx->root, owner_type, name, mem_type); + rdim_type_add_member_virtual_method(ctx->root, owner_type, name, mem_type); }break; } } @@ -963,8 +963,8 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ list_item_opl_off = name_off + name.size + 1; // emit member - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, nest_type->itype); - raddbgic_type_add_member_nested_type(ctx->root, owner_type, mem_type); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, nest_type->itype); + rdim_type_add_member_nested_type(ctx->root, owner_type, mem_type); } }break; @@ -984,8 +984,8 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit member - RADDBGIC_Type *mem_type = p2r_type_resolve_itype(ctx, nest_type->itype); - raddbgic_type_add_member_nested_type(ctx->root, owner_type, mem_type); + RDIM_Type *mem_type = p2r_type_resolve_itype(ctx, nest_type->itype); + rdim_type_add_member_nested_type(ctx->root, owner_type, mem_type); } }break; @@ -1005,9 +1005,9 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit member - RADDBGIC_Type *base_type = p2r_type_resolve_itype(ctx, bclass->itype); + RDIM_Type *base_type = p2r_type_resolve_itype(ctx, bclass->itype); U32 offset_u32 = p2r_u32_from_numeric(ctx, &offset); - raddbgic_type_add_member_base(ctx->root, owner_type, base_type, offset_u32); + rdim_type_add_member_base(ctx->root, owner_type, base_type, offset_u32); } }break; @@ -1031,11 +1031,11 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ // TODO(allen): handle attribs // emit member - RADDBGIC_Type *base_type = p2r_type_resolve_itype(ctx, vbclass->itype); + RDIM_Type *base_type = p2r_type_resolve_itype(ctx, vbclass->itype); U32 vbptr_offset_u32 = p2r_u32_from_numeric(ctx, &num1); U32 vtable_offset_u32 = p2r_u32_from_numeric(ctx, &num2); - raddbgic_type_add_member_virtual_base(ctx->root, owner_type, base_type, - vbptr_offset_u32, vtable_offset_u32); + rdim_type_add_member_virtual_base(ctx->root, owner_type, base_type, + vbptr_offset_u32, vtable_offset_u32); } }break; @@ -1053,8 +1053,8 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ default: { String8 kind_str = cv_string_from_leaf_kind(field_kind); - raddbgic_push_errorf(ctx->root, "unhandled/invalid case: equip_members -> %.*s", - str8_varg(kind_str)); + rdim_push_errorf(ctx->root, "unhandled/invalid case: equip_members -> %.*s", + str8_varg(kind_str)); }break; } @@ -1068,7 +1068,7 @@ p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_ } internal void -p2r_type_equip_enumerates(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_itype) +p2r_type_equip_enumerates(P2R_Ctx *ctx, RDIM_Type *owner_type, CV_TypeId field_itype) { Temp scratch = scratch_begin(0, 0); @@ -1181,15 +1181,15 @@ p2r_type_equip_enumerates(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId fie // emit enum val U64 val_u64 = cv_u64_from_numeric(&val); - raddbgic_type_add_enum_val(ctx->root, owner_type, name, val_u64); + rdim_type_add_enum_val(ctx->root, owner_type, name, val_u64); }break; // unhandled or invalid cases default: { String8 kind_str = cv_string_from_leaf_kind(field_kind); - raddbgic_push_errorf(ctx->root, "unhandled/invalid case: equip_enumerates -> %.*s", - str8_varg(kind_str)); + rdim_push_errorf(ctx->root, "unhandled/invalid case: equip_enumerates -> %.*s", + str8_varg(kind_str)); }break; } @@ -1202,7 +1202,7 @@ p2r_type_equip_enumerates(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId fie scratch_end(scratch); } -internal RADDBGIC_Type* +internal RDIM_Type* p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype) { Assert(itype < 0x1000); @@ -1210,183 +1210,183 @@ p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype) CV_BasicPointerKind basic_ptr_kind = CV_BasicPointerKindFromTypeId(itype); CV_BasicType basic_type_code = CV_BasicTypeFromTypeId(itype); - RADDBGIC_Reservation *basic_res = raddbgic_type_reserve_id(ctx->root, basic_type_code, basic_type_code); + RDIM_Reservation *basic_res = rdim_type_reserve_id(ctx->root, basic_type_code, basic_type_code); - RADDBGIC_Type *basic_type = 0; + RDIM_Type *basic_type = 0; switch (basic_type_code) { case CV_BasicType_VOID: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Void, str8_lit("void")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Void, str8_lit("void")); }break; case CV_BasicType_HRESULT: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Handle, str8_lit("HRESULT")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Handle, str8_lit("HRESULT")); }break; case CV_BasicType_RCHAR: case CV_BasicType_CHAR: case CV_BasicType_CHAR8: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Char8, str8_lit("char")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Char8, str8_lit("char")); }break; case CV_BasicType_UCHAR: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_UChar8, str8_lit("UCHAR")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_UChar8, str8_lit("UCHAR")); }break; case CV_BasicType_WCHAR: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_UChar16, str8_lit("WCHAR")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_UChar16, str8_lit("WCHAR")); }break; case CV_BasicType_CHAR16: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Char16, str8_lit("CHAR16")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Char16, str8_lit("CHAR16")); }break; case CV_BasicType_CHAR32: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Char32, str8_lit("CHAR32")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Char32, str8_lit("CHAR32")); }break; case CV_BasicType_BOOL8: case CV_BasicType_INT8: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_S8, str8_lit("S8")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_S8, str8_lit("S8")); }break; case CV_BasicType_BOOL16: case CV_BasicType_INT16: case CV_BasicType_SHORT: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_S16, str8_lit("S16")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_S16, str8_lit("S16")); }break; case CV_BasicType_BOOL32: case CV_BasicType_INT32: case CV_BasicType_LONG: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_S32, str8_lit("S32")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_S32, str8_lit("S32")); }break; case CV_BasicType_BOOL64: case CV_BasicType_INT64: case CV_BasicType_QUAD: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_S64, str8_lit("S64")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_S64, str8_lit("S64")); }break; case CV_BasicType_INT128: case CV_BasicType_OCT: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_S128, str8_lit("S128")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_S128, str8_lit("S128")); }break; case CV_BasicType_UINT8: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_U8, str8_lit("U8")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_U8, str8_lit("U8")); }break; case CV_BasicType_UINT16: case CV_BasicType_USHORT: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_U16, str8_lit("U16")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_U16, str8_lit("U16")); }break; case CV_BasicType_UINT32: case CV_BasicType_ULONG: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_U32, str8_lit("U32")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_U32, str8_lit("U32")); }break; case CV_BasicType_UINT64: case CV_BasicType_UQUAD: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_U64, str8_lit("U64")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_U64, str8_lit("U64")); }break; case CV_BasicType_UINT128: case CV_BasicType_UOCT: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_U128, str8_lit("U128")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_U128, str8_lit("U128")); }break; case CV_BasicType_FLOAT16: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F16, str8_lit("F16")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F16, str8_lit("F16")); }break; case CV_BasicType_FLOAT32: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F32, str8_lit("F32")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F32, str8_lit("F32")); }break; case CV_BasicType_FLOAT32PP: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F32PP, str8_lit("F32PP")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F32PP, str8_lit("F32PP")); }break; case CV_BasicType_FLOAT48: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F48, str8_lit("F48")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F48, str8_lit("F48")); }break; case CV_BasicType_FLOAT64: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F64, str8_lit("F64")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F64, str8_lit("F64")); }break; case CV_BasicType_FLOAT80: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F80, str8_lit("F80")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F80, str8_lit("F80")); }break; case CV_BasicType_FLOAT128: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_F128, str8_lit("F128")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_F128, str8_lit("F128")); }break; case CV_BasicType_COMPLEX32: { basic_type = - raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF32, str8_lit("ComplexF32")); + rdim_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF32, str8_lit("ComplexF32")); }break; case CV_BasicType_COMPLEX64: { basic_type = - raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF64, str8_lit("ComplexF64")); + rdim_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF64, str8_lit("ComplexF64")); }break; case CV_BasicType_COMPLEX80: { basic_type = - raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF80, str8_lit("ComplexF80")); + rdim_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF80, str8_lit("ComplexF80")); }break; case CV_BasicType_COMPLEX128: { basic_type = - raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF128, str8_lit("ComplexF128")); + rdim_type_basic(ctx->root, RADDBGI_TypeKind_ComplexF128, str8_lit("ComplexF128")); }break; case CV_BasicType_PTR: { - basic_type = raddbgic_type_basic(ctx->root, RADDBGI_TypeKind_Handle, str8_lit("PTR")); + basic_type = rdim_type_basic(ctx->root, RADDBGI_TypeKind_Handle, str8_lit("PTR")); }break; } // basic resolve - raddbgic_type_fill_id(ctx->root, basic_res, basic_type); + rdim_type_fill_id(ctx->root, basic_res, basic_type); // wrap in constructed type - RADDBGIC_Type *constructed_type = 0; + RDIM_Type *constructed_type = 0; if(basic_ptr_kind != 0 && basic_type != 0) { - RADDBGIC_Reservation *constructed_res = raddbgic_type_reserve_id(ctx->root, itype, itype); + RDIM_Reservation *constructed_res = rdim_type_reserve_id(ctx->root, itype, itype); switch (basic_ptr_kind) { @@ -1397,16 +1397,16 @@ p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype) case CV_BasicPointerKind_16_32BIT: case CV_BasicPointerKind_64BIT: { - constructed_type = raddbgic_type_pointer(ctx->root, basic_type, RADDBGI_TypeKind_Ptr); + constructed_type = rdim_type_pointer(ctx->root, basic_type, RADDBGI_TypeKind_Ptr); }break; } // constructed resolve - raddbgic_type_fill_id(ctx->root, constructed_res, constructed_type); + rdim_type_fill_id(ctx->root, constructed_res, constructed_type); } // select output - RADDBGIC_Type *result = basic_type; + RDIM_Type *result = basic_type; if(basic_ptr_kind != 0) { result = constructed_type; @@ -1415,17 +1415,17 @@ p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype) return(result); } -internal RADDBGIC_Type* +internal RDIM_Type* p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) { Assert(ctx->leaf->itype_first <= itype && itype < ctx->leaf->itype_opl); - RADDBGIC_Reservation *res = raddbgic_type_reserve_id(ctx->root, itype, itype); + RDIM_Reservation *res = rdim_type_reserve_id(ctx->root, itype, itype); CV_RecRange *range = &ctx->leaf->leaf_ranges.ranges[itype - ctx->leaf->itype_first]; String8 data = ctx->leaf->data; - RADDBGIC_Type *result = 0; + RDIM_Type *result = 0; if(range->off + range->hdr.size <= data.size) { U8 *first = data.str + range->off + 2; @@ -1450,10 +1450,10 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) flags |= RADDBGI_TypeModifierFlag_Volatile; } - RADDBGIC_Type *direct_type = p2r_type_resolve_and_check(ctx, modifier->itype); + RDIM_Type *direct_type = p2r_type_resolve_and_check(ctx, modifier->itype); if(flags != 0) { - result = raddbgic_type_modifier(ctx->root, direct_type, flags); + result = rdim_type_modifier(ctx->root, direct_type, flags); } else { @@ -1505,13 +1505,13 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) type_kind = RADDBGI_TypeKind_RRef; } - RADDBGIC_Type *direct_type = p2r_type_resolve_and_check(ctx, pointer->itype); - RADDBGIC_Type *ptr_type = raddbgic_type_pointer(ctx->root, direct_type, type_kind); + RDIM_Type *direct_type = p2r_type_resolve_and_check(ctx, pointer->itype); + RDIM_Type *ptr_type = rdim_type_pointer(ctx->root, direct_type, type_kind); result = ptr_type; if(modifier_flags != 0) { - result = raddbgic_type_modifier(ctx->root, ptr_type, modifier_flags); + result = rdim_type_modifier(ctx->root, ptr_type, modifier_flags); } } }break; @@ -1527,12 +1527,12 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) // TODO(allen): handle call_kind & attribs - RADDBGIC_Type *ret_type = p2r_type_resolve_and_check(ctx, procedure->ret_itype); + RDIM_Type *ret_type = p2r_type_resolve_and_check(ctx, procedure->ret_itype); - RADDBGIC_TypeList param_list = {0}; + RDIM_TypeList param_list = {0}; p2r_type_resolve_arglist(scratch.arena, ¶m_list, ctx, procedure->arg_itype); - result = raddbgic_type_proc(ctx->root, ret_type, ¶m_list); + result = rdim_type_proc(ctx->root, ret_type, ¶m_list); scratch_end(scratch); } @@ -1550,20 +1550,20 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) // TODO(allen): handle call_kind & attribs // TODO(allen): preserve "this_adjust" - RADDBGIC_Type *ret_type = p2r_type_resolve_and_check(ctx, mfunction->ret_itype); + RDIM_Type *ret_type = p2r_type_resolve_and_check(ctx, mfunction->ret_itype); - RADDBGIC_TypeList param_list = {0}; + RDIM_TypeList param_list = {0}; p2r_type_resolve_arglist(scratch.arena, ¶m_list, ctx, mfunction->arg_itype); - RADDBGIC_Type *this_type = 0; + RDIM_Type *this_type = 0; if(mfunction->this_itype != 0) { this_type = p2r_type_resolve_and_check(ctx, mfunction->this_itype); - result = raddbgic_type_method(ctx->root, this_type, ret_type, ¶m_list); + result = rdim_type_method(ctx->root, this_type, ret_type, ¶m_list); } else { - result = raddbgic_type_proc(ctx->root, ret_type, ¶m_list); + result = rdim_type_proc(ctx->root, ret_type, ¶m_list); } scratch_end(scratch); @@ -1576,8 +1576,8 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) if(sizeof(CV_LeafBitField) <= cap) { CV_LeafBitField *bit_field = (CV_LeafBitField*)first; - RADDBGIC_Type *direct_type = p2r_type_resolve_and_check(ctx, bit_field->itype); - result = raddbgic_type_bitfield(ctx->root, direct_type, bit_field->pos, bit_field->len); + RDIM_Type *direct_type = p2r_type_resolve_and_check(ctx, bit_field->itype); + result = rdim_type_bitfield(ctx->root, direct_type, bit_field->pos, bit_field->len); } }break; @@ -1594,7 +1594,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) U64 full_size = cv_u64_from_numeric(&array_count); - RADDBGIC_Type *direct_type = p2r_type_resolve_and_check(ctx, array->entry_itype); + RDIM_Type *direct_type = p2r_type_resolve_and_check(ctx, array->entry_itype); U64 count = full_size; if(direct_type != 0 && direct_type->byte_size != 0) { @@ -1602,7 +1602,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) } // build type - result = raddbgic_type_array(ctx->root, direct_type, count); + result = rdim_type_array(ctx->root, direct_type, count); } }break; @@ -1633,7 +1633,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) { type_kind = RADDBGI_TypeKind_IncompleteClass; } - result = raddbgic_type_incomplete(ctx->root, type_kind, name); + result = rdim_type_incomplete(ctx->root, type_kind, name); } // complete type @@ -1644,7 +1644,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) { type_kind = RADDBGI_TypeKind_Class; } - result = raddbgic_type_udt(ctx->root, type_kind, name, size_u64); + result = rdim_type_udt(ctx->root, type_kind, name, size_u64); // remember to revisit this for members { @@ -1684,7 +1684,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) { type_kind = RADDBGI_TypeKind_IncompleteClass; } - result = raddbgic_type_incomplete(ctx->root, type_kind, name); + result = rdim_type_incomplete(ctx->root, type_kind, name); } // complete type @@ -1695,7 +1695,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) { type_kind = RADDBGI_TypeKind_Class; } - result = raddbgic_type_udt(ctx->root, type_kind, name, size_u64); + result = rdim_type_udt(ctx->root, type_kind, name, size_u64); // remember to revisit this for members { @@ -1730,13 +1730,13 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) if(lf_union->props & CV_TypeProp_FwdRef) { result = - raddbgic_type_incomplete(ctx->root, RADDBGI_TypeKind_IncompleteUnion, name); + rdim_type_incomplete(ctx->root, RADDBGI_TypeKind_IncompleteUnion, name); } // complete type else { - result = raddbgic_type_udt(ctx->root, RADDBGI_TypeKind_Union, name, size_u64); + result = rdim_type_udt(ctx->root, RADDBGI_TypeKind_Union, name, size_u64); // remember to revisit this for members { @@ -1765,14 +1765,14 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) // incomplete type if(lf_enum->props & CV_TypeProp_FwdRef) { - result = raddbgic_type_incomplete(ctx->root, RADDBGI_TypeKind_IncompleteEnum, name); + result = rdim_type_incomplete(ctx->root, RADDBGI_TypeKind_IncompleteEnum, name); } // complete type else { - RADDBGIC_Type *direct_type = p2r_type_resolve_and_check(ctx, lf_enum->base_itype); - result = raddbgic_type_enum(ctx->root, direct_type, name); + RDIM_Type *direct_type = p2r_type_resolve_and_check(ctx, lf_enum->base_itype); + result = rdim_type_enum(ctx->root, direct_type, name); // remember to revisit this for enumerates { @@ -1791,7 +1791,7 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) case CV_LeafKind_VFTABLE: case CV_LeafKind_LABEL: { - result = raddbgic_type_handled_nil(ctx->root); + result = rdim_type_handled_nil(ctx->root); }break; // do nothing cases - these get handled in special passes and @@ -1932,30 +1932,30 @@ p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype) default: { String8 kind_str = cv_string_from_leaf_kind(range->hdr.kind); - raddbgic_push_errorf(ctx->root, "pdbconv: unhandled leaf case %.*s (0x%x)", - str8_varg(kind_str), range->hdr.kind); + rdim_push_errorf(ctx->root, "pdbconv: unhandled leaf case %.*s (0x%x)", + str8_varg(kind_str), range->hdr.kind); }break; } } - raddbgic_type_fill_id(ctx->root, res, result); + rdim_type_fill_id(ctx->root, res, result); return(result); } -internal RADDBGIC_Type* +internal RDIM_Type* p2r_type_resolve_and_check(P2R_Ctx *ctx, CV_TypeId itype) { - RADDBGIC_Type *result = p2r_type_resolve_itype(ctx, itype); - if(raddbgic_type_is_unhandled_nil(ctx->root, result)) + RDIM_Type *result = p2r_type_resolve_itype(ctx, itype); + if(rdim_type_is_unhandled_nil(ctx->root, result)) { - raddbgic_push_errorf(ctx->root, "pdbconv: could not resolve itype (itype = %u)", itype); + rdim_push_errorf(ctx->root, "pdbconv: could not resolve itype (itype = %u)", itype); } return(result); } internal void -p2r_type_resolve_arglist(Arena *arena, RADDBGIC_TypeList *out, +p2r_type_resolve_arglist(Arena *arena, RDIM_TypeList *out, P2R_Ctx *ctx, CV_TypeId arglist_itype) { ProfBeginFunction(); @@ -1982,8 +1982,8 @@ p2r_type_resolve_arglist(Arena *arena, RADDBGIC_TypeList *out, U32 clamped_count = ClampTop(arglist->count, max_count); for(U32 i = 0; i < clamped_count; i += 1) { - RADDBGIC_Type *param_type = p2r_type_resolve_and_check(ctx, itypes[i]); - raddbgic_type_list_push(arena, out, param_type); + RDIM_Type *param_type = p2r_type_resolve_and_check(ctx, itypes[i]); + rdim_type_list_push(arena, out, param_type); } } @@ -1993,12 +1993,12 @@ p2r_type_resolve_arglist(Arena *arena, RADDBGIC_TypeList *out, ProfEnd(); } -internal RADDBGIC_Type* +internal RDIM_Type* p2r_type_from_name(P2R_Ctx *ctx, String8 name) { // TODO(rjf): no idea if this is correct CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(ctx->hash, ctx->leaf, name, 0); - RADDBGIC_Type *result = raddbgic_type_from_id(ctx->root, cv_type_id, cv_type_id); + RDIM_Type *result = rdim_type_from_id(ctx->root, cv_type_id, cv_type_id); return(result); } @@ -2099,7 +2099,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // ProfScope("map out data associations") { - RADDBGIC_Symbol *current_proc = 0; + RDIM_Symbol *current_proc = 0; CV_RecRange *rec_ranges_first = sym->sym_ranges.ranges; CV_RecRange *rec_ranges_opl = rec_ranges_first + sym->sym_ranges.count; for(CV_RecRange *rec_range = rec_ranges_first; @@ -2149,7 +2149,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { U64 symbol_id = user_id_base + sym_off_first; U64 symbol_hash = p2r_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - current_proc = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + current_proc = rdim_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); }break; } } @@ -2160,7 +2160,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // ProfScope("main symbol construction pass") { - RADDBGIC_LocationSet *defrange_target = 0; + RDIM_LocationSet *defrange_target = 0; B32 defrange_target_is_param = 0; U64 local_num = 1; U64 scope_num = 1; @@ -2193,8 +2193,8 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) } //- rjf: unpack current state - RADDBGIC_Scope *current_scope = p2r_symbol_current_scope(ctx); - RADDBGIC_Symbol *current_procedure = 0; + RDIM_Scope *current_scope = p2r_symbol_current_scope(ctx); + RDIM_Symbol *current_procedure = 0; if(current_scope != 0) { current_procedure = current_scope->symbol; @@ -2222,8 +2222,8 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) U64 scope_id = user_id_base + scope_num; scope_num += 1; U64 scope_hash = p2r_hash_from_scope_user_id(sym_unique_id_hash, scope_id); - RADDBGIC_Scope *block_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); - raddbgic_scope_set_parent(ctx->root, block_scope, current_scope); + RDIM_Scope *block_scope = rdim_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); + rdim_scope_set_parent(ctx->root, block_scope, current_scope); p2r_symbol_push_scope(ctx, block_scope, current_procedure); // set voff range @@ -2232,7 +2232,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { U64 voff_first = section->voff + block32->off; U64 voff_last = voff_first + block32->len; - raddbgic_scope_add_voff_range(ctx->root, block_scope, voff_first, voff_last); + rdim_scope_add_voff_range(ctx->root, block_scope, voff_first, voff_last); } }break; @@ -2256,10 +2256,10 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) p2r_known_global_insert(ctx->arena, &ctx->known_globals, name, voff); // type of variable - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, data32->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, data32->itype); // container type - RADDBGIC_Type *container_type = 0; + RDIM_Type *container_type = 0; U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); if(container_name_opl > 2) { @@ -2268,7 +2268,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) } // container symbol - RADDBGIC_Symbol *container_symbol = 0; + RDIM_Symbol *container_symbol = 0; if(container_type == 0) { container_symbol = current_procedure; @@ -2280,10 +2280,10 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // cons this symbol U64 symbol_id = user_id_base + sym_off_first; U64 symbol_hash = p2r_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + RDIM_Symbol *symbol = rdim_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_GlobalVariable; + RDIM_SymbolInfo info = zero_struct; + info.kind = RDIM_SymbolKind_GlobalVariable; info.name = name; info.type = type; info.is_extern = is_extern; @@ -2291,7 +2291,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) info.container_type = container_type; info.container_symbol = container_symbol; - raddbgic_symbol_set_info(ctx->root, symbol, &info); + rdim_symbol_set_info(ctx->root, symbol, &info); } }break; @@ -2301,10 +2301,10 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { CV_SymProc32 *proc32 = (CV_SymProc32*)sym_header_struct_base; String8 name = str8_cstring_capped(proc32+1, sym_data_opl); - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, proc32->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, proc32->itype); // container type - RADDBGIC_Type *container_type = 0; + RDIM_Type *container_type = 0; U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); if(container_name_opl > 2) { @@ -2313,7 +2313,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) } // container symbol - RADDBGIC_Symbol *container_symbol = 0; + RDIM_Symbol *container_symbol = 0; if(container_type == 0) { container_symbol = current_procedure; @@ -2322,7 +2322,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // get this symbol handle U64 symbol_id = user_id_base + sym_off_first; U64 symbol_hash = p2r_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *proc_symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + RDIM_Symbol *proc_symbol = rdim_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); // scope @@ -2333,7 +2333,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // no parent. U64 scope_id = user_id_base + scope_num; U64 scope_hash = p2r_hash_from_scope_user_id(sym_unique_id_hash, scope_id); - RADDBGIC_Scope *root_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); + RDIM_Scope *root_scope = rdim_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); p2r_symbol_push_scope(ctx, root_scope, proc_symbol); scope_num += 1; @@ -2344,7 +2344,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { U64 voff_first = section->voff + proc32->off; U64 voff_last = voff_first + proc32->len; - raddbgic_scope_add_voff_range(ctx->root, root_scope, voff_first, voff_last); + rdim_scope_add_voff_range(ctx->root, root_scope, voff_first, voff_last); voff = voff_first; } @@ -2360,8 +2360,8 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) B32 is_extern = (kind == CV_SymKind_GPROC32); // set symbol info - RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_Procedure; + RDIM_SymbolInfo info = zero_struct; + info.kind = RDIM_SymbolKind_Procedure; info.name = name; info.link_name = link_name; info.type = type; @@ -2370,7 +2370,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) info.container_symbol = container_symbol; info.root_scope = root_scope; - raddbgic_symbol_set_info(ctx->root, proc_symbol, &info); + rdim_symbol_set_info(ctx->root, proc_symbol, &info); }break; //- rjf: REGREL32 @@ -2381,7 +2381,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) CV_SymRegrel32 *regrel32 = (CV_SymRegrel32*)sym_header_struct_base; String8 name = str8_cstring_capped(regrel32+1, sym_data_opl); - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, regrel32->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, regrel32->itype); // extract regrel's info CV_Reg cv_reg = regrel32->reg; @@ -2419,15 +2419,15 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // emit local U64 local_id = user_id_base + local_num;; U64 local_id_hash = p2r_hash_from_local_user_id(sym_unique_id_hash, local_id); - RADDBGIC_Local *local_var = raddbgic_local_handle_from_user_id(ctx->root, local_id, local_id_hash); + RDIM_Local *local_var = rdim_local_handle_from_user_id(ctx->root, local_id, local_id_hash); local_num += 1; - RADDBGIC_LocalInfo info = {0}; + RDIM_LocalInfo info = {0}; info.kind = local_kind; info.scope = current_scope; info.name = name; info.type = type; - raddbgic_local_set_basic_info(ctx->root, local_var, &info); + rdim_local_set_basic_info(ctx->root, local_var, &info); // add location to local { @@ -2461,12 +2461,12 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) U32 byte_pos = 0; // set location case - RADDBGIC_Location *loc = + RDIM_Location *loc = p2r_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, (S64)(S32)var_off, extra_indirection_to_value); - RADDBGIC_LocationSet *locset = raddbgic_location_set_from_local(ctx->root, local_var); - raddbgic_location_set_add_case(ctx->root, locset, 0, max_U64, loc); + RDIM_LocationSet *locset = rdim_location_set_from_local(ctx->root, local_var); + rdim_location_set_add_case(ctx->root, locset, 0, max_U64, loc); } }break; @@ -2477,10 +2477,10 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) CV_SymThread32 *thread32 = (CV_SymThread32*)sym_header_struct_base; String8 name = str8_cstring_capped(thread32+1, sym_data_opl); U32 tls_off = thread32->tls_off; - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, thread32->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, thread32->itype); // container type - RADDBGIC_Type *container_type = 0; + RDIM_Type *container_type = 0; U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); if(container_name_opl > 2) { @@ -2489,7 +2489,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) } // container symbol - RADDBGIC_Symbol *container_symbol = 0; + RDIM_Symbol *container_symbol = 0; if(container_type == 0) { container_symbol = current_procedure; @@ -2501,10 +2501,10 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // setup symbol U64 symbol_id = user_id_base + sym_off_first; U64 symbol_hash = p2r_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + RDIM_Symbol *symbol = rdim_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_ThreadVariable; + RDIM_SymbolInfo info = zero_struct; + info.kind = RDIM_SymbolKind_ThreadVariable; info.name = name; info.type = type; info.is_extern = is_extern; @@ -2512,7 +2512,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) info.container_type = container_type; info.container_symbol = container_symbol; - raddbgic_symbol_set_info(ctx->root, symbol, &info); + rdim_symbol_set_info(ctx->root, symbol, &info); }break; //- rjf: LOCAL @@ -2520,7 +2520,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { CV_SymLocal *slocal = (CV_SymLocal*)sym_header_struct_base; String8 name = str8_cstring_capped(slocal+1, sym_data_opl); - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, slocal->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, slocal->itype); // determine how to handle B32 begin_a_global_modification = 0; @@ -2551,20 +2551,20 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) // emit local U64 local_id = user_id_base + local_num; U64 local_id_hash = p2r_hash_from_local_user_id(sym_unique_id_hash, local_id); - RADDBGIC_Local *local_var = raddbgic_local_handle_from_user_id(ctx->root, local_id, local_id_hash); + RDIM_Local *local_var = rdim_local_handle_from_user_id(ctx->root, local_id, local_id_hash); local_num += 1; local_var->kind = local_kind; local_var->name = name; local_var->type = type; - RADDBGIC_LocalInfo info = {0}; + RDIM_LocalInfo info = {0}; info.kind = local_kind; info.scope = current_scope; info.name = name; info.type = type; - raddbgic_local_set_basic_info(ctx->root, local_var, &info); + rdim_local_set_basic_info(ctx->root, local_var, &info); - defrange_target = raddbgic_location_set_from_local(ctx->root, local_var); + defrange_target = rdim_location_set_from_local(ctx->root, local_var); defrange_target_is_param = (local_kind == RADDBGI_LocalKind_Parameter); } }break; @@ -2581,7 +2581,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); // setup location - RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); + RDIM_Location *location = rdim_location_val_reg(ctx->root, register_code); // extract range info CV_LvarAddrRange *range = &defrange_register->range; @@ -2610,7 +2610,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) U32 byte_size = ctx->addr_size; U32 byte_pos = 0; S64 var_off = (S64)defrange_fprel->off; - RADDBGIC_Location *location = + RDIM_Location *location = p2r_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); @@ -2640,7 +2640,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); // setup location - RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); + RDIM_Location *location = rdim_location_val_reg(ctx->root, register_code); // extract range info CV_LvarAddrRange *range = &defrange_subfield_register->range; @@ -2671,13 +2671,13 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) U32 byte_size = ctx->addr_size; U32 byte_pos = 0; S64 var_off = (S64)defrange_fprel_full_scope->off; - RADDBGIC_Location *location = + RDIM_Location *location = p2r_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); // emit location - raddbgic_location_set_add_case(ctx->root, defrange_target, 0, max_U64, location); + rdim_location_set_add_case(ctx->root, defrange_target, 0, max_U64, location); }break; //- rjf: DEFRANGE_REGISTER_REL @@ -2697,7 +2697,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) S64 var_off = defrange_register_rel->reg_off; // setup location - RADDBGIC_Location *location = + RDIM_Location *location = p2r_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, var_off, extra_indirection_to_value); @@ -2716,7 +2716,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { CV_SymFileStatic *file_static = (CV_SymFileStatic*)sym_header_struct_base; String8 name = str8_cstring_capped(file_static+1, sym_data_opl); - RADDBGIC_Type *type = p2r_type_resolve_itype(ctx, file_static->itype); + RDIM_Type *type = p2r_type_resolve_itype(ctx, file_static->itype); // TODO(allen): emit a global modifier symbol @@ -2729,7 +2729,7 @@ p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) //- rjf: non-empty scope stack? -> error { - RADDBGIC_Scope *scope = p2r_symbol_current_scope(ctx); + RDIM_Scope *scope = p2r_symbol_current_scope(ctx); if(scope != 0) { // TODO(allen): emit error @@ -2804,7 +2804,7 @@ p2r_gather_link_names(P2R_Ctx *ctx, CV_SymParsed *sym) // "frameproc" map internal void -p2r_symbol_frame_proc_write(P2R_Ctx *ctx,RADDBGIC_Symbol *key,P2R_FrameProcData *data) +p2r_symbol_frame_proc_write(P2R_Ctx *ctx,RDIM_Symbol *key,P2R_FrameProcData *data) { ProfBeginFunction(); U64 key_int = IntFromPtr(key); @@ -2844,7 +2844,7 @@ p2r_symbol_frame_proc_write(P2R_Ctx *ctx,RADDBGIC_Symbol *key,P2R_FrameProcData } internal P2R_FrameProcData* -p2r_symbol_frame_proc_read(P2R_Ctx *ctx, RADDBGIC_Symbol *key) +p2r_symbol_frame_proc_read(P2R_Ctx *ctx, RDIM_Symbol *key) { U64 key_int = IntFromPtr(key); P2R_FrameProcMap *map = &ctx->frame_proc_map; @@ -2868,7 +2868,7 @@ p2r_symbol_frame_proc_read(P2R_Ctx *ctx, RADDBGIC_Symbol *key) // scope stack internal void -p2r_symbol_push_scope(P2R_Ctx *ctx, RADDBGIC_Scope *scope, RADDBGIC_Symbol *symbol) +p2r_symbol_push_scope(P2R_Ctx *ctx, RDIM_Scope *scope, RDIM_Symbol *symbol) { P2R_ScopeNode *node = ctx->scope_node_free; if(node == 0) @@ -3007,7 +3007,7 @@ p2r_known_global_insert(Arena *arena, P2R_KnownGlobalSet *set, String8 name, U64 // location info helpers -internal RADDBGIC_Location* +internal RDIM_Location* p2r_location_from_addr_reg_off(P2R_Ctx *ctx, RADDBGI_RegisterCode reg_code, U32 reg_byte_size, @@ -3015,40 +3015,40 @@ p2r_location_from_addr_reg_off(P2R_Ctx *ctx, S64 offset, B32 extra_indirection) { - RADDBGIC_Location *result = 0; + RDIM_Location *result = 0; if(0 <= offset && offset <= (S64)max_U16) { if(extra_indirection) { - result = raddbgic_location_addr_addr_reg_plus_u16(ctx->root, reg_code, (U16)offset); + result = rdim_location_addr_addr_reg_plus_u16(ctx->root, reg_code, (U16)offset); } else { - result = raddbgic_location_addr_reg_plus_u16(ctx->root, reg_code, (U16)offset); + result = rdim_location_addr_reg_plus_u16(ctx->root, reg_code, (U16)offset); } } else { Arena *arena = ctx->arena; - RADDBGIC_EvalBytecode bytecode = {0}; + RDIM_EvalBytecode bytecode = {0}; U32 regread_param = RADDBGI_EncodeRegReadParam(reg_code, reg_byte_size, reg_byte_pos); - raddbgic_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_RegRead, regread_param); - raddbgic_bytecode_push_sconst(arena, &bytecode, offset); - raddbgic_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_Add, 0); + rdim_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_RegRead, regread_param); + rdim_bytecode_push_sconst(arena, &bytecode, offset); + rdim_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_Add, 0); if(extra_indirection) { - raddbgic_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_MemRead, ctx->addr_size); + rdim_bytecode_push_op(arena, &bytecode, RADDBGI_EvalOp_MemRead, ctx->addr_size); } - result = raddbgic_location_addr_bytecode_stream(ctx->root, &bytecode); + result = rdim_location_addr_bytecode_stream(ctx->root, &bytecode); } return(result); } internal CV_EncodedFramePtrReg -p2r_cv_encoded_fp_reg_from_proc(P2R_Ctx *ctx, RADDBGIC_Symbol *proc, B32 param_base) +p2r_cv_encoded_fp_reg_from_proc(P2R_Ctx *ctx, RDIM_Symbol *proc, B32 param_base) { CV_EncodedFramePtrReg result = 0; if(proc != 0) @@ -3119,8 +3119,8 @@ p2r_reg_code_from_arch_encoded_fp_reg(RADDBGI_Arch arch, CV_EncodedFramePtrReg e internal void p2r_location_over_lvar_addr_range(P2R_Ctx *ctx, - RADDBGIC_LocationSet *locset, - RADDBGIC_Location *location, + RDIM_LocationSet *locset, + RDIM_Location *location, CV_LvarAddrRange *range, CV_LvarAddrGap *gaps, U64 gap_count) { @@ -3145,14 +3145,14 @@ p2r_location_over_lvar_addr_range(P2R_Ctx *ctx, U64 voff_gap_opl = voff_gap_first + gap_ptr->len; if(voff_cursor < voff_gap_first) { - raddbgic_location_set_add_case(ctx->root, locset, voff_cursor, voff_gap_first, location); + rdim_location_set_add_case(ctx->root, locset, voff_cursor, voff_gap_first, location); } voff_cursor = voff_gap_opl; } if(voff_cursor < voff_opl) { - raddbgic_location_set_add_case(ctx->root, locset, voff_cursor, voff_opl, location); + rdim_location_set_add_case(ctx->root, locset, voff_cursor, voff_opl, location); } } @@ -3494,7 +3494,7 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ // setup root - RADDBGIC_RootParams root_params = {0}; + RDIM_RootParams root_params = {0}; root_params.addr_size = addr_size; root_params.bucket_count_units = comp_unit_count; @@ -3504,7 +3504,7 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ root_params.bucket_count_types = tpi->itype_opl; root_params.bucket_count_type_constructs = tpi->itype_opl; - RADDBGIC_Root *root = raddbgic_root_alloc(&root_params); + RDIM_Root *root = rdim_root_alloc(&root_params); out->root = root; // top level info @@ -3522,13 +3522,13 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ } // set top level info - RADDBGIC_TopLevelInfo tli = {0}; + RDIM_TopLevelInfo tli = {0}; tli.architecture = architecture; tli.exe_name = params->input_exe_name; tli.exe_hash = exe_hash; tli.voff_max = voff_max; - raddbgic_set_top_level_info(root, &tli); + rdim_set_top_level_info(root, &tli); } @@ -3543,9 +3543,9 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ String8 name = str8_cstring_capped(name_first, name_opl); RADDBGI_BinarySectionFlags flags = raddbgi_binary_section_flags_from_coff_section_flags(coff_ptr->flags); - raddbgic_add_binary_section(root, name, flags, - coff_ptr->voff, coff_ptr->voff + coff_ptr->vsize, - coff_ptr->foff, coff_ptr->foff + coff_ptr->fsize); + rdim_add_binary_section(root, name, flags, + coff_ptr->voff, coff_ptr->voff + coff_ptr->vsize, + coff_ptr->foff, coff_ptr->foff + coff_ptr->fsize); } } @@ -3592,16 +3592,16 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ RADDBGI_Language lang = raddbgi_language_from_cv_language(sym->info.language); // basic per unit info - RADDBGIC_Unit *unit_handle = raddbgic_unit_handle_from_user_id(root, i, i); + RDIM_Unit *unit_handle = rdim_unit_handle_from_user_id(root, i, i); - RADDBGIC_UnitInfo info = {0}; + RDIM_UnitInfo info = {0}; info.unit_name = unit_name; info.compiler_name = compiler_name; info.object_file = obj_name; info.archive_file = archive_file; info.language = lang; - raddbgic_unit_set_info(root, unit_handle, &info); + rdim_unit_set_info(root, unit_handle, &info); // unit's line info for(CV_C13SubSectionNode *node = unit_c13->first_sub_section; @@ -3615,13 +3615,13 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ lines_n = lines_n->next) { CV_C13LinesParsed *lines = &lines_n->v; - RADDBGIC_LineSequence seq = {0}; + RDIM_LineSequence seq = {0}; seq.file_name = lines->file_name; seq.voffs = lines->voffs; seq.line_nums = lines->line_nums; seq.col_nums = lines->col_nums; seq.line_count = lines->line_count; - raddbgic_unit_add_line_sequence(root, unit_handle, &seq); + rdim_unit_add_line_sequence(root, unit_handle, &seq); } } } @@ -3637,10 +3637,10 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ { if(contrib_ptr->mod < root->unit_count) { - RADDBGIC_Unit *unit_handle = raddbgic_unit_handle_from_user_id(root, contrib_ptr->mod, contrib_ptr->mod); - raddbgic_unit_vmap_add_range(root, unit_handle, - contrib_ptr->voff_first, - contrib_ptr->voff_opl); + RDIM_Unit *unit_handle = rdim_unit_handle_from_user_id(root, contrib_ptr->mod, contrib_ptr->mod); + rdim_unit_vmap_add_range(root, unit_handle, + contrib_ptr->voff_first, + contrib_ptr->voff_opl); } } } @@ -3673,7 +3673,7 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ // conversion errors if(!params->hide_errors.converting) { - for(RADDBGIC_Error *error = raddbgic_first_error_from_root(root); + for(RDIM_Error *error = rdim_first_error_from_root(root); error != 0; error = error->next) { @@ -3894,12 +3894,12 @@ str8_list_pushf(arena, &out->errors, fmt, __VA_ARGS__);\ {str8_lit("p2r_ctx frame_proc_map"), p2r_ctx?p2r_ctx->frame_proc_map.buckets_count:0, p2r_ctx?p2r_ctx->frame_proc_map.pair_count:0, p2r_ctx?p2r_ctx->frame_proc_map.bucket_collision_count:0}, {str8_lit("p2r_ctx known_globals"), p2r_ctx?p2r_ctx->known_globals.buckets_count:0, p2r_ctx?p2r_ctx->known_globals.global_count:0, p2r_ctx?p2r_ctx->known_globals.bucket_collision_count:0}, {str8_lit("p2r_ctx link_names"), p2r_ctx?p2r_ctx->link_names.buckets_count:0, p2r_ctx?p2r_ctx->link_names.link_name_count:0, p2r_ctx?p2r_ctx->link_names.bucket_collision_count:0}, - {str8_lit("raddbgic_root unit_map"), out->root->unit_map.buckets_count, out->root->unit_map.pair_count, out->root->unit_map.bucket_collision_count}, - {str8_lit("raddbgic_root symbol_map"), out->root->symbol_map.buckets_count, out->root->symbol_map.pair_count, out->root->symbol_map.bucket_collision_count}, - {str8_lit("raddbgic_root scope_map"), out->root->scope_map.buckets_count, out->root->scope_map.pair_count, out->root->scope_map.bucket_collision_count}, - {str8_lit("raddbgic_root local_map"), out->root->local_map.buckets_count, out->root->local_map.pair_count, out->root->local_map.bucket_collision_count}, - {str8_lit("raddbgic_root type_from_id_map"), out->root->type_from_id_map.buckets_count, out->root->type_from_id_map.pair_count, out->root->type_from_id_map.bucket_collision_count}, - {str8_lit("raddbgic_root construct_map"), out->root->construct_map.buckets_count, out->root->construct_map.pair_count, out->root->construct_map.bucket_collision_count}, + {str8_lit("rdim_root unit_map"), out->root->unit_map.buckets_count, out->root->unit_map.pair_count, out->root->unit_map.bucket_collision_count}, + {str8_lit("rdim_root symbol_map"), out->root->symbol_map.buckets_count, out->root->symbol_map.pair_count, out->root->symbol_map.bucket_collision_count}, + {str8_lit("rdim_root scope_map"), out->root->scope_map.buckets_count, out->root->scope_map.pair_count, out->root->scope_map.bucket_collision_count}, + {str8_lit("rdim_root local_map"), out->root->local_map.buckets_count, out->root->local_map.pair_count, out->root->local_map.bucket_collision_count}, + {str8_lit("rdim_root type_from_id_map"), out->root->type_from_id_map.buckets_count, out->root->type_from_id_map.pair_count, out->root->type_from_id_map.bucket_collision_count}, + {str8_lit("rdim_root construct_map"), out->root->construct_map.buckets_count, out->root->construct_map.pair_count, out->root->construct_map.bucket_collision_count}, }; for(U64 idx = 0; idx < ArrayCount(table_info); idx += 1) { diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.h b/src/raddbgi_from_pdb/raddbgi_from_pdb.h index 6a2b4050..a1b4787d 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.h +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.h @@ -67,7 +67,7 @@ typedef struct P2R_TypeRev P2R_TypeRev; struct P2R_TypeRev { P2R_TypeRev *next; - RADDBGIC_Type *owner_type; + RDIM_Type *owner_type; CV_TypeId field_itype; }; @@ -84,7 +84,7 @@ typedef struct P2R_FrameProcNode P2R_FrameProcNode; struct P2R_FrameProcNode { P2R_FrameProcNode *next; - RADDBGIC_Symbol *key; + RDIM_Symbol *key; P2R_FrameProcData data; }; @@ -103,8 +103,8 @@ typedef struct P2R_ScopeNode P2R_ScopeNode; struct P2R_ScopeNode { P2R_ScopeNode *next; - RADDBGIC_Scope *scope; - RADDBGIC_Symbol *symbol; + RDIM_Scope *scope; + RDIM_Symbol *symbol; }; //- rjf: known global map @@ -179,7 +179,7 @@ struct P2R_Ctx U64 section_count; // OUTPUT data - RADDBGIC_Root *root; + RDIM_Root *root; // TEMPORARY STATE P2R_FwdMap fwd_map; @@ -201,7 +201,7 @@ typedef struct P2R_Out P2R_Out; struct P2R_Out { B32 good_parse; - RADDBGIC_Root *root; + RDIM_Root *root; String8List dump; String8List errors; }; @@ -227,7 +227,7 @@ internal RADDBGI_Language raddbgi_language_from_cv_language(CV_Language lang //~ rjf: Conversion Implementation Helpers //- rjf: pdb conversion context creation -internal P2R_Ctx *p2r_ctx_alloc(P2R_CtxParams *params, RADDBGIC_Root *out_root); +internal P2R_Ctx *p2r_ctx_alloc(P2R_CtxParams *params, RDIM_Root *out_root); //- rjf: pdb types and symbols internal void p2r_types_and_symbols(P2R_Ctx *pdb_ctx, P2R_TypesSymbolsParams *params); @@ -249,19 +249,19 @@ internal COFF_SectionHeader* p2r_sec_header_from_sec_num(P2R_Ctx *ctx, U32 sec_n // type info construction passes internal void p2r_type_cons_main_passes(P2R_Ctx *ctx); internal CV_TypeId p2r_type_resolve_fwd(P2R_Ctx *ctx, CV_TypeId itype); -internal RADDBGIC_Type* p2r_type_resolve_itype(P2R_Ctx *ctx, CV_TypeId itype); -internal void p2r_type_equip_members(P2R_Ctx *ctx, RADDBGIC_Type *owern_type, CV_TypeId field_itype); -internal void p2r_type_equip_enumerates(P2R_Ctx *ctx, RADDBGIC_Type *owner_type, CV_TypeId field_itype); +internal RDIM_Type* p2r_type_resolve_itype(P2R_Ctx *ctx, CV_TypeId itype); +internal void p2r_type_equip_members(P2R_Ctx *ctx, RDIM_Type *owern_type, CV_TypeId field_itype); +internal void p2r_type_equip_enumerates(P2R_Ctx *ctx, RDIM_Type *owner_type, CV_TypeId field_itype); // type info construction helpers -internal RADDBGIC_Type* p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype); -internal RADDBGIC_Type* p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype); -internal RADDBGIC_Type* p2r_type_resolve_and_check(P2R_Ctx *ctx, CV_TypeId itype); -internal void p2r_type_resolve_arglist(Arena *arena, RADDBGIC_TypeList *out, +internal RDIM_Type* p2r_type_cons_basic(P2R_Ctx *ctx, CV_TypeId itype); +internal RDIM_Type* p2r_type_cons_leaf_record(P2R_Ctx *ctx, CV_TypeId itype); +internal RDIM_Type* p2r_type_resolve_and_check(P2R_Ctx *ctx, CV_TypeId itype); +internal void p2r_type_resolve_arglist(Arena *arena, RDIM_TypeList *out, P2R_Ctx *ctx, CV_TypeId arglist_itype); // type info resolution helpers -internal RADDBGIC_Type* p2r_type_from_name(P2R_Ctx *ctx, String8 name); +internal RDIM_Type* p2r_type_from_name(P2R_Ctx *ctx, String8 name); // type fwd map internal void p2r_type_fwd_map_set(Arena *arena, P2R_FwdMap *map, @@ -278,12 +278,12 @@ internal void p2r_symbol_cons(P2R_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id internal void p2r_gather_link_names(P2R_Ctx *ctx, CV_SymParsed *sym); // "frameproc" map -internal void p2r_symbol_frame_proc_write(P2R_Ctx *ctx,RADDBGIC_Symbol *key, +internal void p2r_symbol_frame_proc_write(P2R_Ctx *ctx,RDIM_Symbol *key, P2R_FrameProcData *data); -internal P2R_FrameProcData* p2r_symbol_frame_proc_read(P2R_Ctx *ctx, RADDBGIC_Symbol *key); +internal P2R_FrameProcData* p2r_symbol_frame_proc_read(P2R_Ctx *ctx, RDIM_Symbol *key); // scope stack -internal void p2r_symbol_push_scope(P2R_Ctx *ctx, RADDBGIC_Scope *scope, RADDBGIC_Symbol *symbol); +internal void p2r_symbol_push_scope(P2R_Ctx *ctx, RDIM_Scope *scope, RDIM_Symbol *symbol); internal void p2r_symbol_pop_scope(P2R_Ctx *ctx); internal void p2r_symbol_clear_scope_stack(P2R_Ctx *ctx); @@ -302,23 +302,23 @@ internal void p2r_known_global_insert(Arena *arena, P2R_KnownGlobalSet *set, // location info helpers -internal RADDBGIC_Location* p2r_location_from_addr_reg_off(P2R_Ctx *ctx, - RADDBGI_RegisterCode reg_code, - U32 reg_byte_size, - U32 reg_byte_pos, - S64 offset, - B32 extra_indirection); +internal RDIM_Location* p2r_location_from_addr_reg_off(P2R_Ctx *ctx, + RADDBGI_RegisterCode reg_code, + U32 reg_byte_size, + U32 reg_byte_pos, + S64 offset, + B32 extra_indirection); internal CV_EncodedFramePtrReg p2r_cv_encoded_fp_reg_from_proc(P2R_Ctx *ctx, - RADDBGIC_Symbol *proc, + RDIM_Symbol *proc, B32 param_base); internal RADDBGI_RegisterCode p2r_reg_code_from_arch_encoded_fp_reg(RADDBGI_Arch arch, CV_EncodedFramePtrReg encoded_reg); internal void p2r_location_over_lvar_addr_range(P2R_Ctx *ctx, - RADDBGIC_LocationSet *locset, - RADDBGIC_Location *location, + RDIM_LocationSet *locset, + RDIM_Location *location, CV_LvarAddrRange *range, CV_LvarAddrGap *gaps, U64 gap_count); diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c index 5b2891d8..fbfa1e23 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c @@ -90,7 +90,7 @@ main(int argc, char **argv){ if(out != 0 && out->good_parse && params->output_name.size > 0 && out->good_parse) { String8List baked = {0}; - raddbgic_bake_file(arena, out->root, &baked); + rdim_bake_file(arena, out->root, &baked); for(String8Node *node = baked.first; node != 0; node = node->next) { fwrite(node->string.str, node->string.size, 1, out_file); diff --git a/src/raddbgi_cons_local/raddbgi_cons_local.c b/src/raddbgi_make_local/raddbgi_make_local.c similarity index 72% rename from src/raddbgi_cons_local/raddbgi_cons_local.c rename to src/raddbgi_make_local/raddbgi_make_local.c index 59334e1d..7e476d6c 100644 --- a/src/raddbgi_cons_local/raddbgi_cons_local.c +++ b/src/raddbgi_make_local/raddbgi_make_local.c @@ -1,4 +1,4 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#include "lib_raddbgi_cons/raddbgi_cons.c" +#include "lib_raddbgi_make/raddbgi_make.c" diff --git a/src/raddbgi_make_local/raddbgi_make_local.h b/src/raddbgi_make_local/raddbgi_make_local.h new file mode 100644 index 00000000..c5f7fee0 --- /dev/null +++ b/src/raddbgi_make_local/raddbgi_make_local.h @@ -0,0 +1,46 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADDBGI_CONS_LOCAL_H +#define RADDBGI_CONS_LOCAL_H + +// rjf: base layer memory ops +#define RDIM_MEMSET_OVERRIDE +#define RDIM_MEMCPY_OVERRIDE +#define rdim_memset MemorySet +#define rdim_memcpy MemoryCopy + +// rjf: base layer string overrides +#define RADDBGI_STRING8_OVERRIDE +#define RDIM_String8 String8 +#define RDIM_String8_BaseMember str +#define RDIM_String8_SizeMember size +#define RADDBGI_STRING8LIST_OVERRIDE +#define RDIM_String8Node String8Node +#define RDIM_String8Node_NextPtrMember next +#define RDIM_String8Node_StringMember string +#define RDIM_String8List String8List +#define RDIM_String8List_FirstMember first +#define RDIM_String8List_LastMember last +#define RDIM_String8List_NodeCountMember node_count +#define RDIM_String8List_TotalSizeMember total_size + +// rjf: base layer arena overrides +#define RDIM_ARENA_OVERRIDE +#define RDIM_Arena Arena +#define rdim_arena_alloc arena_alloc +#define rdim_arena_release arena_release +#define rdim_arena_pos arena_pos +#define rdim_arena_push arena_push +#define rdim_arena_pop_to arena_pop_to + +// rjf: base layer scratch arena overrides +#define RDIM_SCRATCH_OVERRIDE +#define RDIM_Temp Temp +#define rdim_temp_arena(t) ((t).arena) +#define rdim_scratch_begin scratch_begin +#define rdim_scratch_end scratch_end + +#include "lib_raddbgi_make/raddbgi_make.h" + +#endif // RADDBGI_CONS_LOCAL_H