mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-09 07:18:09 +00:00
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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+295
-293
File diff suppressed because it is too large
Load Diff
+465
-465
File diff suppressed because it is too large
Load Diff
+41
-41
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -1485,15 +1498,15 @@ main(int argc, char **argv)
|
|||||||
os_lnx_state.arena = arena_alloc();
|
os_lnx_state.arena = arena_alloc();
|
||||||
os_lnx_state.entity_arena = arena_alloc();
|
os_lnx_state.entity_arena = arena_alloc();
|
||||||
pthread_mutex_init(&os_lnx_state.entity_mutex, 0);
|
pthread_mutex_init(&os_lnx_state.entity_mutex, 0);
|
||||||
|
|
||||||
// cache default environment
|
// cache default environment
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|||||||
+248
-204
@@ -341,7 +341,7 @@ rb_thread_entry_point(void *p)
|
|||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_format == RB_FileFormat_COFF_OBJ || file_format == RB_FileFormat_COFF_BigOBJ)
|
if(file_format == RB_FileFormat_COFF_OBJ || file_format == RB_FileFormat_COFF_BigOBJ)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
@@ -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"));
|
||||||
@@ -535,8 +535,9 @@ 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
|
|
||||||
U64 unit_idx = rdi_vmap_idx_from_voff(bake_results.unit_vmap.vmap.vmap, bake_results.unit_vmap.vmap.count, voff_range.min);
|
// rjf: dump function lines
|
||||||
if(0 < unit_idx && unit_idx <= bake_results.units.units_count)
|
U64 unit_vmap_count = 0;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -1058,7 +1202,7 @@ rb_thread_entry_point(void *p)
|
|||||||
#undef X
|
#undef X
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
B32 verbose = cmd_line_has_flag(cmdline, str8_lit("verbose"));
|
B32 verbose = cmd_line_has_flag(cmdline, str8_lit("verbose"));
|
||||||
|
|
||||||
//- rjf: unpack dump subset flags
|
//- rjf: unpack dump subset flags
|
||||||
@@ -1147,7 +1291,7 @@ rb_thread_entry_point(void *p)
|
|||||||
{
|
{
|
||||||
elf = elf_bin_from_data(arena, f->data);
|
elf = elf_bin_from_data(arena, f->data);
|
||||||
arch = arch_from_elf_machine(elf.hdr.e_machine);
|
arch = arch_from_elf_machine(elf.hdr.e_machine);
|
||||||
|
|
||||||
for EachIndex(sect_idx, elf.hdr.e_shnum)
|
for EachIndex(sect_idx, elf.hdr.e_shnum)
|
||||||
{
|
{
|
||||||
ELF_Shdr64 *shdr = &elf.shdrs.v[sect_idx];
|
ELF_Shdr64 *shdr = &elf.shdrs.v[sect_idx];
|
||||||
@@ -1156,7 +1300,7 @@ rb_thread_entry_point(void *p)
|
|||||||
{
|
{
|
||||||
eh_frame_hdr = str8_substr(f->data, r1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size));
|
eh_frame_hdr = str8_substr(f->data, r1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size));
|
||||||
eh_frame_hdr_vaddr = shdr->sh_addr;
|
eh_frame_hdr_vaddr = shdr->sh_addr;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(str8_match(name, str8_lit(".eh_frame"), 0))
|
else if(str8_match(name, str8_lit(".eh_frame"), 0))
|
||||||
{
|
{
|
||||||
@@ -1268,7 +1412,7 @@ rb_thread_entry_point(void *p)
|
|||||||
}
|
}
|
||||||
lane_sync();
|
lane_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eh_dump_subset_flags)
|
if(eh_dump_subset_flags)
|
||||||
{
|
{
|
||||||
if(lane_idx() == 0)
|
if(lane_idx() == 0)
|
||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@@ -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|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -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 ) \
|
||||||
|
|||||||
Vendored
+15
-15
@@ -631,17 +631,17 @@ cl = lg; \
|
|||||||
dp = 0;
|
dp = 0;
|
||||||
cs = 0;
|
cs = 0;
|
||||||
}goto scopy;
|
}goto scopy;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
{
|
{
|
||||||
stbsp__flush_cb();
|
stbsp__flush_cb();
|
||||||
|
|
||||||
static const U64 one_kib = 1ull * 1024;
|
static const U64 one_kib = 1ull * 1024;
|
||||||
static const U64 one_mib = 1ull * 1024 * 1024;
|
static const U64 one_mib = 1ull * 1024 * 1024;
|
||||||
static const U64 one_gib = 1ull * 1024 * 1024 * 1024;
|
static const U64 one_gib = 1ull * 1024 * 1024 * 1024;
|
||||||
static const U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024;
|
static const U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024;
|
||||||
|
|
||||||
U64 size;
|
U64 size;
|
||||||
if(f[0] == 'M')
|
if(f[0] == 'M')
|
||||||
{
|
{
|
||||||
@@ -651,11 +651,11 @@ cl = lg; \
|
|||||||
{
|
{
|
||||||
size = va_arg(va, U32);
|
size = va_arg(va, U32);
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 lo = 0;
|
U64 lo = 0;
|
||||||
U64 hi = 0;
|
U64 hi = 0;
|
||||||
char *units = "";
|
char *units = "";
|
||||||
|
|
||||||
if(size < one_kib)
|
if(size < one_kib)
|
||||||
{
|
{
|
||||||
hi = size;
|
hi = size;
|
||||||
@@ -686,7 +686,7 @@ cl = lg; \
|
|||||||
lo = ((size * 100) / one_tib) % 100;
|
lo = ((size * 100) / one_tib) % 100;
|
||||||
units = "TiB";
|
units = "TiB";
|
||||||
}
|
}
|
||||||
|
|
||||||
// format high part
|
// format high part
|
||||||
if(hi > 0)
|
if(hi > 0)
|
||||||
{
|
{
|
||||||
@@ -707,37 +707,37 @@ cl = lg; \
|
|||||||
*bf = '0';
|
*bf = '0';
|
||||||
++bf;
|
++bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// format low part
|
// format low part
|
||||||
if(lo > 0)
|
if(lo > 0)
|
||||||
{
|
{
|
||||||
*bf = '.';
|
*bf = '.';
|
||||||
++bf;
|
++bf;
|
||||||
|
|
||||||
s = num;
|
s = num;
|
||||||
for(U64 n = lo; n > 0; n /= 10ull)
|
for(U64 n = lo; n > 0; n /= 10ull)
|
||||||
{
|
{
|
||||||
*s = (char)(n % 10ull) + '0';
|
*s = (char)(n % 10ull) + '0';
|
||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 lead_zero_count = 3 - (U64)(s-num);
|
U64 lead_zero_count = 3 - (U64)(s-num);
|
||||||
for(U64 i = 1; i < lead_zero_count; ++i)
|
for(U64 i = 1; i < lead_zero_count; ++i)
|
||||||
{
|
{
|
||||||
*bf = '0';
|
*bf = '0';
|
||||||
++bf;
|
++bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(S64 i = (S64)(s-num)-1; i >= 0; --i)
|
for(S64 i = (S64)(s-num)-1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
*bf = num[i];
|
*bf = num[i];
|
||||||
++bf;
|
++bf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*bf = ' ';
|
*bf = ' ';
|
||||||
++bf;
|
++bf;
|
||||||
|
|
||||||
// copy units
|
// copy units
|
||||||
for(U64 i = 0; units[i] != 0; ++i)
|
for(U64 i = 0; units[i] != 0; ++i)
|
||||||
{
|
{
|
||||||
@@ -745,14 +745,14 @@ cl = lg; \
|
|||||||
++bf;
|
++bf;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
//
|
//
|
||||||
// NOTE(rjf): DEBUGGER PROJECT ADDITION ^^^
|
// NOTE(rjf): DEBUGGER PROJECT ADDITION ^^^
|
||||||
//-
|
//-
|
||||||
|
|||||||
+22
-22
@@ -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__))
|
||||||
|
|||||||
+262
-262
@@ -7,7 +7,7 @@ internal RDI_Parsed *
|
|||||||
d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
|
d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
String8 raw_coff;
|
String8 raw_coff;
|
||||||
{
|
{
|
||||||
OBJ *obj = obj_alloc(0, Arch_x64);
|
OBJ *obj = obj_alloc(0, Arch_x64);
|
||||||
@@ -18,26 +18,26 @@ d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
|
|||||||
raw_coff = coff_from_obj(scratch.arena, obj);
|
raw_coff = coff_from_obj(scratch.arena, obj);
|
||||||
obj_release(&obj);
|
obj_release(&obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(t_write_file(str8_lit("a.obj"), raw_coff));
|
Assert(t_write_file(str8_lit("a.obj"), raw_coff));
|
||||||
t_invoke(t_radlink_path(), str8_lit("/subsystem:console /out:a.exe /entry:main /DEBUG:FULL /opt:noref /opt:noicf a.obj"), max_U64);
|
t_invoke(t_radlink_path(), str8_lit("/subsystem:console /out:a.exe /entry:main /DEBUG:FULL /opt:noref /opt:noicf a.obj"), max_U64);
|
||||||
Assert(g_last_exit_code == 0);
|
Assert(g_last_exit_code == 0);
|
||||||
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
|
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
|
||||||
Assert(exe.size > 0);
|
Assert(exe.size > 0);
|
||||||
|
|
||||||
B32 was_pdb_deleted = os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
|
B32 was_pdb_deleted = os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
|
||||||
Assert(was_pdb_deleted);
|
Assert(was_pdb_deleted);
|
||||||
|
|
||||||
t_invoke_(t_radbin_path(), str8_lit("-rdi a.exe -out:a.rdi"), max_U64, 0, 0);
|
t_invoke_(t_radbin_path(), str8_lit("-rdi a.exe -out:a.rdi"), max_U64, 0, 0);
|
||||||
Assert(g_last_exit_code == 0);
|
Assert(g_last_exit_code == 0);
|
||||||
|
|
||||||
String8 raw_rdi = t_read_file(arena, str8_lit("a.rdi"));
|
String8 raw_rdi = t_read_file(arena, str8_lit("a.rdi"));
|
||||||
Assert(raw_rdi.size > 0);
|
Assert(raw_rdi.size > 0);
|
||||||
|
|
||||||
RDI_Parsed *rdi = push_array(arena, RDI_Parsed, 1);
|
RDI_Parsed *rdi = push_array(arena, RDI_Parsed, 1);
|
||||||
RDI_ParseStatus rdi_parse_status = rdi_parse(raw_rdi.str, raw_rdi.size, rdi);
|
RDI_ParseStatus rdi_parse_status = rdi_parse(raw_rdi.str, raw_rdi.size, rdi);
|
||||||
Assert(rdi_parse_status == RDI_ParseStatus_Good);
|
Assert(rdi_parse_status == RDI_ParseStatus_Good);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return rdi;
|
return rdi;
|
||||||
}
|
}
|
||||||
@@ -47,10 +47,10 @@ d2rt_type_from_name(RDI_Parsed *rdi, RDI_ParsedNameMap *map, char *name)
|
|||||||
{
|
{
|
||||||
String8 s = str8_cstring(name);
|
String8 s = str8_cstring(name);
|
||||||
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, map, s.str, s.size);
|
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, map, s.str, s.size);
|
||||||
|
|
||||||
U32 id_count = 0;
|
U32 id_count = 0;
|
||||||
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
|
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
|
||||||
|
|
||||||
if (id_count == 1) {
|
if (id_count == 1) {
|
||||||
return rdi_element_from_name_idx(rdi, TypeNodes, ids[0]);
|
return rdi_element_from_name_idx(rdi, TypeNodes, ids[0]);
|
||||||
}
|
}
|
||||||
@@ -63,104 +63,104 @@ T_BeginTest(d2r_types)
|
|||||||
{
|
{
|
||||||
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");
|
||||||
|
|
||||||
#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);
|
||||||
}
|
}
|
||||||
|
|
||||||
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
|
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
|
||||||
RDI_NameMap *types_nm = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types);
|
RDI_NameMap *types_nm = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types);
|
||||||
T_Ok(types_nm);
|
T_Ok(types_nm);
|
||||||
|
|
||||||
RDI_ParsedNameMap types_map = {0};
|
RDI_ParsedNameMap types_map = {0};
|
||||||
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);
|
||||||
@@ -193,21 +193,21 @@ T_BeginTest(d2r_types)
|
|||||||
TestBuiltinType("_Decimal64", 8, Decimal64);
|
TestBuiltinType("_Decimal64", 8, Decimal64);
|
||||||
TestBuiltinType("_Decimal128", 16, Decimal128);
|
TestBuiltinType("_Decimal128", 16, Decimal128);
|
||||||
#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");
|
||||||
@@ -217,7 +217,7 @@ T_BeginTest(d2r_types)
|
|||||||
TestStdint("int32_t", 4, "int");
|
TestStdint("int32_t", 4, "int");
|
||||||
TestStdint("int64_t", 8, "long int");
|
TestStdint("int64_t", 8, "long int");
|
||||||
#undef TestStdint
|
#undef TestStdint
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -227,10 +227,10 @@ T_BeginTest(d2r_line_table)
|
|||||||
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);
|
||||||
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_WriterFile *foo_file = dw_writer_new_file(writer, str8_lit("/mnt/C/Devel/foo.c"));
|
DW_WriterFile *foo_file = dw_writer_new_file(writer, str8_lit("/mnt/C/Devel/foo.c"));
|
||||||
DW_WriterFile *comp_file = dw_writer_new_file(writer, str8f(scratch.arena, "%S%S", comp_dir, comp_name));
|
DW_WriterFile *comp_file = dw_writer_new_file(writer, str8f(scratch.arena, "%S%S", comp_dir, comp_name));
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
DW_WriterFile *file; U64 ln; U64 line_size; U64 voff;
|
DW_WriterFile *file; U64 ln; U64 line_size; U64 voff;
|
||||||
} test_table[] = {
|
} test_table[] = {
|
||||||
@@ -243,7 +243,7 @@ T_BeginTest(d2r_line_table)
|
|||||||
{ foo_file, 100, 1 },
|
{ foo_file, 100, 1 },
|
||||||
{ comp_file, max_U32 - 0x100, 10 },
|
{ comp_file, max_U32 - 0x100, 10 },
|
||||||
};
|
};
|
||||||
|
|
||||||
U64 exe_base = coff_default_exe_base_from_machine(COFF_MachineType_X64);
|
U64 exe_base = coff_default_exe_base_from_machine(COFF_MachineType_X64);
|
||||||
U64 voff = 0x1000;
|
U64 voff = 0x1000;
|
||||||
for EachElement(i, test_table) {
|
for EachElement(i, test_table) {
|
||||||
@@ -251,25 +251,25 @@ T_BeginTest(d2r_line_table)
|
|||||||
dw_writer_line_emit(writer, test_table[i].file, test_table[i].ln, 0, exe_base + voff);
|
dw_writer_line_emit(writer, test_table[i].file, test_table[i].ln, 0, exe_base + voff);
|
||||||
voff += test_table[i].line_size;
|
voff += test_table[i].line_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit one past last line
|
// emit one past last line
|
||||||
dw_writer_line_emit(writer,
|
dw_writer_line_emit(writer,
|
||||||
test_table[ArrayCount(test_table) - 1].file,
|
test_table[ArrayCount(test_table) - 1].file,
|
||||||
test_table[ArrayCount(test_table) - 1].ln,
|
test_table[ArrayCount(test_table) - 1].ln,
|
||||||
0,
|
0,
|
||||||
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);
|
||||||
|
|
||||||
for EachElement(i, test_table) {
|
for EachElement(i, test_table) {
|
||||||
for EachIndex(k, test_table[i].line_size) {
|
for EachIndex(k, test_table[i].line_size) {
|
||||||
String8 cmd_line = str8f(scratch.arena, "-voff2line -voff:0x%llx a.rdi", test_table[i].voff + k);
|
String8 cmd_line = str8f(scratch.arena, "-voff2line -voff:0x%llx a.rdi", test_table[i].voff + k);
|
||||||
@@ -279,7 +279,7 @@ T_BeginTest(d2r_line_table)
|
|||||||
T_MatchLinef(&output, "%S:%llu", test_table[i].file->path, test_table[i].ln);
|
T_MatchLinef(&output, "%S:%llu", test_table[i].file->path, test_table[i].ln);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -287,35 +287,35 @@ T_EndTest;
|
|||||||
T_BeginTest(d2r_checksums)
|
T_BeginTest(d2r_checksums)
|
||||||
{
|
{
|
||||||
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_WriterFile *foo_file = dw_writer_new_file(writer, str8_lit("/mnt/c/devel/foo.c"));
|
DW_WriterFile *foo_file = dw_writer_new_file(writer, str8_lit("/mnt/c/devel/foo.c"));
|
||||||
DW_WriterFile *comp_file = dw_writer_new_file(writer, str8_lit("/home/main.c"));
|
DW_WriterFile *comp_file = dw_writer_new_file(writer, str8_lit("/home/main.c"));
|
||||||
foo_file->md5 = *(U128 *)&(U8[16]){ 0x04, 0x70, 0xe9, 0x6b, 0xa3, 0x05, 0x2c, 0xc8, 0x2d, 0x70, 0xc5, 0xe9, 0x80, 0x8e, 0x8a, 0x4e, };
|
foo_file->md5 = *(U128 *)&(U8[16]){ 0x04, 0x70, 0xe9, 0x6b, 0xa3, 0x05, 0x2c, 0xc8, 0x2d, 0x70, 0xc5, 0xe9, 0x80, 0x8e, 0x8a, 0x4e, };
|
||||||
comp_file->md5 = *(U128 *)&(U8[16]){ 0x82, 0x3c, 0xc6, 0x02, 0x82, 0x9e, 0xf6, 0xce, 0x53, 0xff, 0x5a, 0x93, 0xb6, 0x6e, 0x59, 0x38 };
|
comp_file->md5 = *(U128 *)&(U8[16]){ 0x82, 0x3c, 0xc6, 0x02, 0x82, 0x9e, 0xf6, 0xce, 0x53, 0xff, 0x5a, 0x93, 0xb6, 0x6e, 0x59, 0x38 };
|
||||||
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);
|
||||||
U64 checksum_count = 0;
|
U64 checksum_count = 0;
|
||||||
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)));
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -324,7 +324,7 @@ T_EndTest;
|
|||||||
T_BeginTest(d2r_subprogram)
|
T_BeginTest(d2r_subprogram)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
U64 image_lo = coff_default_exe_base_from_machine(COFF_MachineType_X64);
|
U64 image_lo = coff_default_exe_base_from_machine(COFF_MachineType_X64);
|
||||||
U64 image_hi = image_lo + 0x10000;
|
U64 image_hi = image_lo + 0x10000;
|
||||||
U64 subprogram_lo = image_lo + 0x1000;
|
U64 subprogram_lo = image_lo + 0x1000;
|
||||||
@@ -332,111 +332,111 @@ T_BeginTest(d2r_subprogram)
|
|||||||
U64 subprogram_entry_addr = subprogram_lo + 5;
|
U64 subprogram_entry_addr = subprogram_lo + 5;
|
||||||
String8 subprogram_link_name = str8_lit("@FOOBAR!");
|
String8 subprogram_link_name = str8_lit("@FOOBAR!");
|
||||||
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_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_ref (writer, DW_AttribKind_Type, char_type);
|
|
||||||
dw_writer_tag_end(writer);
|
|
||||||
|
|
||||||
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_Encoding, DW_ATE_Signed);
|
|
||||||
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "int");
|
|
||||||
dw_writer_tag_end(writer);
|
|
||||||
|
|
||||||
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_ref (writer, DW_AttribKind_Type, int_type);
|
|
||||||
dw_writer_tag_end(writer);
|
|
||||||
|
|
||||||
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_AddressClass, DW_AddrClassKind_None);
|
|
||||||
dw_writer_push_attrib_uint (writer, DW_AttribKind_Alignment, 32);
|
|
||||||
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_flag (writer, DW_AttribKind_Deleted, 1);
|
|
||||||
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_External, 1);
|
|
||||||
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_enum (writer, DW_AttribKind_Inline, DW_Inl_DeclaredNotInlined);
|
|
||||||
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_flag (writer, DW_AttribKind_MainSubProgram, 1);
|
|
||||||
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_Prototyped, 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_ref (writer, DW_AttribKind_Type, int_type);
|
|
||||||
dw_writer_push_attrib_enum (writer, DW_AttribKind_Visibility, DW_Vis_Local);
|
|
||||||
// TODO: DW_AttribKind_ObjectPointer
|
|
||||||
// TODO: DW_AttribKind_Ranges
|
|
||||||
// TODO: DW_AttribKind_StartScope
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
|
||||||
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_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg2)); // rcx
|
|
||||||
dw_writer_tag_end(writer);
|
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
|
||||||
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_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg5)); // rdi
|
|
||||||
dw_writer_tag_end(writer);
|
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_UnspecifiedParameters);
|
|
||||||
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 *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_tag_end(writer);
|
|
||||||
|
|
||||||
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_tag_end(writer);
|
|
||||||
|
|
||||||
dw_writer_tag_begin_reserved(writer, my_struct_type);
|
|
||||||
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure");
|
|
||||||
dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100);
|
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
|
|
||||||
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyMethod");
|
|
||||||
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type);
|
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
|
||||||
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_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_ref (writer, DW_AttribKind_Type, char_type);
|
||||||
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
|
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_Encoding, DW_ATE_Signed);
|
||||||
|
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "int");
|
||||||
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
|
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_ref (writer, DW_AttribKind_Type, int_type);
|
||||||
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
|
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_AddressClass, DW_AddrClassKind_None);
|
||||||
|
dw_writer_push_attrib_uint (writer, DW_AttribKind_Alignment, 32);
|
||||||
|
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_flag (writer, DW_AttribKind_Deleted, 1);
|
||||||
|
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_External, 1);
|
||||||
|
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_enum (writer, DW_AttribKind_Inline, DW_Inl_DeclaredNotInlined);
|
||||||
|
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_flag (writer, DW_AttribKind_MainSubProgram, 1);
|
||||||
|
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_Prototyped, 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_ref (writer, DW_AttribKind_Type, int_type);
|
||||||
|
dw_writer_push_attrib_enum (writer, DW_AttribKind_Visibility, DW_Vis_Local);
|
||||||
|
// TODO: DW_AttribKind_ObjectPointer
|
||||||
|
// TODO: DW_AttribKind_Ranges
|
||||||
|
// TODO: DW_AttribKind_StartScope
|
||||||
|
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
||||||
|
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_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg2)); // rcx
|
||||||
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
|
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
||||||
|
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_exprv (writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg5)); // rdi
|
||||||
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
|
dw_writer_tag_begin(writer, DW_TagKind_UnspecifiedParameters);
|
||||||
|
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 *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_tag_end(writer);
|
||||||
|
|
||||||
|
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_tag_end(writer);
|
||||||
|
|
||||||
|
dw_writer_tag_begin_reserved(writer, my_struct_type);
|
||||||
|
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure");
|
||||||
|
dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100);
|
||||||
|
|
||||||
|
dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
|
||||||
|
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyMethod");
|
||||||
|
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type);
|
||||||
|
|
||||||
|
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
|
||||||
|
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);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -448,53 +448,53 @@ 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);
|
||||||
|
|
||||||
RDI_Procedure *proc = rdi_procedure_from_name_cstr(rdi, "FooBar");
|
RDI_Procedure *proc = rdi_procedure_from_name_cstr(rdi, "FooBar");
|
||||||
T_Ok(proc);
|
T_Ok(proc);
|
||||||
T_Ok(proc->link_flags == RDI_LinkFlag_External);
|
T_Ok(proc->link_flags == RDI_LinkFlag_External);
|
||||||
String8 proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx);
|
String8 proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx);
|
||||||
T_Ok(str8_match(proc_name, str8_lit("FooBar"), 0));
|
T_Ok(str8_match(proc_name, str8_lit("FooBar"), 0));
|
||||||
|
|
||||||
RDI_Scope *root_scope = rdi_root_scope_from_procedure(rdi, proc);
|
RDI_Scope *root_scope = rdi_root_scope_from_procedure(rdi, proc);
|
||||||
T_Ok(root_scope);
|
T_Ok(root_scope);
|
||||||
T_Ok(root_scope->local_count == 1);
|
T_Ok(root_scope->local_count == 1);
|
||||||
|
|
||||||
RDI_Local *test_local = rdi_element_from_name_idx(rdi, Locals, root_scope->local_first + 0);
|
RDI_Local *test_local = rdi_element_from_name_idx(rdi, Locals, root_scope->local_first + 0);
|
||||||
T_Ok(test_local);
|
T_Ok(test_local);
|
||||||
T_Ok(test_local->kind == RDI_LocalKind_Variable);
|
T_Ok(test_local->kind == RDI_LocalKind_Variable);
|
||||||
String8 test_local_name = str8_from_rdi_string_idx(rdi, test_local->name_string_idx);
|
String8 test_local_name = str8_from_rdi_string_idx(rdi, test_local->name_string_idx);
|
||||||
T_Ok(str8_match(test_local_name, str8_lit("TestLocal"), 0));
|
T_Ok(str8_match(test_local_name, str8_lit("TestLocal"), 0));
|
||||||
|
|
||||||
RDI_TypeNode *test_local_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local->type_idx);
|
RDI_TypeNode *test_local_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local->type_idx);
|
||||||
T_Ok(test_local_type);
|
T_Ok(test_local_type);
|
||||||
T_Ok(test_local_type->kind == RDI_TypeKind_Alias);
|
T_Ok(test_local_type->kind == RDI_TypeKind_Alias);
|
||||||
T_Ok(test_local_type->flags == 0);
|
T_Ok(test_local_type->flags == 0);
|
||||||
String8 alias_name = str8_from_rdi_string_idx(rdi, test_local_type->user_defined.name_string_idx);
|
String8 alias_name = str8_from_rdi_string_idx(rdi, test_local_type->user_defined.name_string_idx);
|
||||||
T_Ok(str8_match(alias_name, str8_lit("char"), 0));
|
T_Ok(str8_match(alias_name, str8_lit("char"), 0));
|
||||||
|
|
||||||
RDI_TypeNode *char_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local_type->user_defined.direct_type_idx);
|
RDI_TypeNode *char_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local_type->user_defined.direct_type_idx);
|
||||||
T_Ok(char_type);
|
T_Ok(char_type);
|
||||||
T_Ok(char_type->kind == RDI_TypeKind_Char8);
|
T_Ok(char_type->kind == RDI_TypeKind_Char8);
|
||||||
@@ -502,7 +502,7 @@ T_BeginTest(d2r_general)
|
|||||||
T_Ok(char_type->byte_size == 1);
|
T_Ok(char_type->byte_size == 1);
|
||||||
String8 char_type_name = str8_from_rdi_string_idx(rdi, char_type->built_in.name_string_idx);
|
String8 char_type_name = str8_from_rdi_string_idx(rdi, char_type->built_in.name_string_idx);
|
||||||
T_Ok(str8_match(char_type_name, str8_lit("Char8"), 0));
|
T_Ok(str8_match(char_type_name, str8_lit("Char8"), 0));
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
|
|||||||
+161
-161
@@ -8,18 +8,18 @@ t_dw_test_uleb128(U64 v, U64 expected_length)
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
B32 is_ok = 0;
|
B32 is_ok = 0;
|
||||||
|
|
||||||
U64 v0 = v;
|
U64 v0 = v;
|
||||||
String8 e = dw_write_uleb128(scratch.arena, v0);
|
String8 e = dw_write_uleb128(scratch.arena, v0);
|
||||||
if (!(expected_length == e.size)) { goto exit; }
|
if (!(expected_length == e.size)) { goto exit; }
|
||||||
|
|
||||||
U64 v1;
|
U64 v1;
|
||||||
U64 bytes_read = str8_deserial_read_uleb128(e, 0, &v1);
|
U64 bytes_read = str8_deserial_read_uleb128(e, 0, &v1);
|
||||||
if (!(bytes_read == e.size)) { goto exit; }
|
if (!(bytes_read == e.size)) { goto exit; }
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -29,18 +29,18 @@ t_dw_test_sleb128(U64 v, U64 expected_length)
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0,0);
|
Temp scratch = scratch_begin(0,0);
|
||||||
B32 is_ok = 0;
|
B32 is_ok = 0;
|
||||||
|
|
||||||
U64 v0 = v;
|
U64 v0 = v;
|
||||||
String8 e = dw_write_sleb128(scratch.arena, v0);
|
String8 e = dw_write_sleb128(scratch.arena, v0);
|
||||||
if (!(expected_length == e.size)) { goto exit; }
|
if (!(expected_length == e.size)) { goto exit; }
|
||||||
|
|
||||||
S64 v1;
|
S64 v1;
|
||||||
U64 bytes_read = str8_deserial_read_sleb128(e, 0, &v1);
|
U64 bytes_read = str8_deserial_read_sleb128(e, 0, &v1);
|
||||||
if (!(bytes_read == e.size)) { goto exit; }
|
if (!(bytes_read == e.size)) { goto exit; }
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -50,13 +50,13 @@ T_BeginTest(test_leb128)
|
|||||||
T_Ok(t_dw_test_uleb128(0, 1));
|
T_Ok(t_dw_test_uleb128(0, 1));
|
||||||
T_Ok(t_dw_test_sleb128(0, 1));
|
T_Ok(t_dw_test_sleb128(0, 1));
|
||||||
T_Ok(t_dw_test_sleb128(-1, 1));
|
T_Ok(t_dw_test_sleb128(-1, 1));
|
||||||
|
|
||||||
T_Ok(t_dw_test_uleb128(max_U64, 10));
|
T_Ok(t_dw_test_uleb128(max_U64, 10));
|
||||||
T_Ok(t_dw_test_sleb128(min_S64, 10));
|
T_Ok(t_dw_test_sleb128(min_S64, 10));
|
||||||
T_Ok(t_dw_test_sleb128(max_S64, 10));
|
T_Ok(t_dw_test_sleb128(max_S64, 10));
|
||||||
|
|
||||||
T_Ok(t_dw_test_uleb128(0xDEADBEEFCAFEBABE, 10));
|
T_Ok(t_dw_test_uleb128(0xDEADBEEFCAFEBABE, 10));
|
||||||
|
|
||||||
for EachIndex(i, 64) {
|
for EachIndex(i, 64) {
|
||||||
T_Ok(t_dw_test_uleb128((1ull << i), 1 + (i / 7)));
|
T_Ok(t_dw_test_uleb128((1ull << i), 1 + (i / 7)));
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ internal B32
|
|||||||
dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
||||||
{
|
{
|
||||||
B32 is_match = 0;
|
B32 is_match = 0;
|
||||||
|
|
||||||
// match headers
|
// match headers
|
||||||
B32 writer_has_children = writer_tag->first_child != 0;
|
B32 writer_has_children = writer_tag->first_child != 0;
|
||||||
if (writer_tag->kind != reader_tag->tag.kind) { goto exit; }
|
if (writer_tag->kind != reader_tag->tag.kind) { goto exit; }
|
||||||
@@ -78,7 +78,7 @@ dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
|||||||
if (writer_tag->attrib_count != reader_tag->tag.attribs.count) { goto exit; }
|
if (writer_tag->attrib_count != reader_tag->tag.attribs.count) { goto exit; }
|
||||||
if (writer_tag->info_off != reader_tag->tag.info_off) { goto exit; }
|
if (writer_tag->info_off != reader_tag->tag.info_off) { goto exit; }
|
||||||
if (writer_has_children != reader_tag->tag.has_children) { goto exit; }
|
if (writer_has_children != reader_tag->tag.has_children) { goto exit; }
|
||||||
|
|
||||||
// match attribs
|
// match attribs
|
||||||
DW_WriterAttrib *writer_attrib = writer_tag->first_attrib;
|
DW_WriterAttrib *writer_attrib = writer_tag->first_attrib;
|
||||||
DW_AttribNode *reader_attrib = reader_tag->tag.attribs.first;
|
DW_AttribNode *reader_attrib = reader_tag->tag.attribs.first;
|
||||||
@@ -89,7 +89,7 @@ dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
|||||||
writer_attrib = writer_attrib->next;
|
writer_attrib = writer_attrib->next;
|
||||||
reader_attrib = reader_attrib->next;
|
reader_attrib = reader_attrib->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit children
|
// visit children
|
||||||
DW_WriterTag *writer_child = writer_tag->first_child;
|
DW_WriterTag *writer_child = writer_tag->first_child;
|
||||||
DW_TagNode *reader_child = reader_tag->first_child;
|
DW_TagNode *reader_child = reader_tag->first_child;
|
||||||
@@ -98,9 +98,9 @@ dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
|||||||
writer_child = writer_child->next;
|
writer_child = writer_child->next;
|
||||||
reader_child = reader_child->sibling;
|
reader_child = reader_child->sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_match = 1;
|
is_match = 1;
|
||||||
exit:;
|
exit:;
|
||||||
return is_match;
|
return is_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ internal DW_Input
|
|||||||
dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
OBJ *obj = obj_alloc(0, Arch_x64);
|
OBJ *obj = obj_alloc(0, Arch_x64);
|
||||||
OBJ_Section *text_section = obj_push_section(obj, str8_lit(".text"), OBJ_SectionFlag_Read|OBJ_SectionFlag_Exec|OBJ_SectionFlag_Load);
|
OBJ_Section *text_section = obj_push_section(obj, str8_lit(".text"), OBJ_SectionFlag_Read|OBJ_SectionFlag_Exec|OBJ_SectionFlag_Load);
|
||||||
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
|
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
|
||||||
@@ -116,20 +116,20 @@ dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
|||||||
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
|
str8_serial_push_u8(obj->arena, &text_section->data, 0x90);
|
||||||
str8_serial_push_u8(obj->arena, &text_section->data, 0xc3);
|
str8_serial_push_u8(obj->arena, &text_section->data, 0xc3);
|
||||||
obj_push_symbol(obj, str8_lit("entry"), OBJ_SymbolScope_Global, OBJ_RefKind_Section, text_section);
|
obj_push_symbol(obj, str8_lit("entry"), OBJ_SymbolScope_Global, OBJ_RefKind_Section, text_section);
|
||||||
|
|
||||||
dw_writer_emit_to_obj(writer, obj);
|
dw_writer_emit_to_obj(writer, obj);
|
||||||
String8 raw_coff = coff_from_obj(scratch.arena, obj);
|
String8 raw_coff = coff_from_obj(scratch.arena, obj);
|
||||||
|
|
||||||
t_write_file(str8_lit("dwarf.obj"), raw_coff);
|
t_write_file(str8_lit("dwarf.obj"), raw_coff);
|
||||||
t_invoke(str8_lit("radlink"), str8_lit("/subsystem:console /entry:entry /out:a.exe /debug:full dwarf.obj"), max_U64);
|
t_invoke(str8_lit("radlink"), str8_lit("/subsystem:console /entry:entry /out:a.exe /debug:full dwarf.obj"), max_U64);
|
||||||
os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
|
os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
|
||||||
|
|
||||||
String8 exe = t_read_file(arena, str8_lit("a.exe"));
|
String8 exe = t_read_file(arena, str8_lit("a.exe"));
|
||||||
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
||||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)(exe.str + pe.section_table_range.min);
|
COFF_SectionHeader *section_table = (COFF_SectionHeader *)(exe.str + pe.section_table_range.min);
|
||||||
String8 string_table = str8_substr(exe, pe.string_table_range);
|
String8 string_table = str8_substr(exe, pe.string_table_range);
|
||||||
DW_Input input = dw_input_from_coff_section_table(arena, exe, string_table, pe.section_count, section_table);
|
DW_Input input = dw_input_from_coff_section_table(arena, exe, string_table, pe.section_count, section_table);
|
||||||
|
|
||||||
obj_release(&obj);
|
obj_release(&obj);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return input;
|
return input;
|
||||||
@@ -139,27 +139,27 @@ 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);
|
||||||
|
|
||||||
for EachElement(sec_idx, input.sec) {
|
for EachElement(sec_idx, input.sec) {
|
||||||
if (sec_idx == DW_Section_Abbrev) continue;
|
if (sec_idx == DW_Section_Abbrev) continue;
|
||||||
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
||||||
for EachIndex(range_idx, unit_ranges.count) {
|
for EachIndex(range_idx, unit_ranges.count) {
|
||||||
Rng1U64 range = unit_ranges.v[range_idx];
|
Rng1U64 range = unit_ranges.v[range_idx];
|
||||||
|
|
||||||
U32 first_four_bytes = 0;
|
U32 first_four_bytes = 0;
|
||||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
||||||
T_Ok(first_four_bytes + 4 == dim_1u64(range));
|
T_Ok(first_four_bytes + 4 == dim_1u64(range));
|
||||||
|
|
||||||
U32 unit_length = 0;
|
U32 unit_length = 0;
|
||||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &unit_length) == sizeof(U32));
|
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &unit_length) == sizeof(U32));
|
||||||
T_Ok(unit_length + 4 == dim_1u64(range));
|
T_Ok(unit_length + 4 == dim_1u64(range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -170,25 +170,25 @@ T_BeginTest(dwarf_64bit)
|
|||||||
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);
|
||||||
|
|
||||||
for EachElement(sec_idx, input.sec) {
|
for EachElement(sec_idx, input.sec) {
|
||||||
if (sec_idx == DW_Section_Abbrev) continue;
|
if (sec_idx == DW_Section_Abbrev) continue;
|
||||||
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
Rng1U64Array unit_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[sec_idx].data);
|
||||||
for EachIndex(range_idx, unit_ranges.count) {
|
for EachIndex(range_idx, unit_ranges.count) {
|
||||||
Rng1U64 range = unit_ranges.v[range_idx];
|
Rng1U64 range = unit_ranges.v[range_idx];
|
||||||
|
|
||||||
U32 first_four_bytes = 0;
|
U32 first_four_bytes = 0;
|
||||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min, &first_four_bytes) == sizeof(first_four_bytes));
|
||||||
T_Ok(first_four_bytes == max_U32);
|
T_Ok(first_four_bytes == max_U32);
|
||||||
|
|
||||||
U64 unit_length = 0;
|
U64 unit_length = 0;
|
||||||
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min + sizeof(U32), &unit_length) == sizeof(U64));
|
T_Ok(str8_deserial_read_struct(input.sec[sec_idx].data, range.min + sizeof(U32), &unit_length) == sizeof(U64));
|
||||||
T_Ok(unit_length + 12 == dim_1u64(range));
|
T_Ok(unit_length + 12 == dim_1u64(range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -200,12 +200,12 @@ 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
|
||||||
DW_WriterFile *file2 = dw_writer_new_file(writer, str8_lit("d:/foobar/qwe.c"));
|
DW_WriterFile *file2 = dw_writer_new_file(writer, str8_lit("d:/foobar/qwe.c"));
|
||||||
file2->time_stamp = 123;
|
file2->time_stamp = 123;
|
||||||
@@ -217,7 +217,7 @@ T_BeginTest(dwarf_line_opcodes)
|
|||||||
file->size = 314;
|
file->size = 314;
|
||||||
file->md5 = *(U128 *)&((U8[sizeof(U128)]) { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, });
|
file->md5 = *(U128 *)&((U8[sizeof(U128)]) { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, });
|
||||||
file->source = str8_lit("int main() { return 057; }\n");
|
file->source = str8_lit("int main() { return 057; }\n");
|
||||||
|
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_copy());
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_copy());
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(7));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(7));
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(-7));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_pc(-7));
|
||||||
@@ -237,32 +237,32 @@ T_BeginTest(dwarf_line_opcodes)
|
|||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_set_address(address));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_set_address(address));
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_set_discriminator(2));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_set_discriminator(2));
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_end_sequence());
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_end_sequence());
|
||||||
|
|
||||||
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
||||||
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[DW_Section_Info].data);
|
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[DW_Section_Info].data);
|
||||||
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
||||||
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
||||||
|
|
||||||
T_Ok(line_vm->header.dir_table.count == 2);
|
T_Ok(line_vm->header.dir_table.count == 2);
|
||||||
T_Ok(line_vm->header.file_table.count == 2);
|
T_Ok(line_vm->header.file_table.count == 2);
|
||||||
|
|
||||||
T_Ok(str8_match(line_vm->header.dir_table.v[0], str8_lit("c:/devel"), 0));
|
T_Ok(str8_match(line_vm->header.dir_table.v[0], str8_lit("c:/devel"), 0));
|
||||||
T_Ok(str8_match(line_vm->header.dir_table.v[1], str8_lit("d:/foobar"), 0));
|
T_Ok(str8_match(line_vm->header.dir_table.v[1], str8_lit("d:/foobar"), 0));
|
||||||
|
|
||||||
DW_LineFile *file_reader = &line_vm->header.file_table.v[0];
|
DW_LineFile *file_reader = &line_vm->header.file_table.v[0];
|
||||||
T_Ok(str8_match(file_reader->path, comp_name, 0));
|
T_Ok(str8_match(file_reader->path, comp_name, 0));
|
||||||
T_Ok(file_reader->dir_idx == 0);
|
T_Ok(file_reader->dir_idx == 0);
|
||||||
T_Ok(file_reader->time_stamp == file->time_stamp);
|
T_Ok(file_reader->time_stamp == file->time_stamp);
|
||||||
T_Ok(u128_match(file_reader->md5, file->md5));
|
T_Ok(u128_match(file_reader->md5, file->md5));
|
||||||
T_Ok(str8_match(file_reader->source, file->source, 0));
|
T_Ok(str8_match(file_reader->source, file->source, 0));
|
||||||
|
|
||||||
DW_LineFile *file2_reader = &line_vm->header.file_table.v[1];
|
DW_LineFile *file2_reader = &line_vm->header.file_table.v[1];
|
||||||
T_Ok(str8_match(file2_reader->path, str8_lit("qwe.c"), 0));
|
T_Ok(str8_match(file2_reader->path, str8_lit("qwe.c"), 0));
|
||||||
T_Ok(file2_reader->dir_idx == 1);
|
T_Ok(file2_reader->dir_idx == 1);
|
||||||
T_Ok(file2_reader->time_stamp == file2->time_stamp);
|
T_Ok(file2_reader->time_stamp == file2->time_stamp);
|
||||||
T_Ok(u128_match(file2_reader->md5, file2->md5));
|
T_Ok(u128_match(file2_reader->md5, file2->md5));
|
||||||
T_Ok(str8_match(file2_reader->source, file2->source, 0));
|
T_Ok(str8_match(file2_reader->source, file2->source, 0));
|
||||||
|
|
||||||
T_Ok(line_vm->new_line == 0);
|
T_Ok(line_vm->new_line == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
||||||
@@ -271,48 +271,48 @@ T_BeginTest(dwarf_line_opcodes)
|
|||||||
T_Ok(line_vm->state.basic_block == 0);
|
T_Ok(line_vm->state.basic_block == 0);
|
||||||
T_Ok(line_vm->state.prologue_end == 0);
|
T_Ok(line_vm->state.prologue_end == 0);
|
||||||
T_Ok(line_vm->state.epilogue_begin == 0);
|
T_Ok(line_vm->state.epilogue_begin == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
||||||
T_Ok(line_vm->state.address == 7);
|
T_Ok(line_vm->state.address == 7);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
||||||
T_Ok(line_vm->state.address == 0);
|
T_Ok(line_vm->state.address == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 5);
|
T_Ok(line_vm->state.line == 5);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 1);
|
T_Ok(line_vm->state.line == 1);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetFile);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetFile);
|
||||||
T_Ok(line_vm->state.file_index == 0);
|
T_Ok(line_vm->state.file_index == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetColumn);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetColumn);
|
||||||
T_Ok(line_vm->state.column == max_U64);
|
T_Ok(line_vm->state.column == max_U64);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetColumn);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetColumn);
|
||||||
T_Ok(line_vm->state.column == 0);
|
T_Ok(line_vm->state.column == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_NegateStmt);
|
T_Ok(line_vm->opcode == DW_StdOpcode_NegateStmt);
|
||||||
T_Ok(line_vm->state.is_stmt == 0);
|
T_Ok(line_vm->state.is_stmt == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_NegateStmt);
|
T_Ok(line_vm->opcode == DW_StdOpcode_NegateStmt);
|
||||||
T_Ok(line_vm->state.is_stmt == 1);
|
T_Ok(line_vm->state.is_stmt == 1);
|
||||||
|
|
||||||
T_Ok(line_vm->state.basic_block == 0);
|
T_Ok(line_vm->state.basic_block == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetBasicBlock);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetBasicBlock);
|
||||||
T_Ok(line_vm->state.basic_block == 1);
|
T_Ok(line_vm->state.basic_block == 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
U64 addr_before = line_vm->state.address;
|
U64 addr_before = line_vm->state.address;
|
||||||
U64 const_advance = (0xffu - line_vm->header.opcode_base) / line_vm->header.line_range;
|
U64 const_advance = (0xffu - line_vm->header.opcode_base) / line_vm->header.line_range;
|
||||||
@@ -320,45 +320,45 @@ T_BeginTest(dwarf_line_opcodes)
|
|||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
T_Ok(line_vm->state.address == addr_before + const_advance);
|
T_Ok(line_vm->state.address == addr_before + const_advance);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Ok(line_vm->state.address == 0x11);
|
T_Ok(line_vm->state.address == 0x11);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_FixedAdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_FixedAdvancePc);
|
||||||
T_Ok(line_vm->state.address == max_U16 + 0x11);
|
T_Ok(line_vm->state.address == max_U16 + 0x11);
|
||||||
|
|
||||||
T_Ok(line_vm->state.prologue_end == 0);
|
T_Ok(line_vm->state.prologue_end == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetPrologueEnd);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetPrologueEnd);
|
||||||
T_Ok(line_vm->state.prologue_end == 1);
|
T_Ok(line_vm->state.prologue_end == 1);
|
||||||
|
|
||||||
T_Ok(line_vm->state.epilogue_begin == 0);
|
T_Ok(line_vm->state.epilogue_begin == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetEpilogueBegin);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetEpilogueBegin);
|
||||||
T_Ok(line_vm->state.epilogue_begin == 1);
|
T_Ok(line_vm->state.epilogue_begin == 1);
|
||||||
|
|
||||||
T_Ok(line_vm->state.isa == 0);
|
T_Ok(line_vm->state.isa == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetIsa);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetIsa);
|
||||||
T_Ok(line_vm->state.isa == max_U64);
|
T_Ok(line_vm->state.isa == max_U64);
|
||||||
|
|
||||||
T_Ok(line_vm->state.address != address);
|
T_Ok(line_vm->state.address != address);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
||||||
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_SetAddress);
|
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_SetAddress);
|
||||||
T_Ok(line_vm->state.address == address);
|
T_Ok(line_vm->state.address == address);
|
||||||
|
|
||||||
T_Ok(line_vm->state.discriminator == 0);
|
T_Ok(line_vm->state.discriminator == 0);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
||||||
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_SetDiscriminator);
|
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_SetDiscriminator);
|
||||||
T_Ok(line_vm->state.discriminator == 2);
|
T_Ok(line_vm->state.discriminator == 2);
|
||||||
|
|
||||||
T_Ok(!line_vm->state.end_sequence);
|
T_Ok(!line_vm->state.end_sequence);
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
||||||
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
||||||
T_Ok(line_vm->state.end_sequence);
|
T_Ok(line_vm->state.end_sequence);
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -369,39 +369,39 @@ 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
|
||||||
DW_WriterFile *file = dw_writer_new_file(writer, comp_name);
|
DW_WriterFile *file = dw_writer_new_file(writer, comp_name);
|
||||||
|
|
||||||
// init sequence
|
// init sequence
|
||||||
dw_writer_line_emit(writer, file, 10000, 0, 1000);
|
dw_writer_line_emit(writer, file, 10000, 0, 1000);
|
||||||
|
|
||||||
for EachIndex(i, abs_s64(writer->line.line_base) + 1) {
|
for EachIndex(i, abs_s64(writer->line.line_base) + 1) {
|
||||||
dw_writer_line_emit(writer, file, writer->line.ln-i, 0, writer->line.addr+1);
|
dw_writer_line_emit(writer, file, writer->line.ln-i, 0, writer->line.addr+1);
|
||||||
|
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(i));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(i));
|
||||||
writer->line.ln += i;
|
writer->line.ln += i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// special opcode line window underflow, must emit three instructions to advance
|
// special opcode line window underflow, must emit three instructions to advance
|
||||||
dw_writer_line_emit(writer, file, (writer->line.ln + writer->line.line_base) - 1, 0, writer->line.addr + 1);
|
dw_writer_line_emit(writer, file, (writer->line.ln + writer->line.line_base) - 1, 0, writer->line.addr + 1);
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(-(writer->line.line_base - 1)));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(-(writer->line.line_base - 1)));
|
||||||
|
|
||||||
for EachIndex(i, (writer->line.line_range + writer->line.line_base) + 1) {
|
for EachIndex(i, (writer->line.line_range + writer->line.line_base) + 1) {
|
||||||
dw_writer_line_emit(writer, file, writer->line.ln+i, 0, writer->line.addr+1);
|
dw_writer_line_emit(writer, file, writer->line.ln+i, 0, writer->line.addr+1);
|
||||||
|
|
||||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(-i));
|
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNS_advance_line(-i));
|
||||||
writer->line.ln -= i;
|
writer->line.ln -= i;
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_writer_line_end_sequence(writer);
|
dw_writer_line_end_sequence(writer);
|
||||||
dw_writer_line_emit(writer, file, 1000, 0, writer->line.addr+1);
|
dw_writer_line_emit(writer, file, 1000, 0, writer->line.addr+1);
|
||||||
|
|
||||||
// test address window
|
// test address window
|
||||||
S64 c = writer->line.line_range + writer->line.line_base;
|
S64 c = writer->line.line_range + writer->line.line_base;
|
||||||
U64 line_addr_count = 0;
|
U64 line_addr_count = 0;
|
||||||
@@ -414,40 +414,40 @@ T_BeginTest(dwarf_line_emit)
|
|||||||
line_addr_count += 1;
|
line_addr_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
DW_Input input = dw_input_from_writer(scratch.arena, writer);
|
||||||
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[DW_Section_Info].data);
|
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(scratch.arena, input.sec[DW_Section_Info].data);
|
||||||
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
||||||
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
||||||
|
|
||||||
// check init sequence
|
// check init sequence
|
||||||
{
|
{
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_SetFile);
|
T_Ok(line_vm->opcode == DW_StdOpcode_SetFile);
|
||||||
T_Ok(line_vm->state.file_index == 0);
|
T_Ok(line_vm->state.file_index == 0);
|
||||||
T_Ok(line_vm->new_line == 0);
|
T_Ok(line_vm->new_line == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
||||||
T_Ok(line_vm->state.address == 1000);
|
T_Ok(line_vm->state.address == 1000);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->new_line == 0);
|
T_Ok(line_vm->new_line == 0);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == 1000);
|
T_Ok(line_vm->state.address == 1000);
|
||||||
T_Ok(line_vm->new_line == 1);
|
T_Ok(line_vm->new_line == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
U64 pc = line_vm->state.address;
|
U64 pc = line_vm->state.address;
|
||||||
for EachIndex(i, abs_s64(writer->line.line_base) + 1) {
|
for EachIndex(i, abs_s64(writer->line.line_base) + 1) {
|
||||||
pc += 1;
|
pc += 1;
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == 0x20 - i);
|
T_Ok(line_vm->opcode == 0x20 - i);
|
||||||
T_Ok(line_vm->state.line == 10000 - i);
|
T_Ok(line_vm->state.line == 10000 - i);
|
||||||
@@ -459,81 +459,81 @@ T_BeginTest(dwarf_line_emit)
|
|||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// line window underflow check
|
// line window underflow check
|
||||||
{
|
{
|
||||||
pc += 1;
|
pc += 1;
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 9994);
|
T_Ok(line_vm->state.line == 9994);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
||||||
T_Ok(line_vm->state.line == 9994);
|
T_Ok(line_vm->state.line == 9994);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(line_vm->new_line);
|
T_Ok(line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
for EachIndex(i, writer->line.line_range + writer->line.line_base) {
|
for EachIndex(i, writer->line.line_range + writer->line.line_base) {
|
||||||
pc += 1;
|
pc += 1;
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == 0x20 + i);
|
T_Ok(line_vm->opcode == 0x20 + i);
|
||||||
T_Ok(line_vm->state.line == 10000 + i);
|
T_Ok(line_vm->state.line == 10000 + i);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(line_vm->new_line);
|
T_Ok(line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// line window overflow check
|
// line window overflow check
|
||||||
{
|
{
|
||||||
pc += 1;
|
pc += 1;
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvancePc);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 10009);
|
T_Ok(line_vm->state.line == 10009);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
T_Ok(line_vm->opcode == DW_StdOpcode_Copy);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(line_vm->state.line == 10009);
|
T_Ok(line_vm->state.line == 10009);
|
||||||
T_Ok(line_vm->new_line);
|
T_Ok(line_vm->new_line);
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
T_Ok(line_vm->opcode == DW_StdOpcode_AdvanceLine);
|
||||||
T_Ok(line_vm->state.line == 10000);
|
T_Ok(line_vm->state.line == 10000);
|
||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(!line_vm->new_line);
|
T_Ok(!line_vm->new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
||||||
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
||||||
@@ -541,19 +541,19 @@ T_BeginTest(dwarf_line_emit)
|
|||||||
T_Ok(line_vm->state.address == pc);
|
T_Ok(line_vm->state.address == pc);
|
||||||
T_Ok(line_vm->new_line);
|
T_Ok(line_vm->new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
|
|
||||||
for EachIndex(i, line_addr_count/*first line is a noop*/-1) {
|
for EachIndex(i, line_addr_count/*first line is a noop*/-1) {
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->header.opcode_base < line_vm->opcode);
|
T_Ok(line_vm->header.opcode_base < line_vm->opcode);
|
||||||
T_Ok(line_vm->new_line);
|
T_Ok(line_vm->new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Ok(dw_line_vm_step(line_vm));
|
T_Ok(dw_line_vm_step(line_vm));
|
||||||
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
T_Ok(line_vm->opcode == DW_StdOpcode_ExtendedOpcode);
|
||||||
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
T_Ok(line_vm->ext_opcode == DW_ExtOpcode_EndSequence);
|
||||||
@@ -581,18 +581,18 @@ T_BeginTest(dwarf_writer)
|
|||||||
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_string(writer, DW_AttribKind_Name, str8_lit("char"));
|
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("char"));
|
||||||
dw_writer_tag_end(writer);
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_ConstType);
|
dw_writer_tag_begin(writer, DW_TagKind_ConstType);
|
||||||
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);
|
||||||
|
|
||||||
// test abbrev dedup
|
// test abbrev dedup
|
||||||
DW_WriterTag *dup_char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
|
DW_WriterTag *dup_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_string(writer, DW_AttribKind_Name, str8_lit("char"));
|
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("char"));
|
||||||
dw_writer_tag_end(writer);
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
// simple struct test
|
// simple struct test
|
||||||
DW_WriterTag *simple_struct_tag = dw_writer_tag_begin(writer, DW_TagKind_StructureType);
|
DW_WriterTag *simple_struct_tag = dw_writer_tag_begin(writer, DW_TagKind_StructureType);
|
||||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("FooBar"));
|
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("FooBar"));
|
||||||
@@ -603,7 +603,7 @@ T_BeginTest(dwarf_writer)
|
|||||||
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
|
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
|
||||||
dw_writer_push_attrib_sint(writer, DW_AttribKind_DataMemberLocation, 0);
|
dw_writer_push_attrib_sint(writer, DW_AttribKind_DataMemberLocation, 0);
|
||||||
dw_writer_tag_end(writer);
|
dw_writer_tag_end(writer);
|
||||||
|
|
||||||
dw_writer_tag_begin(writer, DW_TagKind_Member);
|
dw_writer_tag_begin(writer, DW_TagKind_Member);
|
||||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("m1"));
|
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, str8_lit("m1"));
|
||||||
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
|
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
|
||||||
@@ -612,7 +612,7 @@ T_BeginTest(dwarf_writer)
|
|||||||
dw_writer_tag_end(writer);
|
dw_writer_tag_end(writer);
|
||||||
}
|
}
|
||||||
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_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);
|
||||||
@@ -625,15 +625,15 @@ T_BeginTest(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);
|
||||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &input);
|
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &input);
|
||||||
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, lu_input, 0, 1);
|
DW_CompUnit cu = dw_cu_from_info_off(scratch.arena, &input, lu_input, 0, 1);
|
||||||
DW_TagTree tag_tree = dw_tag_tree_from_cu(scratch.arena, &input, &cu);
|
DW_TagTree tag_tree = dw_tag_tree_from_cu(scratch.arena, &input, &cu);
|
||||||
AssertAlways(dwt_tags_must_match(writer->root, tag_tree.root));
|
AssertAlways(dwt_tags_must_match(writer->root, tag_tree.root));
|
||||||
|
|
||||||
// validate the writer
|
// validate the writer
|
||||||
|
|
||||||
T_Ok(writer->current == 0);
|
T_Ok(writer->current == 0);
|
||||||
T_Ok(writer->format == DW_Format_32Bit);
|
T_Ok(writer->format == DW_Format_32Bit);
|
||||||
T_Ok(writer->cu_kind == DW_CompUnitKind_Compile);
|
T_Ok(writer->cu_kind == DW_CompUnitKind_Compile);
|
||||||
@@ -642,7 +642,7 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(writer->abbrev_base_info_off == 8);
|
T_Ok(writer->abbrev_base_info_off == 8);
|
||||||
T_Ok(writer->fixups.count == 0);
|
T_Ok(writer->fixups.count == 0);
|
||||||
T_Ok(writer->abbrev_id_map->count == 7);
|
T_Ok(writer->abbrev_id_map->count == 7);
|
||||||
|
|
||||||
DW_WriterTag *comp_unit_tag = writer->root;
|
DW_WriterTag *comp_unit_tag = writer->root;
|
||||||
{
|
{
|
||||||
T_Ok(comp_unit_tag->kind == DW_TagKind_CompileUnit);
|
T_Ok(comp_unit_tag->kind == DW_TagKind_CompileUnit);
|
||||||
@@ -651,24 +651,24 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(comp_unit_tag->attrib_count == 5);
|
T_Ok(comp_unit_tag->attrib_count == 5);
|
||||||
T_Ok(comp_unit_tag->abbrev_id == 1);
|
T_Ok(comp_unit_tag->abbrev_id == 1);
|
||||||
T_Ok(comp_unit_tag->info_off == 0xc);
|
T_Ok(comp_unit_tag->info_off == 0xc);
|
||||||
|
|
||||||
DW_WriterAttrib *producer_attrib = comp_unit_tag->first_attrib;
|
DW_WriterAttrib *producer_attrib = comp_unit_tag->first_attrib;
|
||||||
T_Ok(producer_attrib->kind == DW_AttribKind_Producer);
|
T_Ok(producer_attrib->kind == DW_AttribKind_Producer);
|
||||||
T_Ok(producer_attrib->form.reader.kind == DW_Form_String);
|
T_Ok(producer_attrib->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(producer_attrib->form.writer.string, str8_lit("RAD DWARF WRITER"), 0));
|
T_Ok(str8_match(producer_attrib->form.writer.string, str8_lit("RAD DWARF WRITER"), 0));
|
||||||
|
|
||||||
DW_WriterAttrib *language_attrib = producer_attrib->next;
|
DW_WriterAttrib *language_attrib = producer_attrib->next;
|
||||||
T_Ok(language_attrib->kind == DW_AttribKind_Language);
|
T_Ok(language_attrib->kind == DW_AttribKind_Language);
|
||||||
T_Ok(language_attrib->form.reader.kind == DW_Form_Data1);
|
T_Ok(language_attrib->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(language_attrib->form.reader.data.size == 1);
|
T_Ok(language_attrib->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)language_attrib->form.reader.data.str == DW_Language_C99);
|
T_Ok(*(U8 *)language_attrib->form.reader.data.str == DW_Language_C99);
|
||||||
|
|
||||||
DW_WriterAttrib *use_utf8_attrib = language_attrib->next;
|
DW_WriterAttrib *use_utf8_attrib = language_attrib->next;
|
||||||
T_Ok(use_utf8_attrib->kind == DW_AttribKind_UseUtf8);
|
T_Ok(use_utf8_attrib->kind == DW_AttribKind_UseUtf8);
|
||||||
T_Ok(use_utf8_attrib->form.reader.kind == DW_Form_Flag);
|
T_Ok(use_utf8_attrib->form.reader.kind == DW_Form_Flag);
|
||||||
T_Ok(use_utf8_attrib->form.reader.flag == 1);
|
T_Ok(use_utf8_attrib->form.reader.flag == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *char_type_tag = comp_unit_tag->first_child;
|
DW_WriterTag *char_type_tag = comp_unit_tag->first_child;
|
||||||
{
|
{
|
||||||
T_Ok(char_type_tag->kind == DW_TagKind_BaseType);
|
T_Ok(char_type_tag->kind == DW_TagKind_BaseType);
|
||||||
@@ -678,25 +678,25 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(char_type_tag->abbrev_id == 2);
|
T_Ok(char_type_tag->abbrev_id == 2);
|
||||||
T_Ok(char_type_tag->info_off == 0x30);
|
T_Ok(char_type_tag->info_off == 0x30);
|
||||||
T_Ok(char_type_tag->first_attrib != char_type_tag->last_attrib);
|
T_Ok(char_type_tag->first_attrib != char_type_tag->last_attrib);
|
||||||
|
|
||||||
DW_WriterAttrib *byte_size_attrib = char_type_tag->first_attrib;
|
DW_WriterAttrib *byte_size_attrib = char_type_tag->first_attrib;
|
||||||
T_Ok(byte_size_attrib->kind == DW_AttribKind_ByteSize);
|
T_Ok(byte_size_attrib->kind == DW_AttribKind_ByteSize);
|
||||||
T_Ok(byte_size_attrib->form.reader.kind == DW_Form_Data1);
|
T_Ok(byte_size_attrib->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(byte_size_attrib->form.reader.data.size == 1);
|
T_Ok(byte_size_attrib->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)byte_size_attrib->form.reader.data.str == 1);
|
T_Ok(*(U8 *)byte_size_attrib->form.reader.data.str == 1);
|
||||||
|
|
||||||
DW_WriterAttrib *encoding_attrib = byte_size_attrib->next;
|
DW_WriterAttrib *encoding_attrib = byte_size_attrib->next;
|
||||||
T_Ok(encoding_attrib->kind == DW_AttribKind_Encoding);
|
T_Ok(encoding_attrib->kind == DW_AttribKind_Encoding);
|
||||||
T_Ok(encoding_attrib->form.reader.kind == DW_Form_Data1);
|
T_Ok(encoding_attrib->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(encoding_attrib->form.reader.data.size == 1);
|
T_Ok(encoding_attrib->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)encoding_attrib->form.reader.data.str == DW_ATE_SignedChar);
|
T_Ok(*(U8 *)encoding_attrib->form.reader.data.str == DW_ATE_SignedChar);
|
||||||
|
|
||||||
DW_WriterAttrib *name_attrib = encoding_attrib->next;
|
DW_WriterAttrib *name_attrib = encoding_attrib->next;
|
||||||
T_Ok(name_attrib->kind == DW_AttribKind_Name);
|
T_Ok(name_attrib->kind == DW_AttribKind_Name);
|
||||||
T_Ok(name_attrib->form.reader.kind == DW_Form_String);
|
T_Ok(name_attrib->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(name_attrib->form.reader.string, str8_lit("char"), 0));
|
T_Ok(str8_match(name_attrib->form.reader.string, str8_lit("char"), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *const_type_tag = char_type_tag->next;
|
DW_WriterTag *const_type_tag = char_type_tag->next;
|
||||||
{
|
{
|
||||||
T_Ok(const_type_tag->kind == DW_TagKind_ConstType);
|
T_Ok(const_type_tag->kind == DW_TagKind_ConstType);
|
||||||
@@ -706,13 +706,13 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(const_type_tag->abbrev_id == 3);
|
T_Ok(const_type_tag->abbrev_id == 3);
|
||||||
T_Ok(const_type_tag->info_off == 0x38);
|
T_Ok(const_type_tag->info_off == 0x38);
|
||||||
T_Ok(const_type_tag->first_attrib && const_type_tag->first_attrib == const_type_tag->last_attrib);
|
T_Ok(const_type_tag->first_attrib && const_type_tag->first_attrib == const_type_tag->last_attrib);
|
||||||
|
|
||||||
DW_WriterAttrib *type_attrib = const_type_tag->first_attrib;
|
DW_WriterAttrib *type_attrib = const_type_tag->first_attrib;
|
||||||
T_Ok(type_attrib->kind == DW_AttribKind_Type);
|
T_Ok(type_attrib->kind == DW_AttribKind_Type);
|
||||||
T_Ok(type_attrib->form.writer.kind == DW_WriterFormKind_Ref);
|
T_Ok(type_attrib->form.writer.kind == DW_WriterFormKind_Ref);
|
||||||
T_Ok(type_attrib->form.writer.ref == char_type_tag);
|
T_Ok(type_attrib->form.writer.ref == char_type_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *dup_char_type_tag = const_type_tag->next;
|
DW_WriterTag *dup_char_type_tag = const_type_tag->next;
|
||||||
{
|
{
|
||||||
T_Ok(dup_char_type_tag->kind == DW_TagKind_BaseType);
|
T_Ok(dup_char_type_tag->kind == DW_TagKind_BaseType);
|
||||||
@@ -722,25 +722,25 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(dup_char_type_tag->abbrev_id == 2);
|
T_Ok(dup_char_type_tag->abbrev_id == 2);
|
||||||
T_Ok(dup_char_type_tag->info_off == 0x3a);
|
T_Ok(dup_char_type_tag->info_off == 0x3a);
|
||||||
T_Ok(dup_char_type_tag->first_attrib != dup_char_type_tag->last_attrib);
|
T_Ok(dup_char_type_tag->first_attrib != dup_char_type_tag->last_attrib);
|
||||||
|
|
||||||
DW_WriterAttrib *byte_size_attrib = dup_char_type_tag->first_attrib;
|
DW_WriterAttrib *byte_size_attrib = dup_char_type_tag->first_attrib;
|
||||||
T_Ok(byte_size_attrib->kind == DW_AttribKind_ByteSize);
|
T_Ok(byte_size_attrib->kind == DW_AttribKind_ByteSize);
|
||||||
T_Ok(byte_size_attrib->form.reader.kind == DW_Form_Data1);
|
T_Ok(byte_size_attrib->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(byte_size_attrib->form.reader.data.size == 1);
|
T_Ok(byte_size_attrib->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)byte_size_attrib->form.reader.data.str == 1);
|
T_Ok(*(U8 *)byte_size_attrib->form.reader.data.str == 1);
|
||||||
|
|
||||||
DW_WriterAttrib *encoding_attrib = byte_size_attrib->next;
|
DW_WriterAttrib *encoding_attrib = byte_size_attrib->next;
|
||||||
T_Ok(encoding_attrib->kind == DW_AttribKind_Encoding);
|
T_Ok(encoding_attrib->kind == DW_AttribKind_Encoding);
|
||||||
T_Ok(encoding_attrib->form.reader.kind == DW_Form_Data1);
|
T_Ok(encoding_attrib->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(encoding_attrib->form.reader.data.size == 1);
|
T_Ok(encoding_attrib->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)encoding_attrib->form.reader.data.str == DW_ATE_SignedChar);
|
T_Ok(*(U8 *)encoding_attrib->form.reader.data.str == DW_ATE_SignedChar);
|
||||||
|
|
||||||
DW_WriterAttrib *name_attrib = encoding_attrib->next;
|
DW_WriterAttrib *name_attrib = encoding_attrib->next;
|
||||||
T_Ok(name_attrib->kind == DW_AttribKind_Name);
|
T_Ok(name_attrib->kind == DW_AttribKind_Name);
|
||||||
T_Ok(name_attrib->form.reader.kind == DW_Form_String);
|
T_Ok(name_attrib->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(name_attrib->form.reader.string, str8_lit("char"), 0));
|
T_Ok(str8_match(name_attrib->form.reader.string, str8_lit("char"), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *simple_struct_tag = dup_char_type_tag->next;
|
DW_WriterTag *simple_struct_tag = dup_char_type_tag->next;
|
||||||
{
|
{
|
||||||
T_Ok(simple_struct_tag->kind == DW_TagKind_StructureType);
|
T_Ok(simple_struct_tag->kind == DW_TagKind_StructureType);
|
||||||
@@ -749,12 +749,12 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(simple_struct_tag->attrib_count == 2);
|
T_Ok(simple_struct_tag->attrib_count == 2);
|
||||||
T_Ok(simple_struct_tag->abbrev_id == 4);
|
T_Ok(simple_struct_tag->abbrev_id == 4);
|
||||||
T_Ok(simple_struct_tag->info_off == 0x42);
|
T_Ok(simple_struct_tag->info_off == 0x42);
|
||||||
|
|
||||||
DW_WriterAttrib *simple_struct_name = simple_struct_tag->first_attrib;
|
DW_WriterAttrib *simple_struct_name = simple_struct_tag->first_attrib;
|
||||||
T_Ok(simple_struct_name->kind == DW_AttribKind_Name);
|
T_Ok(simple_struct_name->kind == DW_AttribKind_Name);
|
||||||
T_Ok(simple_struct_name->form.reader.kind == DW_Form_String);
|
T_Ok(simple_struct_name->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(simple_struct_name->form.reader.string, str8_lit("FooBar"), 0));
|
T_Ok(str8_match(simple_struct_name->form.reader.string, str8_lit("FooBar"), 0));
|
||||||
|
|
||||||
DW_WriterTag *m0_tag = simple_struct_tag->first_child;
|
DW_WriterTag *m0_tag = simple_struct_tag->first_child;
|
||||||
{
|
{
|
||||||
T_Ok(m0_tag->kind == DW_TagKind_Member);
|
T_Ok(m0_tag->kind == DW_TagKind_Member);
|
||||||
@@ -762,24 +762,24 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(m0_tag->attrib_count == 3);
|
T_Ok(m0_tag->attrib_count == 3);
|
||||||
T_Ok(m0_tag->info_off == 0x4b);
|
T_Ok(m0_tag->info_off == 0x4b);
|
||||||
T_Ok(m0_tag->abbrev_id == 5);
|
T_Ok(m0_tag->abbrev_id == 5);
|
||||||
|
|
||||||
DW_WriterAttrib *name = m0_tag->first_attrib;
|
DW_WriterAttrib *name = m0_tag->first_attrib;
|
||||||
T_Ok(name->kind == DW_AttribKind_Name);
|
T_Ok(name->kind == DW_AttribKind_Name);
|
||||||
T_Ok(name->form.reader.kind == DW_Form_String);
|
T_Ok(name->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(name->form.reader.string, str8_lit("m0"), 0));
|
T_Ok(str8_match(name->form.reader.string, str8_lit("m0"), 0));
|
||||||
|
|
||||||
DW_WriterAttrib *type = name->next;
|
DW_WriterAttrib *type = name->next;
|
||||||
T_Ok(type->kind == DW_AttribKind_Type);
|
T_Ok(type->kind == DW_AttribKind_Type);
|
||||||
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
||||||
T_Ok(type->form.reader.ref == 0x30);
|
T_Ok(type->form.reader.ref == 0x30);
|
||||||
|
|
||||||
DW_WriterAttrib *data_loc = type->next;
|
DW_WriterAttrib *data_loc = type->next;
|
||||||
T_Ok(data_loc->kind == DW_AttribKind_DataMemberLocation);
|
T_Ok(data_loc->kind == DW_AttribKind_DataMemberLocation);
|
||||||
T_Ok(data_loc->form.reader.kind == DW_Form_Data1);
|
T_Ok(data_loc->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(data_loc->form.reader.data.size == 1);
|
T_Ok(data_loc->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)data_loc->form.reader.data.str == 0);
|
T_Ok(*(U8 *)data_loc->form.reader.data.str == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *m1_tag = m0_tag->next;
|
DW_WriterTag *m1_tag = m0_tag->next;
|
||||||
{
|
{
|
||||||
T_Ok(m1_tag->kind == DW_TagKind_Member);
|
T_Ok(m1_tag->kind == DW_TagKind_Member);
|
||||||
@@ -787,30 +787,30 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(m1_tag->attrib_count == 4);
|
T_Ok(m1_tag->attrib_count == 4);
|
||||||
T_Ok(m1_tag->info_off == 0x51);
|
T_Ok(m1_tag->info_off == 0x51);
|
||||||
T_Ok(m1_tag->abbrev_id == 6);
|
T_Ok(m1_tag->abbrev_id == 6);
|
||||||
|
|
||||||
DW_WriterAttrib *name = m1_tag->first_attrib;
|
DW_WriterAttrib *name = m1_tag->first_attrib;
|
||||||
T_Ok(name->kind == DW_AttribKind_Name);
|
T_Ok(name->kind == DW_AttribKind_Name);
|
||||||
T_Ok(name->form.reader.kind == DW_Form_String);
|
T_Ok(name->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(name->form.reader.string, str8_lit("m1"), 0));
|
T_Ok(str8_match(name->form.reader.string, str8_lit("m1"), 0));
|
||||||
|
|
||||||
DW_WriterAttrib *type = name->next;
|
DW_WriterAttrib *type = name->next;
|
||||||
T_Ok(type->kind == DW_AttribKind_Type);
|
T_Ok(type->kind == DW_AttribKind_Type);
|
||||||
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
||||||
T_Ok(type->form.reader.ref == 0x30);
|
T_Ok(type->form.reader.ref == 0x30);
|
||||||
|
|
||||||
DW_WriterAttrib *data_loc = type->next;
|
DW_WriterAttrib *data_loc = type->next;
|
||||||
T_Ok(data_loc->kind == DW_AttribKind_DataMemberLocation);
|
T_Ok(data_loc->kind == DW_AttribKind_DataMemberLocation);
|
||||||
T_Ok(data_loc->form.reader.kind == DW_Form_Data1);
|
T_Ok(data_loc->form.reader.kind == DW_Form_Data1);
|
||||||
T_Ok(data_loc->form.reader.data.size == 1);
|
T_Ok(data_loc->form.reader.data.size == 1);
|
||||||
T_Ok(*(U8 *)data_loc->form.reader.data.str == 10);
|
T_Ok(*(U8 *)data_loc->form.reader.data.str == 10);
|
||||||
|
|
||||||
DW_WriterAttrib *byte_size = data_loc->next;
|
DW_WriterAttrib *byte_size = data_loc->next;
|
||||||
T_Ok(byte_size->kind == DW_AttribKind_ByteSize);
|
T_Ok(byte_size->kind == DW_AttribKind_ByteSize);
|
||||||
T_Ok(byte_size->form.reader.kind == DW_Form_ImplicitConst);
|
T_Ok(byte_size->form.reader.kind == DW_Form_ImplicitConst);
|
||||||
T_Ok(byte_size->form.reader.implicit_const == 123);
|
T_Ok(byte_size->form.reader.implicit_const == 123);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_WriterTag *main_tag = simple_struct_tag->next;
|
DW_WriterTag *main_tag = simple_struct_tag->next;
|
||||||
T_Ok(main_tag->next == 0);
|
T_Ok(main_tag->next == 0);
|
||||||
T_Ok(main_tag->kind == DW_TagKind_SubProgram);
|
T_Ok(main_tag->kind == DW_TagKind_SubProgram);
|
||||||
@@ -821,34 +821,34 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(external->kind == DW_AttribKind_External);
|
T_Ok(external->kind == DW_AttribKind_External);
|
||||||
T_Ok(external->form.reader.kind == DW_Form_Flag);
|
T_Ok(external->form.reader.kind == DW_Form_Flag);
|
||||||
T_Ok(external->form.reader.flag);
|
T_Ok(external->form.reader.flag);
|
||||||
|
|
||||||
DW_WriterAttrib *prototyped = external->next;
|
DW_WriterAttrib *prototyped = external->next;
|
||||||
T_Ok(prototyped->kind == DW_AttribKind_Prototyped);
|
T_Ok(prototyped->kind == DW_AttribKind_Prototyped);
|
||||||
T_Ok(prototyped->form.reader.kind == DW_Form_Flag);
|
T_Ok(prototyped->form.reader.kind == DW_Form_Flag);
|
||||||
T_Ok(prototyped->form.reader.flag);
|
T_Ok(prototyped->form.reader.flag);
|
||||||
|
|
||||||
DW_WriterAttrib *low_pc = prototyped->next;
|
DW_WriterAttrib *low_pc = prototyped->next;
|
||||||
T_Ok(low_pc->kind == DW_AttribKind_LowPc);
|
T_Ok(low_pc->kind == DW_AttribKind_LowPc);
|
||||||
T_Ok(low_pc->form.reader.kind == DW_Form_Addr);
|
T_Ok(low_pc->form.reader.kind == DW_Form_Addr);
|
||||||
T_Ok(low_pc->form.reader.addr.size == sizeof(U64));
|
T_Ok(low_pc->form.reader.addr.size == sizeof(U64));
|
||||||
T_Ok(*(U64 *)low_pc->form.reader.addr.str == 0x140001000);
|
T_Ok(*(U64 *)low_pc->form.reader.addr.str == 0x140001000);
|
||||||
|
|
||||||
DW_WriterAttrib *high_pc = low_pc->next;
|
DW_WriterAttrib *high_pc = low_pc->next;
|
||||||
T_Ok(high_pc->kind == DW_AttribKind_HighPc);
|
T_Ok(high_pc->kind == DW_AttribKind_HighPc);
|
||||||
T_Ok(high_pc->form.reader.kind == DW_Form_Addr);
|
T_Ok(high_pc->form.reader.kind == DW_Form_Addr);
|
||||||
T_Ok(high_pc->form.reader.addr.size == sizeof(U64));
|
T_Ok(high_pc->form.reader.addr.size == sizeof(U64));
|
||||||
T_Ok(*(U64 *)high_pc->form.reader.addr.str == 0x140001004);
|
T_Ok(*(U64 *)high_pc->form.reader.addr.str == 0x140001004);
|
||||||
|
|
||||||
DW_WriterAttrib *name = high_pc->next;
|
DW_WriterAttrib *name = high_pc->next;
|
||||||
T_Ok(name->kind == DW_AttribKind_Name);
|
T_Ok(name->kind == DW_AttribKind_Name);
|
||||||
T_Ok(name->form.reader.kind == DW_Form_String);
|
T_Ok(name->form.reader.kind == DW_Form_String);
|
||||||
T_Ok(str8_match(name->form.reader.string, str8_lit("main"), 0));
|
T_Ok(str8_match(name->form.reader.string, str8_lit("main"), 0));
|
||||||
|
|
||||||
DW_WriterAttrib *type = name->next;
|
DW_WriterAttrib *type = name->next;
|
||||||
T_Ok(type->kind == DW_AttribKind_Type);
|
T_Ok(type->kind == DW_AttribKind_Type);
|
||||||
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
T_Ok(type->form.reader.kind == DW_Form_Ref1);
|
||||||
T_Ok(type->form.reader.ref == simple_struct_tag->info_off);
|
T_Ok(type->form.reader.ref == simple_struct_tag->info_off);
|
||||||
|
|
||||||
DW_WriterAttrib *frame_base = type->next;
|
DW_WriterAttrib *frame_base = type->next;
|
||||||
T_Ok(frame_base->kind == DW_AttribKind_FrameBase);
|
T_Ok(frame_base->kind == DW_AttribKind_FrameBase);
|
||||||
T_Ok(frame_base->form.reader.kind == DW_Form_ExprLoc);
|
T_Ok(frame_base->form.reader.kind == DW_Form_ExprLoc);
|
||||||
@@ -860,7 +860,7 @@ T_BeginTest(dwarf_writer)
|
|||||||
T_Ok(frame_base_expr.first->next == 0);
|
T_Ok(frame_base_expr.first->next == 0);
|
||||||
T_Ok(frame_base_expr.first->prev == 0);
|
T_Ok(frame_base_expr.first->prev == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_writer_end(&writer);
|
dw_writer_end(&writer);
|
||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
@@ -873,7 +873,7 @@ T_BeginTest(value_in_register)
|
|||||||
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
U64 value = 0xc0ffee;
|
U64 value = 0xc0ffee;
|
||||||
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
|
|
||||||
// compile a simple program which reads the value from register 3
|
// compile a simple program which reads the value from register 3
|
||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
@@ -882,7 +882,7 @@ T_BeginTest(value_in_register)
|
|||||||
// evaluate the program
|
// evaluate the program
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
||||||
|
|
||||||
// validate eval result
|
// validate eval result
|
||||||
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_U64);
|
T_Ok(expr_value.type == DW_ExprValueType_U64);
|
||||||
@@ -898,16 +898,16 @@ T_BeginTest(value_in_x_register)
|
|||||||
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
U64 value = 0xc0ffee;
|
U64 value = 0xc0ffee;
|
||||||
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
|
|
||||||
// compile a simple program which reads the value from register 3
|
// compile a simple program which reads the value from register 3
|
||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(RegX), DW_ExprEnc_ULEB128(DW_RegX64_FsBase) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(RegX), DW_ExprEnc_ULEB128(DW_RegX64_FsBase) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
// evaluate the program
|
// evaluate the program
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
||||||
|
|
||||||
// validate eval result
|
// validate eval result
|
||||||
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_U64);
|
T_Ok(expr_value.type == DW_ExprValueType_U64);
|
||||||
@@ -922,11 +922,11 @@ T_BeginTest(address_of_value)
|
|||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_U64(addr) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_U64(addr) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
// evaluate the program
|
// evaluate the program
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
|
||||||
|
|
||||||
// validate eval result
|
// validate eval result
|
||||||
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
||||||
@@ -942,14 +942,14 @@ T_BeginTest(register_relative_variable)
|
|||||||
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
U64 value = 1;
|
U64 value = 1;
|
||||||
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
|
|
||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BReg11), DW_ExprEnc_SLEB128(44) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BReg11), DW_ExprEnc_SLEB128(44) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
||||||
|
|
||||||
// validate eval result
|
// validate eval result
|
||||||
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
||||||
@@ -962,11 +962,11 @@ T_BeginTest(frame_relative_variable)
|
|||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(FBReg), DW_ExprEnc_SLEB128(-50) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(FBReg), DW_ExprEnc_SLEB128(-50) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
U64 frame_base = 123;
|
U64 frame_base = 123;
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, frame_base, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, frame_base, 0, 0, max_U64, expr, 0, 0, 0, 0, &expr_value);
|
||||||
|
|
||||||
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
T_Ok(expr_eval == DW_ExprEvalResult_Ok);
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
||||||
T_Ok(expr_value.addr == frame_base -50);
|
T_Ok(expr_value.addr == frame_base -50);
|
||||||
@@ -985,20 +985,20 @@ T_BeginTest(call_by_reference)
|
|||||||
U8 *memory = push_array(scratch.arena, U8, 128);
|
U8 *memory = push_array(scratch.arena, U8, 128);
|
||||||
U64 value = 0xc0ffee;
|
U64 value = 0xc0ffee;
|
||||||
MemoryCopy(memory + 32, &value, sizeof(value));
|
MemoryCopy(memory + 32, &value, sizeof(value));
|
||||||
|
|
||||||
REGS_RegBlockX64 regs = {0};
|
REGS_RegBlockX64 regs = {0};
|
||||||
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, 58); // fsbase
|
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, 58); // fsbase
|
||||||
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
U64 memory_ptr = IntFromPtr(memory);
|
U64 memory_ptr = IntFromPtr(memory);
|
||||||
MemoryCopy((U8 *)®s + reg_range.min, &memory_ptr, sizeof(memory_ptr));
|
MemoryCopy((U8 *)®s + reg_range.min, &memory_ptr, sizeof(memory_ptr));
|
||||||
|
|
||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BRegX), DW_ExprEnc_ULEB128(58), DW_ExprEnc_SLEB128(32), DW_ExprEnc_Op(Deref) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(BRegX), DW_ExprEnc_ULEB128(58), DW_ExprEnc_SLEB128(32), DW_ExprEnc_Op(Deref) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
DW_ExprValue expr_value = { 0 };
|
DW_ExprValue expr_value = { 0 };
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, t_machine_op_mem_read, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, t_machine_op_mem_read, 0, &expr_value);
|
||||||
|
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_Generic);
|
T_Ok(expr_value.type == DW_ExprValueType_Generic);
|
||||||
T_Ok(expr_value.generic.size == sizeof(U64));
|
T_Ok(expr_value.generic.size == sizeof(U64));
|
||||||
T_Ok(*(U64 *)expr_value.generic.str == value);
|
T_Ok(*(U64 *)expr_value.generic.str == value);
|
||||||
@@ -1011,10 +1011,10 @@ T_BeginTest(plus_uconst)
|
|||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_Addr(struct_addr), DW_ExprEnc_Op(PlusUConst), DW_ExprEnc_ULEB128(4) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Addr), DW_ExprEnc_Addr(struct_addr), DW_ExprEnc_Op(PlusUConst), DW_ExprEnc_ULEB128(4) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, t_machine_op_mem_read, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, 0, 0, t_machine_op_mem_read, 0, &expr_value);
|
||||||
|
|
||||||
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
T_Ok(expr_value.type == DW_ExprValueType_Addr);
|
||||||
T_Ok(expr_value.addr == 0x123 + 4);
|
T_Ok(expr_value.addr == 0x123 + 4);
|
||||||
}
|
}
|
||||||
@@ -1037,11 +1037,11 @@ T_BeginTest(reg_split_spill)
|
|||||||
U64 value = 0xbbbb;
|
U64 value = 0xbbbb;
|
||||||
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(4), DW_ExprEnc_Op(Reg10), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(2) };
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(4), DW_ExprEnc_Op(Reg10), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(2) };
|
||||||
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
DW_ExprValue expr_value;
|
DW_ExprValue expr_value;
|
||||||
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user