first pass at (rdi -> loose rdim) path, used in (rdi * ... * rdi) -> rdi joining in radbin; plug in regular conversion path before voff -> line & breakpad paths in radbin, such that PDBs, DWARFs, RDIs, etc. can be used as input; fix up voff -> line path to plug into regular output systems; remove String8 union thing - three reasons: (a) it was only ever introduced for convenience in Linux layers, so let's just keep zero-terminated Linux nonsense in Linux land, (b) it was just alternate syntax for a cast, so let's just cast, (c) it was misleading - 'cstr' implies null-termination, which String8 of course doesn't guarantee. this led to some misuses, where .cstr was trusted to be zero-terminated, when that was not necessarily true (semaphore opening).

This commit is contained in:
Ryan Fleury
2026-03-03 16:24:54 -08:00
parent 2af3990971
commit 4312ee14fd
17 changed files with 1797 additions and 1508 deletions
+1 -5
View File
@@ -10,11 +10,7 @@
typedef struct String8 String8; typedef struct String8 String8;
struct String8 struct String8
{ {
union U8 *str;
{
U8 *str;
char *cstr;
};
U64 size; U64 size;
}; };
+44 -42
View File
@@ -106,13 +106,13 @@ dmn_lnx_exe_path_from_pid(Arena *arena, pid_t pid)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
String8 exe_link_path = str8f(scratch.arena, "/proc/%d/exe", pid); String8 exe_link_path = str8f(scratch.arena, "/proc/%d/exe", pid);
String8List parts = {0}; String8List parts = {0};
int readlink_result = 0; int readlink_result = 0;
for(S64 r = 0, cap = PATH_MAX; r < 4; cap *= 2, r += 1) for(S64 r = 0, cap = PATH_MAX; r < 4; cap *= 2, r += 1)
{ {
U8 *buffer = push_array(arena, U8, cap); U8 *buffer = push_array(arena, U8, cap);
readlink_result = readlink(exe_link_path.cstr, (char *)buffer, cap); readlink_result = readlink((char *)exe_link_path.str, (char *)buffer, cap);
if(readlink_result < 0) if(readlink_result < 0)
{ {
@@ -139,7 +139,7 @@ dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base)
String8 dl_path = {0}; String8 dl_path = {0};
int maps_fd = OS_LNX_RETRY_ON_EINTR(open(str8f(scratch.arena, "/proc/%d/maps", pid).cstr, O_RDONLY)); int maps_fd = OS_LNX_RETRY_ON_EINTR(open((char *)str8f(scratch.arena, "/proc/%d/maps", pid).str, O_RDONLY));
if(maps_fd != -1) if(maps_fd != -1)
{ {
// read entire /proc/pid/maps // read entire /proc/pid/maps
@@ -147,7 +147,7 @@ dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base)
U8 *maps_ptr = push_array(scratch.arena, U8, maps_size); U8 *maps_ptr = push_array(scratch.arena, U8, maps_size);
U64 read_size = dmn_lnx_read(maps_fd, r1u64(0, maps_size), maps_ptr); U64 read_size = dmn_lnx_read(maps_fd, r1u64(0, maps_size), maps_ptr);
// split map file on lines // split map file on lines
String8List lines = str8_split_by_string_chars(scratch.arena, str8(maps_ptr, maps_size), str8_lit("\n"), 0); String8List lines = str8_split_by_string_chars(scratch.arena, str8(maps_ptr, maps_size), str8_lit("\n"), 0);
// scan each line until a virtual mapping whose low part matches the DL base address is found // scan each line until a virtual mapping whose low part matches the DL base address is found
@@ -212,7 +212,7 @@ dmn_lnx_ehdr_from_pid(pid_t pid)
ELF_Hdr64 exe = {0}; ELF_Hdr64 exe = {0};
B32 is_read = 0; B32 is_read = 0;
char *exe_path = push_str8f(scratch.arena, "/proc/%d/exe", pid).cstr; char *exe_path = (char *)str8f(scratch.arena, "/proc/%d/exe", pid).str;
int exe_fd = OS_LNX_RETRY_ON_EINTR(open(exe_path, O_RDONLY)); int exe_fd = OS_LNX_RETRY_ON_EINTR(open(exe_path, O_RDONLY));
if(exe_fd >= 0) if(exe_fd >= 0)
@@ -233,8 +233,8 @@ dmn_lnx_auxv_from_pid(pid_t pid, ELF_Class elf_class)
DMN_LNX_Auxv result = {0}; DMN_LNX_Auxv result = {0};
// rjf: open aux data // rjf: open aux data
String8 auxv_path = push_str8f(scratch.arena, "/proc/%d/auxv", pid); String8 auxv_path = str8f(scratch.arena, "/proc/%d/auxv", pid);
int auxv_fd = OS_LNX_RETRY_ON_EINTR(open(auxv_path.cstr, O_RDONLY)); int auxv_fd = OS_LNX_RETRY_ON_EINTR(open((char *)auxv_path.str, O_RDONLY));
// rjf: scan aux data // rjf: scan aux data
if(auxv_fd >= 0) if(auxv_fd >= 0)
@@ -245,18 +245,18 @@ dmn_lnx_auxv_from_pid(pid_t pid, ELF_Class elf_class)
ELF_Auxv64 auxv = {0}; ELF_Auxv64 auxv = {0};
switch(elf_class) switch(elf_class)
{ {
case ELF_Class_None:{}break; case ELF_Class_None:{}break;
case ELF_Class_32: case ELF_Class_32:
{ {
ELF_Auxv32 auxv32 = {0}; ELF_Auxv32 auxv32 = {0};
if(read(auxv_fd, &auxv32, sizeof(auxv32)) != sizeof(auxv32)) { goto brkloop; } if(read(auxv_fd, &auxv32, sizeof(auxv32)) != sizeof(auxv32)) { goto brkloop; }
auxv = elf_auxv64_from_auxv32(auxv32); auxv = elf_auxv64_from_auxv32(auxv32);
}break; }break;
case ELF_Class_64: case ELF_Class_64:
{ {
if(read(auxv_fd, &auxv, sizeof(auxv)) != sizeof(auxv)) { goto brkloop; } if(read(auxv_fd, &auxv, sizeof(auxv)) != sizeof(auxv)) { goto brkloop; }
}break; }break;
default:{NotImplemented;}break; default:{NotImplemented;}break;
} }
// rjf: fill result // rjf: fill result
@@ -465,7 +465,7 @@ dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vbase, B32 is_rebased
} }
} }
exit:; exit:;
scratch_end(scratch); scratch_end(scratch);
return rdebug_vaddr; return rdebug_vaddr;
} }
@@ -490,8 +490,8 @@ dmn_lnx_read_probes(Arena *arena, int fd, U64 offset, U64 image_base)
ELF_Shdr64 stapsdt_base_shdr = {0}; ELF_Shdr64 stapsdt_base_shdr = {0};
ELF_Shdr64 stapsdt_shdr = {0}; ELF_Shdr64 stapsdt_shdr = {0};
for(U64 shdr_off = offset + ehdr.e_shoff, shdr_opl = shdr_off + ehdr.e_shentsize * ehdr.e_shnum; for(U64 shdr_off = offset + ehdr.e_shoff, shdr_opl = shdr_off + ehdr.e_shentsize * ehdr.e_shnum;
shdr_off < shdr_opl; shdr_off < shdr_opl;
shdr_off += ehdr.e_shentsize) { shdr_off += ehdr.e_shentsize) {
ELF_Shdr64 shdr = {0}; ELF_Shdr64 shdr = {0};
if(elf_read_shdr(dmn_lnx_machine_op_mem_read, &fd, shdr_off, ehdr.e_ident[ELF_Identifier_Class], &shdr) != MachineOpResult_Ok) { goto exit; } if(elf_read_shdr(dmn_lnx_machine_op_mem_read, &fd, shdr_off, ehdr.e_ident[ELF_Identifier_Class], &shdr) != MachineOpResult_Ok) { goto exit; }
@@ -591,7 +591,7 @@ dmn_lnx_read_probes(Arena *arena, int fd, U64 offset, U64 image_base)
probes.count += 1; probes.count += 1;
} }
exit:; exit:;
scratch_end(scratch); scratch_end(scratch);
return probes; return probes;
} }
@@ -630,7 +630,7 @@ dmn_lnx_process_alloc(pid_t pid, DMN_LNX_ProcessState state, DMN_LNX_Process *pa
DMN_LNX_Process *process = &dmn_lnx_entity_alloc(DMN_LNX_EntityKind_Process)->process; DMN_LNX_Process *process = &dmn_lnx_entity_alloc(DMN_LNX_EntityKind_Process)->process;
process->pid = pid; process->pid = pid;
process->fd = OS_LNX_RETRY_ON_EINTR(open(str8f(scratch.arena, "/proc/%d/mem", pid).cstr, O_RDWR)); process->fd = OS_LNX_RETRY_ON_EINTR(open((char *)str8f(scratch.arena, "/proc/%d/mem", pid).str, O_RDWR));
process->state = state; process->state = state;
process->debug_subprocesses = debug_subprocesses; process->debug_subprocesses = debug_subprocesses;
process->is_cow = is_cow; process->is_cow = is_cow;
@@ -698,7 +698,7 @@ dmn_lnx_process_ctx_alloc(DMN_LNX_Process *process, B32 is_rebased)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 dl_path = dmn_lnx_dl_path_from_pid(scratch.arena, process->pid, auxv.base); String8 dl_path = dmn_lnx_dl_path_from_pid(scratch.arena, process->pid, auxv.base);
int dl_fd = OS_LNX_RETRY_ON_EINTR(open(dl_path.cstr, O_RDONLY)); int dl_fd = OS_LNX_RETRY_ON_EINTR(open((char *)dl_path.str, O_RDONLY));
DMN_LNX_ProbeList probes = {0}; DMN_LNX_ProbeList probes = {0};
if(dl_fd >= 0) if(dl_fd >= 0)
@@ -838,7 +838,7 @@ dmn_lnx_module_alloc(DMN_LNX_ProcessCtx *ctx, int memory_fd, U64 base_vaddr, U64
// push base address -> module mapping // push base address -> module mapping
hash_table_push_u64_raw(ctx->arena, ctx->loaded_modules_ht, base_vaddr, module); hash_table_push_u64_raw(ctx->arena, ctx->loaded_modules_ht, base_vaddr, module);
exit:; exit:;
return module; return module;
} }
@@ -1347,7 +1347,7 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
default: { InvalidPath; } break; default: { InvalidPath; } break;
} }
exit:; exit:;
return is_reg_block_read; return is_reg_block_read;
} }
@@ -1542,7 +1542,7 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
default: { InvalidPath; } break; default: { InvalidPath; } break;
} }
exit:; exit:;
return is_reg_block_written; return is_reg_block_written;
} }
@@ -2156,8 +2156,8 @@ dmn_lnx_event_attach(Arena *arena, DMN_EventList *events, pid_t pid)
// extract threads from /proc/pid/task // extract threads from /proc/pid/task
{ {
String8 task_path = push_str8f(scratch.arena, "/proc/%d/task", pid); String8 task_path = str8f(scratch.arena, "/proc/%d/task", pid);
DIR *task_dirp = opendir(task_path.cstr); DIR *task_dirp = opendir((char *)task_path.str);
if(task_dirp) if(task_dirp)
{ {
for(;;) for(;;)
@@ -2279,7 +2279,8 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
U64 idx = 0; U64 idx = 0;
for EachNode(n, String8Node, params->cmd_line.first) for EachNode(n, String8Node, params->cmd_line.first)
{ {
argv[idx++] = push_str8_copy(scratch.arena, n->string).cstr; argv[idx] = (char *)str8_copy(scratch.arena, n->string).str;
idx += 1;
} }
} }
@@ -2294,12 +2295,13 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
U64 idx = os_lnx_state.default_env_count; U64 idx = os_lnx_state.default_env_count;
for EachNode(n, String8Node, params->env.first) for EachNode(n, String8Node, params->env.first)
{ {
envp[idx++] = push_str8_copy(scratch.arena, n->string).cstr; envp[idx] = (char *)str8_copy(scratch.arena, n->string).str;
idx += 1;
} }
} }
// create zero-terminated work directory path // create zero-terminated work directory path
char *work_dir_path = push_str8_copy(scratch.arena, params->path).cstr; char *work_dir_path = (char *)str8_copy(scratch.arena, params->path).str;
// fork process // fork process
pid_t pid = fork(); pid_t pid = fork();
@@ -2738,13 +2740,13 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{ {
switch(siginfo.si_code) switch(siginfo.si_code)
{ {
case SI_KERNEL: { dmn_lnx_event_breakpoint(arena, &events, active_trap_first, wait_id); } break; case SI_KERNEL: { dmn_lnx_event_breakpoint(arena, &events, active_trap_first, wait_id); } break;
case TRAP_BRKPT: { dmn_lnx_event_breakpoint(arena, &events, active_trap_first, wait_id); } break; case TRAP_BRKPT: { dmn_lnx_event_breakpoint(arena, &events, active_trap_first, wait_id); } break;
case TRAP_TRACE: { dmn_lnx_event_single_step(arena, &events, wait_id); } break; case TRAP_TRACE: { dmn_lnx_event_single_step(arena, &events, wait_id); } break;
case TRAP_HWBKPT: { dmn_lnx_event_data_breakpoint(arena, &events, wait_id); } break; case TRAP_HWBKPT: { dmn_lnx_event_data_breakpoint(arena, &events, wait_id); } break;
case TRAP_BRANCH: { NotImplemented; }break; case TRAP_BRANCH: { NotImplemented; }break;
case TRAP_UNK: { NotImplemented; }break; case TRAP_UNK: { NotImplemented; }break;
default: { InvalidPath; } break; default: { InvalidPath; } break;
} }
} else { Assert(0 && "failed to get signal info"); } } else { Assert(0 && "failed to get signal info"); }
}break; }break;
+464 -464
View File
File diff suppressed because it is too large Load Diff
+41 -41
View File
@@ -5,51 +5,51 @@
//~ rjf: API Implementation Helper Macros //~ rjf: API Implementation Helper Macros
#define RDIM_IdxedChunkListPush(arena, list, chunk_type, element_type, cap_value, result, ...) \ #define RDIM_IdxedChunkListPush(arena, list, chunk_type, element_type, cap_value, result, ...) \
element_type *result = 0; \ element_type *result = 0; \
do \ do \
{ \ { \
chunk_type *n = list->last; \ chunk_type *n = list->last; \
if(n == 0 || n->count >= n->cap) \ if(n == 0 || n->count >= n->cap) \
{ \ { \
n = rdim_push_array(arena, chunk_type, 1); \ n = rdim_push_array(arena, chunk_type, 1); \
n->cap = cap_value; \ n->cap = cap_value; \
n->base_idx = list->total_count; \ n->base_idx = list->total_count; \
__VA_ARGS__; \ __VA_ARGS__; \
n->v = rdim_push_array_no_zero(arena, element_type, n->cap); \ n->v = rdim_push_array_no_zero(arena, element_type, n->cap); \
RDIM_SLLQueuePush(list->first, list->last, n); \ RDIM_SLLQueuePush(list->first, list->last, n); \
list->chunk_count += 1; \ list->chunk_count += 1; \
} \ } \
result = &n->v[n->count]; \ result = &n->v[n->count]; \
result->chunk = n; \ result->chunk = n; \
n->count += 1; \ n->count += 1; \
list->total_count += 1; \ list->total_count += 1; \
}while(0) }while(0)
#define RDIM_IdxedChunkListElementGetIdx(ptr, result) \ #define RDIM_IdxedChunkListElementGetIdx(ptr, result) \
RDI_U64 idx = 0; \ RDI_U64 idx = 0; \
if(ptr != 0 && ptr->chunk != 0) \ if(ptr != 0 && ptr->chunk != 0) \
{ \ { \
idx = ptr->chunk->base_idx + (ptr - ptr->chunk->v) + 1; \ idx = ptr->chunk->base_idx + (ptr - ptr->chunk->v) + 1; \
} }
#define RDIM_IdxedChunkListConcatInPlace(chunk_type, dst, to_push, ...) \ #define RDIM_IdxedChunkListConcatInPlace(chunk_type, dst, to_push, ...) \
for(chunk_type *n = to_push->first; n != 0; n = n->next) \ for(chunk_type *n = to_push->first; n != 0; n = n->next) \
{ \ { \
n->base_idx += dst->total_count; \ n->base_idx += dst->total_count; \
} \ } \
if(dst->last != 0 && to_push->first != 0) \ if(dst->last != 0 && to_push->first != 0) \
{ \ { \
dst->last->next = to_push->first; \ dst->last->next = to_push->first; \
dst->last = to_push->last; \ dst->last = to_push->last; \
dst->chunk_count += to_push->chunk_count; \ dst->chunk_count += to_push->chunk_count; \
dst->total_count += to_push->total_count; \ dst->total_count += to_push->total_count; \
__VA_ARGS__; \ __VA_ARGS__; \
} \ } \
else if(dst->first == 0) \ else if(dst->first == 0) \
{ \ { \
rdim_memcpy_struct(dst, to_push); \ rdim_memcpy_struct(dst, to_push); \
} \ } \
rdim_memzero_struct(to_push); rdim_memzero_struct(to_push);
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
+5
View File
@@ -1757,4 +1757,9 @@ RDI_PROC RDIM_SerializedSection rdim_serialized_section_make_unpacked(void *data
RDI_PROC RDIM_SerializedSectionBundle rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results); RDI_PROC RDIM_SerializedSectionBundle rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results);
RDI_PROC RDIM_String8List rdim_file_blobs_from_section_bundle(RDIM_Arena *arena, RDIM_SerializedSectionBundle *bundle); RDI_PROC RDIM_String8List rdim_file_blobs_from_section_bundle(RDIM_Arena *arena, RDIM_SerializedSectionBundle *bundle);
////////////////////////////////
//~ rjf: [Serializing] Parsed RDI -> Bake Results
RDI_PROC RDIM_BakeResults *rdim_bake_results_from_rdi(RDIM_Arena *arena, RDI_Parsed *rdi);
#endif // RDI_MAKE_H #endif // RDI_MAKE_H
+2 -2
View File
@@ -2432,7 +2432,7 @@ THREAD_POOL_TASK_FUNC(lnk_replace_type_names_with_hashes_lenient_task)
} else { } else {
// replace uniuqe type name with hash // replace uniuqe type name with hash
udt_info.unique_name.str = udt_info.name.str + udt_info.name.size + 1; udt_info.unique_name.str = udt_info.name.str + udt_info.name.size + 1;
udt_info.unique_name.size = raddbg_snprintf(udt_info.unique_name.cstr, udt_info.unique_name.size, "%llx", name_hash); udt_info.unique_name.size = raddbg_snprintf((char *)udt_info.unique_name.str, udt_info.unique_name.size, "%llx", name_hash);
// update leaf header // update leaf header
U64 new_size = sizeof(CV_LeafKind) + U64 new_size = sizeof(CV_LeafKind) +
@@ -2498,7 +2498,7 @@ THREAD_POOL_TASK_FUNC(lnk_replace_type_names_with_hashes_full_task)
} }
// replace name with hash // replace name with hash
udt_info.name.size = raddbg_snprintf(udt_info.name.cstr, udt_info.name.size, "%llx", name_hash); udt_info.name.size = raddbg_snprintf((char *)udt_info.name.str, udt_info.name.size, "%llx", name_hash);
// parse struct size // parse struct size
CV_NumericParsed dummy; CV_NumericParsed dummy;
+1 -2
View File
@@ -9,7 +9,7 @@ msf_raw_stream_table_from_data(Arena *arena, String8 msf_data)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
MSF_RawStreamTable *result = 0; MSF_RawStreamTable *result = push_array(arena, MSF_RawStreamTable, 1);
//- determine msf type //- determine msf type
U32 index_size = 0; U32 index_size = 0;
@@ -214,7 +214,6 @@ msf_raw_stream_table_from_data(Arena *arena, String8 msf_data)
} }
if (got_streams) { if (got_streams) {
result = push_array(arena, MSF_RawStreamTable, 1);
result->total_page_count = whole_file_page_count; result->total_page_count = whole_file_page_count;
result->index_size = index_size; result->index_size = index_size;
result->page_size = page_size; result->page_size = page_size;
+46 -33
View File
@@ -159,7 +159,7 @@ os_get_process_start_time_unix(void)
pid_t pid = getpid(); pid_t pid = getpid();
String8 path = push_str8f(scratch.arena, "/proc/%u", pid); String8 path = push_str8f(scratch.arena, "/proc/%u", pid);
struct stat st; struct stat st;
int err = stat(path.cstr, &st); int err = stat((char *)path.str, &st);
if(err == 0) if(err == 0)
{ {
start_time = st.st_mtime; start_time = st.st_mtime;
@@ -240,7 +240,7 @@ os_set_thread_name(String8 name)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 name_copy = push_str8_copy(scratch.arena, name); String8 name_copy = push_str8_copy(scratch.arena, name);
pthread_t current_thread = pthread_self(); pthread_t current_thread = pthread_self();
pthread_setname_np(current_thread, name_copy.cstr); pthread_setname_np(current_thread, (char *)name_copy.str);
scratch_end(scratch); scratch_end(scratch);
} }
@@ -285,7 +285,7 @@ os_file_open(OS_AccessFlags flags, String8 path)
lnx_flags |= O_CREAT; lnx_flags |= O_CREAT;
} }
lnx_flags |= O_CLOEXEC; lnx_flags |= O_CLOEXEC;
int fd = open(path_copy.cstr, lnx_flags, 0755); int fd = open((char *)path_copy.str, lnx_flags, 0755);
OS_Handle handle = {0}; OS_Handle handle = {0};
if(fd != -1) if(fd != -1)
{ {
@@ -400,7 +400,7 @@ os_delete_file_at_path(String8 path)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
B32 result = 0; B32 result = 0;
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = push_str8_copy(scratch.arena, path);
if(remove(path_copy.cstr) != -1) if(remove((char *)path_copy.str) != -1)
{ {
result = 1; result = 1;
} }
@@ -447,8 +447,8 @@ os_move_file_path(String8 dst, String8 src)
B32 good = 0; B32 good = 0;
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
{ {
char *src_cstr = push_str8_copy(scratch.arena, src).cstr; char *src_cstr = (char *)str8_copy(scratch.arena, src).str;
char *dst_cstr = push_str8_copy(scratch.arena, dst).cstr; char *dst_cstr = (char *)str8_copy(scratch.arena, dst).str;
int rename_result = rename(src_cstr, dst_cstr); int rename_result = rename(src_cstr, dst_cstr);
good = (rename_result != -1); good = (rename_result != -1);
} }
@@ -460,10 +460,10 @@ internal String8
os_full_path_from_path(Arena *arena, String8 path) os_full_path_from_path(Arena *arena, String8 path)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = str8_copy(scratch.arena, path);
char buffer[PATH_MAX] = {0}; char buffer[PATH_MAX] = {0};
realpath(path_copy.cstr, buffer); realpath((char *)path_copy.str, buffer);
String8 result = push_str8_copy(arena, str8_cstring(buffer)); String8 result = str8_copy(arena, str8_cstring(buffer));
scratch_end(scratch); scratch_end(scratch);
return result; return result;
} }
@@ -473,7 +473,7 @@ os_file_path_exists(String8 path)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = push_str8_copy(scratch.arena, path);
int access_result = access(path_copy.cstr, F_OK); int access_result = access((char *)path_copy.str, F_OK);
B32 result = 0; B32 result = 0;
if(access_result == 0) if(access_result == 0)
{ {
@@ -487,9 +487,9 @@ internal B32
os_folder_path_exists(String8 path) os_folder_path_exists(String8 path)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
B32 exists = 0; B32 exists = 0;
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = str8_copy(scratch.arena, path);
DIR *handle = opendir(path_copy.cstr); DIR *handle = opendir((char *)path_copy.str);
if(handle) if(handle)
{ {
closedir(handle); closedir(handle);
@@ -503,9 +503,9 @@ internal FileProperties
os_properties_from_file_path(String8 path) os_properties_from_file_path(String8 path)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = str8_copy(scratch.arena, path);
struct stat f_stat = {0}; struct stat f_stat = {0};
int stat_result = stat(path_copy.cstr, &f_stat); int stat_result = stat((char *)path_copy.str, &f_stat);
FileProperties props = {0}; FileProperties props = {0};
if(stat_result != -1) if(stat_result != -1)
{ {
@@ -564,7 +564,7 @@ os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags)
OS_LNX_FileIter *iter = (OS_LNX_FileIter *)base_iter->memory; OS_LNX_FileIter *iter = (OS_LNX_FileIter *)base_iter->memory;
{ {
String8 path_copy = push_str8_copy(arena, path); String8 path_copy = push_str8_copy(arena, path);
iter->dir = opendir(path_copy.cstr); iter->dir = opendir((char *)path_copy.str);
iter->path = path_copy; iter->path = path_copy;
} }
return base_iter; return base_iter;
@@ -588,7 +588,7 @@ os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
String8 full_path = push_str8f(scratch.arena, "%S/%s", lnx_iter->path, lnx_iter->dp->d_name); String8 full_path = push_str8f(scratch.arena, "%S/%s", lnx_iter->path, lnx_iter->dp->d_name);
stat_result = stat(full_path.cstr, &st); stat_result = stat((char *)full_path.str, &st);
scratch_end(scratch); scratch_end(scratch);
} }
@@ -637,7 +637,7 @@ os_make_directory(String8 path)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
B32 result = 0; B32 result = 0;
String8 path_copy = push_str8_copy(scratch.arena, path); String8 path_copy = push_str8_copy(scratch.arena, path);
if(mkdir(path_copy.cstr, 0755) != -1) if(mkdir((char *)path_copy.str, 0755) != -1)
{ {
result = 1; result = 1;
} }
@@ -653,7 +653,7 @@ os_shared_memory_alloc(U64 size, String8 name)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 name_copy = push_str8_copy(scratch.arena, name); String8 name_copy = push_str8_copy(scratch.arena, name);
int id = shm_open(name_copy.cstr, O_RDWR|O_CREAT, 0666); int id = shm_open((char *)name_copy.str, O_RDWR|O_CREAT, 0666);
ftruncate(id, size); ftruncate(id, size);
OS_Handle result = {(U64)id}; OS_Handle result = {(U64)id};
scratch_end(scratch); scratch_end(scratch);
@@ -665,7 +665,7 @@ os_shared_memory_open(String8 name)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8 name_copy = push_str8_copy(scratch.arena, name); String8 name_copy = push_str8_copy(scratch.arena, name);
int id = shm_open(name_copy.cstr, O_RDWR, 0); int id = shm_open((char *)name_copy.str, O_RDWR, 0);
OS_Handle result = {(U64)id}; OS_Handle result = {(U64)id};
scratch_end(scratch); scratch_end(scratch);
return result; return result;
@@ -802,9 +802,13 @@ os_process_launch(OS_ProcessLaunchParams *params)
str8_list_push(scratch.arena, &l, params->cmd_line.first->string); str8_list_push(scratch.arena, &l, params->cmd_line.first->string);
String8 path_to_exe = str8_path_list_join_by_style(scratch.arena, &l, PathStyle_SystemAbsolute); String8 path_to_exe = str8_path_list_join_by_style(scratch.arena, &l, PathStyle_SystemAbsolute);
argv[0] = path_to_exe.cstr; argv[0] = (char *)path_to_exe.str;
U64 arg_idx = 1; U64 arg_idx = 1;
for EachNode(n, String8Node, params->cmd_line.first->next) { argv[arg_idx++] = n->string.cstr; } for EachNode(n, String8Node, params->cmd_line.first->next)
{
argv[arg_idx] = (char *)n->string.str;
arg_idx += 1;
}
} }
// package envp // package envp
@@ -819,7 +823,8 @@ os_process_launch(OS_ProcessLaunchParams *params)
U64 env_idx = 0; U64 env_idx = 0;
for EachNode(n, String8Node, params->cmd_line.first) for EachNode(n, String8Node, params->cmd_line.first)
{ {
envp[env_idx] = n->string.cstr; envp[env_idx] = (char *)n->string.str;
env_idx += 1;
} }
} }
@@ -1170,15 +1175,17 @@ os_cond_var_broadcast(CondVar cv)
internal Semaphore internal Semaphore
os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name) os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name)
{ {
Temp scratch = scratch_begin(0, 0);
Semaphore result = {0}; Semaphore result = {0};
if (name.size > 0) if(name.size > 0)
{ {
for EachIndex(attempt_idx, 64) for EachIndex(attempt_idx, 64)
{ {
sem_t *s = sem_open(name.cstr, O_CREAT | O_EXCL, 0666, initial_count); String8 name_copy = str8_copy(scratch.arena, name);
sem_t *s = sem_open((char *)name_copy.str, O_CREAT | O_EXCL, 0666, initial_count);
if(s == SEM_FAILED) if(s == SEM_FAILED)
{ {
s = sem_open(name.cstr, 0); s = sem_open((char *)name_copy.str, 0);
} }
if(s != SEM_FAILED) if(s != SEM_FAILED)
{ {
@@ -1197,6 +1204,7 @@ os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name)
result.u64[0] = (U64)s; result.u64[0] = (U64)s;
} }
} }
scratch_end(scratch);
return result; return result;
} }
@@ -1211,10 +1219,15 @@ internal Semaphore
os_semaphore_open(String8 name) os_semaphore_open(String8 name)
{ {
Semaphore result = {0}; Semaphore result = {0};
sem_t *s = sem_open(name.cstr, 0);
if(s != SEM_FAILED)
{ {
result.u64[0] = (U64)s; Temp scratch = scratch_begin(0, 0);
String8 name_copy = str8_copy(scratch.arena, name);
sem_t *s = sem_open((char *)name_copy.str, 0);
if(s != SEM_FAILED)
{
result.u64[0] = (U64)s;
}
scratch_end(scratch);
} }
return result; return result;
} }
@@ -1310,7 +1323,7 @@ internal OS_Handle
os_library_open(String8 path) os_library_open(String8 path)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
char *path_cstr = push_str8_copy(scratch.arena, path).cstr; char *path_cstr = (char *)str8_copy(scratch.arena, path).str;
void *so = dlopen(path_cstr, RTLD_LAZY|RTLD_LOCAL); void *so = dlopen(path_cstr, RTLD_LAZY|RTLD_LOCAL);
OS_Handle lib = { (U64)so }; OS_Handle lib = { (U64)so };
scratch_end(scratch); scratch_end(scratch);
@@ -1322,7 +1335,7 @@ os_library_load_proc(OS_Handle lib, String8 name)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
void *so = (void *)lib.u64; void *so = (void *)lib.u64;
char *name_cstr = push_str8_copy(scratch.arena, name).cstr; char *name_cstr = (char *)str8_copy(scratch.arena, name).str;
VoidProc *proc = (VoidProc *)dlsym(so, name_cstr); VoidProc *proc = (VoidProc *)dlsym(so, name_cstr);
scratch_end(scratch); scratch_end(scratch);
return proc; return proc;
@@ -1491,9 +1504,9 @@ main(int argc, char **argv)
U64 env_count = 0; U64 env_count = 0;
for(; __environ[env_count] != 0; env_count += 1) {} for(; __environ[env_count] != 0; env_count += 1) {}
char **default_env = push_array(os_lnx_state.arena, char *, env_count+1); char **default_env = push_array(os_lnx_state.arena, char *, env_count+1);
for EachIndex(i, env_count) for EachIndex(idx, env_count)
{ {
default_env[i] = str8_copy(os_lnx_state.arena, str8_cstring(__environ[i])).cstr; default_env[idx] = (char *)str8_copy(os_lnx_state.arena, str8_cstring(__environ[idx])).str;
} }
default_env[env_count] = 0; default_env[env_count] = 0;
os_lnx_state.default_env_count = env_count; os_lnx_state.default_env_count = env_count;
+241 -197
View File
@@ -432,7 +432,7 @@ rb_thread_entry_point(void *p)
{str8_lit_comp("rdi"), str8_lit_comp("RAD Debug Info (.rdi) Conversion")}, {str8_lit_comp("rdi"), str8_lit_comp("RAD Debug Info (.rdi) Conversion")},
{str8_lit_comp("dump"), str8_lit_comp("Textual Dumping")}, {str8_lit_comp("dump"), str8_lit_comp("Textual Dumping")},
{str8_lit_comp("breakpad"), str8_lit_comp("Breakpad Debug Info Conversion")}, {str8_lit_comp("breakpad"), str8_lit_comp("Breakpad Debug Info Conversion")},
{str8_lit_comp("voff2line"), str8_lit_comp("Map virtual offset to a source line")}, {str8_lit_comp("voff2line"), str8_lit_comp("Virtual Offset -> Line Mapping")},
}; };
OutputKind output_kind = OutputKind_Null; OutputKind output_kind = OutputKind_Null;
String8 output_path = cmd_line_string(cmdline, str8_lit("out")); String8 output_path = cmd_line_string(cmdline, str8_lit("out"));
@@ -536,7 +536,8 @@ rb_thread_entry_point(void *p)
fprintf(stderr, "--breakpad Specifies that the utility should convert debug information\n"); fprintf(stderr, "--breakpad Specifies that the utility should convert debug information\n");
fprintf(stderr, " data to the textual Breakpad format.\n\n"); fprintf(stderr, " data to the textual Breakpad format.\n\n");
fprintf(stderr, "--voff2line Specifies that the utility should map virtual offset to source line.\n\n"); fprintf(stderr, "--voff2line Specifies that the utility should map a virtual offset to a\n");
fprintf(stderr, " line.\n\n");
fprintf(stderr, "--out:<path> Specifies the path to which output data should be written. If\n"); fprintf(stderr, "--out:<path> Specifies the path to which output data should be written. If\n");
fprintf(stderr, " not specified, the utility will choose a fallback. If dumping\n"); fprintf(stderr, " not specified, the utility will choose a fallback. If dumping\n");
@@ -554,10 +555,11 @@ rb_thread_entry_point(void *p)
}break; }break;
//////////////////////////// ////////////////////////////
//- rjf: RDI, Breakpad -> conversion based on inputs //- rjf: RDI, Breakpad, Debug Info Operations -> conversion based on inputs
// //
case OutputKind_RDI: case OutputKind_RDI:
case OutputKind_Breakpad: case OutputKind_Breakpad:
case OutputKind_VOff2Line:
{ {
//- rjf: no inputs => help //- rjf: no inputs => help
if(lane_idx() == 0 && cmdline->inputs.node_count == 0) switch(output_kind) if(lane_idx() == 0 && cmdline->inputs.node_count == 0) switch(output_kind)
@@ -592,6 +594,12 @@ rb_thread_entry_point(void *p)
fprintf(stderr, "All input files specified on the command line will be dumped. The following\n"); fprintf(stderr, "All input files specified on the command line will be dumped. The following\n");
fprintf(stderr, "formats are currently supported: PE, COFF, RDI, and ELF\n\n"); fprintf(stderr, "formats are currently supported: PE, COFF, RDI, and ELF\n\n");
}break; }break;
case OutputKind_VOff2Line:
{
fprintf(stderr, "ARGUMENTS\n\n");
fprintf(stderr, "--voff:<offset> Specifies the virtual offset to map to a source line.\n");
fprintf(stderr, "\n");
}break;
} }
//- rjf: unpack subset flags //- rjf: unpack subset flags
@@ -630,12 +638,24 @@ rb_thread_entry_point(void *p)
{ {
subset_flags = (RDIM_SubsetFlag_Units|RDIM_SubsetFlag_Procedures|RDIM_SubsetFlag_Scopes|RDIM_SubsetFlag_LineInfo|RDIM_SubsetFlag_InlineLineInfo); subset_flags = (RDIM_SubsetFlag_Units|RDIM_SubsetFlag_Procedures|RDIM_SubsetFlag_Scopes|RDIM_SubsetFlag_LineInfo|RDIM_SubsetFlag_InlineLineInfo);
}break; }break;
case OutputKind_VOff2Line:
{
subset_flags = (RDIM_SubsetFlag_Units|RDIM_SubsetFlag_LineInfo|RDIM_SubsetFlag_InlineLineInfo|RDIM_SubsetFlag_Procedures);
}break;
} }
//- rjf: convert inputs to RDI info //- rjf: convert inputs to RDI info
B32 convert_done = 0; B32 convert_done = 0;
RDIM_BakeParams pdb_bake_params = {0}; RDIM_BakeParams pdb_bake_params = {0};
RDIM_BakeParams dwarf_bake_params = {0}; RDIM_BakeParams dwarf_bake_params = {0};
typedef struct RDIM_BakeParamsNode RDIM_BakeParamsNode;
struct RDIM_BakeParamsNode
{
RDIM_BakeParamsNode *next;
RDIM_BakeParams v;
};
RDIM_BakeParamsNode *first_rdi_bake_params = 0;
RDIM_BakeParamsNode *last_rdi_bake_params = 0;
{ {
//- rjf: PE inputs w/ DWARF, or ELF inputs => DWARF -> RDI conversion //- rjf: PE inputs w/ DWARF, or ELF inputs => DWARF -> RDI conversion
B32 pe_w_dwarf = (input_files_from_format_table[RB_FileFormat_PE].count != 0 && B32 pe_w_dwarf = (input_files_from_format_table[RB_FileFormat_PE].count != 0 &&
@@ -758,6 +778,43 @@ rb_thread_entry_point(void *p)
} }
ProfScope("convert") pdb_bake_params = p2r_convert(arena, &convert_params); ProfScope("convert") pdb_bake_params = p2r_convert(arena, &convert_params);
} }
//- rjf: RDI inputs => RDI joining
if(input_files_from_format_table[RB_FileFormat_RDI].count > 1)
{
convert_done = 1;
log_infof("RDIs specified; joining RDIs\n");
// rjf: produce bake params for each RDI
for EachNode(n, RB_FileNode, input_files_from_format_table[RB_FileFormat_RDI].first)
{
RB_File *f = n->v;
// rjf: decompress RDI
RDI_Parsed *rdi = 0;
if(lane_idx() == 0)
{
rdi = push_array(arena, RDI_Parsed, 1);
RDI_ParseStatus rdi_status = rdi_parse(f->data.str, f->data.size, rdi);
U64 decompressed_size = rdi_decompressed_size_from_parsed(rdi);
if(decompressed_size > rdi->raw_data_size)
{
U8 *decompressed_data = push_array_no_zero(arena, U8, decompressed_size);
rdi_decompress_parsed(decompressed_data, decompressed_size, rdi);
rdi_status = rdi_parse(decompressed_data, decompressed_size, rdi);
}
}
lane_sync_u64(&rdi, 0);
// rjf: RDI -> loose
RDIM_BakeParams rdi_loose = rdim_loose_from_rdi(arena, subset_flags, rdi);
// rjf: add
RDIM_BakeParamsNode *n = push_array(arena, RDIM_BakeParamsNode, 1);
n->v = rdi_loose;
SLLQueuePush(first_rdi_bake_params, last_rdi_bake_params, n);
}
}
} }
lane_sync(); lane_sync();
@@ -768,6 +825,10 @@ rb_thread_entry_point(void *p)
bake_params = push_array(arena, RDIM_BakeParams, 1); bake_params = push_array(arena, RDIM_BakeParams, 1);
rdim_bake_params_concat_in_place(bake_params, &pdb_bake_params); rdim_bake_params_concat_in_place(bake_params, &pdb_bake_params);
rdim_bake_params_concat_in_place(bake_params, &dwarf_bake_params); rdim_bake_params_concat_in_place(bake_params, &dwarf_bake_params);
for EachNode(n, RDIM_BakeParamsNode, first_rdi_bake_params)
{
rdim_bake_params_concat_in_place(bake_params, &n->v);
}
} }
lane_sync_u64(&bake_params, 0); lane_sync_u64(&bake_params, 0);
@@ -779,24 +840,35 @@ rb_thread_entry_point(void *p)
if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PE])->path); } if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PE])->path); }
if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_ELF64])->path); } if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_ELF64])->path); }
if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_ELF32])->path); } if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_ELF32])->path); }
if(output_path__noext.size == 0) { output_path__noext = str8_chop_last_dot(rb_file_list_first(&input_files_from_format_table[RB_FileFormat_RDI])->path); }
switch(output_kind) switch(output_kind)
{ {
default:{}break; default:{}break;
case OutputKind_RDI: case OutputKind_RDI:
{ {
output_path = push_str8f(arena, "%S.rdi", output_path__noext); output_path = str8f(arena, "%S.rdi", output_path__noext);
}break; }break;
case OutputKind_Breakpad: case OutputKind_Breakpad:
{ {
output_path = push_str8f(arena, "%S.psym", output_path__noext); output_path = str8f(arena, "%S.psym", output_path__noext);
}break; }break;
} }
} }
//- rjf: special case: only a single RDI file passed? all conversion is trivially done, just
// package up RDI data as serialized section bundle, and let the rest of the paths use it.
B32 noop_conversion = 0;
if(input_files.count == 1 && rb_file_list_first(&input_files)->format == RB_FileFormat_RDI)
{
noop_conversion = 1;
convert_done = 1;
log_infof("Single RDI specified; passing through (skipping conversion)");
}
//- rjf: no viable input paths //- rjf: no viable input paths
if(!convert_done && cmdline->inputs.node_count != 0) if(!convert_done && cmdline->inputs.node_count != 0)
{ {
log_user_errorf("Could not load debug info from the specified inputs. You must provide either a valid PDB file or an executable image (PE, ELF) file with DWARF debug info."); log_user_errorf("Could not load debug info from the specified inputs. You must provide a valid PDB file, an executable image (PE, ELF) file with DWARF debug info, or RDI file(s).");
} }
//- rjf: bake //- rjf: bake
@@ -806,6 +878,41 @@ rb_thread_entry_point(void *p)
bake_results = rdim_bake(arena, bake_params); bake_results = rdim_bake(arena, bake_params);
} }
//- rjf: serialize
RDIM_SerializedSectionBundle *serialized_section_bundle = 0;
ProfScope("serialize") if(lane_idx() == 0)
{
serialized_section_bundle = push_array(arena, RDIM_SerializedSectionBundle, 1);
serialized_section_bundle[0] = rdim_serialized_section_bundle_from_bake_results(&bake_results);
}
lane_sync_u64(&serialized_section_bundle, 0);
//- rjf: special case: no-op conversion (single RDI file)
if(lane_idx() == 0 && noop_conversion)
{
RB_File *f = rb_file_list_first(&input_files);
RDI_Parsed rdi = {0};
RDI_ParseStatus rdi_status = rdi_parse(f->data.str, f->data.size, &rdi);
U64 decompressed_size = rdi_decompressed_size_from_parsed(&rdi);
if(decompressed_size > rdi.raw_data_size)
{
U8 *decompressed_data = push_array_no_zero(arena, U8, decompressed_size);
rdi_decompress_parsed(decompressed_data, decompressed_size, &rdi);
rdi_status = rdi_parse(decompressed_data, decompressed_size, &rdi);
}
for EachIndex(idx, rdi.sections_count)
{
if(idx < RDI_SectionKind_COUNT)
{
serialized_section_bundle->sections[idx].data = rdi.raw_data + rdi.sections[idx].off;
serialized_section_bundle->sections[idx].encoded_size = rdi.sections[idx].encoded_size;
serialized_section_bundle->sections[idx].unpacked_size = rdi.sections[idx].unpacked_size;
serialized_section_bundle->sections[idx].encoding = rdi.sections[idx].encoding;
}
}
}
lane_sync();
//- rjf: convert done => generate output //- rjf: convert done => generate output
if(convert_done) switch(output_kind) if(convert_done) switch(output_kind)
{ {
@@ -814,15 +921,6 @@ rb_thread_entry_point(void *p)
//- rjf: generate RDI blobs //- rjf: generate RDI blobs
case OutputKind_RDI: case OutputKind_RDI:
{ {
// rjf: serialize
RDIM_SerializedSectionBundle *serialized_section_bundle = 0;
ProfScope("serialize") if(lane_idx() == 0)
{
serialized_section_bundle = push_array(arena, RDIM_SerializedSectionBundle, 1);
serialized_section_bundle[0] = rdim_serialized_section_bundle_from_bake_results(&bake_results);
}
lane_sync_u64(&serialized_section_bundle, 0);
// rjf: compress // rjf: compress
RDIM_SerializedSectionBundle serialized_section_bundle__compressed = serialized_section_bundle[0]; RDIM_SerializedSectionBundle serialized_section_bundle__compressed = serialized_section_bundle[0];
if(cmd_line_has_flag(cmdline, str8_lit("compress"))) ProfScope("compress") if(cmd_line_has_flag(cmdline, str8_lit("compress"))) ProfScope("compress")
@@ -838,28 +936,36 @@ rb_thread_entry_point(void *p)
//- rjf: generate breakpad text //- rjf: generate breakpad text
case OutputKind_Breakpad: case OutputKind_Breakpad:
{ {
//- rjf: flatten to RDI data
String8List rdi_blobs = rdim_file_blobs_from_section_bundle(arena, serialized_section_bundle);
String8 rdi_data = str8_list_join(arena, &rdi_blobs, 0);
RDI_Parsed rdi_ = {0};
RDI_Parsed *rdi = &rdi_;
RDI_ParseStatus rdi_status = rdi_parse(rdi_data.str, rdi_data.size, rdi);
//- rjf: set up shared state //- rjf: set up shared state
typedef struct P2B_Shared P2B_Shared; typedef struct P2B_Shared P2B_Shared;
struct P2B_Shared struct P2B_Shared
{ {
String8List dump; String8List dump;
String8List *lane_chunk_file_dumps; String8List *lane_file_dumps;
String8List *lane_chunk_func_dumps; String8List *lane_func_dumps;
}; };
local_persist P2B_Shared *p2b_shared = 0; P2B_Shared *p2b_shared = 0;
if(lane_idx() == 0) if(lane_idx() == 0)
{ {
p2b_shared = push_array(arena, P2B_Shared, 1); p2b_shared = push_array(arena, P2B_Shared, 1);
p2b_shared->lane_chunk_file_dumps = push_array(arena, String8List, lane_count()*bake_params->src_files.chunk_count); p2b_shared->lane_file_dumps = push_array(arena, String8List, lane_count());
p2b_shared->lane_chunk_func_dumps = push_array(arena, String8List, lane_count()*bake_params->procedures.chunk_count); p2b_shared->lane_func_dumps = push_array(arena, String8List, lane_count());
} }
lane_sync(); lane_sync_u64(&p2b_shared, 0);
//- rjf: dump MODULE record //- rjf: dump MODULE record
if(lane_idx() == 0) if(lane_idx() == 0)
{ {
// rjf: pick name to identify module // rjf: pick name to identify module
String8 module_name_string = bake_params->top_level_info.exe_name; RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
String8 module_name_string = str8_from_rdi_string_idx(rdi, tli->exe_name_string_idx);
if(module_name_string.size == 0 && input_files.first != 0) if(module_name_string.size == 0 && input_files.first != 0)
{ {
module_name_string = input_files.first->v->path; module_name_string = input_files.first->v->path;
@@ -867,9 +973,9 @@ rb_thread_entry_point(void *p)
// rjf: pick string for unique code // rjf: pick string for unique code
String8 unique_identifier_string = {0}; String8 unique_identifier_string = {0};
if(unique_identifier_string.size == 0 && bake_params->top_level_info.exe_hash != 0) if(unique_identifier_string.size == 0 && tli->exe_hash != 0)
{ {
unique_identifier_string = str8f(arena, "%I64x", bake_params->top_level_info.exe_hash); unique_identifier_string = str8f(arena, "%I64x", tli->exe_hash);
} }
if(unique_identifier_string.size == 0) if(unique_identifier_string.size == 0)
{ {
@@ -906,86 +1012,74 @@ rb_thread_entry_point(void *p)
//- rjf: dump FILE records //- rjf: dump FILE records
ProfScope("dump FILE records") ProfScope("dump FILE records")
{ {
U64 chunk_idx = 0; U64 count = 0;
for EachNode(n, RDIM_SrcFileChunkNode, bake_params->src_files.first) RDI_SourceFile *v = rdi_table_from_name(rdi, SourceFiles, &count);
Rng1U64 range = lane_range(count);
for EachInRange(idx, range)
{ {
Rng1U64 range = lane_range(n->count); String8List *out = &p2b_shared->lane_file_dumps[lane_idx()];
for EachInRange(idx, range) Temp scratch = scratch_begin(&arena, 1);
{ String8 src_path = str8_from_rdi_path_node_idx(scratch.arena, rdi, PathStyle_Relative, v[idx].file_path_node_idx);
U64 file_idx = rdim_idx_from_src_file(&n->v[idx]); str8_list_pushf(arena, out, "FILE %I64u %S\n", idx, src_path);
String8 src_path = n->v[idx].path; scratch_end(scratch);
str8_list_pushf(arena, &p2b_shared->lane_chunk_file_dumps[lane_idx()*bake_params->src_files.chunk_count + chunk_idx], "FILE %I64u %S\n", file_idx, src_path);
}
chunk_idx += 1;
} }
} }
//- rjf: dump FUNC records //- rjf: dump FUNC records
ProfScope("dump FUNC records") ProfScope("dump FUNC records")
{ {
U64 chunk_idx = 0; U64 count = 0;
for EachNode(n, RDIM_SymbolChunkNode, bake_params->procedures.first) RDI_Procedure *v = rdi_table_from_name(rdi, Procedures, &count);
Rng1U64 range = lane_range(count);
for EachInRange(idx, range)
{ {
String8List *out = &p2b_shared->lane_chunk_func_dumps[lane_idx()*bake_params->procedures.chunk_count + chunk_idx]; // NOTE(rjf): breakpad does not support multiple voff ranges per procedure.
Rng1U64 range = lane_range(n->count); String8List *out = &p2b_shared->lane_func_dumps[lane_idx()];
for EachInRange(idx, range) RDI_Procedure *proc = &v[idx];
RDI_Scope *root_scope = rdi_element_from_name_idx(rdi, Scopes, proc->root_scope_idx);
if(root_scope->voff_range_opl > root_scope->voff_range_first)
{ {
// NOTE(rjf): breakpad does not support multiple voff ranges per procedure. // rjf: dump function record
RDIM_Symbol *proc = &n->v[idx]; RDIM_Rng1U64 voff_range =
RDIM_Scope *root_scope = proc->root_scope;
if(root_scope != 0 && root_scope->voff_ranges.first != 0)
{ {
// rjf: dump function record *rdi_element_from_name_idx(rdi, ScopeVOffData, root_scope->voff_range_first),
RDIM_Rng1U64 voff_range = root_scope->voff_ranges.first->v; *rdi_element_from_name_idx(rdi, ScopeVOffData, root_scope->voff_range_opl - 1),
str8_list_pushf(arena, out, "FUNC %I64x %I64x %I64x %S\n", voff_range.min, voff_range.max-voff_range.min, 0ull, proc->name); };
str8_list_pushf(arena, out, "FUNC %I64x %I64x %I64x %S\n", voff_range.min, voff_range.max-voff_range.min, 0ull, str8_from_rdi_string_idx(rdi, proc->name_string_idx));
// rjf: dump function lines // rjf: dump function lines
U64 unit_idx = rdi_vmap_idx_from_voff(bake_results.unit_vmap.vmap.vmap, bake_results.unit_vmap.vmap.count, voff_range.min); U64 unit_vmap_count = 0;
if(0 < unit_idx && unit_idx <= bake_results.units.units_count) RDI_VMapEntry *unit_vmap = rdi_table_from_name(rdi, UnitVMap, &unit_vmap_count);
RDI_Unit *unit = rdi_unit_from_voff(rdi, voff_range.min);
RDI_LineTable *line_table = rdi_line_table_from_unit(rdi, unit);
RDI_ParsedLineTable line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &line_info);
for(U64 voff = voff_range.min, last_voff = 0;
voff < voff_range.max && voff > last_voff;)
{
RDI_U64 line_info_idx = rdi_line_info_idx_from_voff(&line_info, voff);
if(line_info_idx < line_info.count)
{ {
U32 line_table_idx = bake_results.units.units[unit_idx].line_table_idx; RDI_Line *line = &line_info.lines[line_info_idx];
if(0 < line_table_idx && line_table_idx <= bake_results.line_tables.line_tables_count) U64 line_voff_min = line_info.voffs[line_info_idx];
U64 line_voff_opl = line_info.voffs[line_info_idx+1];
if(line->file_idx != 0)
{ {
// rjf: unpack unit line info str8_list_pushf(arena, out, "%I64x %I64x %I64u %I64u\n",
RDI_LineTable *line_table = &bake_results.line_tables.line_tables[line_table_idx]; line_voff_min,
RDI_ParsedLineTable line_info = line_voff_opl-line_voff_min,
{ (U64)line->line_num,
bake_results.line_tables.line_table_voffs + line_table->voffs_base_idx, (U64)line->file_idx);
bake_results.line_tables.line_table_lines + line_table->lines_base_idx,
0,
line_table->lines_count,
0
};
for(U64 voff = voff_range.min, last_voff = 0;
voff < voff_range.max && voff > last_voff;)
{
RDI_U64 line_info_idx = rdi_line_info_idx_from_voff(&line_info, voff);
if(line_info_idx < line_info.count)
{
RDI_Line *line = &line_info.lines[line_info_idx];
U64 line_voff_min = line_info.voffs[line_info_idx];
U64 line_voff_opl = line_info.voffs[line_info_idx+1];
if(line->file_idx != 0)
{
str8_list_pushf(arena, out, "%I64x %I64x %I64u %I64u\n",
line_voff_min,
line_voff_opl-line_voff_min,
(U64)line->line_num,
(U64)line->file_idx);
}
last_voff = voff;
voff = line_voff_opl;
}
else
{
break;
}
}
} }
last_voff = voff;
voff = line_voff_opl;
}
else
{
break;
} }
} }
} }
chunk_idx += 1;
} }
} }
@@ -993,24 +1087,74 @@ rb_thread_entry_point(void *p)
lane_sync(); lane_sync();
if(lane_idx() == 0) if(lane_idx() == 0)
{ {
for EachIndex(chunk_idx, bake_params->src_files.chunk_count) for EachIndex(ln_idx, lane_count())
{ {
for EachIndex(ln_idx, lane_count()) str8_list_concat_in_place(&p2b_shared->dump, &p2b_shared->lane_file_dumps[ln_idx]);
{
str8_list_concat_in_place(&p2b_shared->dump, &p2b_shared->lane_chunk_file_dumps[ln_idx*bake_params->src_files.chunk_count + chunk_idx]);
}
} }
for EachIndex(chunk_idx, bake_params->procedures.chunk_count) for EachIndex(ln_idx, lane_count())
{ {
for EachIndex(ln_idx, lane_count()) str8_list_concat_in_place(&p2b_shared->dump, &p2b_shared->lane_func_dumps[ln_idx]);
{
str8_list_concat_in_place(&p2b_shared->dump, &p2b_shared->lane_chunk_func_dumps[ln_idx*bake_params->procedures.chunk_count + chunk_idx]);
}
} }
} }
lane_sync(); lane_sync();
output_blobs = p2b_shared->dump; output_blobs = p2b_shared->dump;
}break; }break;
//- rjf: generate voff -> line results
case OutputKind_VOff2Line:
{
//- rjf: unpack voff arg
U64 voff = 0;
{
String8 voff_str = cmd_line_string(cmdline, str8_lit("voff"));
try_u64_from_str8_c_rules(voff_str, &voff);
log_infof("User specified \"%S\" as virtual offset; parsed as 0x%I64x", voff_str, voff);
}
//- rjf: flatten to RDI data
String8List rdi_blobs = rdim_file_blobs_from_section_bundle(arena, serialized_section_bundle);
String8 rdi_data = str8_list_join(arena, &rdi_blobs, 0);
RDI_Parsed rdi_ = {0};
RDI_Parsed *rdi = &rdi_;
RDI_ParseStatus rdi_status = rdi_parse(rdi_data.str, rdi_data.size, rdi);
//- rjf: voff -> line
RDI_Line line = rdi_line_from_voff(rdi, voff);
RDI_SourceFile *src_file = rdi_element_from_name_idx(rdi, SourceFiles, line.file_idx);
//- rjf: dump line info
{
Temp scratch = scratch_begin(0, 0);
RDI_Scope *voff_scope = rdi_scope_from_voff(rdi, voff);
for(RDI_Scope *scope = voff_scope, *null_scope = rdi_element_from_name_idx(rdi, Scopes, 0);
scope != 0 && scope != null_scope;
scope = rdi_parent_from_scope(rdi, scope))
{
RDI_InlineSite *inline_site = rdi_inline_site_from_scope(rdi, scope);
RDI_InlineSite *null_inline_site = rdi_element_from_name_idx(rdi, InlineSites, 0);
if(inline_site && inline_site != null_inline_site)
{
RDI_LineTable *inline_line_table = rdi_element_from_name_idx(rdi, LineTables, inline_site->line_table_idx);
RDI_LineTable *null_inline_line_table = rdi_element_from_name_idx(rdi, LineTables, 0);
if(inline_line_table && inline_line_table != null_inline_line_table)
{
String8 inline_name = str8_from_rdi_string_idx(rdi, inline_site->name_string_idx);
RDI_Line inline_line = rdi_line_from_line_table_voff(rdi, inline_line_table, voff);
RDI_SourceFile *inline_src_file = rdi_element_from_name_idx(rdi, SourceFiles, inline_line.file_idx);
RDI_SourceFile *null_inline_src_file = rdi_element_from_name_idx(rdi, SourceFiles, 0);
if(inline_src_file && inline_src_file != null_inline_src_file)
{
String8 path = str8_from_rdi_path_node_idx(scratch.arena, rdi, PathStyle_SystemAbsolute, src_file->file_path_node_idx);
str8_list_pushf(arena, &output_blobs, "[inlined] %S %S:%u\n", inline_name, path, inline_line.line_num);
}
}
}
}
String8 path = str8_from_rdi_path_node_idx(scratch.arena, rdi, PathStyle_SystemAbsolute, src_file->file_path_node_idx);
str8_list_pushf(arena, &output_blobs, "%S:%u\n", path, line.line_num);
scratch_end(scratch);
}
}break;
} }
}break; }break;
@@ -1280,106 +1424,6 @@ rb_thread_entry_point(void *p)
} }
} }
}break; }break;
case OutputKind_VOff2Line:
{
if(lane_idx() != 0) { break; }
if(cmdline->inputs.node_count == 0)
{
fprintf(stderr, "ARGUMENTS\n\n");
fprintf(stderr, "--voff:OFFSET Map specified virtual offset to a source line.\n");
break;
}
if(cmdline->inputs.node_count > 1)
{
fprintf(stderr, "ERROR: too many input files!\n");
break;
}
if(!cmd_line_has_argument(cmdline, str8_lit("voff"))) {
fprintf(stderr, "ERROR: missing -voff\n");
break;
}
String8 voff_str = cmd_line_string(cmdline, str8_lit("voff"));
if(voff_str.size == 0)
{
fprintf(stderr, "ERROR: missing argument for -voff\n");
break;
}
U64 voff = 0;
if(!try_u64_from_str8_c_rules(voff_str, &voff))
{
fprintf(stderr, "ERROR: invalid argument for -voff\n");
break;
}
RB_File *f = input_files.first->v;
if(f->format != RB_FileFormat_RDI)
{
fprintf(stderr, "ERROR: input file must be RDI.\n");
break;
}
RDI_Parsed rdi = {0};
RDI_ParseStatus rdi_parse_status = rdi_parse(f->data.str, f->data.size, &rdi);
if(rdi_parse_status != RDI_ParseStatus_Good)
{
fprintf(stderr, "ERROR: failed to parse RDI with code %d\n", rdi_parse_status);
break;
}
RDI_Line line = rdi_line_from_voff(&rdi, voff);
if(line.file_idx == 0 || line.line_num == 0)
{
fprintf(stderr, "ERROR: failed to find mapping for virtual offset 0x%llx.\n", voff);
break;
}
RDI_SourceFile *src_file = rdi_element_from_name_idx(&rdi, SourceFiles, line.file_idx);
if(src_file == 0)
{
fprintf(stderr, "ERROR: failed to find source file with index %u.\n", line.file_idx);
break;
}
Temp scratch = scratch_begin(0, 0);
// format inline site stack
{
RDI_Scope *voff_scope = rdi_scope_from_voff(&rdi, voff);
for(RDI_Scope *scope = voff_scope, *null_scope = rdi_element_from_name_idx(&rdi, Scopes, 0); scope != 0 && scope != null_scope; scope = rdi_parent_from_scope(&rdi, scope))
{
RDI_InlineSite *inline_site = rdi_inline_site_from_scope(&rdi, scope);
RDI_InlineSite *null_inline_site = rdi_element_from_name_idx(&rdi, InlineSites, 0);
if(inline_site && inline_site != null_inline_site)
{
RDI_LineTable *inline_line_table = rdi_element_from_name_idx(&rdi, LineTables, inline_site->line_table_idx);
RDI_LineTable *null_inline_line_table = rdi_element_from_name_idx(&rdi, LineTables, 0);
if(inline_line_table && inline_line_table != null_inline_line_table)
{
String8 inline_name = str8_from_rdi_string_idx(&rdi, inline_site->name_string_idx);
RDI_Line inline_line = rdi_line_from_line_table_voff(&rdi, inline_line_table, voff);
RDI_SourceFile *inline_src_file = rdi_element_from_name_idx(&rdi, SourceFiles, inline_line.file_idx);
RDI_SourceFile *null_inline_src_file = rdi_element_from_name_idx(&rdi, SourceFiles, 0);
if(inline_src_file && inline_src_file != null_inline_src_file)
{
String8 path = str8_from_rdi_path_node_idx(scratch.arena, &rdi, PathStyle_SystemAbsolute, src_file->file_path_node_idx);
fprintf(stdout, "[inlined] %.*s %.*s:%u\n", str8_varg(inline_name), str8_varg(path), inline_line.line_num);
}
}
}
}
}
String8 path = str8_from_rdi_path_node_idx(scratch.arena, &rdi, PathStyle_SystemAbsolute, src_file->file_path_node_idx);
fprintf(stdout, "%.*s:%u\n", str8_varg(path), line.line_num);
scratch_end(scratch);
}break;
} }
////////////////////////////// //////////////////////////////
-1
View File
@@ -1208,7 +1208,6 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params)
lane_sync_u64(&units_first_inline_site_line_tables, 0); lane_sync_u64(&units_first_inline_site_line_tables, 0);
RDIM_Unit *units = all_units_ptr->first ? all_units_ptr->first->v : 0; RDIM_Unit *units = all_units_ptr->first ? all_units_ptr->first->v : 0;
U64 units_count = all_units_ptr->first ? all_units_ptr->first->count : 0; U64 units_count = all_units_ptr->first ? all_units_ptr->first->count : 0;
Assert(units_count == comp_units->count);
//- rjf: do per-lane work //- rjf: do per-lane work
if(params->subset_flags & (RDIM_SubsetFlag_Units| if(params->subset_flags & (RDIM_SubsetFlag_Units|
+230
View File
@@ -46,6 +46,236 @@ rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_Binar
return top_level_info; return top_level_info;
} }
internal RDIM_BakeParams
rdim_loose_from_rdi(Arena *arena, RDIM_SubsetFlags subset_flags, RDI_Parsed *rdi)
{
//- rjf: setup bake params
RDIM_BakeParams *bp = 0;
if(lane_idx() == 0)
{
bp = push_array(arena, RDIM_BakeParams, 1);
bp->subset_flags = subset_flags;
}
lane_sync_u64(&bp, 0);
//- rjf: convert top level info
if(lane_idx() == 0)
{
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
bp->top_level_info.arch = tli->arch;
bp->top_level_info.exe_name.str = rdi_string_from_idx(rdi, tli->exe_name_string_idx, &bp->top_level_info.exe_name.size);
bp->top_level_info.exe_hash = tli->exe_hash;
bp->top_level_info.voff_max = tli->voff_max;
bp->top_level_info.guid = tli->guid;
bp->top_level_info.producer_name.str = rdi_string_from_idx(rdi, tli->producer_name_string_idx, &bp->top_level_info.producer_name.size);
}
lane_sync();
//- rjf: convert binary sections
if(lane_idx() == 0)
{
U64 count = 0;
RDI_BinarySection *v = rdi_table_from_name(rdi, BinarySections, &count);
for EachIndex(idx, count)
{
RDIM_BinarySection *bsec = rdim_binary_section_list_push(arena, &bp->binary_sections);
bsec->name.str = rdi_string_from_idx(rdi, v[idx].name_string_idx, &bsec->name.size);
bsec->flags = v[idx].flags;
bsec->voff_first = v[idx].voff_first;
bsec->voff_opl = v[idx].voff_opl;
bsec->foff_first = v[idx].foff_first;
bsec->foff_opl = v[idx].foff_opl;
}
}
lane_sync();
//- rjf: bucket voff ranges by unit idx
RDIM_Rng1U64ChunkList *unit_ranges = 0;
if(lane_idx() == 0)
{
U64 units_count = 0;
rdi_table_from_name(rdi, Units, &units_count);
U64 unit_vmap_count = 0;
RDI_VMapEntry *unit_vmap = rdi_table_from_name(rdi, UnitVMap, &unit_vmap_count);
unit_ranges = push_array(arena, RDIM_Rng1U64ChunkList, units_count);
if(unit_vmap_count > 0)
{
for EachIndex(idx, unit_vmap_count-1)
{
RDIM_Rng1U64 rng = {unit_vmap[idx].voff, unit_vmap[idx+1].voff};
rdim_rng1u64_chunk_list_push(arena, &unit_ranges[unit_vmap[idx].idx], 256, rng);
}
}
}
lane_sync_u64(&unit_ranges, 0);
//- rjf: convert src files
RDIM_SrcFileChunkList *src_files = 0;
RDIM_SrcFile **src_file_from_idx_table = 0;
{
U64 src_file_count = 0;
RDI_SourceFile *src_file_v = rdi_table_from_name(rdi, SourceFiles, &src_file_count);
RDIM_SrcFileChunkList *lane_srcfiles = 0;
if(lane_idx() == 0)
{
src_files = push_array(arena, RDIM_SrcFileChunkList, 1);
src_file_from_idx_table = push_array(arena, RDIM_SrcFile *, src_file_count);
lane_srcfiles = push_array(arena, RDIM_SrcFileChunkList, lane_count());
}
lane_sync_u64(&lane_srcfiles, 0);
{
Rng1U64 range = lane_range(src_file_count);
for EachInRange(idx, range)
{
RDI_SourceFile *src = &src_file_v[idx];
RDIM_SrcFile *dst = rdim_src_file_chunk_list_push(arena, &lane_srcfiles[lane_idx()], dim_1u64(range));
// rjf: get checksum
String8 checksum = {0};
switch(src->checksum_kind)
{
default:{}break;
case RDI_ChecksumKind_MD5: {checksum = str8(rdi_element_from_name_idx(rdi, MD5Checksums, src->checksum_idx)->u8, sizeof(RDI_MD5));}break;
case RDI_ChecksumKind_SHA1: {checksum = str8(rdi_element_from_name_idx(rdi, SHA1Checksums, src->checksum_idx)->u8, sizeof(RDI_SHA1));}break;
case RDI_ChecksumKind_SHA256: {checksum = str8(rdi_element_from_name_idx(rdi, SHA256Checksums, src->checksum_idx)->u8, sizeof(RDI_SHA256));}break;
case RDI_ChecksumKind_Timestamp:{checksum = str8((U8 *)rdi_element_from_name_idx(rdi, Timestamps, src->checksum_idx), sizeof(RDI_U64));}break;
}
// rjf: fill basics
dst->path = str8_from_rdi_path_node_idx(arena, rdi, PathStyle_Relative, src->file_path_node_idx);
dst->checksum_kind = src->checksum_kind;
dst->checksum = checksum;
src_file_from_idx_table[idx] = dst;
}
}
lane_sync();
if(lane_idx() == 0)
{
for EachIndex(lidx, lane_count())
{
rdim_src_file_chunk_list_concat_in_place(src_files, &lane_srcfiles[lidx]);
}
}
}
lane_sync();
//- rjf: convert units
RDIM_UnitChunkList *units = 0;
RDIM_LineTableChunkList *line_tables = 0;
{
RDIM_UnitChunkList *lane_units = 0;
RDIM_LineTableChunkList *lane_linetables = 0;
if(lane_idx() == 0)
{
lane_units = push_array(arena, RDIM_UnitChunkList, lane_count());
lane_linetables = push_array(arena, RDIM_LineTableChunkList, lane_count());
units = push_array(arena, RDIM_UnitChunkList, 1);
line_tables = push_array(arena, RDIM_LineTableChunkList, 1);
}
lane_sync_u64(&lane_units, 0);
lane_sync_u64(&lane_linetables, 0);
lane_sync_u64(&units, 0);
lane_sync_u64(&line_tables, 0);
U64 count = 0;
RDI_Unit *v = rdi_table_from_name(rdi, Units, &count);
U64 unit_take_idx_ = 0;
U64 *unit_take_idx_ptr = &unit_take_idx_;
lane_sync_u64(&unit_take_idx_ptr, 0);
for(;;)
{
U64 unit_idx = ins_atomic_u64_inc_eval(unit_take_idx_ptr)-1;
if(unit_idx >= count)
{
break;
}
RDI_Unit *src = &v[unit_idx];
// rjf: convert flat top parts
RDIM_Unit *dst = rdim_unit_chunk_list_push(arena, &lane_units[lane_idx()], 64);
dst->unit_name = str8_from_rdi_string_idx(rdi, src->unit_name_string_idx);
dst->compiler_name = str8_from_rdi_string_idx(rdi, src->compiler_name_string_idx);
dst->source_file = str8_from_rdi_path_node_idx(arena, rdi, PathStyle_Relative, src->source_file_path_node);
dst->object_file = str8_from_rdi_path_node_idx(arena, rdi, PathStyle_Relative, src->object_file_path_node);
dst->archive_file = str8_from_rdi_path_node_idx(arena, rdi, PathStyle_Relative, src->archive_file_path_node);
dst->build_path = str8_from_rdi_path_node_idx(arena, rdi, PathStyle_Relative, src->build_path_node);
dst->language = src->language;
dst->voff_ranges = unit_ranges[unit_idx];
// rjf: convert line table
dst->line_table = rdim_line_table_chunk_list_push(arena, &lane_linetables[lane_idx()], 64);
{
RDI_LineTable *src_lt_unparsed = rdi_element_from_name_idx(rdi, LineTables, src->line_table_idx);
RDI_ParsedLineTable src_lt = {0};
rdi_parsed_from_line_table(rdi, src_lt_unparsed, &src_lt);
RDIM_LineTable *dst_lt = dst->line_table;
{
RDIM_SrcFile *seq_src_file = 0;
U64 seq_start_idx = 0;
for(U64 line_idx = 0; line_idx <= src_lt.count; line_idx += 1)
{
// rjf: get next src file
RDIM_SrcFile *next_src_file = 0;
if(line_idx < src_lt.count)
{
next_src_file = src_file_from_idx_table[src_lt.lines[line_idx].file_idx];
}
// rjf: next file doesn't match current sequence? -> complete sequence
if(next_src_file != seq_src_file && seq_src_file != 0)
{
U64 seq_line_count = (line_idx - seq_start_idx);
U32 *seq_line_nums = push_array(arena, U32, seq_line_count);
for(U64 line_idx_2 = seq_start_idx; line_idx_2 < line_idx; line_idx_2 += 1)
{
seq_line_nums[line_idx_2] = src_lt.lines[line_idx_2].line_num;
}
rdim_line_table_push_sequence(arena, &lane_linetables[lane_idx()], dst_lt, seq_src_file,
src_lt.voffs + seq_start_idx,
seq_line_nums,
0, // TODO(rjf): column support
seq_line_count);
}
// rjf: start next sequence
if(next_src_file != seq_src_file)
{
seq_src_file = next_src_file;
seq_start_idx = line_idx;
}
}
}
}
}
lane_sync();
if(lane_idx() == 0)
{
for EachIndex(l_idx, lane_count())
{
rdim_unit_chunk_list_concat_in_place(units, &lane_units[l_idx]);
}
for EachIndex(l_idx, lane_count())
{
rdim_line_table_chunk_list_concat_in_place(line_tables, &lane_linetables[l_idx]);
}
}
}
lane_sync();
// TODO(rjf): convert types
// TODO(rjf): convert udts
// TODO(rjf): convert locations
// TODO(rjf): convert global variables
// TODO(rjf): convert thread variables
// TODO(rjf): convert constants
// TODO(rjf): convert procedures
// TODO(rjf): convert scopes
// TODO(rjf): convert inline sites
// TODO(rjf): package & return
RDIM_BakeParams result = bp[0];
return result;
}
internal RDIM_BakeResults internal RDIM_BakeResults
rdim_bake(Arena *arena, RDIM_BakeParams *params) rdim_bake(Arena *arena, RDIM_BakeParams *params)
{ {
+1
View File
@@ -162,6 +162,7 @@ global RDIM_Shared *rdim_shared = 0;
internal RDIM_DataModel rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch); internal RDIM_DataModel rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch);
internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections); internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections);
internal RDIM_BakeParams rdim_loose_from_rdi(Arena *arena, RDIM_SubsetFlags subset_flags, RDI_Parsed *rdi);
internal RDIM_BakeResults rdim_bake(Arena *arena, RDIM_BakeParams *params); internal RDIM_BakeResults rdim_bake(Arena *arena, RDIM_BakeParams *params);
internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in);
+1 -1
View File
@@ -115,7 +115,7 @@ typedef struct RS_MAX_BUBBLE_BUF { char b[RS_SMALL_FLIP_TO_INSERTION_GT_SIZE]; }
#if _MSC_VER #if _MSC_VER
# define radsort_break_ __debugbreak() # define radsort_break_ __debugbreak()
#else #else
# define radsort_break_ ___builtin_trap() # define radsort_break_ __builtin_trap()
#endif #endif
#define radsort( start, len, is_before_func ) \ #define radsort( start, len, is_before_func ) \
+1 -1
View File
@@ -750,7 +750,7 @@ cl = lg; \
{ {
stbsp__flush_cb(); stbsp__flush_cb();
Rng1U64 range = va_arg(va, Rng1U64); Rng1U64 range = va_arg(va, Rng1U64);
bf += STB_SPRINTF_DECORATE(sprintf)(bf, "[0x%llx, 0x%llx)", range.min, range.max); bf += STB_SPRINTF_DECORATE(sprintf)(bf, "[0x%llx, 0x%llx)", (unsigned long long)range.min, (unsigned long long)range.max);
}break; }break;
// //
+22 -22
View File
@@ -40,39 +40,39 @@ extern U64 g_torture_test_count;
extern T_Test g_torture_tests[0xffffff]; extern T_Test g_torture_tests[0xffffff];
#define T_AddTest(name, l, ...) \ #define T_AddTest(name, l, ...) \
T_RunResult t_##name(void); \ T_RunResult t_##name(void); \
__VA_ARGS__ void t_add_test_##name(void) \ __VA_ARGS__ void t_add_test_##name(void) \
{ \ { \
g_torture_tests[g_torture_test_count].group = T_Group; \ g_torture_tests[g_torture_test_count].group = T_Group; \
g_torture_tests[g_torture_test_count].label = Stringify(name); \ g_torture_tests[g_torture_test_count].label = Stringify(name); \
g_torture_tests[g_torture_test_count].r = &t_##name; \ g_torture_tests[g_torture_test_count].r = &t_##name; \
g_torture_tests[g_torture_test_count].decl_line = l; \ g_torture_tests[g_torture_test_count].decl_line = l; \
g_torture_test_count += 1; \ g_torture_test_count += 1; \
} }
#if COMPILER_MSVC #if COMPILER_MSVC
#pragma section(".CRT$XCU", read) #pragma section(".CRT$XCU", read)
# define T_BeginTest_(name) \ # define T_BeginTest_(name) \
T_AddTest(name, __LINE__) \ T_AddTest(name, __LINE__) \
__declspec(allocate(".CRT$XCU")) void(*r_##name)(void) = t_add_test_##name; \ __declspec(allocate(".CRT$XCU")) void(*r_##name)(void) = t_add_test_##name; \
__pragma(comment(linker, "/include:" Stringify(r_##name))) __pragma(comment(linker, "/include:" Stringify(r_##name)))
#else #else
# define T_BeginTest_(name) \ # define T_BeginTest_(name) \
T_AddTest(name, __LINE__, __attribute__((constructor))) T_AddTest(name, __LINE__, __attribute__((constructor)))
#endif #endif
#define T_BeginTest(name) \ #define T_BeginTest(name) \
T_BeginTest_(name) \ T_BeginTest_(name) \
T_RunResult t_##name(void) { \ T_RunResult t_##name(void) { \
Temp scratch = scratch_begin(0,0); \ Temp scratch = scratch_begin(0,0); \
T_RunResult result = { .status = T_RunStatus_Fail }; T_RunResult result = { .status = T_RunStatus_Fail };
#define T_EndTest \ #define T_EndTest \
result.status = T_RunStatus_Pass; \ result.status = T_RunStatus_Pass; \
exit__:; \ exit__:; \
scratch_end(scratch); \ scratch_end(scratch); \
return result; \ return result; \
} }
#define T_Ok(c) do { if (!(c)) { result.fail_file = __FILE__; result.fail_line = __LINE__; result.fail_cond = Stringify(c); goto exit__; } } while(0) #define T_Ok(c) do { if (!(c)) { result.fail_file = __FILE__; result.fail_line = __LINE__; result.fail_cond = Stringify(c); goto exit__; } } while(0)
#define T_MatchLinef(out, ...) T_Ok(t_match_linef(out, __VA_ARGS__)) #define T_MatchLinef(out, ...) T_Ok(t_match_linef(out, __VA_ARGS__))
+204 -204
View File
@@ -65,76 +65,76 @@ T_BeginTest(d2r_types)
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test");
#define DeclBaseType(tt, n, e, s) \ #define DeclBaseType(tt, n, e, s) \
DW_WriterTag *tt = dw_writer_tag_begin(writer, DW_TagKind_BaseType); \ DW_WriterTag *tt = dw_writer_tag_begin(writer, DW_TagKind_BaseType); \
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, s); \ dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, s); \
dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_##e); \ dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_##e); \
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \ dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DeclBaseType(char_type, "char", SignedChar, 1); DeclBaseType(char_type, "char", SignedChar, 1);
DeclBaseType(unsigned_char_type, "unsigned char", UnsignedChar, 1); DeclBaseType(unsigned_char_type, "unsigned char", UnsignedChar, 1);
DeclBaseType(char8_type, "char8_t", Utf, 1); DeclBaseType(char8_type, "char8_t", Utf, 1);
DeclBaseType(char16_type, "char16_t", Utf, 2); DeclBaseType(char16_type, "char16_t", Utf, 2);
DeclBaseType(char32_type, "char32_t", Utf, 4); DeclBaseType(char32_type, "char32_t", Utf, 4);
DeclBaseType(wchar_type, "wchar_t", Signed, 4); DeclBaseType(wchar_type, "wchar_t", Signed, 4);
DeclBaseType(bool_type, "_Bool", Boolean, 1); DeclBaseType(bool_type, "_Bool", Boolean, 1);
DeclBaseType(short_type, "short", Signed, 2); DeclBaseType(short_type, "short", Signed, 2);
DeclBaseType(unsigned_short_type, "unsigned short", Unsigned, 2); DeclBaseType(unsigned_short_type, "unsigned short", Unsigned, 2);
DeclBaseType(short_unsigned_int_type, "short unsigned int", Unsigned, 2); DeclBaseType(short_unsigned_int_type, "short unsigned int", Unsigned, 2);
DeclBaseType(short_int_type, "short int", Signed, 2); DeclBaseType(short_int_type, "short int", Signed, 2);
DeclBaseType(unsigned_int_type, "unsigned int", Unsigned, 4); DeclBaseType(unsigned_int_type, "unsigned int", Unsigned, 4);
DeclBaseType(int_type, "int", Signed, 4); DeclBaseType(int_type, "int", Signed, 4);
DeclBaseType(long_int_type, "long int", Signed, 8); DeclBaseType(long_int_type, "long int", Signed, 8);
DeclBaseType(long_unsigned_int_type, "long unsigned int", Unsigned, 8); DeclBaseType(long_unsigned_int_type, "long unsigned int", Unsigned, 8);
DeclBaseType(long_long_int_type, "long long int", Signed, 8); DeclBaseType(long_long_int_type, "long long int", Signed, 8);
DeclBaseType(long_long_unsigned_int, "long long unsigned int", Unsigned, 8); DeclBaseType(long_long_unsigned_int, "long long unsigned int", Unsigned, 8);
DeclBaseType(float_type, "float", Float, 4); DeclBaseType(float_type, "float", Float, 4);
DeclBaseType(double_type, "double", Float, 8); DeclBaseType(double_type, "double", Float, 8);
DeclBaseType(long_double_type, "long double", Float, 16); DeclBaseType(long_double_type, "long double", Float, 16);
DeclBaseType(int128_type, "__int128", Signed, 16); DeclBaseType(int128_type, "__int128", Signed, 16);
DeclBaseType(uint128_type, "__int128 unsigned", Unsigned, 16); DeclBaseType(uint128_type, "__int128 unsigned", Unsigned, 16);
DeclBaseType(float16_type, "_Float16", Float, 2); DeclBaseType(float16_type, "_Float16", Float, 2);
DeclBaseType(bfloat16_type, "__bf16", Float, 2); DeclBaseType(bfloat16_type, "__bf16", Float, 2);
DeclBaseType(float80_type, "__float80", Float, 16); DeclBaseType(float80_type, "__float80", Float, 16);
DeclBaseType(float128_type, "_float128", Float, 16); DeclBaseType(float128_type, "_float128", Float, 16);
DeclBaseType(complex_float_type, "complex float", ComplexFloat, 8); DeclBaseType(complex_float_type, "complex float", ComplexFloat, 8);
DeclBaseType(complex_doulbe_type, "complex double", ComplexFloat, 16); DeclBaseType(complex_doulbe_type, "complex double", ComplexFloat, 16);
DeclBaseType(complex_long_double_type, "complex long double", ComplexFloat, 32); DeclBaseType(complex_long_double_type, "complex long double", ComplexFloat, 32);
DeclBaseType(decimal32_type, "_Decimal32", DecimalFloat, 4); DeclBaseType(decimal32_type, "_Decimal32", DecimalFloat, 4);
DeclBaseType(decimal64_type, "_Decimal64", DecimalFloat, 8); DeclBaseType(decimal64_type, "_Decimal64", DecimalFloat, 8);
DeclBaseType(decimal128_type, "_Decimal128", DecimalFloat, 16); DeclBaseType(decimal128_type, "_Decimal128", DecimalFloat, 16);
#undef DeclBaseType #undef DeclBaseType
#define DeclStdint(n, a) \ #define DeclStdint(n, a) \
do { \ do { \
dw_writer_tag_begin(writer, DW_TagKind_Typedef); \ dw_writer_tag_begin(writer, DW_TagKind_Typedef); \
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \ dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, a); \ dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, a); \
dw_writer_tag_end(writer); \ dw_writer_tag_end(writer); \
} while (0) } while (0)
DeclStdint("uint8_t", unsigned_char_type); DeclStdint("uint8_t", unsigned_char_type);
DeclStdint("uint16_t", unsigned_short_type); DeclStdint("uint16_t", unsigned_short_type);
DeclStdint("uint32_t", unsigned_int_type); DeclStdint("uint32_t", unsigned_int_type);
DeclStdint("uint64_t", long_unsigned_int_type); DeclStdint("uint64_t", long_unsigned_int_type);
DeclStdint("int8_t", char_type); DeclStdint("int8_t", char_type);
DeclStdint("int16_t", short_type); DeclStdint("int16_t", short_type);
DeclStdint("int32_t", int_type); DeclStdint("int32_t", int_type);
DeclStdint("int64_t", long_int_type); DeclStdint("int64_t", long_int_type);
#undef DeclStdInt #undef DeclStdInt
// TODO: @native_vector_support // TODO: @native_vector_support
// //
// typedef int __attribute__((vector_size(32))) int256 // typedef int __attribute__((vector_size(32))) int256
// typedef unsigned int __attribute__((vector_size(32))) uint256 // typedef unsigned int __attribute__((vector_size(32))) uint256
// typedef int __attribute__((vector_size(64))) int512 // typedef int __attribute__((vector_size(64))) int512
// typedef unsigned int __attribute__((vector_size(64))) uint512 // typedef unsigned int __attribute__((vector_size(64))) uint512
// //
#if 0 #if 0
dw_writer_tag_begin(writer, DW_TagKind_ArrayType); dw_writer_tag_begin(writer, DW_TagKind_ArrayType);
dw_writer_push_attrib_flag(writer, DW_AttribKind_GNU_Vector, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_GNU_Vector, 1);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, int_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, int_type);
dw_writer_tag_begin(writer, DW_TagKind_SubrangeType); dw_writer_tag_begin(writer, DW_TagKind_SubrangeType);
dw_writer_push_attrib_uint(writer, DW_AttribKind_UpperBound, 15); dw_writer_push_attrib_uint(writer, DW_AttribKind_UpperBound, 15);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
#endif #endif
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
@@ -148,19 +148,19 @@ T_BeginTest(d2r_types)
rdi_parsed_from_name_map(rdi, types_nm, &types_map); rdi_parsed_from_name_map(rdi, types_nm, &types_map);
#define TestBuiltinType(n, bs, r) \ #define TestBuiltinType(n, bs, r) \
do { \ do { \
RDI_TypeNode *alias = d2rt_type_from_name(rdi, &types_map, n); \ RDI_TypeNode *alias = d2rt_type_from_name(rdi, &types_map, n); \
T_Ok(alias); \ T_Ok(alias); \
T_Ok(alias->kind == RDI_TypeKind_Alias); \ T_Ok(alias->kind == RDI_TypeKind_Alias); \
T_Ok(alias->flags == 0); \ T_Ok(alias->flags == 0); \
T_Ok(alias->byte_size == bs); \ T_Ok(alias->byte_size == bs); \
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, alias->user_defined.direct_type_idx); \ RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, alias->user_defined.direct_type_idx); \
T_Ok(type); \ T_Ok(type); \
T_Ok(type->kind == RDI_TypeKind_##r); \ T_Ok(type->kind == RDI_TypeKind_##r); \
T_Ok(type->flags == 0); \ T_Ok(type->flags == 0); \
T_Ok(type->byte_size == alias->byte_size); \ T_Ok(type->byte_size == alias->byte_size); \
T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(Stringify(r)), 0)); \ T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(Stringify(r)), 0)); \
} while (0) } while (0)
TestBuiltinType("char", 1, Char8); TestBuiltinType("char", 1, Char8);
TestBuiltinType("char8_t", 1, UChar8); TestBuiltinType("char8_t", 1, UChar8);
TestBuiltinType("char16_t", 2, UChar16); TestBuiltinType("char16_t", 2, UChar16);
@@ -195,19 +195,19 @@ T_BeginTest(d2r_types)
#undef TestBuiltinType #undef TestBuiltinType
#define TestStdint(n, s, t) \ #define TestStdint(n, s, t) \
do { \ do { \
RDI_TypeNode *td = d2rt_type_from_name(rdi, &types_map, n); \ RDI_TypeNode *td = d2rt_type_from_name(rdi, &types_map, n); \
T_Ok(td); \ T_Ok(td); \
T_Ok(td->kind == RDI_TypeKind_Alias); \ T_Ok(td->kind == RDI_TypeKind_Alias); \
T_Ok(td->flags == 0); \ T_Ok(td->flags == 0); \
T_Ok(td->byte_size == s); \ T_Ok(td->byte_size == s); \
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, td->user_defined.direct_type_idx); \ RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, td->user_defined.direct_type_idx); \
T_Ok(type); \ T_Ok(type); \
T_Ok(type->kind == RDI_TypeKind_Alias); \ T_Ok(type->kind == RDI_TypeKind_Alias); \
T_Ok(type->flags == 0); \ T_Ok(type->flags == 0); \
T_Ok(type->byte_size = td->byte_size); \ T_Ok(type->byte_size = td->byte_size); \
T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(t), 0)); \ T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(t), 0)); \
} while (0) } while (0)
TestStdint("uint8_t", 1, "unsigned char"); TestStdint("uint8_t", 1, "unsigned char");
TestStdint("uint16_t", 2, "unsigned short"); TestStdint("uint16_t", 2, "unsigned short");
TestStdint("uint32_t", 4, "unsigned int"); TestStdint("uint32_t", 4, "unsigned int");
@@ -260,12 +260,12 @@ T_BeginTest(d2r_line_table)
exe_base + voff); exe_base + voff);
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir); dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, exe_base); dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, exe_base);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, exe_base + voff); dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, exe_base + voff);
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0); dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
d2r_rdi_from_dwarf_writer(scratch.arena, writer); d2r_rdi_from_dwarf_writer(scratch.arena, writer);
@@ -295,10 +295,10 @@ T_BeginTest(d2r_checksums)
comp_file->time_stamp = 123; // convert must pick MD5 checksum over time stamp comp_file->time_stamp = 123; // convert must pick MD5 checksum over time stamp
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, str8_chop_last_slash(comp_file->path)); dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, str8_chop_last_slash(comp_file->path));
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_skip_last_slash(comp_file->path)); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_skip_last_slash(comp_file->path));
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0); dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer); RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
@@ -306,12 +306,12 @@ T_BeginTest(d2r_checksums)
RDI_MD5 *checksums = rdi_table_from_name(rdi, MD5Checksums, &checksum_count); RDI_MD5 *checksums = rdi_table_from_name(rdi, MD5Checksums, &checksum_count);
T_Ok(checksum_count == writer->line.file_count + 1); T_Ok(checksum_count == writer->line.file_count + 1);
RDI_SourceFile *foo_src_file = rdi_source_file_from_normal_path_cstr(rdi, foo_file->path.cstr); RDI_SourceFile *foo_src_file = rdi_source_file_from_normal_path_cstr(rdi, (char *)foo_file->path.str);
T_Ok(foo_src_file); T_Ok(foo_src_file);
T_Ok(foo_src_file->checksum_kind == RDI_ChecksumKind_MD5); T_Ok(foo_src_file->checksum_kind == RDI_ChecksumKind_MD5);
T_Ok(MemoryMatch(&foo_file->md5, &checksums[foo_src_file->checksum_idx], sizeof(U128))); T_Ok(MemoryMatch(&foo_file->md5, &checksums[foo_src_file->checksum_idx], sizeof(U128)));
RDI_SourceFile *comp_src_file = rdi_source_file_from_normal_path_cstr(rdi, comp_file->path.cstr); RDI_SourceFile *comp_src_file = rdi_source_file_from_normal_path_cstr(rdi, (char *)comp_file->path.str);
T_Ok(comp_src_file); T_Ok(comp_src_file);
T_Ok(comp_src_file->checksum_kind == RDI_ChecksumKind_MD5); T_Ok(comp_src_file->checksum_kind == RDI_ChecksumKind_MD5);
T_Ok(MemoryMatch(&comp_file->md5, &checksums[comp_src_file->checksum_idx], sizeof(U128))); T_Ok(MemoryMatch(&comp_file->md5, &checksums[comp_src_file->checksum_idx], sizeof(U128)));
@@ -334,106 +334,106 @@ T_BeginTest(d2r_subprogram)
String8 subprogram_name = str8_lit("foobar"); String8 subprogram_name = str8_lit("foobar");
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string (writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string (writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, image_lo); dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, image_lo);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, image_hi); dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, image_hi);
DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType); DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
dw_writer_push_attrib_sint (writer, DW_AttribKind_ByteSize, 1); dw_writer_push_attrib_sint (writer, DW_AttribKind_ByteSize, 1);
dw_writer_push_attrib_sint (writer, DW_AttribKind_Encoding, DW_ATE_SignedChar); dw_writer_push_attrib_sint (writer, DW_AttribKind_Encoding, DW_ATE_SignedChar);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char");
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DW_WriterTag *char_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType); DW_WriterTag *char_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType);
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 8); dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 8);
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, char_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, char_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DW_WriterTag *int_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType); DW_WriterTag *int_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
dw_writer_push_attrib_sint (writer, DW_AttribKind_ByteSize, 4); dw_writer_push_attrib_sint (writer, DW_AttribKind_ByteSize, 4);
dw_writer_push_attrib_sint (writer, DW_AttribKind_Encoding, DW_ATE_Signed); dw_writer_push_attrib_sint (writer, DW_AttribKind_Encoding, DW_ATE_Signed);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "int"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "int");
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DW_WriterTag *int_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType); DW_WriterTag *int_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType);
dw_writer_push_attrib_uint(writer, DW_AttribKind_ByteSize, 8); dw_writer_push_attrib_uint(writer, DW_AttribKind_ByteSize, 8);
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin(writer, DW_TagKind_SubProgram); dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_enum (writer, DW_AttribKind_Accessibility, DW_AccessKind_Private); dw_writer_push_attrib_enum (writer, DW_AttribKind_Accessibility, DW_AccessKind_Private);
dw_writer_push_attrib_enum (writer, DW_AttribKind_AddressClass, DW_AddrClassKind_None); dw_writer_push_attrib_enum (writer, DW_AttribKind_AddressClass, DW_AddrClassKind_None);
dw_writer_push_attrib_uint (writer, DW_AttribKind_Alignment, 32); dw_writer_push_attrib_uint (writer, DW_AttribKind_Alignment, 32);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Artificial, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Artificial, 1);
dw_writer_push_attrib_enum (writer, DW_AttribKind_CallingConvention, DW_CallingConventionKind_Program); dw_writer_push_attrib_enum (writer, DW_AttribKind_CallingConvention, DW_CallingConventionKind_Program);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Deleted, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Deleted, 1);
dw_writer_push_attrib_address(writer, DW_AttribKind_EntryPc, subprogram_entry_addr); dw_writer_push_attrib_address(writer, DW_AttribKind_EntryPc, subprogram_entry_addr);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Explicit, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Explicit, 1);
dw_writer_push_attrib_flag (writer, DW_AttribKind_External, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_External, 1);
dw_writer_push_attrib_exprv (writer, DW_AttribKind_FrameBase, DW_ExprEnc_Op(Reg7)); dw_writer_push_attrib_exprv (writer, DW_AttribKind_FrameBase, DW_ExprEnc_Op(Reg7));
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, subprogram_hi); dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, subprogram_hi);
dw_writer_push_attrib_enum (writer, DW_AttribKind_Inline, DW_Inl_DeclaredNotInlined); dw_writer_push_attrib_enum (writer, DW_AttribKind_Inline, DW_Inl_DeclaredNotInlined);
dw_writer_push_attrib_string (writer, DW_AttribKind_LinkageName, subprogram_link_name); dw_writer_push_attrib_string (writer, DW_AttribKind_LinkageName, subprogram_link_name);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, subprogram_lo); dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, subprogram_lo);
dw_writer_push_attrib_flag (writer, DW_AttribKind_MainSubProgram, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_MainSubProgram, 1);
dw_writer_push_attrib_string (writer, DW_AttribKind_Name, subprogram_name); dw_writer_push_attrib_string (writer, DW_AttribKind_Name, subprogram_name);
dw_writer_push_attrib_flag (writer, DW_AttribKind_NoReturn, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_NoReturn, 1);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Prototyped, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Prototyped, 1);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Pure, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Pure, 1);
dw_writer_push_attrib_flag (writer, DW_AttribKind_Recursive, 1); dw_writer_push_attrib_flag (writer, DW_AttribKind_Recursive, 1);
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_type);
dw_writer_push_attrib_enum (writer, DW_AttribKind_Visibility, DW_Vis_Local); dw_writer_push_attrib_enum (writer, DW_AttribKind_Visibility, DW_Vis_Local);
// TODO: DW_AttribKind_ObjectPointer // TODO: DW_AttribKind_ObjectPointer
// TODO: DW_AttribKind_Ranges // TODO: DW_AttribKind_Ranges
// TODO: DW_AttribKind_StartScope // TODO: DW_AttribKind_StartScope
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter); dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "a"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "a");
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type);
dw_writer_push_attrib_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg2)); // rcx dw_writer_push_attrib_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg2)); // rcx
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter); dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "b"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "b");
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, char_ptr_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, char_ptr_type);
dw_writer_push_attrib_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg5)); // rdi dw_writer_push_attrib_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg5)); // rdi
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin(writer, DW_TagKind_UnspecifiedParameters); dw_writer_tag_begin(writer, DW_TagKind_UnspecifiedParameters);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
DW_WriterTag *my_struct_type = dw_writer_tag_reserve(writer, DW_TagKind_StructureType); DW_WriterTag *my_struct_type = dw_writer_tag_reserve(writer, DW_TagKind_StructureType);
DW_WriterTag *const_my_struct_type = dw_writer_tag_begin(writer, DW_TagKind_ConstType); DW_WriterTag *const_my_struct_type = dw_writer_tag_begin(writer, DW_TagKind_ConstType);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DW_WriterTag *my_struct_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType); DW_WriterTag *my_struct_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, const_my_struct_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, const_my_struct_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin_reserved(writer, my_struct_type); dw_writer_tag_begin_reserved(writer, my_struct_type);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure");
dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100); dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100);
dw_writer_tag_begin(writer, DW_TagKind_SubProgram); dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyMethod"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyMethod");
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type);
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter); dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_ptr_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_ptr_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer); RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
RDI_Procedure *proc = rdi_procedure_from_name_cstr(rdi, subprogram_name.cstr); RDI_Procedure *proc = rdi_procedure_from_name_cstr(rdi, (char *)subprogram_name.str);
RDI_TypeNode *proc_type = rdi_element_from_name_idx(rdi, TypeNodes, proc->type_idx); RDI_TypeNode *proc_type = rdi_element_from_name_idx(rdi, TypeNodes, proc->type_idx);
String8 proc_string = rdi_string_from_type(scratch.arena, rdi, proc, proc_type); String8 proc_string = rdi_string_from_type(scratch.arena, rdi, proc, proc_type);
@@ -448,26 +448,26 @@ T_BeginTest(d2r_general)
{ {
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test");
// declare char type // declare char type
DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType); DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1); dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1);
dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_SignedChar); dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_SignedChar);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char");
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
// declare function // declare function
dw_writer_tag_begin(writer, DW_TagKind_SubProgram); dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140173f9); dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140173f9);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x14017474b); dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x14017474b);
dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1);
dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1); dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "FooBar"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "FooBar");
// declare variable // declare variable
dw_writer_tag_begin(writer, DW_TagKind_Variable); dw_writer_tag_begin(writer, DW_TagKind_Variable);
dw_writer_push_attrib_exprv(writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg7)); dw_writer_push_attrib_exprv(writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg7));
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "TestLocal"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "TestLocal");
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
} }
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer); RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
+12 -12
View File
@@ -19,7 +19,7 @@ t_dw_test_uleb128(U64 v, U64 expected_length)
if (!(v0 == v1)) { goto exit; } if (!(v0 == v1)) { goto exit; }
is_ok = 1; is_ok = 1;
exit:; exit:;
scratch_end(scratch); scratch_end(scratch);
return is_ok; return is_ok;
} }
@@ -40,7 +40,7 @@ t_dw_test_sleb128(U64 v, U64 expected_length)
if (!(v0 == v1)) { goto exit; } if (!(v0 == v1)) { goto exit; }
is_ok = 1; is_ok = 1;
exit:; exit:;
scratch_end(scratch); scratch_end(scratch);
return is_ok; return is_ok;
} }
@@ -100,7 +100,7 @@ dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
} }
is_match = 1; is_match = 1;
exit:; exit:;
return is_match; return is_match;
} }
@@ -139,7 +139,7 @@ T_BeginTest(dwarf_32bit)
{ {
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64); DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
DW_Input input = dw_input_from_writer(scratch.arena, writer); DW_Input input = dw_input_from_writer(scratch.arena, writer);
@@ -200,10 +200,10 @@ T_BeginTest(dwarf_line_opcodes)
String8 comp_name = str8_lit("test.c"); String8 comp_name = str8_lit("test.c");
U64 address = 0xDEADBEEFCAFEBABE; U64 address = 0xDEADBEEFCAFEBABE;
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir); dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name);
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0); dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
// test directory table and file table // test directory table and file table
@@ -369,10 +369,10 @@ T_BeginTest(dwarf_line_emit)
String8 comp_dir = str8_lit("c:/devel/"); String8 comp_dir = str8_lit("c:/devel/");
String8 comp_name = str8_lit("test.c"); String8 comp_name = str8_lit("test.c");
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER")); dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir); dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name); dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name);
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0); dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
// test special opcode writer and reader // test special opcode writer and reader