eliminate os_core, move into base; eliminate regs, move into arch abstraction layer, define x64 regs in x64 layer; move win32 backend for os core (now base) functionality to top-level win32 layer

This commit is contained in:
Ryan Fleury
2026-05-08 15:21:21 -07:00
parent 24c858171f
commit aea4a4ff9d
148 changed files with 7942 additions and 5268 deletions
-1
View File
@@ -144,7 +144,6 @@ if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker
if "%radbin%"=="1" set didbuild=1 && %compile% ..\src\radbin\radbin_main.c %compile_link% %out%radbin.exe || exit /b 1
if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1
if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
if "%eval_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\eval_scratch.c %compile_link% %out%eval_scratch.exe || exit /b 1
if "%textperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\textperf.c %compile_link% %out%textperf.exe || exit /b 1
if "%convertperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\convertperf.c %compile_link% %out%convertperf.exe || exit /b 1
if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1
+4 -3
View File
@@ -49,13 +49,13 @@ commands =
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [raddbg wsl]
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [scratch]
.f2 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f2 = { .win = "build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [textperf]
// .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
@@ -67,7 +67,8 @@ commands =
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: running target
.f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f3 = { .win = "build torture", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "wsl ./build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+168
View File
@@ -0,0 +1,168 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Abstracted Architecture Functions
internal ARCH_Info *
arch_info_from_arch(Arch arch)
{
ARCH_Info *result = &arch_info_nil;
switch(arch)
{
default:{}break;
#if defined(X64_H)
case Arch_x64:
{
local_persist read_only ARCH_Info info =
{
.reg_block_size = sizeof(X64_RegBlock),
.instruction_pointer_reg_code = X64_RegCode_rip,
.stack_pointer_reg_code = X64_RegCode_rsp,
.reg_code_count = X64_RegCode_COUNT,
.reg_code_rng_table = x64_reg_code_rng_table,
.reg_code_name_table = x64_reg_code_name_table,
.reg_code_base_table = x64_reg_code_base_table,
.reg_code_is_vector_table = x64_reg_code_is_vector_table,
};
result = &info;
}break;
#endif
}
return result;
}
internal ARCH_RegCode
arch_reg_code_from_name(ARCH_Info *arch_info, String8 name)
{
ARCH_RegCode result = 0;
for EachIndex(code, arch_info->reg_code_count)
{
if(str8_match(arch_info->reg_code_name_table[code], name, 0))
{
result = code;
break;
}
}
return result;
}
internal ARCH_RegCode
arch_reg_code_from_rdi(Arch arch, RDI_RegCode code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *rdi_from_reg_code_table = arch_rdi_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(rdi_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
internal ARCH_RegCode
arch_reg_code_from_dw(Arch arch, DW_Reg code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *dw_from_reg_code_table = arch_dw_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(dw_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
internal B32
arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst)
{
B32 result = 0;
{
Rng1U16 legal_range = r1u16(0, arch_info->reg_block_size);
Rng1U16 try_range = range;
Rng1U16 read_range = intersect_1u16(legal_range, try_range);
U64 read_size = dim_1u16(read_range);
if(read_size != 0)
{
MemoryCopy(dst, (U8 *)block + read_range.min, read_size);
result = 1;
}
}
return result;
}
internal B32
arch_reg_block_write_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *src)
{
B32 result = 0;
Rng1U16 legal_range = r1u16(0, arch_info->reg_block_size);
Rng1U16 try_range = range;
Rng1U16 write_range = intersect_1u16(legal_range, try_range);
U64 write_size = dim_1u16(write_range);
if(write_size != 0)
{
MemoryCopy((U8 *)block + write_range.min, src, write_size);
result = 1;
}
return result;
}
internal U64
arch_ip_from_reg_block(ARCH_Info *arch_info, void *block)
{
U64 result = 0;
ARCH_RegCode reg_code = arch_info->instruction_pointer_reg_code;
if(reg_code < arch_info->reg_code_count)
{
arch_reg_block_read_range(arch_info, block, arch_info->reg_code_rng_table[reg_code], &result);
}
return result;
}
internal U64
arch_sp_from_reg_block(ARCH_Info *arch_info, void *block)
{
U64 result = 0;
ARCH_RegCode reg_code = arch_info->stack_pointer_reg_code;
if(reg_code < arch_info->reg_code_count)
{
arch_reg_block_read_range(arch_info, block, arch_info->reg_code_rng_table[reg_code], &result);
}
return result;
}
internal B32
arch_reg_block_write_ip(ARCH_Info *arch_info, void *block, U64 ip)
{
B32 result = 0;
ARCH_RegCode reg_code = arch_info->instruction_pointer_reg_code;
if(reg_code < arch_info->reg_code_count)
{
result = arch_reg_block_write_range(arch_info, block, arch_info->reg_code_rng_table[reg_code], &ip);
}
return result;
}
internal B32
arch_reg_block_write_sp(ARCH_Info *arch_info, void *block, U64 sp)
{
B32 result = 0;
ARCH_RegCode reg_code = arch_info->stack_pointer_reg_code;
if(reg_code < arch_info->reg_code_count)
{
result = arch_reg_block_write_range(arch_info, block, arch_info->reg_code_rng_table[reg_code], &sp);
}
return result;
}
+47
View File
@@ -0,0 +1,47 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ARCH_H
#define ARCH_H
////////////////////////////////
//~ rjf: Abstraction Backend Info
typedef U8 ARCH_RegCode;
typedef struct ARCH_Info ARCH_Info;
struct ARCH_Info
{
U16 reg_block_size;
ARCH_RegCode instruction_pointer_reg_code;
ARCH_RegCode stack_pointer_reg_code;
U16 reg_code_count;
Rng1U16 *reg_code_rng_table;
String8 *reg_code_name_table;
U8 *reg_code_base_table;
B8 *reg_code_is_vector_table;
};
////////////////////////////////
//~ rjf: Globals
global read_only Rng1U16 arch_reg_code_rng_nil = {0};
global read_only String8 arch_reg_code_name_nil = {0};
global read_only U8 arch_reg_code_u8_nil = 0;
global read_only ARCH_Info arch_info_nil = {0, 0, 0, 0, &arch_reg_code_rng_nil, &arch_reg_code_name_nil, &arch_reg_code_u8_nil, &arch_reg_code_u8_nil};
////////////////////////////////
//~ rjf: Abstracted Architecture Functions
internal ARCH_Info *arch_info_from_arch(Arch arch);
internal ARCH_RegCode arch_reg_code_from_name(ARCH_Info *arch_info, String8 name);
internal ARCH_RegCode arch_reg_code_from_rdi(Arch arch, RDI_RegCode code);
internal ARCH_RegCode arch_reg_code_from_dw(Arch arch, DW_Reg code);
internal B32 arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst);
internal B32 arch_reg_block_write_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *src);
internal U64 arch_ip_from_reg_block(ARCH_Info *arch_info, void *block);
internal U64 arch_sp_from_reg_block(ARCH_Info *arch_info, void *block);
internal B32 arch_reg_block_write_ip(ARCH_Info *arch_info, void *block, U64 ip);
internal B32 arch_reg_block_write_sp(ARCH_Info *arch_info, void *block, U64 sp);
#endif // REGS_H
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "arch/arch.c"
#if defined(DWARF_H)
# include "arch/dwarf/arch_dwarf.c"
#endif
#if defined(RDI_H)
# include "arch/rdi/arch_rdi.c"
#endif
+15
View File
@@ -0,0 +1,15 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ARCH_INC_H
#define ARCH_INC_H
#include "arch/arch.h"
#if defined(DWARF_H)
# include "arch/dwarf/arch_dwarf.h"
#endif
#if defined(RDI_H)
# include "arch/rdi/arch_rdi.h"
#endif
#endif // ARCH_INC_H
+19
View File
@@ -0,0 +1,19 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal U8 *
arch_dw_from_reg_code_table_from_arch(Arch arch)
{
U8 *result = &arch_reg_code_u8_nil;
switch(arch)
{
default:{}break;
#if defined(X64_H)
case Arch_x64:
{
result = dw_reg_code_from_x64_table;
}break;
#endif
}
return result;
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ARCH_DWARF_H
#define ARCH_DWARF_H
internal U8 *arch_dw_from_reg_code_table_from_arch(Arch arch);
#endif // ARCH_DWARF_H
+19
View File
@@ -0,0 +1,19 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal U8 *
arch_rdi_from_reg_code_table_from_arch(Arch arch)
{
U8 *result = &arch_reg_code_u8_nil;
switch(arch)
{
default:{}break;
#if defined(X64_H)
case Arch_x64:
{
result = rdi_reg_code_from_x64_table;
}break;
#endif
}
return result;
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ARCH_RDI_H
#define ARCH_RDI_H
internal U8 *arch_rdi_from_reg_code_table_from_arch(Arch arch);
#endif // ARCH_RDI_H
+3 -3
View File
@@ -108,7 +108,7 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
{
RWMutexScope(stripe->rw_mutex, 1) for(;;)
{
B32 out_of_time = (os_now_microseconds() >= endt_us);
B32 out_of_time = (now_time_us() >= endt_us);
// rjf: find node in cache
AC_Node *node = 0;
@@ -141,7 +141,7 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
node->working_count = 1;
node->evict_threshold_us = params->evict_threshold_us;
}
node->access_pt.last_time_touched_us = os_now_microseconds();
node->access_pt.last_time_touched_us = now_time_us();
node->access_pt.last_update_idx_touched = update_tick_idx();
// rjf: request
@@ -602,7 +602,7 @@ ac_cancel_thread_entry_point(void *p)
{
for(;;)
{
os_sleep_milliseconds(50);
sleep_ms(50);
semaphore_take(ac_shared->cancel_thread_semaphore, max_U64);
{
for EachIndex(cache_slot_idx, ac_shared->cache_slots_count)
+14 -14
View File
@@ -19,24 +19,24 @@ arena_alloc_(ArenaParams *params)
// rjf: round up reserve/commit sizes
if(params->flags & ArenaFlag_LargePages)
{
reserve_size = AlignPow2(reserve_size, os_get_system_info()->large_page_size);
commit_size = AlignPow2(commit_size, os_get_system_info()->large_page_size);
reserve_size = AlignPow2(reserve_size, get_system_info()->large_page_size);
commit_size = AlignPow2(commit_size, get_system_info()->large_page_size);
}
else
{
reserve_size = AlignPow2(reserve_size, os_get_system_info()->page_size);
commit_size = AlignPow2(commit_size, os_get_system_info()->page_size);
reserve_size = AlignPow2(reserve_size, get_system_info()->page_size);
commit_size = AlignPow2(commit_size, get_system_info()->page_size);
}
if(params->flags & ArenaFlag_LargePages)
{
base = os_reserve_large(reserve_size);
os_commit_large(base, commit_size);
base = reserve_memory_large(reserve_size);
commit_memory_large(base, commit_size);
}
else
{
base = os_reserve(reserve_size);
os_commit(base, commit_size);
base = reserve_memory(reserve_size);
commit_memory(base, commit_size);
}
AsanPoisonMemoryRegion(base, commit_size);
// TODO(rjf): we need to reintroduce this later when we have the ability to remove annotations...
@@ -52,7 +52,7 @@ arena_alloc_(ArenaParams *params)
if(Unlikely(base == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
abort_self(1);
}
#endif
@@ -90,7 +90,7 @@ arena_release(Arena *arena)
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
{
prev = n->prev;
os_release(n, n->res);
release_memory(n, n->res);
}
}
@@ -179,11 +179,11 @@ arena_push(Arena *arena, U64 size, U64 align, B32 zero)
U8 *cmt_ptr = (U8 *)current + current->cmt;
if(current->flags & ArenaFlag_LargePages)
{
os_commit_large(cmt_ptr, cmt_size);
commit_memory_large(cmt_ptr, cmt_size);
}
else
{
os_commit(cmt_ptr, cmt_size);
commit_memory(cmt_ptr, cmt_size);
}
AsanPoisonMemoryRegion(cmt_ptr, cmt_size);
current->cmt = cmt_pst_clamped;
@@ -213,7 +213,7 @@ arena_push(Arena *arena, U64 size, U64 align, B32 zero)
if(Unlikely(result == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
abort_self(1);
}
#endif
@@ -246,7 +246,7 @@ arena_pop_to(Arena *arena, U64 pos)
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
{
prev = current->prev;
os_release(current, current->res);
release_memory(current, current->res);
}
#endif
arena->current = current;
+45
View File
@@ -471,6 +471,8 @@ union U128
U16 u16[8];
U32 u32[4];
U64 u64[2];
F32 f32[4];
F64 f64[2];
};
typedef union U256 U256;
union U256
@@ -480,6 +482,8 @@ union U256
U32 u32[8];
U64 u64[4];
U128 u128[2];
F32 f32[8];
F64 f64[4];
};
typedef union U512 U512;
union U512
@@ -490,8 +494,19 @@ union U512
U64 u64[8];
U128 u128[4];
U256 u256[2];
F32 f32[16];
F64 f64[8];
};
#pragma pack(push, 1)
typedef struct U80 U80;
struct U80
{
U64 int1_frac63;
U16 sign1_exp15;
};
#pragma pack(pop)
////////////////////////////////
//~ rjf: Basic Type Structures
@@ -653,6 +668,21 @@ Compiler;
# define Compiler_CURRENT Compiler_Null
#endif
////////////////////////////////
//~ rjf: Access Flags
typedef U32 AccessFlags;
enum
{
AccessFlag_Read = (1<<0),
AccessFlag_Write = (1<<1),
AccessFlag_Execute = (1<<2),
AccessFlag_Append = (1<<3),
AccessFlag_ShareRead = (1<<4),
AccessFlag_ShareWrite = (1<<5),
AccessFlag_Inherited = (1<<6),
};
////////////////////////////////
//~ rjf: Text 2D Coordinates & Ranges
@@ -1044,6 +1074,21 @@ internal DateTime date_time_from_dense_time(DenseTime time);
internal DateTime date_time_from_micro_seconds(U64 time);
internal DateTime date_time_from_unix_time(U64 unix_time);
////////////////////////////////
//~ rjf: @per_os_impl Platform Time Functions
internal U64 now_time_us(void);
internal U32 now_time_unix(void);
internal DateTime now_time_universal(void);
internal DateTime universal_from_local_time(DateTime *dt);
internal DateTime local_from_universal_time(DateTime *dt);
internal void sleep_ms(U32 ms);
////////////////////////////////
//~ rjf: @per_os_impl Platform GUID Functions
internal Guid make_guid(void);
////////////////////////////////
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+20
View File
@@ -0,0 +1,20 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_DYNAMIC_LIBARIES_H
#define BASE_DYNAMIC_LIBARIES_H
typedef struct Library Library;
struct Library
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: @per_os_impl Dynamically-Loaded Libraries
internal Library library_open(String8 path);
internal void library_close(Library lib);
internal VoidProc *library_load_proc(Library lib, String8 name);
#endif // BASE_DYNAMIC_LIBARIES_H
+5 -2
View File
@@ -11,6 +11,9 @@ global B32 async_loop_again_high_priority = 0;
global B32 global_async_exit = 0;
thread_static B32 is_async_thread = 0;
// NOTE(rjf): defined by target
internal void entry_point(CmdLine *cmdline);
internal void
main_thread_base_entry_point(int arguments_count, char **arguments)
{
@@ -100,7 +103,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
#if defined(DBG_ENGINE_CORE_H)
num_main_threads += 1;
#endif
U64 num_async_threads = os_get_system_info()->logical_processor_count;
U64 num_async_threads = get_system_info()->logical_processor_count;
U64 num_main_threads_clamped = Min(num_async_threads, num_main_threads);
num_async_threads -= num_main_threads_clamped;
String8 num_async_threads_string = cmd_line_string(&cmdline, str8_lit("async_thread_count"));
@@ -192,7 +195,7 @@ async_thread_entry_point(void *params)
{
if(!ins_atomic_u32_eval(&async_loop_again))
{
MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, os_now_microseconds()+1000000);
MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, now_time_us()+1000000);
}
ins_atomic_u32_eval_assign(&async_loop_again, 0);
ins_atomic_u32_eval_assign(&async_loop_again_high_priority, 0);
+169
View File
@@ -0,0 +1,169 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Handle Type Functions
internal File
file_zero(void)
{
File f = {0};
return f;
}
internal B32
file_match(File a, File b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8
data_from_file_path(Arena *arena, String8 path)
{
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
FileProperties props = properties_from_file(file);
String8 data = string_from_file_range(arena, file, r1u64(0, props.size));
file_close(file);
return data;
}
internal B32
write_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
File file = file_open(AccessFlag_Write, path);
if(!file_match(file, file_zero()))
{
U64 bytes_written = file_write(file, r1u64(0, data.size), data.str);
good = (bytes_written == data.size);
file_close(file);
}
return good;
}
internal B32
write_data_list_to_file_path(String8 path, String8List list)
{
B32 good = 0;
File file = file_open(AccessFlag_Write, path);
if(!file_match(file, file_zero()))
{
Temp scratch = scratch_begin(0, 0);
U64 write_buffer_size = KB(64);
U8 *write_buffer = push_array_no_zero(scratch.arena, U8, write_buffer_size);
U64 write_buffer_write_pos = 0;
U64 write_buffer_read_pos = 0;
U64 file_off = 0;
{
for(String8Node *n = list.first; n != 0; n = n->next)
{
for(U64 n_off = 0; n_off < n->string.size;)
{
U64 write_buffer_unconsumed_size = (write_buffer_write_pos - write_buffer_read_pos);
U64 write_buffer_available_size = (write_buffer_size - write_buffer_unconsumed_size);
if(write_buffer_available_size == 0)
{
U64 file_write_size = file_write(file, r1u64(file_off, file_off+write_buffer_size), write_buffer);
if(file_write_size != write_buffer_size)
{
goto dbl_break;
}
file_off += write_buffer_size;
write_buffer_read_pos += write_buffer_size;
}
else
{
U64 bytes_to_copy = Min(write_buffer_available_size, n->string.size - n_off);
write_buffer_write_pos += ring_write(write_buffer, write_buffer_size, write_buffer_write_pos, n->string.str + n_off, bytes_to_copy);
n_off += bytes_to_copy;
}
}
}
if(write_buffer_write_pos > write_buffer_read_pos)
{
U64 file_write_size = file_write(file, r1u64(file_off, file_off + (write_buffer_write_pos-write_buffer_read_pos)), write_buffer);
file_off += file_write_size;
}
}
dbl_break:;
good = (file_off == list.total_size);
file_close(file);
scratch_end(scratch);
}
return good;
}
internal B32
append_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
if(data.size != 0)
{
File file = file_open(AccessFlag_Write|AccessFlag_Append, path);
if(!file_match(file, file_zero()))
{
U64 pos = properties_from_file(file).size;
U64 bytes_written = file_write(file, r1u64(pos, pos+data.size), data.str);
good = (bytes_written == data.size);
file_close(file);
}
}
return good;
}
internal FileID
id_from_file_path(String8 path)
{
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
FileID id = id_from_file(file);
file_close(file);
return id;
}
internal S64
file_id_compare(FileID a, FileID b)
{
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
return cmp;
}
internal String8
string_from_file_range(Arena *arena, File file, Rng1U64 range)
{
U64 pre_pos = arena_pos(arena);
String8 result;
result.size = dim_1u64(range);
result.str = push_array_no_zero(arena, U8, result.size);
U64 actual_read_size = file_read(file, range, result.str);
if(actual_read_size < result.size)
{
arena_pop_to(arena, pre_pos + actual_read_size);
result.size = actual_read_size;
}
return result;
}
internal String8
file_read_cstring(Arena *arena, File file, U64 off)
{
Temp scratch = scratch_begin(&arena, 1);
String8List block_list = {0};
for(U64 cursor = off, stride = 256;; cursor += stride)
{
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
U64 read_size = file_read(file, r1u64(cursor, cursor + stride), raw_block);
String8 block = str8_cstring_capped(raw_block, raw_block+read_size);
str8_list_push(scratch.arena, &block_list, block);
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
{
break;
}
}
String8 result = str8_list_join(arena, &block_list, 0);
scratch_end(scratch);
return result;
}
+102
View File
@@ -0,0 +1,102 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_FILES_H
#define BASE_FILES_H
typedef U32 FileIterFlags;
enum
{
FileIterFlag_SkipFolders = (1 << 0),
FileIterFlag_SkipFiles = (1 << 1),
FileIterFlag_SkipHiddenFiles = (1 << 2),
FileIterFlag_Done = (1 << 31),
};
typedef struct FileIter FileIter;
struct FileIter
{
FileIterFlags flags;
U8 memory[800];
};
typedef struct FileInfo FileInfo;
struct FileInfo
{
String8 name;
FileProperties props;
};
// nick: on-disk file identifier
typedef struct FileID FileID;
struct FileID
{
U64 v[3];
};
typedef struct File File;
struct File
{
U64 u64[1];
};
typedef struct FileMap FileMap;
struct FileMap
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: Handle Type Functions
internal File file_zero(void);
internal B32 file_match(File a, File b);
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8 data_from_file_path(Arena *arena, String8 path);
internal B32 write_data_to_file_path(String8 path, String8 data);
internal B32 write_data_list_to_file_path(String8 path, String8List list);
internal B32 append_data_to_file_path(String8 path, String8 data);
internal FileID id_from_file_path(String8 path);
internal S64 file_id_compare(FileID a, FileID b);
internal String8 string_from_file_range(Arena *arena, File file, Rng1U64 range);
internal String8 file_read_cstring(Arena *arena, File file, U64 off);
////////////////////////////////
//~ rjf: @per_os_impl File System (Implemented Per-OS)
//- rjf: files
internal File file_open(AccessFlags flags, String8 path);
internal void file_close(File file);
internal U64 file_read(File file, Rng1U64 rng, void *out_data);
#define file_read_struct(f, off, ptr) file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr))
internal U64 file_write(File file, Rng1U64 rng, void *data);
internal B32 file_set_times(File file, DateTime time);
internal FileProperties properties_from_file(File file);
internal FileID id_from_file(File file);
internal B32 file_reserve_size(File file, U64 size);
internal B32 delete_file_at_path(String8 path);
internal B32 copy_file_path(String8 dst, String8 src);
internal B32 move_file_path(String8 dst, String8 src);
internal String8 full_path_from_path(Arena *arena, String8 path);
internal B32 file_path_exists(String8 path);
internal B32 folder_path_exists(String8 path);
internal FileProperties properties_from_file_path(String8 path);
//- rjf: file maps
internal FileMap file_map_open(AccessFlags flags, File file);
internal void file_map_close(FileMap map);
internal void * file_map_view_open(FileMap map, AccessFlags flags, Rng1U64 range);
internal void file_map_view_close(FileMap map, void *ptr, Rng1U64 range);
//- rjf: directory iteration
internal FileIter *file_iter_begin(Arena *arena, String8 path, FileIterFlags flags);
internal B32 file_iter_next(Arena *arena, FileIter *iter, FileInfo *info_out);
internal void file_iter_end(FileIter *iter);
//- rjf: directory creation
internal B32 make_directory(String8 path);
#endif // BASE_FILES_H
+14
View File
@@ -9,14 +9,28 @@
#include "base_core.c"
#include "base_profile.c"
#include "base_memory.c"
#include "base_arena.c"
#include "base_math.c"
#include "base_strings.c"
#include "base_hash.c"
#include "base_system.c"
#include "base_threads.c"
#include "base_thread_context.c"
#include "base_files.c"
#include "base_shared_memory.c"
#include "base_processes.c"
#include "base_dynamic_libraries.c"
#include "base_command_line.c"
#include "base_markup.c"
#include "base_meta.c"
#include "base_log.c"
#include "base_entry_point.c"
#if OS_WINDOWS
# include "win32/base/win32_base.c"
#elif OS_LINUX
# include "linux/base/linux_base.c"
#else
# error Operating system backend not found for base layer.
#endif
+14
View File
@@ -11,16 +11,30 @@
#include "base_core.h"
#include "base_profile.h"
#include "base_memory.h"
#include "base_arena.h"
#include "base_math.h"
#include "base_strings.h"
#include "base_hash.h"
#include "base_system.h"
#include "base_threads.h"
#include "base_thread_context.h"
#include "base_files.h"
#include "base_shared_memory.h"
#include "base_processes.h"
#include "base_dynamic_libraries.h"
#include "base_command_line.h"
#include "base_markup.h"
#include "base_meta.h"
#include "base_log.h"
#include "base_entry_point.h"
#if OS_WINDOWS
# include "win32/base/win32_base.h"
#elif OS_LINUX
# include "linux/base/linux_base.h"
#else
# error Operating system backend not found for base layer.
#endif
#endif // BASE_INC_H
-19
View File
@@ -1,21 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal void
set_thread_name(String8 string)
{
ProfThreadName("%.*s", str8_varg(string));
os_set_thread_name(string);
}
internal void
set_thread_namef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
set_thread_name(string);
va_end(args);
scratch_end(scratch);
}
-2
View File
@@ -15,8 +15,6 @@
# define LAYER_COLOR 0x404040ff
#endif
internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...);
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__), raddbg_thread_color_u32(LAYER_COLOR))
#endif // BASE_MARKUP_H
+20
View File
@@ -407,6 +407,26 @@ transpose_4x4f32(Mat4x4F32 mat)
////////////////////////////////
//~ rjf: Range Ops
internal Rng1U8 rng_1u8(U8 min, U8 max) {Rng1U8 r = {min, max}; if(r.min > r.max) { Swap(U8, r.min, r.max); } return r;}
internal Rng1U8 shift_1u8(Rng1U8 r, U8 x) {r.min += x; r.max += x; return r;}
internal Rng1U8 pad_1u8(Rng1U8 r, U8 x) {r.min -= x; r.max += x; return r;}
internal U8 center_1u8(Rng1U8 r) {U8 c = (r.min+r.max)/2; return c;}
internal B32 contains_1u8(Rng1U8 r, U8 x) {B32 c = (r.min <= x && x < r.max); return c;}
internal U8 dim_1u8(Rng1U8 r) {U8 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;}
internal Rng1U8 union_1u8(Rng1U8 a, Rng1U8 b) {Rng1U8 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;}
internal Rng1U8 intersect_1u8(Rng1U8 a, Rng1U8 b) {Rng1U8 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;}
internal U8 clamp_1u8(Rng1U8 r, U8 v) {v = Clamp(r.min, v, r.max); return v;}
internal Rng1U16 rng_1u16(U16 min, U16 max) {Rng1U16 r = {min, max}; if(r.min > r.max) { Swap(U16, r.min, r.max); } return r;}
internal Rng1U16 shift_1u16(Rng1U16 r, U16 x) {r.min += x; r.max += x; return r;}
internal Rng1U16 pad_1u16(Rng1U16 r, U16 x) {r.min -= x; r.max += x; return r;}
internal U16 center_1u16(Rng1U16 r) {U16 c = (r.min+r.max)/2; return c;}
internal B32 contains_1u16(Rng1U16 r, U16 x) {B32 c = (r.min <= x && x < r.max); return c;}
internal U16 dim_1u16(Rng1U16 r) {U16 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;}
internal Rng1U16 union_1u16(Rng1U16 a, Rng1U16 b) {Rng1U16 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;}
internal Rng1U16 intersect_1u16(Rng1U16 a, Rng1U16 b) {Rng1U16 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;}
internal U16 clamp_1u16(Rng1U16 r, U16 v) {v = Clamp(r.min, v, r.max); return v;}
internal Rng1U32 rng_1u32(U32 min, U32 max) {Rng1U32 r = {min, max}; if(r.min > r.max) { Swap(U32, r.min, r.max); } return r;}
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x) {r.min += x; r.max += x; return r;}
internal Rng1U32 pad_1u32(Rng1U32 r, U32 x) {r.min -= x; r.max += x; return r;}
+44
View File
@@ -177,6 +177,28 @@ struct Mat4x4F32
//- rjf: 1-range
typedef union Rng1U8 Rng1U8;
union Rng1U8
{
struct
{
U8 min;
U8 max;
};
U8 v[2];
};
typedef union Rng1U16 Rng1U16;
union Rng1U16
{
struct
{
U16 min;
U16 max;
};
U16 v[2];
};
typedef union Rng1U32 Rng1U32;
union Rng1U32
{
@@ -546,6 +568,28 @@ internal Mat4x4F32 transpose_4x4f32(Mat4x4F32 mat);
////////////////////////////////
//~ rjf: Range Ops
#define r1u8(min, max) rng_1u8((min), (max))
internal Rng1U8 rng_1u8(U8 min, U8 max);
internal Rng1U8 shift_1u8(Rng1U8 r, U8 x);
internal Rng1U8 pad_1u8(Rng1U8 r, U8 x);
internal U8 center_1u8(Rng1U8 r);
internal B32 contains_1u8(Rng1U8 r, U8 x);
internal U8 dim_1u8(Rng1U8 r);
internal Rng1U8 union_1u8(Rng1U8 a, Rng1U8 b);
internal Rng1U8 intersect_1u8(Rng1U8 a, Rng1U8 b);
internal U8 clamp_1u8(Rng1U8 r, U8 v);
#define r1u16(min, max) rng_1u16((min), (max))
internal Rng1U16 rng_1u16(U16 min, U16 max);
internal Rng1U16 shift_1u16(Rng1U16 r, U16 x);
internal Rng1U16 pad_1u16(Rng1U16 r, U16 x);
internal U16 center_1u16(Rng1U16 r);
internal B32 contains_1u16(Rng1U16 r, U16 x);
internal U16 dim_1u16(Rng1U16 r);
internal Rng1U16 union_1u16(Rng1U16 a, Rng1U16 b);
internal Rng1U16 intersect_1u16(Rng1U16 a, Rng1U16 b);
internal U16 clamp_1u16(Rng1U16 r, U16 v);
#define r1u32(min, max) rng_1u32((min), (max))
internal Rng1U32 rng_1u32(U32 min, U32 max);
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x);
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+26
View File
@@ -0,0 +1,26 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_MEMORY_H
#define BASE_MEMORY_H
typedef struct SharedMemory SharedMemory;
struct SharedMemory
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: @per_os_impl Platform Memory Allocation
//- rjf: basic
internal void *reserve_memory(U64 size);
internal B32 commit_memory(void *ptr, U64 size);
internal void decommit_memory(void *ptr, U64 size);
internal void release_memory(void *ptr, U64 size);
//- rjf: large pages
internal void *reserve_memory_large(U64 size);
internal B32 commit_memory_large(void *ptr, U64 size);
#endif // BASE_MEMORY_H
+115
View File
@@ -0,0 +1,115 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Handle Type Functions
internal Process
process_zero(void)
{
Process p = {0};
return p;
}
internal B32
process_match(Process a, Process b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
internal void
process_list_push(Arena *arena, ProcessList *list, Process p)
{
ProcessNode *n = push_array(arena, ProcessNode, 1);
SLLQueuePush(list->first, list->last, n);
n->v = p;
list->count += 1;
}
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal Process
launch_cmd_line(String8 string)
{
Temp scratch = scratch_begin(0, 0);
U8 split_chars[] = {' '};
String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0);
Process process = {0};
if(parts.node_count != 0)
{
// rjf: unpack exe part
String8 exe = parts.first->string;
String8 exe_folder = str8_chop_last_slash(exe);
if(exe_folder.size == 0)
{
exe_folder = get_current_path(scratch.arena);
}
// rjf: find stdout delimiter
String8Node *stdout_delimiter_n = 0;
for(String8Node *n = parts.first; n != 0; n = n->next)
{
if(str8_match(n->string, str8_lit(">"), 0))
{
stdout_delimiter_n = n;
break;
}
}
// rjf: read stdout path
String8 stdout_path = {0};
if(stdout_delimiter_n && stdout_delimiter_n->next)
{
stdout_path = stdout_delimiter_n->next->string;
}
// rjf: open stdout handle
File stdout_handle = {0};
if(stdout_path.size != 0)
{
File file = file_open(AccessFlag_Write|AccessFlag_Read, stdout_path);
file_close(file);
stdout_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, stdout_path);
}
// rjf: form command line
String8List cmdline = {0};
for(String8Node *n = parts.first; n != stdout_delimiter_n && n != 0; n = n->next)
{
str8_list_push(scratch.arena, &cmdline, n->string);
}
// rjf: launch
ProcessLaunchParams params = {0};
params.cmd_line = cmdline;
params.path = exe_folder;
params.inherit_env = 1;
params.stdout_file = stdout_handle;
process = process_launch(&params);
// rjf: close stdout handle
{
if(stdout_path.size != 0)
{
file_close(stdout_handle);
}
}
}
scratch_end(scratch);
return process;
}
internal Process
launch_cmd_linef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = str8fv(scratch.arena, fmt, args);
Process result = launch_cmd_line(string);
va_end(args);
scratch_end(scratch);
return result;
}
+87
View File
@@ -0,0 +1,87 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_PROCESSES_H
#define BASE_PROCESSES_H
typedef struct ProcessInfo ProcessInfo;
struct ProcessInfo
{
U32 pid;
B32 large_pages_allowed;
String8 binary_path;
String8 initial_path;
String8 user_program_data_path;
String8List module_load_paths;
String8List environment;
};
typedef struct Process Process;
struct Process
{
U64 u64[1];
};
typedef struct ProcessNode ProcessNode;
struct ProcessNode
{
ProcessNode *next;
Process v;
};
typedef struct ProcessList ProcessList;
struct ProcessList
{
ProcessNode *first;
ProcessNode *last;
U64 count;
};
typedef struct ProcessLaunchParams ProcessLaunchParams;
struct ProcessLaunchParams
{
String8List cmd_line;
String8 path;
String8List env;
B32 inherit_env;
B32 debug_subprocesses;
B32 consoleless;
File stdout_file;
File stderr_file;
File stdin_file;
};
////////////////////////////////
//~ rjf: Handle Type Functions
internal Process process_zero(void);
internal B32 process_match(Process a, Process b);
internal void process_list_push(Arena *arena, ProcessList *list, Process p);
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal Process launch_cmd_line(String8 string);
internal Process launch_cmd_linef(char *fmt, ...);
////////////////////////////////
//~ rjf: @per_os_impl Aborting
internal void abort_self(S32 exit_code);
////////////////////////////////
//~ rjf: @per_os_impl Process Info
internal ProcessInfo *get_process_info(void);
internal String8 get_current_path(Arena *arena);
internal U32 get_process_start_time_unix(void);
////////////////////////////////
//~ rjf: @per_os_impl Child Processes
internal Process process_launch(ProcessLaunchParams *params);
internal B32 process_join(Process process, U64 endt_us, U64 *exit_code_out);
internal void process_detach(Process process);
internal B32 process_kill(Process process);
#endif // BASE_PROCESSES_H
+1 -1
View File
@@ -24,7 +24,7 @@ spall_begin(char *fmt, ...)
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
spall_buffer_begin_ex(&spall_profile, &spall_buffer, string.str, string.size, os_now_microseconds(), spall_tid, spall_pid);
spall_buffer_begin_ex(&spall_profile, &spall_buffer, string.str, string.size, now_time_us(), spall_tid, spall_pid);
va_end(args);
scratch_end(scratch);
}
+1 -1
View File
@@ -79,7 +79,7 @@ thread_static U32 spall_pid = 0;
internal inline void spall_begin(char *fmt, ...);
# define ProfBegin(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
# define ProfBeginDynamic(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
# define ProfEnd(...) (spall_capturing ? (spall_buffer_end_ex(&spall_profile, &spall_buffer, os_now_microseconds(), spall_tid, spall_pid)), 0 : 0)
# define ProfEnd(...) (spall_capturing ? (spall_buffer_end_ex(&spall_profile, &spall_buffer, now_time_us(), spall_tid, spall_pid)), 0 : 0)
# define ProfTick(...)
# define ProfIsCapturing(...) (!!spall_capturing)
# define ProfBeginCapture(...) (spall_capturing = 1)
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_SHARED_MEMORY_H
#define BASE_SHARED_MEMORY_H
////////////////////////////////
//~ rjf: @os_hooks Shared Memory
internal SharedMemory shared_memory_alloc(U64 size, String8 name);
internal SharedMemory shared_memory_open(String8 name);
internal void shared_memory_close(SharedMemory handle);
internal void * shared_memory_view_open(SharedMemory handle, Rng1U64 range);
internal void shared_memory_view_close(SharedMemory handle, void *ptr, Rng1U64 range);
#endif // BASE_SHARED_MEMORY_H
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+22
View File
@@ -0,0 +1,22 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_SYSTEM_H
#define BASE_SYSTEM_H
typedef struct SystemInfo SystemInfo;
struct SystemInfo
{
U32 logical_processor_count;
U64 page_size;
U64 large_page_size;
U64 allocation_granularity;
String8 machine_name;
};
////////////////////////////////
//~ rjf: @per_os_impl System Info
internal SystemInfo *get_system_info(void);
#endif // BASE_SYSTEM_H
+4 -4
View File
@@ -108,7 +108,7 @@ tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_sr
}
// rjf: all cases: barrier
os_barrier_wait(tctx->lane_ctx.barrier);
barrier_wait(tctx->lane_ctx.barrier);
// rjf: doing broadcast -> copy from broadcast memory on destination lanes
if(broadcast_ptr != 0 && lane_idx() != broadcast_src_lane_idx)
@@ -119,7 +119,7 @@ tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_sr
// rjf: doing broadcast -> barrier on all lanes
if(broadcast_ptr != 0)
{
os_barrier_wait(tctx->lane_ctx.barrier);
barrier_wait(tctx->lane_ctx.barrier);
}
ProfEnd();
@@ -202,7 +202,7 @@ internal void
access_touch(Access *access, AccessPt *pt, CondVar cv)
{
ins_atomic_u64_inc_eval(&pt->access_refcount);
ins_atomic_u64_eval_assign(&pt->last_time_touched_us, os_now_microseconds());
ins_atomic_u64_eval_assign(&pt->last_time_touched_us, now_time_us());
ins_atomic_u64_eval_assign(&pt->last_update_idx_touched, update_tick_idx());
Touch *touch = tctx_thread_local->free_touch;
if(touch != 0)
@@ -228,7 +228,7 @@ access_pt_is_expired_(AccessPt *pt, AccessPtExpireParams *params)
U64 last_time_touched_us = ins_atomic_u64_eval(&pt->last_time_touched_us);
U64 last_update_idx_touched = ins_atomic_u64_eval(&pt->last_update_idx_touched);
B32 result = (access_refcount == 0 &&
last_time_touched_us + params->time <= os_now_microseconds() &&
last_time_touched_us + params->time <= now_time_us() &&
last_update_idx_touched + params->update_idxs <= update_tick_idx());
return result;
}
+23 -65
View File
@@ -1,70 +1,6 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Thread Functions
internal Thread
thread_launch(ThreadEntryPointFunctionType *f, void *p)
{
Thread thread = os_thread_launch(f, p);
return thread;
}
internal B32
thread_join(Thread thread, U64 endt_us)
{
B32 result = os_thread_join(thread, endt_us);
return result;
}
internal void
thread_detach(Thread thread)
{
os_thread_detach(thread);
}
////////////////////////////////
//~ rjf: Synchronization Primitive Functions
//- rjf: recursive mutexes
internal Mutex mutex_alloc(void) {return os_mutex_alloc();}
internal void mutex_release(Mutex mutex) {os_mutex_release(mutex);}
internal void mutex_take(Mutex mutex) {os_mutex_take(mutex);}
internal void mutex_drop(Mutex mutex) {os_mutex_drop(mutex);}
//- rjf: reader/writer mutexes
internal RWMutex rw_mutex_alloc(void) {return os_rw_mutex_alloc();}
internal void rw_mutex_release(RWMutex mutex) {os_rw_mutex_release(mutex);}
internal void rw_mutex_take(RWMutex mutex, B32 write_mode) {os_rw_mutex_take(mutex, write_mode);}
internal void rw_mutex_drop(RWMutex mutex, B32 write_mode) {os_rw_mutex_drop(mutex, write_mode);}
//- rjf: condition variables
internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();}
internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);}
internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) {return os_cond_var_wait(cv, mutex, endt_us);}
internal B32 cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us) {return os_cond_var_wait_rw(cv, mutex_rw, write_mode, endt_us);}
internal void cond_var_signal(CondVar cv) {os_cond_var_signal(cv);}
internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);}
//- rjf: cross-process semaphores
internal Semaphore semaphore_alloc(U32 initial_count, U32 max_count, String8 name) {return os_semaphore_alloc(initial_count, max_count, name);}
internal void semaphore_release(Semaphore semaphore) {os_semaphore_release(semaphore);}
internal Semaphore semaphore_open(String8 name) {return os_semaphore_open(name);}
internal void semaphore_close(Semaphore semaphore) {os_semaphore_close(semaphore);}
internal B32 semaphore_take(Semaphore semaphore, U64 endt_us) {return os_semaphore_take(semaphore, endt_us);}
internal void semaphore_drop(Semaphore semaphore) {os_semaphore_drop(semaphore);}
//- rjf: barriers
internal Barrier barrier_alloc(U64 count) {return os_barrier_alloc(count);}
internal void barrier_release(Barrier barrier) {os_barrier_release(barrier);}
internal void barrier_wait(Barrier barrier) {os_barrier_wait(barrier);}
////////////////////////////////
//~ rjf: Table Stripe Functions
@@ -72,7 +8,7 @@ internal StripeArray
stripe_array_alloc(Arena *arena)
{
StripeArray array = {0};
array.count = os_get_system_info()->logical_processor_count;
array.count = get_system_info()->logical_processor_count;
array.v = push_array(arena, Stripe, array.count);
for EachIndex(idx, array.count)
{
@@ -100,3 +36,25 @@ stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx)
Stripe *stripe = &stripes->v[slot_idx%stripes->count];
return stripe;
}
////////////////////////////////
//~ rjf: Thread Info Helpers
internal void
set_thread_name(String8 string)
{
ProfThreadName("%.*s", str8_varg(string));
set_platform_thread_name(string);
}
internal void
set_thread_namef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
set_thread_name(string);
va_end(args);
scratch_end(scratch);
}
+23 -6
View File
@@ -67,14 +67,33 @@ struct StripeArray
};
////////////////////////////////
//~ rjf: Thread Functions
//~ rjf: Table Stripe Functions
internal StripeArray stripe_array_alloc(Arena *arena);
internal void stripe_array_release(StripeArray *stripes);
internal Stripe *stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx);
////////////////////////////////
//~ rjf: Thread Info Helpers
internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...);
////////////////////////////////
//~ rjf: @per_os_impl Current Thread Info
internal U32 tid(void);
internal void set_platform_thread_name(String8 name);
////////////////////////////////
//~ rjf: @per_os_impl Thread Functions
internal Thread thread_launch(ThreadEntryPointFunctionType *f, void *p);
internal B32 thread_join(Thread thread, U64 endt_us);
internal void thread_detach(Thread thread);
////////////////////////////////
//~ rjf: Synchronization Primitive Functions
//~ rjf: @per_os_impl Synchronization Primitive Functions
//- rjf: recursive mutexes
internal Mutex mutex_alloc(void);
@@ -124,10 +143,8 @@ internal void barrier_wait(Barrier barrier);
#define MutexScopeRWPromote(mutex) DeferLoop((rw_mutex_drop_r(mutex), rw_mutex_take_w(mutex)), (rw_mutex_drop_w(mutex), rw_mutex_take_r(mutex)))
////////////////////////////////
//~ rjf: Table Stripe Functions
//~ rjf: @per_os_impl Safe Calls
internal StripeArray stripe_array_alloc(Arena *arena);
internal void stripe_array_release(StripeArray *stripes);
internal Stripe *stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx);
internal void safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr);
#endif // BASE_THREADS_H
+3 -3
View File
@@ -46,7 +46,7 @@ c_init(void)
c_shared = push_array(arena, C_Shared, 1);
c_shared->arena = arena;
c_shared->blob_slots_count = 16384;
c_shared->blob_stripes_count = Min(c_shared->blob_slots_count, os_get_system_info()->logical_processor_count);
c_shared->blob_stripes_count = Min(c_shared->blob_slots_count, get_system_info()->logical_processor_count);
c_shared->blob_slots = push_array(arena, C_BlobSlot, c_shared->blob_slots_count);
c_shared->blob_stripes = push_array(arena, C_Stripe, c_shared->blob_stripes_count);
c_shared->blob_stripes_free_nodes = push_array(arena, C_BlobNode *, c_shared->blob_stripes_count);
@@ -58,7 +58,7 @@ c_init(void)
stripe->cv = cond_var_alloc();
}
c_shared->key_slots_count = 4096;
c_shared->key_stripes_count = Min(c_shared->key_slots_count, os_get_system_info()->logical_processor_count);
c_shared->key_stripes_count = Min(c_shared->key_slots_count, get_system_info()->logical_processor_count);
c_shared->key_slots = push_array(arena, C_KeySlot, c_shared->key_slots_count);
c_shared->key_stripes = push_array(arena, C_Stripe, c_shared->key_stripes_count);
c_shared->key_stripes_free_nodes = push_array(arena, C_KeyNode *, c_shared->key_stripes_count);
@@ -70,7 +70,7 @@ c_init(void)
stripe->cv = cond_var_alloc();
}
c_shared->root_slots_count = 4096;
c_shared->root_stripes_count = Min(c_shared->root_slots_count, os_get_system_info()->logical_processor_count);
c_shared->root_stripes_count = Min(c_shared->root_slots_count, get_system_info()->logical_processor_count);
c_shared->root_slots = push_array(arena, C_RootSlot, c_shared->root_slots_count);
c_shared->root_stripes = push_array(arena, C_Stripe, c_shared->root_stripes_count);
c_shared->root_stripes_free_nodes = push_array(arena, C_RootNode *, c_shared->root_stripes_count);
+9 -15
View File
@@ -17,26 +17,20 @@ d_init(void)
Arena *arena = arena_alloc();
d_ctrl_state = push_array(arena, D_CtrlState, 1);
d_ctrl_state->arena = arena;
for(Arch arch = (Arch)0; arch < Arch_COUNT; arch = (Arch)(arch+1))
for EachEnumVal(Arch, arch)
{
String8 *reg_names = regs_reg_code_string_table_from_arch(arch);
U64 reg_count = regs_reg_code_count_from_arch(arch);
String8 *alias_names = regs_alias_code_string_table_from_arch(arch);
U64 alias_count = regs_alias_code_count_from_arch(arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 reg_count = arch_info->reg_code_count;
String8 *reg_names = arch_info->reg_code_name_table;
d_ctrl_state->arch_string2reg_tables[arch] = e_string2num_map_make(d_ctrl_state->arena, 256);
d_ctrl_state->arch_string2alias_tables[arch] = e_string2num_map_make(d_ctrl_state->arena, 256);
for(U64 idx = 1; idx < reg_count; idx += 1)
{
e_string2num_map_insert(d_ctrl_state->arena, &d_ctrl_state->arch_string2reg_tables[arch], reg_names[idx], idx);
}
for(U64 idx = 1; idx < alias_count; idx += 1)
{
e_string2num_map_insert(d_ctrl_state->arena, &d_ctrl_state->arch_string2alias_tables[arch], alias_names[idx], idx);
}
}
d_ctrl_state->thread_reg_cache.slots_count = 1024;
d_ctrl_state->thread_reg_cache.slots = push_array(arena, D_ThreadRegCacheSlot, d_ctrl_state->thread_reg_cache.slots_count);
d_ctrl_state->thread_reg_cache.stripes_count = os_get_system_info()->logical_processor_count;
d_ctrl_state->thread_reg_cache.stripes_count = get_system_info()->logical_processor_count;
d_ctrl_state->thread_reg_cache.stripes = push_array(arena, D_ThreadRegCacheStripe, d_ctrl_state->thread_reg_cache.stripes_count);
for(U64 idx = 0; idx < d_ctrl_state->thread_reg_cache.stripes_count; idx += 1)
{
@@ -45,7 +39,7 @@ d_init(void)
}
d_ctrl_state->module_image_info_cache.slots_count = 1024;
d_ctrl_state->module_image_info_cache.slots = push_array(arena, D_ModuleImageInfoCacheSlot, d_ctrl_state->module_image_info_cache.slots_count);
d_ctrl_state->module_image_info_cache.stripes_count = os_get_system_info()->logical_processor_count;
d_ctrl_state->module_image_info_cache.stripes_count = get_system_info()->logical_processor_count;
d_ctrl_state->module_image_info_cache.stripes = push_array(arena, D_ModuleImageInfoCacheStripe, d_ctrl_state->module_image_info_cache.stripes_count);
for(U64 idx = 0; idx < d_ctrl_state->module_image_info_cache.stripes_count; idx += 1)
{
@@ -63,11 +57,11 @@ d_init(void)
d_ctrl_state->c2u_ring_cv = cond_var_alloc();
{
Temp scratch = scratch_begin(0, 0);
String8 user_program_data_path = os_get_process_info()->user_program_data_path;
String8 user_program_data_path = get_process_info()->user_program_data_path;
String8 user_data_folder = push_str8f(scratch.arena, "%S/raddbg/logs", user_program_data_path);
os_make_directory(user_data_folder);
make_directory(user_data_folder);
d_ctrl_state->ctrl_thread_log_path = push_str8f(d_ctrl_state->arena, "%S/ctrl_thread.raddbg_log", user_data_folder);
os_write_data_to_file_path(d_ctrl_state->ctrl_thread_log_path, str8_zero());
write_data_to_file_path(d_ctrl_state->ctrl_thread_log_path, str8_zero());
scratch_end(scratch);
}
d_ctrl_state->ctrl_thread_entity_ctx_rw_mutex = rw_mutex_alloc();
+113 -124
View File
@@ -885,7 +885,7 @@ d_entity_ctx_rw_store_alloc(void)
D_Entity *root = store->ctx.root = d_entity_alloc(store, &d_entity_nil, D_EntityKind_Root, Arch_Null, d_handle_zero(), 0);
D_Entity *local_machine = d_entity_alloc(store, root, D_EntityKind_Machine, Arch_CURRENT, d_handle_make(D_MachineID_Local, dmn_handle_zero()), 0);
Temp scratch = scratch_begin(0, 0);
String8 local_machine_name = push_str8f(scratch.arena, "This PC (%S)", os_get_system_info()->machine_name);
String8 local_machine_name = push_str8f(scratch.arena, "This PC (%S)", get_system_info()->machine_name);
d_entity_equip_string(store, local_machine, local_machine_name);
scratch_end(scratch);
return store;
@@ -1476,7 +1476,8 @@ d_reg_block_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle handle)
D_ThreadRegCache *cache = &d_ctrl_state->thread_reg_cache;
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
Arch arch = thread_entity->arch;
U64 reg_block_size = regs_block_size_from_arch(arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 reg_block_size = arch_info->reg_block_size;
U64 hash = d_hash_from_handle(handle);
U64 slot_idx = hash%cache->slots_count;
U64 stripe_idx = slot_idx%cache->stripes_count;
@@ -1543,8 +1544,9 @@ d_rip_from_thread(D_EntityCtx *ctx, D_Handle handle)
Temp scratch = scratch_begin(0, 0);
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
Arch arch = thread_entity->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
void *block = d_reg_block_from_thread(scratch.arena, ctx, handle);
U64 result = regs_rip_from_arch_block(arch, block);
U64 result = arch_ip_from_reg_block(arch_info, block);
scratch_end(scratch);
return result;
}
@@ -1555,8 +1557,9 @@ d_rsp_from_thread(D_EntityCtx *ctx, D_Handle handle)
Temp scratch = scratch_begin(0, 0);
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
Arch arch = thread_entity->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
void *block = d_reg_block_from_thread(scratch.arena, ctx, handle);
U64 result = regs_rsp_from_arch_block(arch, block);
U64 result = arch_sp_from_reg_block(arch_info, block);
scratch_end(scratch);
return result;
}
@@ -1708,7 +1711,7 @@ d_raddbg_data_from_module(Arena *arena, D_Handle module_handle)
}
////////////////////////////////
//~ rjf: Unwinding Functions}
//~ rjf: Unwinding Functions
//- rjf: [dwarf]
@@ -1765,6 +1768,7 @@ internal D_UnwindStepResult
d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D_Handle module_handle, Arch arch, void *regs, U64 endt_us, D_FrameUnwindContext *ctx_out)
{
Temp scratch = scratch_begin(&arena, 1);
ARCH_Info *arch_info = arch_info_from_arch(arch);
D_UnwindStepResult result = { .flags = D_UnwindFlag_Error };
// gather context for virtual stack unwinder
@@ -1794,7 +1798,7 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
}
// grab IP
U64 ip = regs_rip_from_arch_block(arch, regs);
U64 ip = arch_ip_from_reg_block(arch_info, regs);
// use .eh_frame_hdr to quickly locate nearest FDE
U64 fde_addr = eh_find_nearest_fde(eh_frame_hdr, &eh_ptr_ctx, ip);
@@ -1914,9 +1918,7 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
{
// setup machine ops
void *mem_read_ctx = 0;
void *reg_read_ctx = 0;
MachineOp_MemRead *mem_read_func = 0;
MachineOp_RegRead *reg_read_func = 0;
switch(arch)
{
case Arch_Null: break;
@@ -1925,12 +1927,8 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
D_MemoryReadContextDwarfX64 *mem_read_ctx_x64 = push_array(scratch.arena, D_MemoryReadContextDwarfX64, 1);
mem_read_ctx_x64->process_handle = process_handle;
mem_read_ctx_x64->endt_us = endt_us;
mem_read_ctx = mem_read_ctx_x64;
reg_read_ctx = regs;
mem_read_func = ctrl_machine_mem_read;
reg_read_func = regs_read_dwarf_x64;
}break;
case Arch_x86:
case Arch_arm64:
@@ -1943,7 +1941,7 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
// compute CFA for the row
U64 cfa = 0;
MachineOpResult unwind_status = dw_compute_cfa(arch, cfi_row, mem_read_func, mem_read_ctx, reg_read_func, reg_read_ctx, &cfa);
MachineOpResult unwind_status = dw_compute_cfa(arch, cfi_row, regs, mem_read_func, mem_read_ctx, &cfa);
// on success fill out output
if(unwind_status == MachineOpResult_Ok)
@@ -1990,26 +1988,17 @@ d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwi
reg_read_ctx = regs;
reg_write_ctx = regs;
mem_read_func = ctrl_machine_mem_read;
reg_read_func = regs_read_dwarf_x64;
reg_write_func = regs_write_dwarf_x64;
}break;
}
// apply register rules to the context
MachineOpResult unwind_status = dw_cfi_apply_register_rules(arch,
frame_ctx->cfa,
frame_ctx->cfi_row,
mem_read_func,
mem_read_ctx,
reg_read_func,
reg_read_ctx,
reg_write_func,
reg_write_ctx);
MachineOpResult unwind_status = dw_cfi_apply_register_rules(arch, frame_ctx->cfa, frame_ctx->cfi_row, regs, mem_read_func, mem_read_ctx);
// last frame typically has undefined rule for IP
if(frame_ctx->cfi_row->regs[frame_ctx->ret_addr_reg].rule == DW_CFI_RegisterRule_Undefined)
{
regs_arch_block_write_rip(arch, regs, 0);
ARCH_Info *arch_info = arch_info_from_arch(arch);
arch_reg_block_write_ip(arch_info, regs, 0);
}
// translate unwind status code
@@ -2021,11 +2010,11 @@ d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwi
//- rjf: [x64]
internal REGS_Reg64 *
d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg)
internal U64 *
d_unwind_reg_from_pe_gpr_reg__pe_x64(X64_RegBlock *regs, PE_UnwindGprRegX64 gpr_reg)
{
local_persist REGS_Reg64 dummy = {0};
REGS_Reg64 *result = &dummy;
local_persist U64 dummy = {0};
U64 *result = &dummy;
switch(gpr_reg)
{
case PE_UnwindGprRegX64_RAX:{result = &regs->rax;}break;
@@ -2049,7 +2038,7 @@ d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64
}
internal D_UnwindStepResult
d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us)
d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, X64_RegBlock *regs, U64 endt_us)
{
B32 is_stale = 0;
B32 is_good = 1;
@@ -2058,7 +2047,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
//////////////////////////////
//- rjf: unpack parameters
//
U64 rip_voff = regs->rip.u64 - module_base_vaddr;
U64 rip_voff = regs->rip - module_base_vaddr;
//////////////////////////////
//- rjf: rip_voff -> first pdata
@@ -2079,7 +2068,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
//- rjf: set up parsing state
B32 is_epilog = 0;
B32 keep_parsing = 1;
U64 read_vaddr = regs->rip.u64;
U64 read_vaddr = regs->rip;
U64 read_vaddr_opl = read_vaddr + 256;
//- rjf: check first instruction
@@ -2271,7 +2260,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
//
if(first_pdata && has_pdata_and_in_epilog) ProfScope("pdata & in epilog -> epilog unwind")
{
U64 read_vaddr = regs->rip.u64;
U64 read_vaddr = regs->rip;
for(B32 keep_parsing = 1;keep_parsing != 0;)
{
//- rjf: assume no more parsing after this instruction
@@ -2307,7 +2296,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
case 0x5F:
{
// rjf: read value at rsp
U64 sp = regs->rsp.u64;
U64 sp = regs->rsp;
U64 value = 0;
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &value, endt_us) ||
is_stale)
@@ -2318,9 +2307,9 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
// rjf: modify registers
PE_UnwindGprRegX64 gpr_reg = (inst_byte - 0x58) + (rex & 1)*8;
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
reg->u64 = value;
regs->rsp.u64 = sp + 8;
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
reg[0] = value;
regs->rsp = sp + 8;
// rjf: not a final instruction, so keep mparsing
keep_parsing = 1;
@@ -2343,7 +2332,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
read_vaddr += 4;
// rjf: update stack pointer
regs->rsp.u64 = (U64)(regs->rsp.u64 + imm);
regs->rsp = (U64)(regs->rsp + imm);
// rjf: not a final instruction; keep parsing
keep_parsing = 1;
@@ -2366,7 +2355,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
read_vaddr += 1;
// rjf: update stack pointer
regs->rsp.u64 = (U64)(regs->rsp.u64 + imm);
regs->rsp = (U64)(regs->rsp + imm);
// rjf: not a final instruction; keep parsing
keep_parsing = 1;
@@ -2385,8 +2374,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
read_vaddr += 1;
PE_UnwindGprRegX64 gpr_reg = (modrm & 7) + (rex & 1)*8;
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
U64 reg_value = reg->u64;
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
U64 reg_value = reg[0];
// rjf: read immediate
S32 imm = 0;
@@ -2419,7 +2408,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: update stack pointer
regs->rsp.u64 = (U64)(reg_value + imm);
regs->rsp = (U64)(reg_value + imm);
// rjf: not a final instruction; keep parsing
keep_parsing = 1;
@@ -2429,7 +2418,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
case 0xC2:
{
// rjf: read new ip
U64 sp = regs->rsp.u64;
U64 sp = regs->rsp;
U64 new_ip = 0;
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
is_stale)
@@ -2449,8 +2438,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
U64 new_sp = sp + 8 + imm;
// rjf: commit registers
regs->rip.u64 = new_ip;
regs->rsp.u64 = new_sp;
regs->rip = new_ip;
regs->rsp = new_sp;
}break;
// rjf: ret / rep; ret
@@ -2461,7 +2450,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
case 0xC3:
{
// rjf: read new ip
U64 sp = regs->rsp.u64;
U64 sp = regs->rsp;
U64 new_ip = 0;
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
is_stale)
@@ -2474,8 +2463,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
U64 new_sp = sp + 8;
// rjf: commit registers
regs->rip.u64 = new_ip;
regs->rsp.u64 = new_sp;
regs->rip = new_ip;
regs->rsp = new_sp;
}break;
// rjf: jmp nnnn
@@ -2505,7 +2494,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
{
//- rjf: get frame reg
B32 bad_frame_reg_info = 0;
REGS_Reg64 *frame_reg = 0;
U64 *frame_reg = 0;
U64 frame_off = 0;
{
U64 unwind_info_off = first_pdata->voff_unwind_info;
@@ -2549,10 +2538,10 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
//- rjf: unpack frame base
U64 frame_base = regs->rsp.u64;
U64 frame_base = regs->rsp;
if(frame_reg != 0)
{
U64 raw_frame_base = frame_reg->u64;
U64 raw_frame_base = frame_reg[0];
U64 adjusted_frame_base = raw_frame_base - frame_off*16;
frame_base = adjusted_frame_base;
}
@@ -2591,7 +2580,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
case PE_UnwindOpCode_PUSH_NONVOL:
{
// rjf: read value from stack pointer
U64 rsp = regs->rsp.u64;
U64 rsp = regs->rsp;
U64 value = 0;
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &value, endt_us) ||
is_stale)
@@ -2605,9 +2594,9 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
U64 new_rsp = rsp + 8;
// rjf: commit registers
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg->u64 = value;
regs->rsp.u64 = new_rsp;
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg[0] = value;
regs->rsp = new_rsp;
}break;
case PE_UnwindOpCode_ALLOC_LARGE:
@@ -2630,23 +2619,23 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: advance stack pointer
U64 rsp = regs->rsp.u64;
U64 rsp = regs->rsp;
U64 new_rsp = rsp + size;
// rjf: advance stack pointer
regs->rsp.u64 = new_rsp;
regs->rsp = new_rsp;
}break;
case PE_UnwindOpCode_ALLOC_SMALL:
{
// rjf: advance stack pointer
regs->rsp.u64 += op_info*8 + 8;
regs->rsp += op_info*8 + 8;
}break;
case PE_UnwindOpCode_SET_FPREG:
{
// rjf: put stack pointer back to the frame base
regs->rsp.u64 = frame_base;
regs->rsp = frame_base;
}break;
case PE_UnwindOpCode_SAVE_NONVOL:
@@ -2664,8 +2653,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: commit to register
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg->u64 = value;
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg[0] = value;
}break;
case PE_UnwindOpCode_SAVE_NONVOL_FAR:
@@ -2683,8 +2672,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: commit to register
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg->u64 = value;
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
reg[0] = value;
}break;
case PE_UnwindOpCode_EPILOG:
@@ -2748,7 +2737,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: read values
U64 sp_og = regs->rsp.u64;
U64 sp_og = regs->rsp;
U64 sp_adj = sp_og;
if(op_info == 1)
{
@@ -2791,10 +2780,10 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
}
// rjf: commit registers
regs->rip.u64 = ip_value;
regs->ss.u16 = ss_value;
regs->rflags.u64 = rflags_value;
regs->rsp.u64 = sp_value;
regs->rip = ip_value;
regs->ss = ss_value;
regs->rflags = rflags_value;
regs->rsp = sp_value;
// rjf: mark machine frame
xdata_unwind_did_machframe = 1;
@@ -2832,7 +2821,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
if(!first_pdata || (!has_pdata_and_in_epilog && !xdata_unwind_did_machframe)) ProfScope("no pdata, or didn't do machframe in xdata unwind -> unwind by reading stack pointer")
{
// rjf: read rip from stack pointer
U64 rsp = regs->rsp.u64;
U64 rsp = regs->rsp;
U64 new_rip = 0;
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &new_rip, endt_us) ||
is_stale)
@@ -2844,8 +2833,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
if(is_good)
{
U64 new_rsp = rsp + 8;
regs->rip.u64 = new_rip;
regs->rsp.u64 = new_rsp;
regs->rip = new_rip;
regs->rsp = new_rsp;
}
}
@@ -2872,7 +2861,8 @@ d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_u
D_Entity *thread_entity = d_entity_from_handle(ctx, thread);
D_Entity *process_entity = thread_entity->parent;
Arch arch = thread_entity->arch;
U64 arch_reg_block_size = regs_block_size_from_arch(arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 arch_reg_block_size = arch_info->reg_block_size;
//- rjf: grab initial register block
void *regs_block = d_reg_block_from_thread(scratch.arena, ctx, thread);
@@ -2886,8 +2876,9 @@ d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_u
{
for(unwind.flags = 0;;)
{
U64 rip = regs_rip_from_arch_block(arch, regs_block);
U64 rsp = regs_rsp_from_arch_block(arch, regs_block);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 rip = arch_ip_from_reg_block(arch_info, regs_block);
U64 rsp = arch_sp_from_reg_block(arch_info, regs_block);
// rjf: cancel on zero rip (except the top frame)
if(rip == 0 && frame_node_count > 0)
@@ -2958,7 +2949,7 @@ d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_u
// stop unwinding on errors or stale data
unwind.flags |= step_result.flags;
if(unwind.flags & (D_UnwindFlag_Stale|D_UnwindFlag_Error) ||
(regs_rsp_from_arch_block(arch, regs_block) == rsp && regs_rip_from_arch_block(arch, regs_block) == rip))
(arch_sp_from_reg_block(arch_info, regs_block) == rsp && arch_ip_from_reg_block(arch_info, regs_block) == rip))
{
break;
}
@@ -3006,8 +2997,9 @@ d_call_stack_from_unwind(Arena *arena, D_Entity *process, D_Unwind *base_unwind)
for(U64 base_frame_idx = 0; base_frame_idx < base_unwind->frames.count; base_frame_idx += 1)
{
// rjf: unpack
ARCH_Info *arch_info = arch_info_from_arch(arch);
D_UnwindFrame *src = &base_unwind->frames.v[base_frame_idx];
U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs);
U64 rip_vaddr = arch_ip_from_reg_block(arch_info, src->regs);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
@@ -3149,12 +3141,6 @@ d_string2reg_from_arch(Arch arch)
return &d_ctrl_state->arch_string2reg_tables[arch];
}
internal E_String2NumMap *
d_string2alias_from_arch(Arch arch)
{
return &d_ctrl_state->arch_string2alias_tables[arch];
}
////////////////////////////////
//~ rjf: Control-Thread Functions
@@ -3178,7 +3164,7 @@ d_u2c_push_msgs(D_MsgList *msgs, U64 endt_us)
good = 1;
break;
}
if(os_now_microseconds() >= endt_us)
if(now_time_us() >= endt_us)
{
break;
}
@@ -3243,7 +3229,7 @@ d_c2u_push_events(D_EventList *events)
d_ctrl_state->c2u_ring_write_pos += ring_write(d_ctrl_state->c2u_ring_base, d_ctrl_state->c2u_ring_size, d_ctrl_state->c2u_ring_write_pos, event_srlzed.str, event_srlzed.size);
break;
}
cond_var_wait(d_ctrl_state->c2u_ring_cv, d_ctrl_state->c2u_ring_mutex, os_now_microseconds()+100);
cond_var_wait(d_ctrl_state->c2u_ring_cv, d_ctrl_state->c2u_ring_mutex, now_time_us()+100);
}
cond_var_broadcast(d_ctrl_state->c2u_ring_cv);
if(d_ctrl_state->wakeup_hook != 0)
@@ -3425,7 +3411,7 @@ d_ctrl_thread__entry_point(void *p)
{
d_entity_equip_string(d_ctrl_state->ctrl_thread_entity_store, debug_info_path, path_normalized_from_string(scratch.arena, path));
}
U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified;
U64 new_dbgi_timestamp = properties_from_file_path(path).modified;
debug_info_path->timestamp = new_dbgi_timestamp;
DI_Key new_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, new_dbgi_timestamp);
di_open(new_dbgi_key);
@@ -3466,7 +3452,7 @@ d_ctrl_thread__entry_point(void *p)
{
D_EntityCtx *entity_ctx = &d_ctrl_state->ctrl_thread_entity_store->ctx;
D_EntityArray threads = d_entity_array_from_kind(entity_ctx, D_EntityKind_Thread);
REGS_RegBlockX64 *blocks = push_array(scratch.arena, REGS_RegBlockX64, threads.count);
X64_RegBlock *blocks = push_array(scratch.arena, X64_RegBlock, threads.count);
{
for EachIndex(idx, threads.count)
{
@@ -3978,7 +3964,7 @@ d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_rang
for(String8Node *n = dbg_path_candidates.first; n != 0; n = n->next)
{
String8 candidate_path = n->string;
FileProperties props = os_properties_from_file_path(candidate_path);
FileProperties props = properties_from_file_path(candidate_path);
if(props.modified != 0 && props.size != 0)
{
initial_debug_info_path = push_str8_copy(arena, path_normalized_from_string(scratch.arena, candidate_path));
@@ -4316,12 +4302,14 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
{
D_Entity *thread = d_entity_from_handle(entity_ctx, d_handle_make(D_MachineID_Local, spoof->thread));
Arch arch = thread->arch;
void *regs_block = push_array(scratch.arena, U8, regs_block_size_from_arch(arch));
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 arch_reg_block_size = arch_info->reg_block_size;
void *regs_block = push_array(scratch.arena, U8, arch_reg_block_size);
dmn_thread_read_reg_block(spoof->thread, regs_block);
U64 spoof_thread_rip = regs_rip_from_arch_block(arch, regs_block);
U64 spoof_thread_rip = arch_ip_from_reg_block(arch_info, regs_block);
if(spoof_thread_rip == spoof->new_ip_value)
{
regs_arch_block_write_rip(arch, regs_block, spoof_old_ip_value);
arch_reg_block_write_ip(arch_info, regs_block, spoof_old_ip_value);
d_thread_write_reg_block(d_handle_make(D_MachineID_Local, spoof->thread), regs_block);
}
}
@@ -4363,7 +4351,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
D_Handle module_handle = d_handle_make(D_MachineID_Local, event->module);
D_Event *out_evt1 = d_event_list_push(scratch.arena, &evts);
String8 module_path = path_normalized_from_string(scratch.arena, event->string);
U64 exe_timestamp = os_properties_from_file_path(module_path).modified;
U64 exe_timestamp = properties_from_file_path(module_path).modified;
d_ctrl_thread__module_open(process_handle, module_handle, r1u64(event->address, event->address+event->size), module_path, event->elf_phdr_vrange, event->elf_phdr_entsize);
out_evt1->kind = D_EventKind_NewModule;
out_evt1->msg_id = msg->msg_id;
@@ -4379,7 +4367,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
out_evt1->tls_offset = event->tls_offset;
D_Event *out_evt2 = d_event_list_push(scratch.arena, &evts);
String8 initial_debug_info_path = d_initial_debug_info_path_from_module(scratch.arena, module_handle);
U64 debug_info_timestamp = os_properties_from_file_path(initial_debug_info_path).modified;
U64 debug_info_timestamp = properties_from_file_path(initial_debug_info_path).modified;
out_evt2->kind = D_EventKind_ModuleDebugInfoPathChange;
out_evt2->msg_id = msg->msg_id;
out_evt2->entity = module_handle;
@@ -4547,7 +4535,8 @@ d_ctrl_eval_space_read(E_Space space, void *out, Rng1U64 range)
{
Temp scratch = scratch_begin(0, 0);
D_EntityCtx *entity_ctx = &d_ctrl_state->ctrl_thread_entity_store->ctx;
U64 regs_size = regs_block_size_from_arch(entity->arch);
ARCH_Info *arch_info = arch_info_from_arch(entity->arch);
U64 regs_size = arch_info->reg_block_size;
void *regs = d_reg_block_from_thread(scratch.arena, entity_ctx, entity->handle);
Rng1U64 legal_range = r1u64(0, regs_size);
Rng1U64 read_range = intersect_1u64(legal_range, range);
@@ -4650,7 +4639,7 @@ d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Enti
else ProfScope("cache miss")
{
D_Entity *debug_info_path = d_entity_child_from_kind(mod, D_EntityKind_DebugInfoPath);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, debug_info_path->string);
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, debug_info_path->string);
ProfScope("determine if %.*s is necessary", str8_varg(debug_info_path->string))
{
//- rjf: determine if file is PDB
@@ -4658,7 +4647,7 @@ d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Enti
if(!file_is_pdb)
{
U8 msf70_magic_maybe[sizeof(msf_msf70_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
{
file_is_pdb = 1;
@@ -4667,7 +4656,7 @@ d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Enti
if(!file_is_pdb)
{
U8 msf20_magic_maybe[sizeof(msf_msf20_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
{
file_is_pdb = 1;
@@ -4678,18 +4667,18 @@ d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Enti
// if any are found in the PDB, then this RDI is necessary.
if(file_is_pdb)
{
FileProperties props = os_properties_from_file(file);
OS_Handle map = os_file_map_open(OS_AccessFlag_Read, file);
void *file_base = os_file_map_view_open(map, OS_AccessFlag_Read, r1u64(0, props.size));
FileProperties props = properties_from_file(file);
FileMap map = file_map_open(AccessFlag_Read, file);
void *file_base = file_map_view_open(map, AccessFlag_Read, r1u64(0, props.size));
String8 file_data = str8(file_base, props.size);
{
rdi_is_necessary = pdb_has_symbol_or_file_ref(file_data, d_ctrl_state->msg_user_bp_touched_symbols, d_ctrl_state->msg_user_bp_touched_files);
}
os_file_map_view_close(map, file_base, r1u64(0, props.size));
os_file_map_close(map);
file_map_view_close(map, file_base, r1u64(0, props.size));
file_map_close(map);
}
}
os_file_close(file);
file_close(file);
node = push_array(d_ctrl_state->ctrl_thread_msg_process_arena, D_ModuleReqCacheNode, 1);
node->next = slot;
d_ctrl_state->module_req_cache_slots[slot_idx] = node;
@@ -4771,7 +4760,6 @@ d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Enti
{
E_IRCtx *ctx = &scope->ir_ctx;
ctx->regs_map = d_string2reg_from_arch(arch);
ctx->reg_alias_map = d_string2alias_from_arch(arch);
ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_dbg_infos_primary->rdi, thread_rip_voff);
ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_dbg_infos_primary->rdi, thread_rip_voff);
ctx->macro_map = push_array(arena, E_String2ExprMap, 1);
@@ -4817,7 +4805,7 @@ d_ctrl_thread__end_and_flush_log(void)
{
Temp scratch = scratch_begin(0, 0);
LogScopeResult log = log_scope_end(scratch.arena);
os_append_data_to_file_path(d_ctrl_state->ctrl_thread_log_path, log.strings[LogMsgKind_Info]);
append_data_to_file_path(d_ctrl_state->ctrl_thread_log_path, log.strings[LogMsgKind_Info]);
if(log.strings[LogMsgKind_UserError].size != 0)
{
D_EventList evts = {0};
@@ -4842,28 +4830,28 @@ d_ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
String8 stderr_path = path_absolute_dst_from_relative_dst_src(scratch.arena, msg->stderr_path, msg->path);
//- rjf: obtain stdout/stderr/stdin handles
OS_Handle stdout_handle = {0};
OS_Handle stderr_handle = {0};
OS_Handle stdin_handle = {0};
File stdout_handle = {0};
File stderr_handle = {0};
File stdin_handle = {0};
if(stdout_path.size != 0)
{
OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path);
os_file_close(f);
stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, msg->stdout_path);
File f = file_open(AccessFlag_Write|AccessFlag_Read, stdout_path);
file_close(f);
stdout_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, msg->stdout_path);
}
if(stderr_path.size != 0)
{
OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stderr_path);
os_file_close(f);
stderr_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, msg->stderr_path);
File f = file_open(AccessFlag_Write|AccessFlag_Read, stderr_path);
file_close(f);
stderr_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, msg->stderr_path);
}
if(stdin_path.size != 0)
{
stdin_handle = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, stdin_path);
stdin_handle = file_open(AccessFlag_Read|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, stdin_path);
}
//- rjf: launch
OS_ProcessLaunchParams params = {0};
ProcessLaunchParams params = {0};
{
params.cmd_line = msg->cmd_line_string_list;
params.path = msg->path;
@@ -4877,9 +4865,9 @@ d_ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
U32 id = dmn_ctrl_launch(ctrl_ctx, &params);
//- rjf: close stdout/stderr/stdin files
os_file_close(stdout_handle);
os_file_close(stderr_handle);
os_file_close(stdin_handle);
file_close(stdout_handle);
file_close(stderr_handle);
file_close(stdin_handle);
//- rjf: record (id -> entry points), so that we know custom entry points for this PID
D_EntityCtxRWStore *entity_ctx_rw_store = d_ctrl_state->ctrl_thread_entity_store;
@@ -6339,7 +6327,7 @@ d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
if(range_size != 0)
{
// rjf: set up arena
U64 page_size = os_get_system_info()->page_size; // TODO(rjf): @page_size_from_process
U64 page_size = get_system_info()->page_size; // TODO(rjf): @page_size_from_process
U64 arena_size = AlignPow2(range_size + ARENA_HEADER_SIZE, page_size);
range_arena = arena_alloc(.reserve_size = range_size+ARENA_HEADER_SIZE, .commit_size = range_size+ARENA_HEADER_SIZE);
@@ -6676,15 +6664,15 @@ d_process_write(D_Handle process, Rng1U64 range, void *src)
// time.
if(result)
{
U64 endt_us = os_now_microseconds()+10000;
U64 page_size = os_get_system_info()->page_size; // TODO(rjf): @page_size_from_process
U64 endt_us = now_time_us()+10000;
U64 page_size = get_system_info()->page_size; // TODO(rjf): @page_size_from_process
Rng1U64 page_range = r1u64(range.min/page_size, (range.max+page_size-1)/page_size);
for EachInRange(page_idx, page_range)
{
Temp scratch = scratch_begin(0, 0);
D_ProcessMemorySlice slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process, r1u64(page_idx*page_size, (page_idx+1)*page_size), 1, endt_us);
scratch_end(scratch);
if(!slice.stale || os_now_microseconds() >= endt_us)
if(!slice.stale || now_time_us() >= endt_us)
{
break;
}
@@ -6826,7 +6814,7 @@ d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U6
{
pre_reg_gen = d_reg_gen();
pre_mem_gen = d_mem_gen();
unwind = d_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+5000);
unwind = d_unwind_from_thread(arena, entity_ctx, thread_handle, now_time_us()+5000);
if(!(unwind.flags & D_UnwindFlag_Stale))
{
good = 1;
@@ -6967,11 +6955,12 @@ d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_ou
D_Handle thread = threads[thread_idx];
D_Handle process = threads_processes[thread_idx];
Arch arch = threads_arches[thread_idx];
ARCH_Info *arch_info = arch_info_from_arch(arch);
D_CallStack call_stack = call_stacks[thread_idx];
D_CallStackTreeNode *thread_node = tree->root;
for EachIndex(frame_idx, call_stack.frames_count)
{
U64 vaddr = regs_rip_from_arch_block(arch, call_stack.frames[frame_idx].regs);
U64 vaddr = arch_ip_from_reg_block(arch_info, call_stack.frames[frame_idx].regs);
U64 depth = call_stack.frames[frame_idx].inline_depth;
D_CallStackTreeNode *next_node = &d_call_stack_tree_node_nil;
for(D_CallStackTreeNode *child = thread_node->first; child != &d_call_stack_tree_node_nil; child = child->next)
+3 -5
View File
@@ -269,9 +269,8 @@ struct D_CtrlState
Arena *arena;
D_WakeupFunctionType *wakeup_hook;
// rjf: name -> register/alias hash tables for eval
// rjf: name -> register hash tables for eval
E_String2NumMap arch_string2reg_tables[Arch_COUNT];
E_String2NumMap arch_string2alias_tables[Arch_COUNT];
// rjf: caches
D_ThreadRegCache thread_reg_cache;
@@ -499,8 +498,8 @@ internal D_UnwindStepResult d_establish_frame_unwind_context__dwarf(Arena *arena
internal D_UnwindStepResult d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwindContext *frame_ctx, U64 endt_us);
//- rjf: [x64]
internal REGS_Reg64 *d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
internal D_UnwindStepResult d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us);
internal U64 *d_unwind_reg_from_pe_gpr_reg__pe_x64(X64_RegBlock *regs, PE_UnwindGprRegX64 gpr_reg);
internal D_UnwindStepResult d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, X64_RegBlock *regs, U64 endt_us);
//- rjf: abstracted full unwind
internal D_Unwind d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us);
@@ -526,7 +525,6 @@ internal U64 d_reg_gen(void);
//- rjf: name -> register/alias hash tables, for eval
internal E_String2NumMap *d_string2reg_from_arch(Arch arch);
internal E_String2NumMap *d_string2alias_from_arch(Arch arch);
////////////////////////////////
//~ rjf: Control-Thread Functions
+12 -9
View File
@@ -300,7 +300,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
String8 machine_code = {0};
{
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, os_now_microseconds()+5000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, now_time_us()+5000);
machine_code = machine_code_slice.data;
}
@@ -393,7 +393,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+50000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, now_time_us()+50000);
machine_code = machine_code_slice.data;
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
LogInfoNamedBlockF("machine_code_slice")
@@ -604,7 +604,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+5000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, now_time_us()+5000);
machine_code = machine_code_slice.data;
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
}
@@ -1215,7 +1215,8 @@ d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, 0);
if(callstack.concrete_frames_count != 0)
{
result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs);
ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
result = arch_ip_from_reg_block(arch_info, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs);
}
access_close(access);
}
@@ -1648,7 +1649,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
String8List env = target->env;
if(working_directory.size == 0)
{
working_directory = os_get_current_path(scratch.arena);
working_directory = get_current_path(scratch.arena);
}
// rjf: build launch options
@@ -1811,12 +1812,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
Access *access = access_open();
// rjf: thread => call stack
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, os_now_microseconds()+10000);
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000);
// rjf: use first unwind frame to generate trap
if(callstack.concrete_frames_count > 1)
{
U64 vaddr = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[1]->regs);
ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
U64 vaddr = arch_ip_from_reg_block(arch_info, callstack.concrete_frames[1]->regs);
D_Trap trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr};
d_trap_list_push(scratch.arena, &trap_net.traps, &trap);
trap_net.good_read = 1;
@@ -1875,9 +1877,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_SetThreadIP:
{
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
U64 vaddr = params->vaddr;
void *block = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, thread->handle);
regs_arch_block_write_rip(thread->arch, block, vaddr);
arch_reg_block_write_ip(arch_info, block, vaddr);
B32 result = d_thread_write_reg_block(thread->handle, block);
(void)result;
}break;
@@ -2120,7 +2123,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
d_user_state->ctrl_soft_halt_issued = 1;
d_halt();
}
if(d_u2c_push_msgs(&d_user_state->ctrl_msgs, os_now_microseconds()+100))
if(d_u2c_push_msgs(&d_user_state->ctrl_msgs, now_time_us()+100))
{
MemoryZeroStruct(&d_user_state->ctrl_msgs);
arena_clear(d_user_state->ctrl_msg_arena);
+40 -40
View File
@@ -71,7 +71,7 @@ di_init(CmdLine *cmdline)
if(!try_u64_from_str8_c_rules(signal_pid_string, &signal_pid))
{
has_parent = 0;
signal_pid = os_get_process_info()->pid;
signal_pid = get_process_info()->pid;
}
U64 signal_code = 0;
String8 signal_code_string = cmd_line_string(cmdline, str8_lit("signal_code"));
@@ -84,16 +84,16 @@ di_init(CmdLine *cmdline)
{
di_shared->conversion_completion_lock_semaphore = semaphore_open(di_shared->conversion_completion_lock_semaphore_name);
di_shared->conversion_completion_signal_semaphore = semaphore_open(di_shared->conversion_completion_signal_semaphore_name);
di_shared->conversion_completion_shared_memory = os_shared_memory_open(di_shared->conversion_completion_shared_memory_name);
di_shared->conversion_completion_shared_memory = shared_memory_open(di_shared->conversion_completion_shared_memory_name);
}
else
{
di_shared->conversion_completion_lock_semaphore = semaphore_alloc(1, 1, di_shared->conversion_completion_lock_semaphore_name);
di_shared->conversion_completion_signal_semaphore = semaphore_alloc(0, 65536, di_shared->conversion_completion_signal_semaphore_name);
di_shared->conversion_completion_shared_memory = os_shared_memory_alloc(KB(4), di_shared->conversion_completion_shared_memory_name);
di_shared->conversion_completion_shared_memory = shared_memory_alloc(KB(4), di_shared->conversion_completion_shared_memory_name);
di_shared->conversion_completion_signal_receiver_thread = thread_launch(di_conversion_completion_signal_receiver_thread_entry_point, 0);
}
di_shared->conversion_completion_shared_memory_base = (U64 *)os_shared_memory_view_open(di_shared->conversion_completion_shared_memory, r1u64(0, KB(4)));
di_shared->conversion_completion_shared_memory_base = (U64 *)shared_memory_view_open(di_shared->conversion_completion_shared_memory, r1u64(0, KB(4)));
di_shared->completion_mutex = mutex_alloc();
di_shared->completion_arena = arena_alloc();
di_shared->event_mutex = mutex_alloc();
@@ -164,8 +164,8 @@ di_key_from_path_timestamp(String8 path, U64 min_timestamp)
//- rjf: try to make key from file's contents
if(!made_key)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
FileProperties props = os_properties_from_file(file);
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
FileProperties props = properties_from_file(file);
if(min_timestamp <= props.modified)
{
//- rjf: PDB magic => use GUID for key
@@ -176,7 +176,7 @@ di_key_from_path_timestamp(String8 path, U64 min_timestamp)
{
read_only local_persist char msf_msf20_magic[] = "Microsoft C/C++ program database 2.00\r\n\x1aJG\0\0";
U8 msf20_magic_maybe[sizeof(msf_msf20_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
{
is_pdb = 1;
@@ -186,7 +186,7 @@ di_key_from_path_timestamp(String8 path, U64 min_timestamp)
{
read_only local_persist char msf_msf70_magic[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
U8 msf70_magic_maybe[sizeof(msf_msf70_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
{
is_pdb = 1;
@@ -198,7 +198,7 @@ di_key_from_path_timestamp(String8 path, U64 min_timestamp)
}
}
}
os_file_close(file);
file_close(file);
}
//- rjf: fallback: hash from path/timestamp
@@ -323,8 +323,8 @@ di_close(DI_Key key, B32 force_closed)
//- rjf: decrement this key's node's refcount; remove if needed
B32 node_released = 0;
OS_Handle file = {0};
OS_Handle file_map = {0};
File file = {0};
FileMap file_map = {0};
FileProperties file_props = {0};
void *file_base = 0;
Arena *arena = 0;
@@ -377,9 +377,9 @@ di_close(DI_Key key, B32 force_closed)
{
ins_atomic_u64_dec_eval(&di_shared->load_count);
ins_atomic_u64_inc_eval(&di_shared->load_gen);
os_file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
os_file_map_close(file_map);
os_file_close(file);
file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
file_map_close(file_map);
file_close(file);
if(arena != 0)
{
arena_release(arena);
@@ -492,7 +492,7 @@ di_rdi_from_key(Access *access, DI_Key key, B32 high_priority, U64 endt_us)
}
// rjf: found current results, or out-of-time? abort
if(grabbed || os_now_microseconds() >= endt_us)
if(grabbed || now_time_us() >= endt_us)
{
break;
}
@@ -681,16 +681,16 @@ di_async_tick(void)
if(!t->og_analyzed)
{
t->og_analyzed = 1;
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, og_path);
FileProperties props = os_properties_from_file(file);
File file = file_open(AccessFlag_ShareRead|AccessFlag_Read, og_path);
FileProperties props = properties_from_file(file);
t->og_size = props.size;
U64 rdi_magic_maybe = 0;
if(os_file_read_struct(file, 0, &rdi_magic_maybe) == 8 &&
if(file_read_struct(file, 0, &rdi_magic_maybe) == 8 &&
rdi_magic_maybe == RDI_MAGIC_CONSTANT)
{
t->og_is_rdi = 1;
}
os_file_close(file);
file_close(file);
}
U64 og_size = t->og_size;
B32 og_is_rdi = t->og_is_rdi;
@@ -713,8 +713,8 @@ di_async_tick(void)
if(!t->rdi_analyzed)
{
t->rdi_analyzed = 1;
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, rdi_path);
FileProperties props = os_properties_from_file(file);
File file = file_open(AccessFlag_ShareRead|AccessFlag_Read, rdi_path);
FileProperties props = properties_from_file(file);
if(props.modified < og_min_timestamp)
{
t->rdi_is_stale = 1;
@@ -723,12 +723,12 @@ di_async_tick(void)
{
t->rdi_is_stale = 1;
RDI_Header header = {0};
if(os_file_read_struct(file, 0, &header) == sizeof(header))
if(file_read_struct(file, 0, &header) == sizeof(header))
{
t->rdi_is_stale = (header.encoding_version != RDI_ENCODING_VERSION);
}
}
os_file_close(file);
file_close(file);
}
B32 rdi_is_stale = t->rdi_is_stale;
@@ -736,7 +736,7 @@ di_async_tick(void)
if(!og_is_rdi && rdi_is_stale && t->thread_count == 0)
{
U64 thread_count = 1;
U64 max_thread_count = os_get_system_info()->logical_processor_count/2;
U64 max_thread_count = get_system_info()->logical_processor_count/2;
if(priority_idx > 0)
{
max_thread_count = Max(1, max_thread_count/2);
@@ -756,7 +756,7 @@ di_async_tick(void)
//- rjf: determine if there are threads available
B32 threads_available = 0;
{
U64 max_threads = os_get_system_info()->logical_processor_count/2;
U64 max_threads = get_system_info()->logical_processor_count/2;
U64 current_threads = di_shared->conversion_thread_count;
U64 needed_threads = (current_threads + t->thread_count);
threads_available = (max_threads >= needed_threads);
@@ -789,8 +789,8 @@ di_async_tick(void)
if(og_is_good && ready_to_launch_conversion)
{
B32 should_compress = 0;
OS_ProcessLaunchParams params = {0};
params.path = os_get_process_info()->binary_path;
ProcessLaunchParams params = {0};
params.path = get_process_info()->binary_path;
params.inherit_env = 1;
params.consoleless = 1;
str8_list_pushf(scratch.arena, &params.cmd_line, "raddbg");
@@ -804,11 +804,11 @@ di_async_tick(void)
str8_list_pushf(scratch.arena, &params.cmd_line, "--rdi");
str8_list_pushf(scratch.arena, &params.cmd_line, "--out:%S", rdi_path);
str8_list_pushf(scratch.arena, &params.cmd_line, "--thread_count:%I64u", t->thread_count);
str8_list_pushf(scratch.arena, &params.cmd_line, "--signal_pid:%I64u", (U64)os_get_process_info()->pid);
str8_list_pushf(scratch.arena, &params.cmd_line, "--signal_pid:%I64u", (U64)get_process_info()->pid);
str8_list_pushf(scratch.arena, &params.cmd_line, "--signal_code:%I64u", (U64)t);
str8_list_pushf(scratch.arena, &params.cmd_line, "%S", og_path);
ProfMsg("launch creation for %.*s", str8_varg(rdi_path));
t->process = os_process_launch(&params);
t->process = process_launch(&params);
t->status = DI_LoadTaskStatus_Active;
di_shared->conversion_process_count += 1;
di_shared->conversion_thread_count += t->thread_count;
@@ -840,7 +840,7 @@ di_async_tick(void)
}
if(!task_is_done)
{
task_is_done = os_process_join(t->process, 0, 0);
task_is_done = process_join(t->process, 0, 0);
}
if(task_is_done)
{
@@ -875,7 +875,7 @@ di_async_tick(void)
//- rjf: if task is done, retire & recycle task; gather path to load
if(t->status == DI_LoadTaskStatus_Done)
{
if(!os_handle_match(t->process, os_handle_zero())) MutexScope(di_shared->event_mutex)
if(!process_match(t->process, process_zero())) MutexScope(di_shared->event_mutex)
{
DI_EventNode *n = push_array(di_shared->event_arena, DI_EventNode, 1);
SLLQueuePush(di_shared->events.first, di_shared->events.last, n);
@@ -937,15 +937,15 @@ di_async_tick(void)
ProfBegin("parse %.*s", str8_varg(rdi_path));
//- rjf: open file
OS_Handle file = {0};
OS_Handle file_map = {0};
File file = {0};
FileMap file_map = {0};
FileProperties file_props = {0};
void *file_base = 0;
{
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, rdi_path);
file_map = os_file_map_open(OS_AccessFlag_Read, file);
file_props = os_properties_from_file(file);
file_base = os_file_map_view_open(file_map, OS_AccessFlag_Read, r1u64(0, file_props.size));
file = file_open(AccessFlag_Read|AccessFlag_ShareRead|AccessFlag_ShareWrite, rdi_path);
file_map = file_map_open(AccessFlag_Read, file);
file_props = properties_from_file(file);
file_base = file_map_view_open(file_map, AccessFlag_Read, r1u64(0, file_props.size));
}
//- rjf: do initial parse of rdi
@@ -1010,9 +1010,9 @@ di_async_tick(void)
{
arena_release(rdi_parsed_arena);
}
os_file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
os_file_map_close(file_map);
os_file_close(file);
file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
file_map_close(file_map);
file_close(file);
}
}
cond_var_broadcast(stripe->cv);
+4 -4
View File
@@ -69,8 +69,8 @@ struct DI_Node
DI_Key key;
// rjf: value
OS_Handle file;
OS_Handle file_map;
File file;
FileMap file_map;
void *file_base;
FileProperties file_props;
Arena *arena;
@@ -145,7 +145,7 @@ struct DI_LoadTask
B32 rdi_is_stale;
U64 thread_count;
OS_Handle process;
Process process;
};
typedef struct DI_LoadCompletion DI_LoadCompletion;
@@ -280,7 +280,7 @@ struct DI_Shared
String8 conversion_completion_shared_memory_name;
Semaphore conversion_completion_lock_semaphore;
Semaphore conversion_completion_signal_semaphore;
OS_Handle conversion_completion_shared_memory;
SharedMemory conversion_completion_shared_memory;
U64 *conversion_completion_shared_memory_base;
Thread conversion_completion_signal_receiver_thread;
+6 -4
View File
@@ -132,10 +132,11 @@ dmn_rip_from_thread(DMN_Handle thread)
Temp scratch = scratch_begin(0, 0);
{
Arch arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_arch(arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 reg_block_size = arch_info->reg_block_size;
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block);
result = regs_rip_from_arch_block(arch, reg_block);
result = arch_ip_from_reg_block(arch_info, reg_block);
}
scratch_end(scratch);
return result;
@@ -148,10 +149,11 @@ dmn_rsp_from_thread(DMN_Handle thread)
Temp scratch = scratch_begin(0, 0);
{
Arch arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_arch(arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 reg_block_size = arch_info->reg_block_size;
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block);
result = regs_rsp_from_arch_block(arch, reg_block);
result = arch_sp_from_reg_block(arch_info, reg_block);
}
scratch_end(scratch);
return result;
+2 -2
View File
@@ -235,7 +235,7 @@ internal DMN_CtrlCtx *dmn_ctrl_begin(void);
internal void dmn_ctrl_exclusive_access_begin(void);
internal void dmn_ctrl_exclusive_access_end(void);
#define DMN_CtrlExclusiveAccessScope DeferLoop(dmn_ctrl_exclusive_access_begin(), dmn_ctrl_exclusive_access_end())
internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params);
internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, ProcessLaunchParams *params);
internal B32 dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid);
internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code);
internal B32 dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process);
@@ -259,7 +259,7 @@ internal U64 dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size)
internal void dmn_process_memory_commit(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_decommit(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFlags flags);
internal void dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, AccessFlags flags);
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
+21 -13
View File
@@ -753,7 +753,8 @@ dmn_lnx_thread_alloc(DMN_LNX_Process *process, DMN_LNX_ThreadState thread_state,
}
else
{
U64 reg_block_size = regs_block_size_from_arch(process->ctx->arch);
ARCH_Info *arch_info = arch_info_from_arch(process->ctx->arch);
U64 reg_block_size = arch_info->reg_block_size;
reg_block = push_array(process->ctx->arena, U8, reg_block_size);
}
@@ -1130,26 +1131,32 @@ dmn_lnx_process_untrap_probes(DMN_LNX_Process *process)
internal U64
dmn_lnx_thread_read_ip(DMN_LNX_Thread *thread)
{
return regs_rip_from_arch_block(thread->process->ctx->arch, thread->reg_block);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
U64 result = arch_ip_from_reg_block(arch_info, thread->reg_block);
return result;
}
internal U64
dmn_lnx_thread_read_sp(DMN_LNX_Thread *thread)
{
return regs_rsp_from_arch_block(thread->process->ctx->arch, thread->reg_block);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
U64 result = arch_sp_from_reg_block(arch_info, thread->reg_block);
return result;
}
internal void
dmn_lnx_thread_write_ip(DMN_LNX_Thread *thread, U64 ip)
{
regs_arch_block_write_rip(thread->process->ctx->arch, thread->reg_block, ip);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
arch_reg_block_write_ip(arch_info, thread->reg_block, ip);
thread->is_reg_block_dirty = 1;
}
internal void
dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp)
{
regs_arch_block_write_rsp(thread->process->ctx->arch, thread->reg_block, sp);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
arch_reg_block_write_sp(arch_info, thread->reg_block, sp);
thread->is_reg_block_dirty = 1;
}
@@ -1166,7 +1173,7 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
case Arch_x64:
{
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
REGS_RegBlockX64 *dst = thread->reg_block;
X64_RegBlock *dst = thread->reg_block;
// general purpose registers
{
@@ -1364,7 +1371,7 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
case Arch_x64:
{
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
REGS_RegBlockX64 *src = thread->reg_block;
X64_RegBlock *src = thread->reg_block;
// general purpose registers
{
@@ -1555,7 +1562,7 @@ dmn_lnx_set_single_step_flag(DMN_LNX_Thread *thread, B32 is_on)
case Arch_Null: {} break;
case Arch_x64:
{
REGS_RegBlockX64 *reg_block = thread->reg_block;
X64_RegBlock *reg_block = thread->reg_block;
if(is_on) { reg_block->rflags.u64 |= X64_RFlag_Trap; }
else { reg_block->rflags.u64 &= ~X64_RFlag_Trap; }
thread->is_reg_block_dirty = 1;
@@ -2082,7 +2089,7 @@ dmn_lnx_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid)
case Arch_Null: {} break;
case Arch_x64:
{
REGS_RegBlockX64 *regs_x64 = thread->reg_block;
X64_RegBlock *regs_x64 = thread->reg_block;
if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B0)
{
address = regs_x64->dr0.u64;
@@ -3021,7 +3028,7 @@ dmn_tls_root_vaddr_from_thread(DMN_Handle thread_handle)
case Arch_Null: {} break;
case Arch_x64:
{
REGS_RegBlockX64 *reg_block = thread->reg_block;
X64_RegBlock *reg_block = thread->reg_block;
U64 dtv_pointer = 0;
if(dmn_lnx_read_struct(thread->process->fd, reg_block->fsbase.u64 + 8, &dtv_pointer))
{
@@ -3050,7 +3057,8 @@ dmn_thread_read_reg_block(DMN_Handle thread_handle, void *reg_block)
DMN_LNX_Thread *thread = dmn_lnx_thread_from_handle(thread_handle);
if(thread)
{
U64 reg_block_size = regs_block_size_from_arch(thread->process->ctx->arch);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
U64 reg_block_size = arch_info->reg_block_size;
MemoryCopy(reg_block, thread->reg_block, reg_block_size);
}
result = 1;
@@ -3067,7 +3075,8 @@ dmn_thread_write_reg_block(DMN_Handle thread_handle, void *reg_block)
DMN_LNX_Thread *thread = dmn_lnx_thread_from_handle(thread_handle);
if(thread)
{
U64 reg_block_size = regs_block_size_from_arch(thread->process->ctx->arch);
ARCH_Info *arch_info = arch_info_from_arch(thread->process->ctx->arch);
U64 reg_block_size = arch_info->reg_block_size;
MemoryCopy(thread->reg_block, reg_block, reg_block_size);
thread->is_reg_block_dirty = 1;
result = 1;
@@ -3148,4 +3157,3 @@ dmn_process_iter_end(DMN_ProcessIter *iter)
}
MemoryZeroStruct(iter);
}
+179 -169
View File
@@ -606,7 +606,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
case Arch_x64:
{
Temp scratch = scratch_begin(0, 0);
REGS_RegBlockX64 *dst = (REGS_RegBlockX64 *)reg_block;
X64_RegBlock *dst = (X64_RegBlock *)reg_block;
//- rjf: unpack info about available features
U32 feature_mask = GetEnabledXStateFeatures();
@@ -648,51 +648,51 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
DWORD64 xstate_mask = 0;
GetXStateFeaturesMask(ctx, &xstate_mask);
//- rjf: convert context -> REGS_RegBlockX64
//- rjf: convert context -> X64_RegBlock
XSAVE_FORMAT *xsave = &ctx->FltSave;
dst->rax.u64 = ctx->Rax;
dst->rcx.u64 = ctx->Rcx;
dst->rdx.u64 = ctx->Rdx;
dst->rbx.u64 = ctx->Rbx;
dst->rsp.u64 = ctx->Rsp;
dst->rbp.u64 = ctx->Rbp;
dst->rsi.u64 = ctx->Rsi;
dst->rdi.u64 = ctx->Rdi;
dst->r8.u64 = ctx->R8;
dst->r9.u64 = ctx->R9;
dst->r10.u64 = ctx->R10;
dst->r11.u64 = ctx->R11;
dst->r12.u64 = ctx->R12;
dst->r13.u64 = ctx->R13;
dst->r14.u64 = ctx->R14;
dst->r15.u64 = ctx->R15;
dst->rip.u64 = ctx->Rip;
dst->cs.u16 = ctx->SegCs;
dst->ds.u16 = ctx->SegDs;
dst->es.u16 = ctx->SegEs;
dst->fs.u16 = ctx->SegFs;
dst->gs.u16 = ctx->SegGs;
dst->ss.u16 = ctx->SegSs;
dst->dr0.u64 = ctx->Dr0;
dst->dr1.u64 = ctx->Dr1;
dst->dr2.u64 = ctx->Dr2;
dst->dr3.u64 = ctx->Dr3;
dst->dr6.u64 = ctx->Dr6;
dst->dr7.u64 = ctx->Dr7;
dst->rax = ctx->Rax;
dst->rcx = ctx->Rcx;
dst->rdx = ctx->Rdx;
dst->rbx = ctx->Rbx;
dst->rsp = ctx->Rsp;
dst->rbp = ctx->Rbp;
dst->rsi = ctx->Rsi;
dst->rdi = ctx->Rdi;
dst->r8 = ctx->R8;
dst->r9 = ctx->R9;
dst->r10 = ctx->R10;
dst->r11 = ctx->R11;
dst->r12 = ctx->R12;
dst->r13 = ctx->R13;
dst->r14 = ctx->R14;
dst->r15 = ctx->R15;
dst->rip = ctx->Rip;
dst->cs = ctx->SegCs;
dst->ds = ctx->SegDs;
dst->es = ctx->SegEs;
dst->fs = ctx->SegFs;
dst->gs = ctx->SegGs;
dst->ss = ctx->SegSs;
dst->dr0 = ctx->Dr0;
dst->dr1 = ctx->Dr1;
dst->dr2 = ctx->Dr2;
dst->dr3 = ctx->Dr3;
dst->dr6 = ctx->Dr6;
dst->dr7 = ctx->Dr7;
// NOTE(rjf): this bit is "supposed to always be 1", according to old info.
// may need to be investigated.
dst->rflags.u64 = ctx->EFlags | 0x2;
dst->fcw.u16 = xsave->ControlWord;
dst->fsw.u16 = xsave->StatusWord;
dst->rflags = ctx->EFlags | 0x2;
dst->fcw = xsave->ControlWord;
dst->fsw = xsave->StatusWord;
dst->ftw = xsave->TagWord;
dst->fop.u16 = xsave->ErrorOpcode;
MemoryCopy(&dst->fip.u64, &xsave->ErrorOffset, sizeof(U64));
MemoryCopy(&dst->fdp.u64, &xsave->DataOffset, sizeof(U64));
dst->mxcsr.u32 = xsave->MxCsr;
dst->mxcsr_mask.u32 = xsave->MxCsr_Mask;
dst->fop = xsave->ErrorOpcode;
MemoryCopy(&dst->fip, &xsave->ErrorOffset, sizeof(U64));
MemoryCopy(&dst->fdp, &xsave->DataOffset, sizeof(U64));
dst->mxcsr = xsave->MxCsr;
dst->mxcsr_mask = xsave->MxCsr_Mask;
{
M128A *float_s = xsave->FloatRegisters;
REGS_Reg80 *float_d = &dst->st0;
U80 *float_d = &dst->st0;
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
{
MemoryCopy(float_d, float_s, sizeof(*float_d));
@@ -702,7 +702,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
// SSE registers are always available in x64
{
M128A *xmm_s = xsave->XmmRegisters;
REGS_Reg512 *zmm_d = &dst->zmm0;
U512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, xmm_s += 1, zmm_d += 1)
{
MemoryCopy(zmm_d, xmm_s, sizeof(*xmm_s));
@@ -714,71 +714,76 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
{
DWORD avx_length = 0;
U8 *avx_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
Assert(avx_length == 16 * sizeof(REGS_Reg128));
REGS_Reg512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx_s += sizeof(REGS_Reg128), zmm_d += 1)
if(avx_length == 16 * sizeof(U128))
{
MemoryCopy(&zmm_d->v[16], avx_s, sizeof(REGS_Reg128));
U512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx_s += sizeof(U128), zmm_d += 1)
{
MemoryCopy(&zmm_d->u8[16], avx_s, sizeof(U128));
}
}
}
else
{
REGS_Reg512 *zmm_d = &dst->zmm0;
U512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, zmm_d += 1)
{
MemoryZero(&zmm_d->v[16], sizeof(REGS_Reg128));
MemoryZero(&zmm_d->u8[16], sizeof(U128));
}
}
// AVX-512
if(xstate_mask & XSTATE_MASK_AVX512)
{
// rjf: kmask
DWORD kmask_length = 0;
U64 *kmask_s = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
Assert(kmask_length == 8 * sizeof(U64));
REGS_Reg64 *kmask_d = &dst->k0;
if(kmask_length == 8 * sizeof(U64))
{
U64 *kmask_d = &dst->k0;
for(U32 n = 0; n < 8; n += 1, kmask_s += 1, kmask_d += 1)
{
MemoryCopy(kmask_d, kmask_s, sizeof(*kmask_s));
}
DWORD avx512h_length = 0;
U8* avx512h_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
Assert(avx512h_length == 16 * sizeof(REGS_Reg256));
REGS_Reg512 *zmmh_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx512h_s += sizeof(REGS_Reg256), zmmh_d += 1)
{
MemoryCopy(&zmmh_d->v[32], avx512h_s, sizeof(REGS_Reg256));
}
// rjf: zmmh
DWORD avx512h_length = 0;
U8 *avx512h_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
if(avx512h_length == 16 * sizeof(U256))
{
U512 *zmmh_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx512h_s += sizeof(U256), zmmh_d += 1)
{
MemoryCopy(&zmmh_d->u8[32], avx512h_s, sizeof(U256));
}
}
// rjf: zmm
DWORD avx512_length = 0;
U8 *avx512_s = (U8 *)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
Assert(avx512_length == 16 * sizeof(REGS_Reg512));
REGS_Reg512 *zmm_d = &dst->zmm16;
for(U32 n = 0; n < 16; n += 1, avx512_s += sizeof(REGS_Reg512), zmm_d += 1)
if(avx512_length == 16 * sizeof(U512))
{
MemoryCopy(zmm_d, avx512_s, sizeof(REGS_Reg512));
U512 *zmm_d = &dst->zmm16;
for(U32 n = 0; n < 16; n += 1, avx512_s += sizeof(U512), zmm_d += 1)
{
MemoryCopy(zmm_d, avx512_s, sizeof(U512));
}
}
}
else
{
REGS_Reg64 *kmask_d = &dst->k0;
U64 *kmask_d = &dst->k0;
for(U32 n = 0; n < 8; n += 1, kmask_d += 1)
{
MemoryZero(kmask_d, sizeof(*kmask_d));
}
REGS_Reg512 *zmmh_d = &dst->zmm0;
U512 *zmmh_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, zmmh_d += 1)
{
MemoryZero(&zmmh_d->v[32], sizeof(REGS_Reg256));
MemoryZero(&zmmh_d->u8[32], sizeof(U256));
}
REGS_Reg512 *zmm_d = &dst->zmm16;
U512 *zmm_d = &dst->zmm16;
for(U32 n = 0; n < 16; n += 1, zmm_d += 1)
{
MemoryZero(zmm_d, sizeof(*zmm_d));
@@ -792,8 +797,8 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
XSAVE_CET_U_FORMAT *cet = LocateXStateFeature(ctx, XSTATE_CET_U, &cet_length);
if (cet_length == sizeof(*cet))
{
dst->cetmsr.u64 = cet->Ia32CetUMsr;
dst->cetssp.u64 = cet->Ia32Pl3SspMsr;
dst->cetmsr = cet->Ia32CetUMsr;
dst->cetssp = cet->Ia32Pl3SspMsr;
}
}
@@ -828,7 +833,7 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
case Arch_x64:
{
Temp scratch = scratch_begin(0, 0);
REGS_RegBlockX64 *src = (REGS_RegBlockX64 *)reg_block;
X64_RegBlock *src = (X64_RegBlock *)reg_block;
//- rjf: unpack info about available features
U32 feature_mask = GetEnabledXStateFeatures();
@@ -860,49 +865,49 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
break;
}
//- rjf: convert REGS_RegBlockX64 -> CONTEXT
//- rjf: convert X64_RegBlock -> CONTEXT
XSAVE_FORMAT *fxsave = &ctx->FltSave;
ctx->ContextFlags = ctx_flags;
ctx->MxCsr = src->mxcsr.u32 & src->mxcsr_mask.u32;
ctx->Rax = src->rax.u64;
ctx->Rcx = src->rcx.u64;
ctx->Rdx = src->rdx.u64;
ctx->Rbx = src->rbx.u64;
ctx->Rsp = src->rsp.u64;
ctx->Rbp = src->rbp.u64;
ctx->Rsi = src->rsi.u64;
ctx->Rdi = src->rdi.u64;
ctx->R8 = src->r8.u64;
ctx->R9 = src->r9.u64;
ctx->R10 = src->r10.u64;
ctx->R11 = src->r11.u64;
ctx->R12 = src->r12.u64;
ctx->R13 = src->r13.u64;
ctx->R14 = src->r14.u64;
ctx->R15 = src->r15.u64;
ctx->Rip = src->rip.u64;
ctx->SegCs = src->cs.u16;
ctx->SegDs = src->ds.u16;
ctx->SegEs = src->es.u16;
ctx->SegFs = src->fs.u16;
ctx->SegGs = src->gs.u16;
ctx->SegSs = src->ss.u16;
ctx->Dr0 = src->dr0.u64;
ctx->Dr1 = src->dr1.u64;
ctx->Dr2 = src->dr2.u64;
ctx->Dr3 = src->dr3.u64;
ctx->Dr6 = src->dr6.u64;
ctx->Dr7 = src->dr7.u64;
ctx->EFlags = src->rflags.u64;
fxsave->ControlWord = src->fcw.u16;
fxsave->StatusWord = src->fsw.u16;
ctx->MxCsr = src->mxcsr & src->mxcsr_mask;
ctx->Rax = src->rax;
ctx->Rcx = src->rcx;
ctx->Rdx = src->rdx;
ctx->Rbx = src->rbx;
ctx->Rsp = src->rsp;
ctx->Rbp = src->rbp;
ctx->Rsi = src->rsi;
ctx->Rdi = src->rdi;
ctx->R8 = src->r8;
ctx->R9 = src->r9;
ctx->R10 = src->r10;
ctx->R11 = src->r11;
ctx->R12 = src->r12;
ctx->R13 = src->r13;
ctx->R14 = src->r14;
ctx->R15 = src->r15;
ctx->Rip = src->rip;
ctx->SegCs = src->cs;
ctx->SegDs = src->ds;
ctx->SegEs = src->es;
ctx->SegFs = src->fs;
ctx->SegGs = src->gs;
ctx->SegSs = src->ss;
ctx->Dr0 = src->dr0;
ctx->Dr1 = src->dr1;
ctx->Dr2 = src->dr2;
ctx->Dr3 = src->dr3;
ctx->Dr6 = src->dr6;
ctx->Dr7 = src->dr7;
ctx->EFlags = src->rflags;
fxsave->ControlWord = src->fcw;
fxsave->StatusWord = src->fsw;
fxsave->TagWord = src->ftw;
fxsave->ErrorOpcode = src->fop.u16;
MemoryCopy(&fxsave->ErrorOffset, &src->fip.u64, sizeof(U64));
MemoryCopy(&fxsave->DataOffset, &src->fdp.u64, sizeof(U64));
fxsave->ErrorOpcode = src->fop;
MemoryCopy(&fxsave->ErrorOffset, &src->fip, sizeof(U64));
MemoryCopy(&fxsave->DataOffset, &src->fdp, sizeof(U64));
{
M128A *float_d = fxsave->FloatRegisters;
REGS_Reg80 *float_s = &src->st0;
U80 *float_s = &src->st0;
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
{
MemoryCopy(float_d, float_s, 10);
@@ -912,7 +917,7 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
// SSE registers are always available in x64
{
M128A *xmm_d = fxsave->XmmRegisters;
REGS_Reg512 *zmm_s = &src->zmm0;
U512 *zmm_s = &src->zmm0;
for(U32 n = 0; n < 16; n += 1, xmm_d += 1, zmm_s += 1)
{
MemoryCopy(xmm_d, zmm_s, sizeof(*xmm_d));
@@ -924,12 +929,13 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
{
DWORD avx_length = 0;
U8* avx_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
Assert(avx_length == 16 * sizeof(REGS_Reg128));
REGS_Reg512 *zmm_s = &src->zmm0;
for(U32 n = 0; n < 16; n += 1, avx_d += sizeof(REGS_Reg128), zmm_s += 1)
if(avx_length == 16 * sizeof(U128))
{
MemoryCopy(avx_d, &zmm_s->v[16], sizeof(REGS_Reg128));
U512 *zmm_s = &src->zmm0;
for(U32 n = 0; n < 16; n += 1, avx_d += sizeof(U128), zmm_s += 1)
{
MemoryCopy(avx_d, &zmm_s->u8[16], sizeof(U128));
}
}
}
@@ -938,32 +944,35 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
{
DWORD kmask_length = 0;
U64* kmask_d = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
Assert(kmask_length == 8 * sizeof(*kmask_d));
REGS_Reg64 *kmask_s = &src->k0;
if(kmask_length == 8 * sizeof(*kmask_d))
{
U64 *kmask_s = &src->k0;
for(U32 n = 0; n < 8; n += 1, kmask_s += 1, kmask_d += 1)
{
MemoryCopy(kmask_d, kmask_s, sizeof(*kmask_d));
}
}
DWORD avx512h_length = 0;
U8* avx512h_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
Assert(avx512h_length == 16 * sizeof(REGS_Reg256));
REGS_Reg512 *zmmh_s = &src->zmm0;
for(U32 n = 0; n < 16; n += 1, avx512h_d += sizeof(REGS_Reg256), zmmh_s += 1)
if(avx512h_length == 16 * sizeof(U256))
{
MemoryCopy(avx512h_d, &zmmh_s->v[32], sizeof(REGS_Reg256));
U512 *zmmh_s = &src->zmm0;
for(U32 n = 0; n < 16; n += 1, avx512h_d += sizeof(U256), zmmh_s += 1)
{
MemoryCopy(avx512h_d, &zmmh_s->u8[32], sizeof(U256));
}
}
DWORD avx512_length = 0;
U8* avx512_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
Assert(avx512_length == 16 * sizeof(REGS_Reg512));
REGS_Reg512 *zmm_s = &src->zmm16;
for(U32 n = 0; n < 16; n += 1, avx512_d += sizeof(REGS_Reg512), zmm_s += 1)
if(avx512_length == 16 * sizeof(U512))
{
MemoryCopy(avx512_d, zmm_s, sizeof(REGS_Reg512));
U512 *zmm_s = &src->zmm16;
for(U32 n = 0; n < 16; n += 1, avx512_d += sizeof(U512), zmm_s += 1)
{
MemoryCopy(avx512_d, zmm_s, sizeof(U512));
}
}
}
@@ -1069,7 +1078,7 @@ dmn_ctrl_exclusive_access_end(void)
}
internal U32
dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
dmn_ctrl_launch(DMN_CtrlCtx *ctx, ProcessLaunchParams *params)
{
Temp scratch = scratch_begin(0, 0);
U32 result = 0;
@@ -1133,21 +1142,21 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
}
BOOL inherit_handles = 0;
STARTUPINFOW startup_info = {sizeof(startup_info)};
if(!os_handle_match(params->stdout_file, os_handle_zero()))
if(!file_match(params->stdout_file, file_zero()))
{
HANDLE stdout_handle = (HANDLE)params->stdout_file.u64[0];
startup_info.hStdOutput = stdout_handle;
startup_info.dwFlags |= STARTF_USESTDHANDLES;
inherit_handles = 1;
}
if(!os_handle_match(params->stderr_file, os_handle_zero()))
if(!file_match(params->stderr_file, file_zero()))
{
HANDLE stderr_handle = (HANDLE)params->stderr_file.u64[0];
startup_info.hStdError = stderr_handle;
startup_info.dwFlags |= STARTF_USESTDHANDLES;
inherit_handles = 1;
}
if(!os_handle_match(params->stdin_file, os_handle_zero()))
if(!file_match(params->stdin_file, file_zero()))
{
HANDLE stdin_handle = (HANDLE)params->stdin_file.u64[0];
startup_info.hStdInput = stdin_handle;
@@ -1502,7 +1511,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
//- rjf: x64
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
X64_RegBlock regs = {0};
dmn_w32_thread_read_reg_block(child->arch, child->handle, &regs);
{
U64 trap_idx = 0;
@@ -1511,7 +1520,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
for(U64 n_idx = 0; n_idx < n->count && trap_idx < 4; n_idx += 1, trap_idx += 1)
{
DMN_Trap *trap = &n->v[n_idx];
REGS_Reg64 *addr_reg = &regs.dr0;
U64 *addr_reg = &regs.dr0;
switch(trap_idx)
{
default:{}break;
@@ -1520,12 +1529,12 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
case 2:{addr_reg = &regs.dr2;}break;
case 3:{addr_reg = &regs.dr3;}break;
}
addr_reg->u64 = trap->vaddr;
regs.dr7.u64 |= bit9|bit10|bit11;
regs.dr7.u64 |= (1ull << (trap_idx*2));
addr_reg[0] = trap->vaddr;
regs.dr7 |= bit9|bit10|bit11;
regs.dr7 |= (1ull << (trap_idx*2));
// NOTE(rjf): global-enable regs.dr7.u64 |= (1ull << (trap_idx*2+1));
regs.dr7.u64 &= ~((U64)(bit17|bit18|bit19|bit20) << (trap_idx*4));
regs.dr7.u64 &= ~((U64)(bit15|bit16));
regs.dr7 &= ~((U64)(bit17|bit18|bit19|bit20) << (trap_idx*4));
regs.dr7 &= ~((U64)(bit15|bit16));
switch(trap->flags)
{
case DMN_TrapFlag_BreakOnExecute:
@@ -1533,14 +1542,14 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
case DMN_TrapFlag_BreakOnWrite:
case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
{
regs.dr7.u64 |= ((U64)bit17) << (trap_idx*4);
regs.dr7 |= ((U64)bit17) << (trap_idx*4);
}break;
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite:
case DMN_TrapFlag_BreakOnRead:
{
regs.dr7.u64 |= (((U64)bit17) << (trap_idx*4));
regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4));
regs.dr7 |= (((U64)bit17) << (trap_idx*4));
regs.dr7 |= (((U64)bit18) << (trap_idx*4));
}break;
}
switch(trap->size)
@@ -1549,16 +1558,16 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
default:{}break;
case 2:
{
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
regs.dr7 |= (((U64)bit19) << (trap_idx*4));
}break;
case 4:
{
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
regs.dr7 |= (((U64)bit19) << (trap_idx*4));
regs.dr7 |= (((U64)bit20) << (trap_idx*4));
}break;
case 8:
{
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
regs.dr7 |= (((U64)bit20) << (trap_idx*4));
}break;
}
}
@@ -1663,7 +1672,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
B32 do_threads_resume = 1;
DMN_W32_EntityNode *first_ran_thread = 0;
DMN_W32_EntityNode *last_ran_thread = 0;
U64 begin_time = os_now_microseconds();
U64 begin_time = now_time_us();
String8List debug_strings = {0};
DMN_Event *debug_strings_event = 0;
for(B32 keep_going = 1; keep_going;)
@@ -2178,11 +2187,12 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
default:
{
Temp temp = temp_begin(scratch.arena);
U64 regs_block_size = regs_block_size_from_arch(thread->arch);
ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
U64 regs_block_size = arch_info->reg_block_size;
void *regs_block = push_array(scratch.arena, U8, regs_block_size);
if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block))
{
regs_arch_block_write_rip(thread->arch, regs_block, instruction_pointer);
arch_reg_block_write_ip(arch_info, regs_block, instruction_pointer);
dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block);
}
temp_end(temp);
@@ -2287,16 +2297,16 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
default:{NotImplemented;}break;
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
X64_RegBlock regs = {0};
dmn_w32_thread_read_reg_block(thread->arch, thread->handle, &regs);
if(regs.dr6.u64 & 0xF)
if(regs.dr6 & 0xF)
{
e->kind = DMN_EventKind_Breakpoint;
if(0){}
else if(regs.dr7.u64 & (1ull<<0) && regs.dr6.u64 & (1ull<<0)) { flagged_trap_idx = 0; e->address = regs.dr0.u64; }
else if(regs.dr7.u64 & (1ull<<2) && regs.dr6.u64 & (1ull<<1)) { flagged_trap_idx = 1; e->address = regs.dr1.u64; }
else if(regs.dr7.u64 & (1ull<<4) && regs.dr6.u64 & (1ull<<2)) { flagged_trap_idx = 2; e->address = regs.dr2.u64; }
else if(regs.dr7.u64 & (1ull<<8) && regs.dr6.u64 & (1ull<<3)) { flagged_trap_idx = 3; e->address = regs.dr3.u64; }
else if(regs.dr7 & (1ull<<0) && regs.dr6 & (1ull<<0)) { flagged_trap_idx = 0; e->address = regs.dr0; }
else if(regs.dr7 & (1ull<<2) && regs.dr6 & (1ull<<1)) { flagged_trap_idx = 1; e->address = regs.dr1; }
else if(regs.dr7 & (1ull<<4) && regs.dr6 & (1ull<<2)) { flagged_trap_idx = 2; e->address = regs.dr2; }
else if(regs.dr7 & (1ull<<8) && regs.dr6 & (1ull<<3)) { flagged_trap_idx = 3; e->address = regs.dr3; }
}
}break;
}
@@ -2540,7 +2550,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
////////////////////////
//- rjf: exit loop after a little while, so we keep pumping e.g. debug strings
//
if(os_now_microseconds() >= begin_time+100000 && debug_strings.total_size != 0)
if(now_time_us() >= begin_time+100000 && debug_strings.total_size != 0)
{
keep_going = 0;
}
@@ -2611,7 +2621,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{
if(thread->kind != DMN_W32_EntityKind_Thread) { continue; }
if(thread->thread.last_name_hash == 0 ||
thread->thread.name_gather_time_us+1000000 <= os_now_microseconds())
thread->thread.name_gather_time_us+1000000 <= now_time_us())
{
String8 name = {0};
{
@@ -2632,7 +2642,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
e->thread = dmn_w32_handle_from_entity(thread);
e->string = push_str8_copy(arena, name);
}
thread->thread.name_gather_time_us = os_now_microseconds();
thread->thread.name_gather_time_us = now_time_us();
thread->thread.last_name_hash = name_hash;
}
}
@@ -2684,9 +2694,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
//- rjf: x64
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
X64_RegBlock regs = {0};
dmn_w32_thread_read_reg_block(child->arch, child->handle, &regs);
regs.dr7.u64 = 0;
regs.dr7 = 0;
dmn_w32_thread_write_reg_block(child->arch, child->handle, &regs);
}break;
}
@@ -2897,7 +2907,7 @@ dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size)
}
internal void
dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFlags flags)
dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, AccessFlags flags)
{
DMN_AccessScope
{
@@ -2907,11 +2917,11 @@ dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFla
switch(flags)
{
default:{}break;
case OS_AccessFlag_Execute:{new_flags = PAGE_EXECUTE;}break;
case OS_AccessFlag_Execute|OS_AccessFlag_Read:{new_flags = PAGE_EXECUTE_READ;}break;
case OS_AccessFlag_Execute|OS_AccessFlag_Read|OS_AccessFlag_Write:{new_flags = PAGE_EXECUTE_READWRITE;}break;
case OS_AccessFlag_Read:{new_flags = PAGE_READONLY;}break;
case OS_AccessFlag_Read|OS_AccessFlag_Write:{new_flags = PAGE_READWRITE;}break;
case AccessFlag_Execute:{new_flags = PAGE_EXECUTE;}break;
case AccessFlag_Execute|AccessFlag_Read:{new_flags = PAGE_EXECUTE_READ;}break;
case AccessFlag_Execute|AccessFlag_Read|AccessFlag_Write:{new_flags = PAGE_EXECUTE_READWRITE;}break;
case AccessFlag_Read:{new_flags = PAGE_READONLY;}break;
case AccessFlag_Read|AccessFlag_Write:{new_flags = PAGE_READWRITE;}break;
}
VirtualProtectEx(process_entity->handle, (void *)vaddr, size, new_flags, &old_flags);
}
+1 -9
View File
@@ -294,13 +294,6 @@ dasm_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_o
//- rjf: data * arch * addr * dbg -> decode artifacts
DASM_LineChunkList line_list = {0};
String8List inst_strings = {0};
switch(params.arch)
{
default:{}break;
//- rjf: x86/x64 decoding
case Arch_x64:
case Arch_x86:
{
// rjf: disassemble
RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
@@ -356,7 +349,7 @@ dasm_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_o
params.style_flags & DASM_StyleFlag_SourceLines &&
file_normalized_full_path.size != 0)
{
FileProperties props = os_properties_from_file_path(file_normalized_full_path);
FileProperties props = properties_from_file_path(file_normalized_full_path);
if(props.modified != 0)
{
// TODO(rjf): need redirection path - this may map to a different path on the local machine,
@@ -437,7 +430,6 @@ dasm_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_o
// rjf: increment
off += inst.size;
}
}break;
}
//- rjf: artifacts -> value bundle
+1 -1
View File
@@ -226,7 +226,7 @@ dr_begin_frame(FNT_Tag icon_font)
}
internal void
dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket)
dr_submit_bucket(OS_Window os_window, R_Handle r_window, DR_Bucket *bucket)
{
r_window_submit(os_window, r_window, &bucket->passes);
}
+1 -1
View File
@@ -134,7 +134,7 @@ internal Vec2F32 dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs);
// (Frame boundaries & bucket submission)
internal void dr_begin_frame(FNT_Tag icon_font);
internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket);
internal void dr_submit_bucket(OS_Window os_window, R_Handle r_window, DR_Bucket *bucket);
////////////////////////////////
//~ rjf: Bucket Construction & Selection API
+5
View File
@@ -1,6 +1,11 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Generated Code
#include "dwarf/generated/dwarf.meta.c"
internal DW_AttribClass
dw_attrib_class_from_attrib_v2(DW_AttribKind k)
{
+5
View File
@@ -1739,6 +1739,11 @@ typedef enum DW_RegX64Enum
DW_RegX64_Last
} DW_RegX64Enum;
////////////////////////////////
//~ rjf: Generated Code
#include "dwarf/generated/dwarf.meta.h"
////////////////////////////////
// Speced Encodings
+89
View File
@@ -0,0 +1,89 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
@table(name code byte_size)
DW_RegCodeTableX64:
{
{rax 0 8}
{rdx 1 8}
{rcx 2 8}
{rbx 3 8}
{rsi 4 8}
{rdi 5 8}
{rbp 6 8}
{rsp 7 8}
{r8 8 8}
{r9 9 8}
{r10 10 8}
{r11 11 8}
{r12 12 8}
{r13 13 8}
{r14 14 8}
{r15 15 8}
{rip 16 8}
{zmm0 17 16}
{zmm1 18 16}
{zmm2 19 16}
{zmm3 20 16}
{zmm4 21 16}
{zmm5 22 16}
{zmm6 23 16}
{zmm7 24 16}
{zmm8 25 16}
{zmm9 26 16}
{zmm10 27 16}
{zmm11 28 16}
{zmm12 29 16}
{zmm13 30 16}
{zmm14 31 16}
{zmm15 32 16}
{zmm16 67 16}
{zmm17 68 16}
{zmm18 69 16}
{zmm19 70 16}
{zmm20 71 16}
{zmm21 72 16}
{zmm22 73 16}
{zmm23 74 16}
{zmm24 75 16}
{zmm25 76 16}
{zmm26 77 16}
{zmm27 78 16}
{zmm28 79 16}
{zmm29 80 16}
{zmm30 81 16}
{zmm31 82 16}
{st0 33 10}
{st1 34 10}
{st2 35 10}
{st3 36 10}
{st4 37 10}
{st5 38 10}
{st6 39 10}
{st7 40 10}
{mm0 41 8}
{mm1 42 8}
{mm2 43 8}
{mm3 44 8}
{mm4 45 8}
{mm5 46 8}
{mm6 47 8}
{mm7 48 8}
{rflags 49 4}
{es 50 2}
{cs 51 2}
{ss 52 2}
{ds 53 2}
{fs 54 2}
{gs 55 2}
{fsbase 58 8}
{gsbase 59 8}
// privileged registers:
// {Tr 62 ???}
// {Ldtr 63 ???}
}
@enum DW_RegCodeX64:
{
@expand(DW_RegCodeTableX64 a) `$(a.name) = $(a.code)`,
}
+48 -34
View File
@@ -1128,20 +1128,12 @@ dw_expr_inst_from_delta(DW_ExprInst *inst, S16 delta)
}
internal DW_ExprEvalResult
dw_eval_expr(Arena *arena,
Arch arch,
DW_Format format,
U64 frame_base,
U64 cfa,
U64 tls,
U64 exec_op_limit,
DW_Expr expr,
MachineOp_RegRead *reg_read, void *reg_read_ud,
MachineOp_MemRead *mem_read, void *mem_read_ud,
DW_ExprValue *value_out)
dw_eval_expr(Arena *arena, Arch arch, DW_Format format, U64 frame_base, U64 cfa, U64 tls, U64 exec_op_limit, DW_Expr expr, void *reg_block, MachineOp_MemRead *mem_read, void *mem_read_ud, DW_ExprValue *value_out)
{
Temp scratch = scratch_begin(&arena, 1);
ARCH_Info *arch_info = arch_info_from_arch(arch);
DW_ExprEvalResult result = DW_ExprEvalResult_Fail;
DW_PieceList pieces = {0};
DW_ExprStack *stack = push_array(scratch.arena, DW_ExprStack, 1);
@@ -1202,12 +1194,17 @@ dw_eval_expr(Arena *arena,
case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23:
case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26:
case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29:
case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: {
DW_Reg reg_id = inst->opcode - DW_ExprOp_Reg0;
U64 reg_size = dw_reg_size_from_code(arch, reg_id);
case DW_ExprOp_Reg30: case DW_ExprOp_Reg31:
{
DW_Reg reg_dw_id = inst->opcode - DW_ExprOp_Reg0;
U64 reg_size = dw_reg_size_from_code(arch, reg_dw_id);
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_dw_id);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
MachineOpResult reg_read_result = reg_read(reg_id, reg_value, reg_size, reg_read_ud);
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
if(!arch_reg_block_read_range(arch_info, reg_block, r1u16(reg_rng.min, reg_rng.min + reg_size), reg_value))
{
goto exit;
}
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
}break;
@@ -1221,35 +1218,51 @@ dw_eval_expr(Arena *arena,
case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23:
case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26:
case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29:
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: {
DW_Reg reg_id = inst->opcode - DW_ExprOp_BReg0;
U64 reg_size = dw_reg_size_from_code(arch, reg_id);
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31:
{
DW_Reg reg_dw_id = inst->opcode - DW_ExprOp_BReg0;
U64 reg_size = dw_reg_size_from_code(arch, reg_dw_id);
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_dw_id);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
AssertAlways(reg_size <= byte_size_from_arch(arch));
U64 reg_value;
MachineOpResult reg_read_result = reg_read(reg_id, &reg_value, reg_size, reg_read_ud);
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
U64 reg_value = 0;
if(!arch_reg_block_read_range(arch_info, reg_block, r1u16(reg_rng.min, reg_rng.min + reg_size), &reg_value))
{
goto exit;
}
U64 addr = (U64)((S64)reg_value + inst->operands[0].s64);
dw_expr_stack_push(scratch.arena, stack, (DW_ExprValue){ .type = DW_ExprValueType_Addr, .addr = addr});
}break;
case DW_ExprOp_RegX: {
U64 reg_size = dw_reg_size_from_code(arch, inst->operands[0].u64);
case DW_ExprOp_RegX:
{
DW_Reg reg_dw_id = inst->operands[0].u64;
U64 reg_size = dw_reg_size_from_code(arch, reg_dw_id);
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
MachineOpResult reg_read_result = reg_read(inst->operands[0].u64, reg_value, reg_size, reg_read_ud);
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_dw_id);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
if(!arch_reg_block_read_range(arch_info, reg_block, r1u16(reg_rng.min, reg_rng.min + reg_size), reg_value))
{
goto exit;
}
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
}break;
case DW_ExprOp_BRegX: {
DW_Reg reg_id = (DW_Reg)inst->operands[0].u64;
U64 reg_size = dw_reg_size_from_code(arch, reg_id);
case DW_ExprOp_BRegX:
{
DW_Reg reg_dw_id = (DW_Reg)inst->operands[0].u64;
U64 reg_size = dw_reg_size_from_code(arch, reg_dw_id);
AssertAlways(reg_size <= byte_size_from_arch(arch));
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_dw_id);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
U64 reg_value;
MachineOpResult reg_read_result = reg_read(reg_id, &reg_value, reg_size, reg_read_ud);
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
U64 reg_value = 0;
if(!arch_reg_block_read_range(arch_info, reg_block, r1u16(reg_rng.min, reg_rng.min + reg_size), &reg_value))
{
goto exit;
}
U64 addr = (U64)((S64)reg_value + inst->operands[1].s64);
dw_expr_stack_push(scratch.arena, stack, (DW_ExprValue){ .type = DW_ExprValueType_Addr, .addr = addr});
@@ -1403,10 +1416,11 @@ dw_eval_expr(Arena *arena,
case DW_ExprOp_RegvalType: { NotImplemented; } break;
case DW_ExprOp_EntryValue:
case DW_ExprOp_GNU_EntryValue: {
case DW_ExprOp_GNU_EntryValue:
{
DW_Expr entry_value_expr = dw_expr_from_data(scratch.arena, format, byte_size_from_arch(arch), inst->operands[0].block);
DW_ExprValue entry_value;
result = dw_eval_expr(scratch.arena, arch, format, frame_base, cfa, tls, exec_op_limit, entry_value_expr, reg_read, reg_read_ud, mem_read, mem_read_ud, &entry_value);
result = dw_eval_expr(scratch.arena, arch, format, frame_base, cfa, tls, exec_op_limit, entry_value_expr, reg_block, mem_read, mem_read_ud, &entry_value);
if (result != DW_ExprEvalResult_Ok) { goto exit; }
dw_expr_stack_push(scratch.arena, stack, entry_value);
} break;
+1 -1
View File
@@ -227,7 +227,7 @@ internal DW_ExprValueNode * dw_expr_stack_pick(DW_ExprStack *stack, U64 idx);
internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprValue v);
// evaluator
internal DW_ExprEvalResult dw_eval_expr(Arena *arena, Arch arch, DW_Format format, U64 frame_base, U64 cfa, U64 tls_base, U64 op_limit, DW_Expr expr, MachineOp_RegRead *reg_read, void *reg_read_ud, MachineOp_MemRead *mem_read, void *mem_read_ud, DW_ExprValue *value_out);
internal DW_ExprEvalResult dw_eval_expr(Arena *arena, Arch arch, DW_Format format, U64 frame_base, U64 cfa, U64 tls_base, U64 op_limit, DW_Expr expr, void *reg_block, MachineOp_MemRead *mem_read, void *mem_read_ud, DW_ExprValue *value_out);
// encoder
internal String8 dw_encode_expr(Arena *arena, Arch arch, DW_Format format, DW_ExprEnc *encs, U64 encs_count);
+3
View File
@@ -13,3 +13,6 @@
#include "dwarf/dwarf_parse_2.c"
#include "dwarf/eh_frame.c"
#include "dwarf/eh_dump.c"
#if defined(X64_H)
# include "dwarf/x64/dwarf_x64.c"
#endif
+3
View File
@@ -16,5 +16,8 @@
#include "dwarf/dwarf_parse_2.h"
#include "dwarf/eh_frame.h"
#include "dwarf/eh_dump.h"
#if defined(X64_H)
# include "dwarf/x64/dwarf_x64.h"
#endif
#endif // DWARF_INC_H
+37
View File
@@ -56,6 +56,43 @@ dw2_read_fmt_u64(String8 data, U64 off, DW_Format format, U64 *out)
return bytes_read;
}
////////////////////////////////
//~ rjf: Unit Range Set Parsing (Top-Level .debug_info, .debug_aranges)
internal Rng1U64Array
dw2_unit_ranges_from_data(Arena *arena, String8 data)
{
Temp scratch = scratch_begin(&arena, 1);
Rng1U64List unit_range_list = {0};
for(U64 off = 0; off < data.size;)
{
U64 start_off = off;
// rjf: read next unit size
U64 unit_size = 0;
U64 unit_size_size = dw2_read_initial_length(data, off, &unit_size, 0);
// rjf: push
if(unit_size > 0)
{
rng1u64_list_push(scratch.arena, &unit_range_list, r1u64(off, off + unit_size_size + unit_size));
}
// rjf: advance
off += unit_size_size;
off += unit_size;
// rjf: break if no movement
if(off == start_off)
{
break;
}
}
Rng1U64Array result = rng1u64_array_from_list(arena, &unit_range_list);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Unit Header Parsing
+5
View File
@@ -240,6 +240,11 @@ global read_only DW2_Attrib dw2_attrib_nil = {0};
internal U64 dw2_read_initial_length(String8 data, U64 off, U64 *out, DW_Format *fmt_out);
internal U64 dw2_read_fmt_u64(String8 data, U64 off, DW_Format format, U64 *out);
////////////////////////////////
//~ rjf: Unit Range Set Parsing (Top-Level .debug_info, .debug_aranges)
internal Rng1U64Array dw2_unit_ranges_from_data(Arena *arena, String8 data);
////////////////////////////////
//~ rjf: Unit Header Parsing
+59 -37
View File
@@ -237,55 +237,61 @@ dw_cfi_row_from_pc(Arena *arena, Arch arch, DW_CIE *cie, DW_FDE *fde, DW_DecodeP
}
internal MachineOpResult
dw_compute_cfa(Arch arch,
DW_CFI_Row *row,
MachineOp_MemRead *mem_read_func, void *mem_read_ud,
MachineOp_RegRead *reg_read_func, void *reg_read_ud,
U64 *cfa_out)
dw_compute_cfa(Arch arch, DW_CFI_Row *row, void *reg_block, MachineOp_MemRead *mem_read_func, void *mem_read_ud, U64 *cfa_out)
{
MachineOpResult unwind_status = MachineOpResult_Fail;
switch (row->cfa.rule) {
case DW_CFA_Rule_Null: break;
case DW_CFA_Rule_RegOff: {
ARCH_Info *arch_info = arch_info_from_arch(arch);
switch(row->cfa.rule)
{
case DW_CFA_Rule_Null:{}break;
case DW_CFA_Rule_RegOff:
{
// TODO: report error (invalid register read)
U64 cfa_reg_value = 0;
U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
AssertAlways(reg_size <= sizeof(cfa_reg_value));
unwind_status = reg_read_func(row->cfa.reg, &cfa_reg_value, reg_size, reg_read_ud);
if (unwind_status != MachineOpResult_Ok) { break; }
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, row->cfa.reg);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
if(!arch_reg_block_read_range(arch_info, reg_block, reg_rng, &cfa_reg_value))
{
unwind_status = MachineOpResult_Fail;
break;
}
*cfa_out = cfa_reg_value + row->cfa.off;
}break;
case DW_CFA_Rule_Expression: {
case DW_CFA_Rule_Expression:
{
// TODO: evaluate expression
NotImplemented;
}break;
}
return unwind_status;
}
internal MachineOpResult
dw_cfi_apply_register_rules(Arch arch,
U64 cfa,
DW_CFI_Row *row,
MachineOp_MemRead *mem_read_func, void *mem_read_ud,
MachineOp_RegRead *reg_read_func, void *reg_read_ud,
MachineOp_RegWrite *reg_write_func, void *reg_write_ud)
dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, void *reg_block, MachineOp_MemRead *mem_read_func, void *mem_read_ud)
{
Temp scratch = scratch_begin(0,0);
MachineOpResult unwind_status = MachineOpResult_Ok;
ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 max_reg_size = dw_reg_max_size_from_arch(arch);
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size);
U64 reg_count = dw_reg_count_from_arch(arch);
for EachIndex(reg_idx, reg_count) {
for EachIndex(reg_idx, reg_count)
{
DW_CFI_Register *reg = &row->regs[reg_idx];
switch (reg->rule) {
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_idx);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
switch(reg->rule)
{
default:{}break;
case DW_CFI_RegisterRule_Undefined: {} break;
case DW_CFI_RegisterRule_SameValue: {} break;
case DW_CFI_RegisterRule_Offset: {
case DW_CFI_RegisterRule_Offset:
{
// read register value from memory
U64 addr = cfa + reg->n;
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
@@ -293,46 +299,62 @@ dw_cfi_apply_register_rules(Arch arch,
if (unwind_status != MachineOpResult_Ok) { goto exit; }
// write register value to the thread context
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud);
if (unwind_status != MachineOpResult_Ok) { goto exit; }
if(!arch_reg_block_write_range(arch_info, reg_block, reg_rng, reg_buffer))
{
unwind_status = MachineOpResult_Fail;
goto exit;
}
}break;
case DW_CFI_RegisterRule_ValOffset: {
case DW_CFI_RegisterRule_ValOffset:
{
// compute register value
U64 reg_value = cfa + reg->n;
// write register value to the thread context
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
unwind_status = reg_write_func(reg_idx, &reg_value, reg_size, reg_write_ud);
if (unwind_status != MachineOpResult_Ok) { goto exit; }
if(!arch_reg_block_write_range(arch_info, reg_block, reg_rng, &reg_value))
{
unwind_status = MachineOpResult_Fail;
goto exit;
}
}break;
case DW_CFI_RegisterRule_Register: {
case DW_CFI_RegisterRule_Register:
{
// read register value from another register
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
unwind_status = reg_read_func(reg->n, reg_buffer, reg_size, reg_read_ud);
if (unwind_status != MachineOpResult_Ok) { goto exit; }
if(!arch_reg_block_read_range(arch_info, reg_block, reg_rng, reg_buffer))
{
unwind_status = MachineOpResult_Fail;
goto exit;
}
// write register value to the thread context
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud);
if(!arch_reg_block_write_range(arch_info, reg_block, reg_rng, reg_buffer))
{
unwind_status = MachineOpResult_Fail;
goto exit;
}
if (unwind_status != MachineOpResult_Ok) { goto exit; }
}break;
case DW_CFI_RegisterRule_Expression: {
case DW_CFI_RegisterRule_Expression:
{
// TODO: evaluate expression
NotImplemented;
}break;
case DW_CFI_RegisterRule_ValExpression: {
case DW_CFI_RegisterRule_ValExpression:
{
// TODO: evaluate expression
NotImplemented;
}break;
case DW_CFI_RegisterRule_Architectural: {
case DW_CFI_RegisterRule_Architectural:
{
NotImplemented;
}break;
default: { InvalidPath; } break;
}
}
// update stack pointer
U64 sp = dw_sp_from_arch(arch);
reg_write_func(sp, &cfa, sizeof(cfa), reg_write_ud);
arch_reg_block_write_sp(arch_info, reg_block, cfa);
exit:;
scratch_end(scratch);
+2 -1
View File
@@ -74,7 +74,8 @@ internal DW_CFI_Unwind * dw_cfi_unwind_init(Arena *arena, Arch arch, DW_CIE *cie
internal B32 dw_cfi_next_row(Arena *arena, DW_CFI_Unwind *uw);
internal DW_CFI_Row * dw_cfi_row_from_pc(Arena *arena, Arch arch, struct DW_CIE *cie, struct DW_FDE *fde, DW_DecodePtr *decode_ptr_func, void *decode_ptr_ctx, U64 pc);
internal MachineOpResult dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, MachineOp_MemRead *mem_read_func, void *mem_read_ud, MachineOp_RegRead *reg_read_func, void *reg_read_ud, MachineOp_RegWrite *reg_write_func, void *reg_write_ud);
internal MachineOpResult dw_compute_cfa(Arch arch, DW_CFI_Row *row, void *reg_block, MachineOp_MemRead *mem_read_func, void *mem_read_ud, U64 *cfa_out);
internal MachineOpResult dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, void *reg_block, MachineOp_MemRead *mem_read_func, void *mem_read_ud);
#endif // DWARF_UNWIND_H
@@ -1,4 +1,5 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "regs/rdi/generated/regs_rdi.meta.c"
//- GENERATED CODE
+87
View File
@@ -0,0 +1,87 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef DWARF_META_H
#define DWARF_META_H
typedef enum DW_RegCodeX64
{
DW_RegCodeX64_rax = 0,
DW_RegCodeX64_rdx = 1,
DW_RegCodeX64_rcx = 2,
DW_RegCodeX64_rbx = 3,
DW_RegCodeX64_rsi = 4,
DW_RegCodeX64_rdi = 5,
DW_RegCodeX64_rbp = 6,
DW_RegCodeX64_rsp = 7,
DW_RegCodeX64_r8 = 8,
DW_RegCodeX64_r9 = 9,
DW_RegCodeX64_r10 = 10,
DW_RegCodeX64_r11 = 11,
DW_RegCodeX64_r12 = 12,
DW_RegCodeX64_r13 = 13,
DW_RegCodeX64_r14 = 14,
DW_RegCodeX64_r15 = 15,
DW_RegCodeX64_rip = 16,
DW_RegCodeX64_zmm0 = 17,
DW_RegCodeX64_zmm1 = 18,
DW_RegCodeX64_zmm2 = 19,
DW_RegCodeX64_zmm3 = 20,
DW_RegCodeX64_zmm4 = 21,
DW_RegCodeX64_zmm5 = 22,
DW_RegCodeX64_zmm6 = 23,
DW_RegCodeX64_zmm7 = 24,
DW_RegCodeX64_zmm8 = 25,
DW_RegCodeX64_zmm9 = 26,
DW_RegCodeX64_zmm10 = 27,
DW_RegCodeX64_zmm11 = 28,
DW_RegCodeX64_zmm12 = 29,
DW_RegCodeX64_zmm13 = 30,
DW_RegCodeX64_zmm14 = 31,
DW_RegCodeX64_zmm15 = 32,
DW_RegCodeX64_zmm16 = 67,
DW_RegCodeX64_zmm17 = 68,
DW_RegCodeX64_zmm18 = 69,
DW_RegCodeX64_zmm19 = 70,
DW_RegCodeX64_zmm20 = 71,
DW_RegCodeX64_zmm21 = 72,
DW_RegCodeX64_zmm22 = 73,
DW_RegCodeX64_zmm23 = 74,
DW_RegCodeX64_zmm24 = 75,
DW_RegCodeX64_zmm25 = 76,
DW_RegCodeX64_zmm26 = 77,
DW_RegCodeX64_zmm27 = 78,
DW_RegCodeX64_zmm28 = 79,
DW_RegCodeX64_zmm29 = 80,
DW_RegCodeX64_zmm30 = 81,
DW_RegCodeX64_zmm31 = 82,
DW_RegCodeX64_st0 = 33,
DW_RegCodeX64_st1 = 34,
DW_RegCodeX64_st2 = 35,
DW_RegCodeX64_st3 = 36,
DW_RegCodeX64_st4 = 37,
DW_RegCodeX64_st5 = 38,
DW_RegCodeX64_st6 = 39,
DW_RegCodeX64_st7 = 40,
DW_RegCodeX64_mm0 = 41,
DW_RegCodeX64_mm1 = 42,
DW_RegCodeX64_mm2 = 43,
DW_RegCodeX64_mm3 = 44,
DW_RegCodeX64_mm4 = 45,
DW_RegCodeX64_mm5 = 46,
DW_RegCodeX64_mm6 = 47,
DW_RegCodeX64_mm7 = 48,
DW_RegCodeX64_rflags = 49,
DW_RegCodeX64_es = 50,
DW_RegCodeX64_cs = 51,
DW_RegCodeX64_ss = 52,
DW_RegCodeX64_ds = 53,
DW_RegCodeX64_fs = 54,
DW_RegCodeX64_gs = 55,
DW_RegCodeX64_fsbase = 58,
DW_RegCodeX64_gsbase = 59,
} DW_RegCodeX64;
#endif // DWARF_META_H
+4
View File
@@ -0,0 +1,4 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "dwarf/x64/generated/dwarf_x64.meta.c"
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DWARF_X64_H
#define DWARF_X64_H
#include "dwarf/x64/generated/dwarf_x64.meta.h"
#endif // DWARF_X64_H
+7
View File
@@ -0,0 +1,7 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
@data(U8) dw_reg_code_from_x64_table:
{
@expand(X64_RegTable a) `$(a.has_dwarf == 'x' -> "DW_RegCodeX64_" .. a.name)$(a.has_dwarf != 'x' -> 0)`
}
+201
View File
@@ -0,0 +1,201 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
C_LINKAGE_BEGIN
U8 dw_reg_code_from_x64_table[189] =
{
0,
DW_RegCodeX64_rax,
DW_RegCodeX64_rcx,
DW_RegCodeX64_rdx,
DW_RegCodeX64_rbx,
DW_RegCodeX64_rsp,
DW_RegCodeX64_rbp,
DW_RegCodeX64_rsi,
DW_RegCodeX64_rdi,
DW_RegCodeX64_r8,
DW_RegCodeX64_r9,
DW_RegCodeX64_r10,
DW_RegCodeX64_r11,
DW_RegCodeX64_r12,
DW_RegCodeX64_r13,
DW_RegCodeX64_r14,
DW_RegCodeX64_r15,
DW_RegCodeX64_fsbase,
DW_RegCodeX64_gsbase,
DW_RegCodeX64_rip,
DW_RegCodeX64_rflags,
0,
0,
0,
0,
0,
0,
0,
0,
DW_RegCodeX64_st0,
DW_RegCodeX64_st1,
DW_RegCodeX64_st2,
DW_RegCodeX64_st3,
DW_RegCodeX64_st4,
DW_RegCodeX64_st5,
DW_RegCodeX64_st6,
DW_RegCodeX64_st7,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
DW_RegCodeX64_ss,
DW_RegCodeX64_cs,
DW_RegCodeX64_ds,
DW_RegCodeX64_es,
DW_RegCodeX64_fs,
DW_RegCodeX64_gs,
DW_RegCodeX64_zmm0,
DW_RegCodeX64_zmm1,
DW_RegCodeX64_zmm2,
DW_RegCodeX64_zmm3,
DW_RegCodeX64_zmm4,
DW_RegCodeX64_zmm5,
DW_RegCodeX64_zmm6,
DW_RegCodeX64_zmm7,
DW_RegCodeX64_zmm8,
DW_RegCodeX64_zmm9,
DW_RegCodeX64_zmm10,
DW_RegCodeX64_zmm11,
DW_RegCodeX64_zmm12,
DW_RegCodeX64_zmm13,
DW_RegCodeX64_zmm14,
DW_RegCodeX64_zmm15,
DW_RegCodeX64_zmm16,
DW_RegCodeX64_zmm17,
DW_RegCodeX64_zmm18,
DW_RegCodeX64_zmm19,
DW_RegCodeX64_zmm20,
DW_RegCodeX64_zmm21,
DW_RegCodeX64_zmm22,
DW_RegCodeX64_zmm23,
DW_RegCodeX64_zmm24,
DW_RegCodeX64_zmm25,
DW_RegCodeX64_zmm26,
DW_RegCodeX64_zmm27,
DW_RegCodeX64_zmm28,
DW_RegCodeX64_zmm29,
DW_RegCodeX64_zmm30,
DW_RegCodeX64_zmm31,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
DW_RegCodeX64_mm0,
DW_RegCodeX64_mm1,
DW_RegCodeX64_mm2,
DW_RegCodeX64_mm3,
DW_RegCodeX64_mm4,
DW_RegCodeX64_mm5,
DW_RegCodeX64_mm6,
DW_RegCodeX64_mm7,
};
C_LINKAGE_END
+14
View File
@@ -0,0 +1,14 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef DWARF_X64_META_H
#define DWARF_X64_META_H
C_LINKAGE_BEGIN
extern U8 dw_reg_code_from_x64_table[189];
C_LINKAGE_END
#endif // DWARF_X64_META_H
+5 -5
View File
@@ -707,11 +707,12 @@ e_oplist_from_location(Arena *arena, RDI_Parsed *rdi, RDI_Location loc)
{
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
Arch arch = arch_from_rdi_arch(tli->arch);
ARCH_Info *arch_info = arch_info_from_arch(arch);
RDI_RegCode rdi_regcode = rdi_regcode_from_location(loc);
REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, rdi_regcode);
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code];
U64 byte_size = (U64)reg_rng.byte_size;
U64 byte_pos = 0;
ARCH_RegCode reg_code = arch_reg_code_from_rdi(arch, rdi_regcode);
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
U64 byte_size = (U64)dim_1u16(reg_rng);
U64 byte_pos = reg_rng.min;
e_oplist_push_op(arena, &result, RDI_EvalOp_RegRead, e_value_u64(RDI_EncodeRegReadParam(rdi_regcode, byte_size, byte_pos)));
}break;
@@ -830,7 +831,6 @@ internal void
e_select_ir_ctx(E_IRCtx *ctx)
{
if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; }
if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; }
if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; }
if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; }
if(ctx->macro_map == 0) { ctx->macro_map = push_array(e_cache->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_cache->arena, 512); }
-2
View File
@@ -165,7 +165,6 @@ typedef enum E_TypeKeyKind
E_TypeKeyKind_Ext,
E_TypeKeyKind_Cons,
E_TypeKeyKind_Reg,
E_TypeKeyKind_RegAlias,
}
E_TypeKeyKind;
@@ -795,7 +794,6 @@ typedef struct E_IRCtx E_IRCtx;
struct E_IRCtx
{
E_String2NumMap *regs_map;
E_String2NumMap *reg_alias_map;
E_String2NumMap *locals_map; // (within `primary_module`)
E_String2NumMap *member_map; // (within `primary_module`)
E_String2ExprMap *macro_map;
+6 -5
View File
@@ -280,13 +280,14 @@ e_interpret(String8 bytecode)
U8 rdi_reg_code = (imm.u64&0x0000FF)>>0;
U8 byte_size = (imm.u64&0x00FF00)>>8;
U8 byte_off = (imm.u64&0xFF0000)>>16;
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(e_interpret_ctx->reg_arch, rdi_reg_code);
REGS_Rng *rng_table = regs_reg_code_rng_table_from_arch(e_interpret_ctx->reg_arch);
Arch arch = e_interpret_ctx->reg_arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
ARCH_RegCode base_reg_code = arch_reg_code_from_rdi(arch, rdi_reg_code);
B32 good_read = 0;
if(0 <= rdi_reg_code && rdi_reg_code < regs_reg_code_count_from_arch(e_interpret_ctx->reg_arch))
if(0 <= base_reg_code && base_reg_code < arch_info->reg_code_count)
{
REGS_Rng rng = rng_table[base_reg_code];
U64 off = (U64)rng.byte_off + byte_off;
Rng1U16 rng = arch_info->reg_code_rng_table[base_reg_code];
U64 off = (U64)rng.min + byte_off;
U64 size = (U64)byte_size;
good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
}
+14 -38
View File
@@ -2016,49 +2016,25 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(reg_num != 0)
{
string_mapped = 1;
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num];
Arch arch = e_base_ctx->primary_module->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch);
ARCH_RegCode reg_code = reg_num;
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
U64 reg_size = dim_1u16(reg_rng);
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off);
e_oplist_push_uconst(arena, &oplist, reg_rng.min);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
REGS_UsageKind reg_usage_kind = regs_reg_code_usage_kind_table_from_arch(e_base_ctx->primary_module->arch)[reg_num];
B32 is_vector = arch_info->reg_code_is_vector_table[reg_code];
if(0){}
else if(reg_usage_kind == REGS_UsageKind_Normal && reg_rng.byte_size == 1) {mapped_type_key = e_type_key_basic(E_TypeKind_U8);}
else if(reg_usage_kind == REGS_UsageKind_Normal && reg_rng.byte_size == 2) {mapped_type_key = e_type_key_basic(E_TypeKind_U16);}
else if(reg_usage_kind == REGS_UsageKind_Normal && reg_rng.byte_size == 4) {mapped_type_key = e_type_key_basic(E_TypeKind_U32);}
else if(reg_usage_kind == REGS_UsageKind_Normal && reg_rng.byte_size == 8) {mapped_type_key = e_type_key_basic(E_TypeKind_U64);}
else if(!is_vector && reg_size == 1) {mapped_type_key = e_type_key_basic(E_TypeKind_U8);}
else if(!is_vector && reg_size == 2) {mapped_type_key = e_type_key_basic(E_TypeKind_U16);}
else if(!is_vector && reg_size == 4) {mapped_type_key = e_type_key_basic(E_TypeKind_U32);}
else if(!is_vector && reg_size == 8) {mapped_type_key = e_type_key_basic(E_TypeKind_U64);}
else
{
mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num);
}
}
}break;
//- rjf: try register aliases
case E_IdentifierResolutionPath_RegisterAliases:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0)))
{
U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string);
if(alias_num != 0)
{
string_mapped = 1;
REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num];
REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code];
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
REGS_UsageKind reg_usage_kind = regs_alias_code_usage_kind_table_from_arch(e_base_ctx->primary_module->arch)[alias_num];
if(0){}
else if(reg_usage_kind == REGS_UsageKind_Normal && alias_slice.byte_size == 1) {mapped_type_key = e_type_key_basic(E_TypeKind_U8);}
else if(reg_usage_kind == REGS_UsageKind_Normal && alias_slice.byte_size == 2) {mapped_type_key = e_type_key_basic(E_TypeKind_U16);}
else if(reg_usage_kind == REGS_UsageKind_Normal && alias_slice.byte_size == 4) {mapped_type_key = e_type_key_basic(E_TypeKind_U32);}
else if(reg_usage_kind == REGS_UsageKind_Normal && alias_slice.byte_size == 8) {mapped_type_key = e_type_key_basic(E_TypeKind_U64);}
else
{
mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num);
mapped_type_key = e_type_key_reg(arch, reg_code);
}
}
}break;
@@ -2185,7 +2161,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
{
Temp scratch = scratch_begin(&arena, 1);
String8 file_path = expr->string;
FileProperties props = os_properties_from_file_path(file_path);
FileProperties props = properties_from_file_path(file_path);
if(!str8_match(expr->qualifier, str8_lit("folder"), 0) && !(props.flags & FilePropertyFlag_IsFolder) && file_path.size != 0)
{
E_Space space = e_space_make(E_SpaceKind_FileSystem);
@@ -2196,7 +2172,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
else
{
String8 folder_path = str8_chop_last_slash(file_path);
props = os_properties_from_file_path(folder_path);
props = properties_from_file_path(folder_path);
if(props.flags & FilePropertyFlag_IsFolder || folder_path.size == 0 || str8_match(folder_path, str8_lit("/"), StringMatchFlag_SlashInsensitive))
{
E_Space space = e_space_make(E_SpaceKind_FileSystem);
-3
View File
@@ -18,7 +18,6 @@ typedef enum E_IdentifierResolutionPath
E_IdentifierResolutionPath_BuiltInConstants,
E_IdentifierResolutionPath_BuiltInTypes,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Macros,
}
E_IdentifierResolutionPath;
@@ -89,7 +88,6 @@ E_IdentifierResolutionPath e_default_identifier_resolution_paths[] =
E_IdentifierResolutionPath_BuiltInTypes,
E_IdentifierResolutionPath_DebugInfoMatch,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Macros,
};
E_IdentifierResolutionRule e_default_identifier_resolution_rule =
@@ -110,7 +108,6 @@ E_IdentifierResolutionPath e_callable_identifier_resolution_paths[] =
E_IdentifierResolutionPath_BuiltInTypes,
E_IdentifierResolutionPath_DebugInfoMatch,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
};
E_IdentifierResolutionRule e_callable_identifier_resolution_rule =
{
+11 -27
View File
@@ -288,7 +288,7 @@ e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_num)
}
internal E_TypeKey
e_type_key_reg(Arch arch, REGS_RegCode code)
e_type_key_reg(Arch arch, ARCH_RegCode code)
{
E_TypeKey key = {E_TypeKeyKind_Reg};
key.u32[0] = (U32)arch;
@@ -296,15 +296,6 @@ e_type_key_reg(Arch arch, REGS_RegCode code)
return key;
}
internal E_TypeKey
e_type_key_reg_alias(Arch arch, REGS_AliasCode code)
{
E_TypeKey key = {E_TypeKeyKind_RegAlias};
key.u32[0] = (U32)arch;
key.u32[1] = (U32)code;
return key;
}
//- rjf: constructed type construction
internal U64
@@ -625,7 +616,6 @@ e_type_kind_from_key(E_TypeKey key)
case E_TypeKeyKind_Ext: {kind = (E_TypeKind)key.u32[0];}break;
case E_TypeKeyKind_Cons: {kind = (E_TypeKind)key.u32[0];}break;
case E_TypeKeyKind_Reg: {kind = E_TypeKind_Union;}break;
case E_TypeKeyKind_RegAlias:{kind = E_TypeKind_Union;}break;
}
return kind;
}
@@ -1100,16 +1090,10 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
case E_TypeKeyKind_Reg:
{
Arch arch = (Arch)key.u32[0];
REGS_RegCode code = (REGS_RegCode)key.u32[1];
REGS_Rng rng = regs_reg_code_rng_table_from_arch(arch)[code];
reg_byte_count = (U64)rng.byte_size;
}goto build_reg_type;
case E_TypeKeyKind_RegAlias:
{
Arch arch = (Arch)key.u32[0];
REGS_AliasCode code = (REGS_AliasCode)key.u32[1];
REGS_Slice slice = regs_alias_code_slice_table_from_arch(arch)[code];
reg_byte_count = (U64)slice.byte_size;
ARCH_Info *arch_info = arch_info_from_arch(arch);
ARCH_RegCode code = (ARCH_RegCode)key.u32[1];
Rng1U16 rng = arch_info->reg_code_rng_table[code];
reg_byte_count = (U64)dim_1u16(rng);
}goto build_reg_type;
build_reg_type:
{
@@ -3117,23 +3101,23 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder)
String8List folder_paths = {0};
String8List file_paths = {0};
{
OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0);
for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);)
FileIter *iter = file_iter_begin(scratch.arena, folder_path, 0);
for(FileInfo info = {0}; file_iter_next(scratch.arena, iter, &info);)
{
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name);
if(matches.count == matches.needle_part_count)
{
if(info.props.flags & FilePropertyFlag_IsFolder)
{
str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name));
str8_list_push(scratch.arena, &folder_paths, str8_copy(arena, info.name));
}
else
{
str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name));
str8_list_push(scratch.arena, &file_paths, str8_copy(arena, info.name));
}
}
}
os_file_iter_end(iter);
file_iter_end(iter);
}
//- rjf: build accelerator
@@ -3252,7 +3236,7 @@ E_TYPE_IREXT_FUNCTION_DEF(file)
//- rjf: fill accel
accel->file_path = push_str8_copy(arena, file_path);
accel->props = os_properties_from_file_path(file_path);
accel->props = properties_from_file_path(file_path);
accel->fields = str8_array_from_list(arena, &fields);
scratch_end(scratch);
+1 -2
View File
@@ -71,8 +71,7 @@ internal E_EnumValArray e_enum_val_array_from_list(Arena *arena, E_EnumValList *
internal E_TypeKey e_type_key_zero(void);
internal E_TypeKey e_type_key_basic(E_TypeKind kind);
internal E_TypeKey e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_num);
internal E_TypeKey e_type_key_reg(Arch arch, REGS_RegCode code);
internal E_TypeKey e_type_key_reg_alias(Arch arch, REGS_AliasCode code);
internal E_TypeKey e_type_key_reg(Arch arch, ARCH_RegCode code);
//- rjf: constructed type construction
internal U64 e_hash_from_cons_type_params(E_ConsTypeParams *params);
+8 -8
View File
@@ -53,7 +53,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
FileProperties pre_props = {0};
if(lane_idx() == 0)
{
pre_props = os_properties_from_file_path(path);
pre_props = properties_from_file_path(path);
file_is_good = (pre_props.modified != 0);
}
lane_sync_u64(&file_is_good, 0);
@@ -80,16 +80,16 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
}
//- rjf: open file
OS_Handle file = {0};
File file = {0};
if(file_is_good)
{
if(lane_idx() == 0)
{
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path);
file = file_open(AccessFlag_Read|AccessFlag_ShareRead|AccessFlag_ShareWrite, path);
}
lane_sync_u64(&file, 0);
}
B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file);
B32 file_handle_is_valid = !file_match(file_zero(), file);
//- rjf: do read
U64 total_bytes_read = 0;
@@ -104,7 +104,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
ProfScope("read \"%.*s\" [0x%I64x, 0x%I64x)", str8_varg(path), range.min, range.max)
{
Rng1U64 lane_read_range = lane_range(data_buffer_size);
U64 bytes_read = os_file_read(file, shift_1u64(lane_read_range, range.min), data_buffer + lane_read_range.min);
U64 bytes_read = file_read(file, shift_1u64(lane_read_range, range.min), data_buffer + lane_read_range.min);
ins_atomic_u64_add_eval(total_bytes_read_ptr, bytes_read);
}
lane_sync();
@@ -116,7 +116,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
{
if(lane_idx() == 0)
{
os_file_close(file);
file_close(file);
}
}
@@ -124,7 +124,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
FileProperties post_props = {0};
if(lane_idx() == 0)
{
post_props = os_properties_from_file_path(path);
post_props = properties_from_file_path(path);
}
//- rjf: form content key
@@ -303,7 +303,7 @@ fs_async_tick(void)
{
for(FS_Node *n = slot->first; n != 0; n = n->next)
{
FileProperties props = os_properties_from_file_path(n->path);
FileProperties props = properties_from_file_path(n->path);
if(props.modified != n->last_modified_timestamp)
{
found_work = 1;
@@ -335,7 +335,7 @@ fp_font_open(String8 path)
//- rjf: try to open font
for(PathTask *t = first_task; t != 0 && font.file == 0; t = t->next)
{
B32 file_exists = (os_properties_from_file_path(t->path).created != 0);
B32 file_exists = (properties_from_file_path(t->path).created != 0);
String16 path16 = str16_from_8(scratch.arena, t->path);
if(file_exists)
{
+12 -12
View File
@@ -136,7 +136,7 @@ lnk_make_default_cmd_line(Arena *arena, LNK_CmdLine user_cmd_line)
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
if (!lnk_cmd_line_has_switch(user_cmd_line, LNK_CmdSwitch_Brepro)) {
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix());
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", get_process_start_time_unix());
}
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_TypeHashAlg, "BLAKE3");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
@@ -150,7 +150,7 @@ lnk_make_default_cmd_line(Arena *arena, LNK_CmdLine user_cmd_line)
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4));
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count);
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", get_system_info()->logical_processor_count);
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%");
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MemoryMapFiles, "");
if (BUILD_DEBUG) {
@@ -374,7 +374,7 @@ lnk_merge_manifest_files(String8 mt_path, String8 out_name, String8List manifest
str8_list_pushf(scratch.arena, &cmd_line, "-nologo");
// register input manifest files on command line
String8 work_dir = os_get_current_path(scratch.arena);
String8 work_dir = get_current_path(scratch.arena);
for (String8Node *man_node = manifest_path_list.first;
man_node != 0;
man_node = man_node->next) {
@@ -390,15 +390,15 @@ lnk_merge_manifest_files(String8 mt_path, String8 out_name, String8List manifest
}
// launch mt.exe with our command line
OS_ProcessLaunchParams launch_opts = {0};
ProcessLaunchParams launch_opts = {0};
launch_opts.cmd_line = cmd_line;
launch_opts.inherit_env = 1;
launch_opts.consoleless = 0;
OS_Handle mt_handle = os_process_launch(&launch_opts);
if (os_handle_match(mt_handle, os_handle_zero())) {
Process mt_handle = process_launch(&launch_opts);
if (process_match(mt_handle, process_zero())) {
lnk_error(LNK_Error_Mt, "unable to start process: %S", mt_path);
} else {
os_process_join(mt_handle, max_U64, 0);
process_join(mt_handle, max_U64, 0);
}
scratch_end(scratch);
@@ -447,8 +447,8 @@ lnk_manifest_from_inputs(Arena *arena,
}
// cleanup disk
os_delete_file_at_path(linker_manifest_path);
os_delete_file_at_path(merged_manifest_path);
delete_file_at_path(linker_manifest_path);
delete_file_at_path(merged_manifest_path);
ProfEnd();
} else {
@@ -804,7 +804,7 @@ lnk_make_res_obj(Arena *arena,
}
// convert res to obj
OS_ProcessInfo *process_info = os_get_process_info();
ProcessInfo *process_info = get_process_info();
String8List exe_path_strs = {0};
str8_list_push(scratch.arena, &exe_path_strs, process_info->binary_path);
String8 exe_path = str8_list_first(&exe_path_strs);
@@ -1032,7 +1032,7 @@ lnk_inputer_push_obj_thin(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, S
{
lnk_log(LNK_Log_InputObj, "Input Obj: %S", path);
Temp scratch = scratch_begin(0,0);
String8 full_path = os_full_path_from_path(scratch.arena, path);
String8 full_path = full_path_from_path(scratch.arena, path);
LNK_Input *input = lnk_inputer_push_thin(inputer->arena, &inputer->new_objs, inputer->objs_ht, full_path);
input->link_member = link_member;
scratch_end(scratch);
@@ -1059,7 +1059,7 @@ lnk_input_from_path(HashTable *load_ht, String8 path)
LNK_Input *input = hash_table_search_path_raw(load_ht, path);
if (input == 0) {
Temp scratch = scratch_begin(0, 0);
String8 full_path = os_full_path_from_path(scratch.arena, path);
String8 full_path = full_path_from_path(scratch.arena, path);
input = hash_table_search_path_raw(load_ht, full_path);
scratch_end(scratch);
}
+17 -17
View File
@@ -1115,7 +1115,7 @@ lnk_unwrap_rsp(Arena *arena, String8List arg_list)
// remove "@"
String8 name = str8_skip(curr->string, 1);
if (os_file_path_exists(name)) {
if (file_path_exists(name)) {
// read rsp from disk
String8 file = lnk_read_data_from_file_path(scratch.arena, 0, name);
@@ -1469,8 +1469,8 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
case LNK_CmdSwitch_LibPath: {
String8List lib_dir_list = str8_list_copy(config->arena, &value_strings);
for (String8Node *dir_n = lib_dir_list.first; dir_n != 0; dir_n = dir_n->next) {
if (!os_folder_path_exists(dir_n->string)) {
String8 full_path = os_full_path_from_path(scratch.arena, dir_n->string);
if (!folder_path_exists(dir_n->string)) {
String8 full_path = full_path_from_path(scratch.arena, dir_n->string);
lnk_error_cmd_switch(LNK_Warning_Cmdl, obj, cmd_switch, "path doesn't exist %S", full_path);
}
}
@@ -1827,7 +1827,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
case LNK_CmdSwitch_Rad_BuildInfo: {
lnk_print_build_info();
os_abort(0);
abort_self(0);
} break;
case LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll: {
@@ -1881,7 +1881,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
if (str8_match_lit("imageblake3", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
config->guid_type = Lnk_DebugInfoGuid_ImageBlake3;
} else if (str8_match_lit("random", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
config->guid = os_make_guid();
config->guid = make_guid();
} else {
Guid guid;
if (try_guid_from_string(value_strings.first->string, &guid)) {
@@ -1897,7 +1897,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
case LNK_CmdSwitch_Rad_LargePages: {
if (value_strings.node_count == 0) {
OS_ProcessInfo *process_info = os_get_process_info();
ProcessInfo *process_info = get_process_info();
if (process_info->large_pages_allowed) {
arena_default_flags |= ArenaFlag_LargePages;
} else {
@@ -1914,7 +1914,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
}
} else if (value_strings.node_count == 1) {
if (str8_match_lit("quiet", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
OS_ProcessInfo *process_info = os_get_process_info();
ProcessInfo *process_info = get_process_info();
if (process_info->large_pages_allowed) {
arena_default_flags |= ArenaFlag_LargePages;
}
@@ -2031,7 +2031,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
} break;
case LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers: {
OS_SystemInfo *sysinfo = os_get_system_info();
SystemInfo *sysinfo = get_system_info();
if (value_strings.node_count == 0) {
config->max_worker_count = sysinfo->logical_processor_count;
} else {
@@ -2101,7 +2101,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
case LNK_CmdSwitch_Rad_Version: {
lnk_fprintf(stdout, "%s\n", BUILD_TITLE_STRING_LITERAL);
os_abort(0);
abort_self(0);
} break;
case LNK_CmdSwitch_Rad_Workers: {
@@ -2113,7 +2113,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
case LNK_CmdSwitch_Help: {
lnk_print_help();
os_abort(0);
abort_self(0);
} break;
}
@@ -2130,7 +2130,7 @@ lnk_config_from_cmd_line(String8List raw_cmd_line, LNK_CmdLine cmd_line)
LNK_Config *config = push_array(arena, LNK_Config, 1);
config->arena = arena;
config->raw_cmd_line = str8_list_copy(arena, &raw_cmd_line);
config->work_dir = os_get_current_path(arena);
config->work_dir = get_current_path(arena);
config->build_imp_lib = 1;
config->build_exp = 1;
config->heap_reserve = MB(1);
@@ -2304,17 +2304,17 @@ lnk_config_from_cmd_line(String8List raw_cmd_line, LNK_CmdLine cmd_line)
}
// convert to full paths
config->out_path = os_full_path_from_path(arena, config->out_path);
config->pdb_name = os_full_path_from_path(arena, config->pdb_name);
config->rad_debug_name = os_full_path_from_path(arena, config->rad_debug_name);
config->imp_lib_name = os_full_path_from_path(arena, config->imp_lib_name);
config->manifest_name = os_full_path_from_path(arena, config->manifest_name);
config->out_path = full_path_from_path(arena, config->out_path);
config->pdb_name = full_path_from_path(arena, config->pdb_name);
config->rad_debug_name = full_path_from_path(arena, config->rad_debug_name);
config->imp_lib_name = full_path_from_path(arena, config->imp_lib_name);
config->manifest_name = full_path_from_path(arena, config->manifest_name);
// collect env vars
HashTable *env_vars = hash_table_init(scratch.arena, 512);
{
#if OS_WINDOWS
OS_ProcessInfo *process_info = os_get_process_info();
ProcessInfo *process_info = get_process_info();
for (String8Node *node = process_info->environment.first; node != 0; node = node->next) {
String8List list = str8_split_by_string_chars(scratch.arena, node->string, str8_lit("="), 0);
+1 -1
View File
@@ -479,7 +479,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
ProfBegin("Set up PCH");
{
// hash_table<obj_path, obj_idx>
String8 work_dir = os_get_current_path(scratch.arena);
String8 work_dir = get_current_path(scratch.arena);
HashTable *debug_p_ht = hash_table_init(scratch.arena, obj_count);
for EachIndex(i, input.debug_p_indices.count) {
U64 obj_idx = input.debug_p_indices.v[i];
+25 -25
View File
@@ -1,41 +1,41 @@
shared_function int
lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
{
OS_Handle handle = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, str8((U8*)path, path_size));
File handle = file_open(AccessFlag_Read|AccessFlag_ShareRead, str8((U8*)path, path_size));
Assert(sizeof(handle) <= handle_buffer_max);
MemoryCopy(handle_buffer, &handle, sizeof(handle));
return !os_handle_match(handle, os_handle_zero());
return !file_match(handle, file_zero());
}
shared_function int
lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
{
OS_Handle handle = os_file_open(OS_AccessFlag_Write, str8((U8*)path, path_size));
File handle = file_open(AccessFlag_Write, str8((U8*)path, path_size));
Assert(sizeof(handle) <= handle_buffer_max);
MemoryCopy(handle_buffer, &handle, sizeof(handle));
return !os_handle_match(handle, os_handle_zero());
return !file_match(handle, file_zero());
}
shared_function void
lnk_close_file(void *raw_handle)
{
OS_Handle handle = *(OS_Handle *)raw_handle;
os_file_close(handle);
File handle = *(File *)raw_handle;
file_close(handle);
}
shared_function uint64_t
lnk_size_from_file(void *raw_handle)
{
OS_Handle handle = *(OS_Handle *)raw_handle;
FileProperties props = os_properties_from_file(handle);
File handle = *(File *)raw_handle;
FileProperties props = properties_from_file(handle);
return props.size;
}
shared_function uint64_t
lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max)
{
OS_Handle handle = *(OS_Handle *)raw_handle;
U64 read_size = os_file_read(handle, rng_1u64(0, buffer_max), buffer);
File handle = *(File *)raw_handle;
U64 read_size = file_read(handle, rng_1u64(0, buffer_max), buffer);
Assert(read_size == buffer_max);
return read_size;
}
@@ -43,8 +43,8 @@ lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max)
shared_function uint64_t
lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size)
{
OS_Handle handle = *(OS_Handle*)raw_handle;
U64 write_size = os_file_write(handle, r1u64(offset, offset + buffer_size), buffer);
File handle = *(File*)raw_handle;
U64 write_size = file_write(handle, r1u64(offset, offset + buffer_size), buffer);
return write_size;
}
@@ -54,10 +54,10 @@ lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
String8 result = {0};
if (os_file_path_exists(path)) {
if (file_path_exists(path)) {
PathStyle path_style = path_style_from_str8(path);
if (path_style == PathStyle_Relative) {
String8 current_path = os_get_current_path(scratch.arena);
String8 current_path = get_current_path(scratch.arena);
String8List l = {0};
str8_list_push(scratch.arena, &l, current_path);
str8_list_push(scratch.arena, &l, path);
@@ -69,7 +69,7 @@ lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
String8 file_name = str8_skip_last_slash(path);
for EachNode(n, String8Node, dir_list.first) {
String8 full_path = push_str8f(scratch.arena, "%S/%S", n->string, file_name);
if (os_file_path_exists(full_path)) {
if (file_path_exists(full_path)) {
result = push_str8_copy(arena, full_path);
break;
}
@@ -80,10 +80,10 @@ lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
return result;
}
internal OS_Handle
internal File
lnk_file_open_with_rename_permissions(String8 path)
{
OS_Handle file_handle = os_handle_zero();
File file_handle = file_zero();
#if OS_WINDOWS
Temp scratch = scratch_begin(0,0);
@@ -109,7 +109,7 @@ lnk_file_open_with_rename_permissions(String8 path)
}
internal B32
lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file)
lnk_file_set_delete_on_close(File handle, B32 delete_file)
{
#if OS_WINDOWS
FILE_DISPOSITION_INFO file_disposition = {0};
@@ -122,7 +122,7 @@ lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file)
}
internal B32
lnk_file_rename(OS_Handle handle, String8 new_name)
lnk_file_rename(File handle, String8 new_name)
{
Temp scratch = scratch_begin(0,0);
#if OS_WINDOWS
@@ -167,7 +167,7 @@ THREAD_POOL_TASK_FUNC(lnk_data_size_from_file_path_task)
LNK_DiskReader *task = raw_task;
String8 path = task->path_arr.v[task_id];
OS_Handle handle = {0};
File handle = {0};
U64 size = 0;
int is_open = lnk_open_file_read((char*)path.str, path.size, &handle, sizeof(handle));
@@ -184,7 +184,7 @@ THREAD_POOL_TASK_FUNC(lnk_data_from_file_path_task)
{
LNK_DiskReader *task = raw_task;
OS_Handle handle = task->handle_arr[task_id];
File handle = task->handle_arr[task_id];
U64 buffer_size = task->size_arr[task_id];
U8 *buffer = task->buffer + task->off_arr[task_id];
@@ -239,7 +239,7 @@ lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, LNK_IO_Flags
Temp scratch = scratch_begin(&arena,1);
reader.path_arr = path_arr;
reader.handle_arr = push_array_no_zero(scratch.arena, OS_Handle, path_arr.count);
reader.handle_arr = push_array_no_zero(scratch.arena, File, path_arr.count);
reader.size_arr = push_array_no_zero(scratch.arena, U64, path_arr.count);
// open handles and get sizes
@@ -284,7 +284,7 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da
ProfBeginV("Write %M to %S", data.total_size, path);
B32 open_with_rename = (temp_path.size > 0);
OS_Handle file_handle = {0};
File file_handle = {0};
String8 open_file_path = {0};
if (open_with_rename) {
file_handle = lnk_file_open_with_rename_permissions(temp_path);
@@ -299,9 +299,9 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da
open_file_path = path;
}
if (!os_handle_match(file_handle, os_handle_zero())) {
if (!file_match(file_handle, file_zero())) {
// try to reserve up front file size
if (!os_file_reserve_size(file_handle, data.total_size)) {
if (!file_reserve_size(file_handle, data.total_size)) {
lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", open_file_path, data.total_size);
}
+4 -4
View File
@@ -11,7 +11,7 @@ typedef struct
LNK_IO_Flags io_flags;
String8Array path_arr;
String8Array data_arr;
OS_Handle *handle_arr;
File *handle_arr;
U64 *size_arr;
U64 *off_arr;
U8 *buffer;
@@ -28,9 +28,9 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void
// --- IO Functions ------------------------------------------------------------
internal OS_Handle lnk_file_open_with_rename_permissions(String8 path);
internal B32 lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file);
internal B32 lnk_file_rename(OS_Handle handle, String8 new_name);
internal File lnk_file_open_with_rename_permissions(String8 path);
internal B32 lnk_file_set_delete_on_close(File handle, B32 delete_file);
internal B32 lnk_file_rename(File handle, String8 new_name);
internal String8 lnk_read_data_from_file_path(Arena *arena, LNK_IO_Flags io_flags, String8 path);
internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, LNK_IO_Flags io_flags, String8Array path_arr);
+2 -2
View File
@@ -6,13 +6,13 @@ global LNK_Timer g_timers[LNK_Timer_Count];
internal void
lnk_timer_begin(LNK_TimerType timer)
{
g_timers[timer].begin = os_now_microseconds();
g_timers[timer].begin = now_time_us();
}
internal void
lnk_timer_end(LNK_TimerType timer)
{
g_timers[timer].end = os_now_microseconds();
g_timers[timer].end = now_time_us();
}
internal String8
+1 -1
View File
@@ -1613,7 +1613,7 @@ pdb_add_src(PDB_InfoContext *info, MSF_Context *msf, String8 file_path, String8
if (comp == PDB_SrcComp_NULL) {
// process path so it passes VS validity checks
String8 virt_path = file_path;
String8 work_dir = os_get_current_path(scratch.arena);
String8 work_dir = get_current_path(scratch.arena);
virt_path = path_absolute_dst_from_relative_dst_src(scratch.arena, virt_path, work_dir);
virt_path = lower_from_str8(scratch.arena, virt_path);
virt_path = path_convert_slashes(scratch.arena, virt_path, PathStyle_UnixAbsolute);
+11 -11
View File
@@ -23,7 +23,7 @@ tp_run_tasks(TP_Context *pool, TP_Worker *worker)
// on last task ping main thread
U64 task_done = ins_atomic_u64_inc_eval(&pool->task_done);
if (task_done == task_count) {
os_semaphore_drop(pool->main_semaphore);
semaphore_drop(pool->main_semaphore);
}
}
}
@@ -34,7 +34,7 @@ tp_worker_main(void *raw_worker)
TP_Worker *worker = raw_worker;
TP_Context *pool = worker->pool;
for (; pool->is_live; ) {
if (os_semaphore_take(pool->task_semaphore, max_U64)) {
if (semaphore_take(pool->task_semaphore, max_U64)) {
tp_run_tasks(pool, worker);
}
}
@@ -46,8 +46,8 @@ tp_worker_main_shared(void *raw_worker)
TP_Worker *worker = raw_worker;
TP_Context *pool = worker->pool;
for (; pool->is_live; ) {
if (os_semaphore_take(pool->exec_semaphore, max_U64)) {
if (os_semaphore_take(pool->task_semaphore, max_U64)) {
if (semaphore_take(pool->exec_semaphore, max_U64)) {
if (semaphore_take(pool->task_semaphore, max_U64)) {
tp_run_tasks(pool, worker);
}
}
@@ -67,13 +67,13 @@ tp_alloc(Arena *arena, U32 worker_count, U32 max_worker_count, String8 name)
Semaphore task_semaphore = {0};
Semaphore exec_semaphore = {0};
if (worker_count > 1) {
main_semaphore = os_semaphore_alloc(0, 1, str8_zero());
main_semaphore = semaphore_alloc(0, 1, str8_zero());
if (is_shared) {
AssertAlways(worker_count <= max_worker_count);
task_semaphore = os_semaphore_alloc(0, max_worker_count, name);
exec_semaphore = os_semaphore_alloc(0, worker_count, str8_zero());
task_semaphore = semaphore_alloc(0, max_worker_count, name);
exec_semaphore = semaphore_alloc(0, worker_count, str8_zero());
} else {
task_semaphore = os_semaphore_alloc(0, worker_count, str8_zero());
task_semaphore = semaphore_alloc(0, worker_count, str8_zero());
}
}
@@ -213,20 +213,20 @@ tp_for_parallel(TP_Context *pool, TP_Arena *task_arena, U64 task_count, TP_TaskF
// if we are in shared mode ping local semaphore
if (pool->exec_semaphore.u64[0] != 0) {
for (U64 worker_idx = 0; worker_idx < drop_count; worker_idx +=1) {
os_semaphore_drop(pool->exec_semaphore);
semaphore_drop(pool->exec_semaphore);
}
}
// ping shared semaphore
for (U64 worker_idx = 0; worker_idx < drop_count; worker_idx += 1) {
os_semaphore_drop(pool->task_semaphore);
semaphore_drop(pool->task_semaphore);
}
// run tasks on main worker
tp_run_tasks(pool, &pool->worker_arr[0]);
// wait for workers to finish tasks
os_semaphore_take(pool->main_semaphore, max_U64);
semaphore_take(pool->main_semaphore, max_U64);
}
}
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+7
View File
@@ -0,0 +1,7 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef LINUX_BASE_H
#define LINUX_BASE_H
#endif // LINUX_BASE_H
+2 -2
View File
@@ -14,7 +14,7 @@ mtx_init(void)
mtx_shared = push_array(arena, MTX_Shared, 1);
mtx_shared->arena = arena;
mtx_shared->slots_count = 256;
mtx_shared->stripes_count = Min(mtx_shared->slots_count, os_get_system_info()->logical_processor_count);
mtx_shared->stripes_count = Min(mtx_shared->slots_count, get_system_info()->logical_processor_count);
mtx_shared->slots = push_array(arena, MTX_Slot, mtx_shared->slots_count);
mtx_shared->stripes = push_array(arena, MTX_Stripe, mtx_shared->stripes_count);
for(U64 idx = 0; idx < mtx_shared->stripes_count; idx += 1)
@@ -22,7 +22,7 @@ mtx_init(void)
mtx_shared->stripes[idx].arena = arena_alloc();
mtx_shared->stripes[idx].rw_mutex = rw_mutex_alloc();
}
mtx_shared->mut_threads_count = Min(os_get_system_info()->logical_processor_count, 4);
mtx_shared->mut_threads_count = Min(get_system_info()->logical_processor_count, 4);
mtx_shared->mut_threads = push_array(arena, MTX_MutThread, mtx_shared->mut_threads_count);
for(U64 idx = 0; idx < mtx_shared->mut_threads_count; idx += 1)
{
-29
View File
@@ -772,23 +772,13 @@ internal OS_Handle
os_process_launch(OS_ProcessLaunchParams *params)
{
OS_Handle handle = {0};
posix_spawn_file_actions_t file_actions = {0};
int file_actions_init_code = posix_spawn_file_actions_init(&file_actions);
if(file_actions_init_code == 0)
{
// redirect STDOUT
int stdout_code = posix_spawn_file_actions_adddup2(&file_actions, (int)params->stdout_file.u64[0], STDOUT_FILENO);
Assert(stdout_code == 0);
// redirect STDERR
int stderr_code = posix_spawn_file_actions_adddup2(&file_actions, (int)params->stderr_file.u64[0], STDERR_FILENO);
Assert(stderr_code == 0);
// redirect STDIN
int stdin_code = posix_spawn_file_actions_adddup2(&file_actions, (int)params->stdin_file.u64[0], STDIN_FILENO);
Assert(stdin_code == 0);
posix_spawnattr_t attr = {0};
int attr_init_code = posix_spawnattr_init(&attr);
if(attr_init_code == 0)
@@ -801,7 +791,6 @@ os_process_launch(OS_ProcessLaunchParams *params)
String8List l = str8_split_path(scratch.arena, params->path);
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);
argv[0] = (char *)path_to_exe.str;
U64 arg_idx = 1;
for EachNode(n, String8Node, params->cmd_line.first->next)
@@ -828,21 +817,9 @@ os_process_launch(OS_ProcessLaunchParams *params)
}
}
if(params->debug_subprocesses)
{
// not suported
InvalidPath;
}
if(!params->consoleless)
{
NotImplemented;
}
// spawn process
pid_t pid = 0;
int spawn_code = posix_spawn(&pid, argv[0], &file_actions, &attr, argv, envp);
if(spawn_code == 0)
{
handle.u64[0] = (U64)pid;
@@ -850,16 +827,12 @@ os_process_launch(OS_ProcessLaunchParams *params)
// clean up attributes
int attr_destroy_code = posix_spawnattr_destroy(&attr);
Assert(attr_destroy_code == 0);
scratch_end(scratch);
}
// clean up file actions
int file_actions_destroy_code = posix_spawn_file_actions_destroy(&file_actions);
Assert(file_actions_destroy_code == 0);
}
return handle;
}
@@ -873,14 +846,12 @@ os_process_join(OS_Handle handle, U64 endt_us, U64 *exit_code_out)
if(kill(pid, 0) >= 0)
{
result = (errno == ENOENT);
if(result)
{
int status;
waitpid(pid, &status, 0);
}
}
else { Assert(0 && "failed to get status from pid"); }
}
else if(endt_us == max_U64)
{
-149
View File
@@ -1,155 +1,6 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Modern Windows SDK Functions
//
// (We must dynamically link to them, since they can be missing in older SDKs)
typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
global W32_SetThreadDescription_Type *w32_SetThreadDescription_func = 0;
global RIO_EXTENSION_FUNCTION_TABLE w32_rio_functions = {0};
////////////////////////////////
//~ rjf: File Info Conversion Helpers
internal FilePropertyFlags
os_w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes)
{
FilePropertyFlags flags = 0;
if(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
flags |= FilePropertyFlag_IsFolder;
}
return flags;
}
internal void
os_w32_file_properties_from_attribute_data(FileProperties *properties, WIN32_FILE_ATTRIBUTE_DATA *attributes)
{
properties->size = Compose64Bit(attributes->nFileSizeHigh, attributes->nFileSizeLow);
os_w32_dense_time_from_file_time(&properties->created, &attributes->ftCreationTime);
os_w32_dense_time_from_file_time(&properties->modified, &attributes->ftLastWriteTime);
properties->flags = os_w32_file_property_flags_from_dwFileAttributes(attributes->dwFileAttributes);
}
////////////////////////////////
//~ rjf: Time Conversion Helpers
internal void
os_w32_date_time_from_system_time(DateTime *out, SYSTEMTIME *in)
{
out->year = in->wYear;
out->mon = in->wMonth - 1;
out->wday = in->wDayOfWeek;
out->day = in->wDay;
out->hour = in->wHour;
out->min = in->wMinute;
out->sec = in->wSecond;
out->msec = in->wMilliseconds;
}
internal void
os_w32_system_time_from_date_time(SYSTEMTIME *out, DateTime *in)
{
out->wYear = (WORD)(in->year);
out->wMonth = in->mon + 1;
out->wDay = in->day;
out->wHour = in->hour;
out->wMinute = in->min;
out->wSecond = in->sec;
out->wMilliseconds = in->msec;
}
internal void
os_w32_dense_time_from_file_time(DenseTime *out, FILETIME *in)
{
SYSTEMTIME systime = {0};
FileTimeToSystemTime(in, &systime);
DateTime date_time = {0};
os_w32_date_time_from_system_time(&date_time, &systime);
*out = dense_time_from_date_time(date_time);
}
internal U32
os_w32_sleep_ms_from_endt_us(U64 endt_us)
{
U32 sleep_ms = 0;
if(endt_us == max_U64)
{
sleep_ms = INFINITE;
}
else
{
U64 begint = os_now_microseconds();
if(begint < endt_us)
{
U64 sleep_us = endt_us - begint;
sleep_ms = (U32)((sleep_us + 999)/1000);
}
}
return sleep_ms;
}
internal U32
os_w32_unix_time_from_file_time(FILETIME file_time)
{
U64 win32_time = ((U64)file_time.dwHighDateTime << 32) | file_time.dwLowDateTime;
U64 unix_time64 = ((win32_time - 0x19DB1DED53E8000ULL) / 10000000);
Assert(unix_time64 <= max_U32);
U32 unix_time32 = (U32)unix_time64;
return unix_time32;
}
////////////////////////////////
//~ rjf: Entity Functions
internal OS_W32_Entity *
os_w32_entity_alloc(OS_W32_EntityKind kind)
{
OS_W32_Entity *result = 0;
EnterCriticalSection(&os_w32_state.entity_mutex);
{
result = os_w32_state.entity_free;
if(result)
{
SLLStackPop(os_w32_state.entity_free);
}
else
{
result = push_array_no_zero(os_w32_state.entity_arena, OS_W32_Entity, 1);
}
MemoryZeroStruct(result);
}
LeaveCriticalSection(&os_w32_state.entity_mutex);
result->kind = kind;
return result;
}
internal void
os_w32_entity_release(OS_W32_Entity *entity)
{
entity->kind = OS_W32_EntityKind_Null;
EnterCriticalSection(&os_w32_state.entity_mutex);
SLLStackPush(os_w32_state.entity_free, entity);
LeaveCriticalSection(&os_w32_state.entity_mutex);
}
////////////////////////////////
//~ rjf: Thread Entry Point
internal DWORD
os_w32_thread_entry_point(void *ptr)
{
OS_W32_Entity *entity = (OS_W32_Entity *)ptr;
ThreadEntryPointFunctionType *func = entity->thread.func;
void *thread_ptr = entity->thread.ptr;
supplement_thread_base_entry_point(func, thread_ptr);
return 0;
}
////////////////////////////////
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
+31 -7
View File
@@ -6,6 +6,30 @@
#include "generated/os_gfx.meta.c"
////////////////////////////////
//~ rjf: Handle Type Helpers
internal OS_Window
os_window_zero(void)
{
OS_Window result = {0};
return result;
}
internal B32
os_window_match(OS_Window a, OS_Window b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
internal B32
os_monitor_match(OS_Monitor a, OS_Monitor b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
////////////////////////////////
//~ rjf: Event Functions (Helpers, Implemented Once)
@@ -182,12 +206,12 @@ os_eat_event(OS_EventList *events, OS_Event *event)
}
internal B32
os_key_press(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_Key key)
os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
{
B32 result = 0;
for(OS_Event *event = events->first; event != 0; event = event->next)
{
if((os_handle_match(event->window, window) || os_handle_match(window, os_handle_zero())) &&
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
event->kind == OS_EventKind_Press && event->key == key && event->modifiers == modifiers)
{
result = 1;
@@ -199,12 +223,12 @@ os_key_press(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_
}
internal B32
os_key_release(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_Key key)
os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
{
B32 result = 0;
for(OS_Event *event = events->first; event != 0; event = event->next)
{
if((os_handle_match(event->window, window) || os_handle_match(window, os_handle_zero())) &&
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
event->kind == OS_EventKind_Release && event->key == key && event->modifiers == modifiers)
{
result = 1;
@@ -216,12 +240,12 @@ os_key_release(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, O
}
internal B32
os_text(OS_EventList *events, OS_Handle window, U32 character)
os_text(OS_EventList *events, OS_Window window, U32 character)
{
B32 result = 0;
for(OS_Event *event = events->first; event != 0; event = event->next)
{
if((os_handle_match(event->window, window) || os_handle_match(window, os_handle_zero())) &&
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
event->kind == OS_EventKind_Text && event->character == character)
{
result = 1;
@@ -270,7 +294,7 @@ os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind)
OS_Event *evt = push_array(arena, OS_Event, 1);
DLLPushBack(evts->first, evts->last, evt);
evts->count += 1;
evt->timestamp_us = os_now_microseconds();
evt->timestamp_us = now_time_us();
evt->kind = kind;
return evt;
}
+72 -34
View File
@@ -25,6 +25,37 @@ enum
OS_WindowFlag_UseDefaultPosition = (1<<1),
};
typedef struct OS_Window OS_Window;
struct OS_Window
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: External Window Types
typedef struct OS_ExternalWindow OS_ExternalWindow;
struct OS_ExternalWindow
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: Monitor Types
typedef struct OS_Monitor OS_Monitor;
struct OS_Monitor
{
U64 u64[1];
};
typedef struct OS_MonitorArray OS_MonitorArray;
struct OS_MonitorArray
{
OS_Monitor *v;
U64 count;
};
////////////////////////////////
//~ rjf: Cursor Types
@@ -81,7 +112,7 @@ struct OS_Event
OS_Event *next;
OS_Event *prev;
U64 timestamp_us;
OS_Handle window;
OS_Window window;
OS_EventKind kind;
OS_Modifiers modifiers;
OS_Key key;
@@ -107,6 +138,13 @@ struct OS_EventList
internal B32 frame(void);
////////////////////////////////
//~ rjf: Handle Type Helpers
internal OS_Window os_window_zero(void);
internal B32 os_window_match(OS_Window a, OS_Window b);
internal B32 os_monitor_match(OS_Monitor a, OS_Monitor b);
////////////////////////////////
//~ rjf: Event Functions (Helpers, Implemented Once)
@@ -115,9 +153,9 @@ internal String8List os_string_list_from_modifiers(Arena *arena, OS_Modifiers fl
internal String8 os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key);
internal U32 os_codepoint_from_modifiers_and_key(OS_Modifiers flags, OS_Key key);
internal void os_eat_event(OS_EventList *events, OS_Event *event);
internal B32 os_key_press(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_Key key);
internal B32 os_key_release(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_Key key);
internal B32 os_text(OS_EventList *events, OS_Handle window, U32 character);
internal B32 os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
internal B32 os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
internal B32 os_text(OS_EventList *events, OS_Window window, U32 character);
internal OS_EventList os_event_list_copy(Arena *arena, OS_EventList *src);
internal void os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push);
internal OS_Event *os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind);
@@ -141,43 +179,43 @@ internal String8 os_get_clipboard_text(Arena *arena);
////////////////////////////////
//~ rjf: @os_hooks Windows (Implemented Per-OS)
internal OS_Handle os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
internal void os_window_close(OS_Handle window);
internal void os_window_set_title(OS_Handle window, String8 title);
internal void os_window_first_paint(OS_Handle window);
internal void os_window_focus(OS_Handle window);
internal B32 os_window_is_focused(OS_Handle window);
internal B32 os_window_is_fullscreen(OS_Handle window);
internal void os_window_set_fullscreen(OS_Handle window, B32 fullscreen);
internal B32 os_window_is_maximized(OS_Handle window);
internal void os_window_set_maximized(OS_Handle window, B32 maximized);
internal B32 os_window_is_minimized(OS_Handle window);
internal void os_window_set_minimized(OS_Handle window, B32 minimized);
internal void os_window_bring_to_front(OS_Handle window);
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
internal void os_window_clear_custom_border_data(OS_Handle handle);
internal void os_window_push_custom_title_bar(OS_Handle handle, F32 thickness);
internal void os_window_push_custom_edges(OS_Handle handle, F32 thickness);
internal void os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect);
internal Rng2F32 os_rect_from_window(OS_Handle window);
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
internal F32 os_dpi_from_window(OS_Handle window);
internal OS_Window os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
internal void os_window_close(OS_Window window);
internal void os_window_set_title(OS_Window window, String8 title);
internal void os_window_first_paint(OS_Window window);
internal void os_window_focus(OS_Window window);
internal B32 os_window_is_focused(OS_Window window);
internal B32 os_window_is_fullscreen(OS_Window window);
internal void os_window_set_fullscreen(OS_Window window, B32 fullscreen);
internal B32 os_window_is_maximized(OS_Window window);
internal void os_window_set_maximized(OS_Window window, B32 maximized);
internal B32 os_window_is_minimized(OS_Window window);
internal void os_window_set_minimized(OS_Window window, B32 minimized);
internal void os_window_bring_to_front(OS_Window window);
internal void os_window_set_monitor(OS_Window window, OS_Monitor monitor);
internal void os_window_clear_custom_border_data(OS_Window handle);
internal void os_window_push_custom_title_bar(OS_Window handle, F32 thickness);
internal void os_window_push_custom_edges(OS_Window handle, F32 thickness);
internal void os_window_push_custom_title_bar_client_area(OS_Window handle, Rng2F32 rect);
internal Rng2F32 os_rect_from_window(OS_Window window);
internal Rng2F32 os_client_rect_from_window(OS_Window window);
internal F32 os_dpi_from_window(OS_Window window);
////////////////////////////////
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
internal OS_Handle os_focused_external_window(void);
internal void os_focus_external_window(OS_Handle handle);
internal OS_ExternalWindow os_focused_external_window(void);
internal void os_focus_external_window(OS_ExternalWindow ext_window);
////////////////////////////////
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
internal OS_HandleArray os_push_monitors_array(Arena *arena);
internal OS_Handle os_primary_monitor(void);
internal OS_Handle os_monitor_from_window(OS_Handle window);
internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor);
internal Vec2F32 os_dim_from_monitor(OS_Handle monitor);
internal F32 os_dpi_from_monitor(OS_Handle monitor);
internal OS_MonitorArray os_push_monitors_array(Arena *arena);
internal OS_Monitor os_primary_monitor(void);
internal OS_Monitor os_monitor_from_window(OS_Window window);
internal String8 os_name_from_monitor(Arena *arena, OS_Monitor monitor);
internal Vec2F32 os_dim_from_monitor(OS_Monitor monitor);
internal F32 os_dpi_from_monitor(OS_Monitor monitor);
////////////////////////////////
//~ rjf: @os_hooks Events (Implemented Per-OS)
@@ -186,7 +224,7 @@ internal void os_send_wakeup_event(void);
internal OS_EventList os_get_events(Arena *arena, B32 wait);
internal OS_Modifiers os_get_modifiers(void);
internal B32 os_key_is_down(OS_Key key);
internal Vec2F32 os_mouse_from_window(OS_Handle window);
internal Vec2F32 os_mouse_from_window(OS_Window window);
////////////////////////////////
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
+55 -45
View File
@@ -32,15 +32,15 @@ os_w32_rng2f32_from_rect(RECT rect)
////////////////////////////////
//~ rjf: Windows
internal OS_Handle
internal OS_Window
os_w32_handle_from_window(OS_W32_Window *window)
{
OS_Handle handle = {(U64)window};
OS_Window handle = {(U64)window};
return handle;
}
internal OS_W32_Window *
os_w32_window_from_handle(OS_Handle handle)
os_w32_window_from_handle(OS_Window handle)
{
OS_W32_Window *window = (OS_W32_Window *)handle.u64[0];
return window;
@@ -342,7 +342,7 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if(good)
{
OS_W32_Window *window = os_w32_window_from_hwnd(hwnd);
OS_Handle window_handle = os_w32_handle_from_window(window);
OS_Window window_handle = os_w32_handle_from_window(window);
B32 release = 0;
switch(uMsg)
@@ -806,8 +806,11 @@ internal BOOL
os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr)
{
OS_W32_MonitorGatherBundle *bundle = (OS_W32_MonitorGatherBundle *)bundle_ptr;
OS_Handle handle = {(U64)monitor};
os_handle_list_push(bundle->arena, bundle->list, handle);
OS_Monitor m = {(U64)monitor};
OS_W32_MonitorGatherNode *n = push_array(bundle->arena, OS_W32_MonitorGatherNode, 1);
n->v = m;
SLLQueuePush(bundle->first_monitor, bundle->last_monitor, n);
bundle->monitor_count += 1;
return 1;
}
@@ -1052,7 +1055,7 @@ os_get_clipboard_text(Arena *arena)
////////////////////////////////
//~ rjf: @os_hooks Windows (Implemented Per-OS)
internal OS_Handle
internal OS_Window
os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
{
B32 custom_border = !!(flags & OS_WindowFlag_CustomBorder);
@@ -1116,19 +1119,19 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
}
//- rjf: convert to handle + return
OS_Handle result = os_w32_handle_from_window(window);
OS_Window result = os_w32_handle_from_window(window);
return result;
}
internal void
os_window_close(OS_Handle handle)
os_window_close(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
os_w32_window_release(window);
}
internal void
os_window_set_title(OS_Handle handle, String8 title)
os_window_set_title(OS_Window handle, String8 title)
{
Temp scratch = scratch_begin(0, 0);
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1138,7 +1141,7 @@ os_window_set_title(OS_Handle handle, String8 title)
}
internal void
os_window_first_paint(OS_Handle window_handle)
os_window_first_paint(OS_Window window_handle)
{
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
window->first_paint_done = 1;
@@ -1150,7 +1153,7 @@ os_window_first_paint(OS_Handle window_handle)
}
internal void
os_window_focus(OS_Handle handle)
os_window_focus(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
SetForegroundWindow(window->hwnd);
@@ -1158,7 +1161,7 @@ os_window_focus(OS_Handle handle)
}
internal B32
os_window_is_focused(OS_Handle handle)
os_window_is_focused(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
HWND active_hwnd = GetActiveWindow();
@@ -1166,7 +1169,7 @@ os_window_is_focused(OS_Handle handle)
}
internal B32
os_window_is_fullscreen(OS_Handle handle)
os_window_is_fullscreen(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
@@ -1174,7 +1177,7 @@ os_window_is_fullscreen(OS_Handle handle)
}
internal void
os_window_set_fullscreen(OS_Handle handle, B32 fullscreen)
os_window_set_fullscreen(OS_Window handle, B32 fullscreen)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
@@ -1208,7 +1211,7 @@ os_window_set_fullscreen(OS_Handle handle, B32 fullscreen)
}
internal B32
os_window_is_maximized(OS_Handle handle)
os_window_is_maximized(OS_Window handle)
{
B32 result = 0;
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1220,7 +1223,7 @@ os_window_is_maximized(OS_Handle handle)
}
internal void
os_window_set_maximized(OS_Handle handle, B32 maximized)
os_window_set_maximized(OS_Window handle, B32 maximized)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
if(window != 0)
@@ -1242,7 +1245,7 @@ os_window_set_maximized(OS_Handle handle, B32 maximized)
}
internal B32
os_window_is_minimized(OS_Handle handle)
os_window_is_minimized(OS_Window handle)
{
B32 result = 0;
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1254,7 +1257,7 @@ os_window_is_minimized(OS_Handle handle)
}
internal void
os_window_set_minimized(OS_Handle handle, B32 minimized)
os_window_set_minimized(OS_Window handle, B32 minimized)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
if(window != 0 && minimized != os_window_is_minimized(handle))
@@ -1269,7 +1272,7 @@ os_window_set_minimized(OS_Handle handle, B32 minimized)
}
internal void
os_window_bring_to_front(OS_Handle handle)
os_window_bring_to_front(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
if(window != 0)
@@ -1279,7 +1282,7 @@ os_window_bring_to_front(OS_Handle handle)
}
internal void
os_window_set_monitor(OS_Handle window_handle, OS_Handle monitor)
os_window_set_monitor(OS_Window window_handle, OS_Monitor monitor)
{
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
HMONITOR hmonitor = (HMONITOR)monitor.u64[0];
@@ -1300,7 +1303,7 @@ os_window_set_monitor(OS_Handle window_handle, OS_Handle monitor)
}
internal void
os_window_clear_custom_border_data(OS_Handle handle)
os_window_clear_custom_border_data(OS_Window handle)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
if(window->custom_border)
@@ -1313,21 +1316,21 @@ os_window_clear_custom_border_data(OS_Handle handle)
}
internal void
os_window_push_custom_title_bar(OS_Handle handle, F32 thickness)
os_window_push_custom_title_bar(OS_Window handle, F32 thickness)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
window->custom_border_title_thickness = thickness;
}
internal void
os_window_push_custom_edges(OS_Handle handle, F32 thickness)
os_window_push_custom_edges(OS_Window handle, F32 thickness)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
window->custom_border_edge_thickness = thickness;
}
internal void
os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
os_window_push_custom_title_bar_client_area(OS_Window handle, Rng2F32 rect)
{
OS_W32_Window *window = os_w32_window_from_handle(handle);
if(window->custom_border)
@@ -1342,7 +1345,7 @@ os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
}
internal Rng2F32
os_rect_from_window(OS_Handle handle)
os_rect_from_window(OS_Window handle)
{
Rng2F32 r = {0};
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1356,7 +1359,7 @@ os_rect_from_window(OS_Handle handle)
}
internal Rng2F32
os_client_rect_from_window(OS_Handle handle)
os_client_rect_from_window(OS_Window handle)
{
Rng2F32 r = {0};
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1370,7 +1373,7 @@ os_client_rect_from_window(OS_Handle handle)
}
internal F32
os_dpi_from_window(OS_Handle handle)
os_dpi_from_window(OS_Window handle)
{
F32 result = 96.f;
OS_W32_Window *window = os_w32_window_from_handle(handle);
@@ -1384,16 +1387,16 @@ os_dpi_from_window(OS_Handle handle)
////////////////////////////////
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
internal OS_Handle
internal OS_ExternalWindow
os_focused_external_window(void)
{
HWND hwnd = GetForegroundWindow();
OS_Handle result = {(U64)hwnd};
OS_ExternalWindow result = {(U64)hwnd};
return result;
}
internal void
os_focus_external_window(OS_Handle handle)
os_focus_external_window(OS_ExternalWindow handle)
{
HWND hwnd = (HWND)handle.u64[0];
if(hwnd != 0)
@@ -1406,40 +1409,47 @@ os_focus_external_window(OS_Handle handle)
////////////////////////////////
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
internal OS_HandleArray
internal OS_MonitorArray
os_push_monitors_array(Arena *arena)
{
Temp scratch = scratch_begin(&arena, 1);
OS_HandleList list = {0};
{
OS_W32_MonitorGatherBundle bundle = {arena, &list};
OS_W32_MonitorGatherBundle bundle = {arena};
EnumDisplayMonitors(0, 0, os_w32_monitor_gather_enum_proc, (LPARAM)&bundle);
OS_MonitorArray array = {0};
array.count = bundle.monitor_count;
array.v = push_array(arena, OS_Monitor, array.count);
{
U64 idx = 0;
for EachNode(n, OS_W32_MonitorGatherNode, bundle.first_monitor)
{
array.v[idx] = n->v;
idx += 1;
}
}
OS_HandleArray array = os_handle_array_from_list(arena, &list);
scratch_end(scratch);
return array;
}
internal OS_Handle
internal OS_Monitor
os_primary_monitor(void)
{
POINT zero_pt = {0, 0};
HMONITOR monitor = MonitorFromPoint(zero_pt, MONITOR_DEFAULTTOPRIMARY);
OS_Handle result = {(U64)monitor};
OS_Monitor result = {(U64)monitor};
return result;
}
internal OS_Handle
os_monitor_from_window(OS_Handle window)
internal OS_Monitor
os_monitor_from_window(OS_Window window)
{
OS_W32_Window *w = os_w32_window_from_handle(window);
HMONITOR handle = MonitorFromWindow(w->hwnd, MONITOR_DEFAULTTOPRIMARY);
OS_Handle result = {(U64)handle};
OS_Monitor result = {(U64)handle};
return result;
}
internal String8
os_name_from_monitor(Arena *arena, OS_Handle monitor)
os_name_from_monitor(Arena *arena, OS_Monitor monitor)
{
String8 result = {0};
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
@@ -1454,7 +1464,7 @@ os_name_from_monitor(Arena *arena, OS_Handle monitor)
}
internal Vec2F32
os_dim_from_monitor(OS_Handle monitor)
os_dim_from_monitor(OS_Monitor monitor)
{
Vec2F32 result = {0};
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
@@ -1469,7 +1479,7 @@ os_dim_from_monitor(OS_Handle monitor)
}
internal F32
os_dpi_from_monitor(OS_Handle monitor)
os_dpi_from_monitor(OS_Monitor monitor)
{
F32 result = 96.f;
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
@@ -1546,7 +1556,7 @@ os_key_is_down(OS_Key key)
}
internal Vec2F32
os_mouse_from_window(OS_Handle handle)
os_mouse_from_window(OS_Window handle)
{
ProfBeginFunction();
Vec2F32 v = {0};
+12 -3
View File
@@ -54,11 +54,20 @@ struct OS_W32_Window
////////////////////////////////
//~ rjf: Monitor Gathering Bundle
typedef struct OS_W32_MonitorGatherNode OS_W32_MonitorGatherNode;
struct OS_W32_MonitorGatherNode
{
OS_W32_MonitorGatherNode *next;
OS_Monitor v;
};
typedef struct OS_W32_MonitorGatherBundle OS_W32_MonitorGatherBundle;
struct OS_W32_MonitorGatherBundle
{
Arena *arena;
OS_HandleList *list;
OS_W32_MonitorGatherNode *first_monitor;
OS_W32_MonitorGatherNode *last_monitor;
U64 monitor_count;
};
////////////////////////////////
@@ -95,8 +104,8 @@ internal Rng2F32 os_w32_rng2f32_from_rect(RECT rect);
////////////////////////////////
//~ rjf: Windows
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window);
internal OS_W32_Window * os_w32_window_from_handle(OS_Handle window);
internal OS_Window os_w32_handle_from_window(OS_W32_Window *window);
internal OS_W32_Window * os_w32_window_from_handle(OS_Window window);
internal OS_W32_Window * os_w32_window_from_hwnd(HWND hwnd);
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
internal OS_W32_Window * os_w32_window_alloc(void);
+2 -2
View File
@@ -1,13 +1,13 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "os/core/os_core.c"
// #include "os/core/os_core.c"
#if OS_FEATURE_GRAPHICAL
# include "os/gfx/os_gfx.c"
#endif
#if OS_WINDOWS
# include "os/core/win32/os_core_win32.c"
// # include "os/core/win32/os_core_win32.c"
#elif OS_LINUX
# include "os/core/linux/os_core_linux.c"
#else
+2 -2
View File
@@ -12,13 +12,13 @@
# define OS_GFX_STUB 0
#endif
#include "os/core/os_core.h"
// #include "os/core/os_core.h"
#if OS_FEATURE_GRAPHICAL
# include "os/gfx/os_gfx.h"
#endif
#if OS_WINDOWS
# include "os/core/win32/os_core_win32.h"
// # include "os/core/win32/os_core_win32.h"
#elif OS_LINUX
# include "os/core/linux/os_core_linux.h"
#else
-21
View File
@@ -520,10 +520,6 @@ pe_bin_info_from_data(Arena *arena, String8 data)
reported_data_dir_offset = sizeof(*pe_optional);
reported_data_dir_count = pe_optional->data_dir_count;
}
else
{
Assert(!"unable to read PE Optional Header");
}
}break;
case PE_PE32PLUS_MAGIC:
{
@@ -539,10 +535,6 @@ pe_bin_info_from_data(Arena *arena, String8 data)
reported_data_dir_offset = sizeof(*pe_optional);
reported_data_dir_count = pe_optional->data_dir_count;
}
else
{
Assert(!"unable to read PE Optional Plus Header");
}
}break;
}
@@ -561,10 +553,6 @@ pe_bin_info_from_data(Arena *arena, String8 data)
U64 file_off = coff_foff_from_voff(sections, clamped_sec_count, dir.virt_off);
data_dir_franges[dir_idx] = r1u64(file_off, file_off+dir.virt_size);
}
else
{
Assert(!"unable to read data directory");
}
}
// export virtual directory ranges
@@ -577,10 +565,6 @@ pe_bin_info_from_data(Arena *arena, String8 data)
{
data_dir_vranges[dir_idx] = r1u64(dir.virt_off, dir.virt_off+dir.virt_size);
}
else
{
Assert(!"unable to read data directory");
}
}
// export directory range
@@ -608,17 +592,12 @@ pe_bin_info_from_data(Arena *arena, String8 data)
tls_header.zero_fill_size = (U64)tls_header32.zero_fill_size;
tls_header.characteristics = (U64)tls_header32.characteristics;
}
else
{
Assert(!"unable to read TLS Header 32");
}
}break;
case COFF_MachineType_X64:
{
if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header) != sizeof(tls_header))
{
MemoryZeroStruct(&tls_header);
Assert(!"unable to read TLS Header 64");
}
}break;
}
+18 -18
View File
@@ -13,7 +13,7 @@ internal void
rb_entry_point(CmdLine *cmdline)
{
Temp scratch = scratch_begin(0, 0);
U64 threads_count = os_get_system_info()->logical_processor_count;
U64 threads_count = get_system_info()->logical_processor_count;
String8 threads_count_from_cmdline_string = cmd_line_string(cmdline, str8_lit("thread_count"));
if(threads_count_from_cmdline_string.size != 0)
{
@@ -70,7 +70,7 @@ rb_thread_entry_point(void *p)
//
ProfScope("analyze & load command line input files") if(lane_idx() == 0)
{
String8 working_directory = os_get_current_path(arena);
String8 working_directory = get_current_path(arena);
String8List input_file_path_tasks = str8_list_copy(arena, &cmdline->inputs);
for(String8Node *n = input_file_path_tasks.first; n != 0; n = n->next)
{
@@ -93,14 +93,14 @@ rb_thread_entry_point(void *p)
RB_FileFormatFlags file_format_flags = 0;
ProfScope("do thin analysis of file")
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, input_file_path);
FileProperties props = os_properties_from_file(file);
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, input_file_path);
FileProperties props = properties_from_file(file);
//- rjf: PDB magic -> PDB input
if(file_format == RB_FileFormat_Null)
{
U8 msf20_magic_maybe[sizeof(msf_msf20_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
file_read(file, r1u64(0, sizeof(msf20_magic_maybe)), msf20_magic_maybe);
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
{
file_format = RB_FileFormat_PDB;
@@ -109,7 +109,7 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
U8 msf70_magic_maybe[sizeof(msf_msf70_magic)] = {0};
os_file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
file_read(file, r1u64(0, sizeof(msf70_magic_maybe)), msf70_magic_maybe);
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
{
file_format = RB_FileFormat_PDB;
@@ -120,11 +120,11 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
PE_DosHeader dos_header_maybe = {0};
os_file_read_struct(file, 0, &dos_header_maybe);
file_read_struct(file, 0, &dos_header_maybe);
if(dos_header_maybe.magic == PE_DOS_MAGIC)
{
U32 pe_magic_maybe = 0;
os_file_read_struct(file, dos_header_maybe.coff_file_offset, &pe_magic_maybe);
file_read_struct(file, dos_header_maybe.coff_file_offset, &pe_magic_maybe);
if(pe_magic_maybe == PE_MAGIC)
{
file_format = RB_FileFormat_PE;
@@ -136,7 +136,7 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
U8 coff_archive_sig_maybe[sizeof(g_coff_archive_sig)] = {0};
os_file_read(file, r1u64(0, sizeof(coff_archive_sig_maybe)), coff_archive_sig_maybe);
file_read(file, r1u64(0, sizeof(coff_archive_sig_maybe)), coff_archive_sig_maybe);
if(MemoryMatch(coff_archive_sig_maybe, g_coff_archive_sig, sizeof(g_coff_archive_sig)))
{
file_format = RB_FileFormat_COFF_Archive;
@@ -145,7 +145,7 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
U8 coff_thin_archive_sig_maybe[sizeof(g_coff_thin_archive_sig)] = {0};
os_file_read(file, r1u64(0, sizeof(coff_thin_archive_sig_maybe)), coff_thin_archive_sig_maybe);
file_read(file, r1u64(0, sizeof(coff_thin_archive_sig_maybe)), coff_thin_archive_sig_maybe);
if(MemoryMatch(coff_thin_archive_sig_maybe, g_coff_thin_archive_sig, sizeof(g_coff_thin_archive_sig)))
{
file_format = RB_FileFormat_COFF_ThinArchive;
@@ -156,7 +156,7 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
COFF_BigObjHeader header_maybe = {0};
os_file_read_struct(file, 0, &header_maybe);
file_read_struct(file, 0, &header_maybe);
if(header_maybe.sig1 == COFF_MachineType_Unknown &&
header_maybe.sig2 == max_U16 &&
header_maybe.version >= 2 &&
@@ -169,7 +169,7 @@ rb_thread_entry_point(void *p)
{
Temp scratch = scratch_begin(&arena, 1);
COFF_FileHeader header_maybe = {0};
os_file_read_struct(file, 0, &header_maybe);
file_read_struct(file, 0, &header_maybe);
U64 section_count = header_maybe.section_count;
U64 section_hdr_opl_off = sizeof(header_maybe) + section_count*sizeof(COFF_SectionHeader);
@@ -202,7 +202,7 @@ rb_thread_entry_point(void *p)
if(props.size >= section_hdr_opl_off)
{
COFF_SectionHeader *section_hdrs = push_array(scratch.arena, COFF_SectionHeader, section_count);
os_file_read(file, r1u64(sizeof(header_maybe), sizeof(header_maybe) + section_count*sizeof(COFF_SectionHeader)), section_hdrs);
file_read(file, r1u64(sizeof(header_maybe), sizeof(header_maybe) + section_count*sizeof(COFF_SectionHeader)), section_hdrs);
B32 section_ranges_valid = 1;
for EachIndex(section_hdr_idx, section_count)
{
@@ -252,7 +252,7 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
U8 identifier_maybe[ELF_Identifier_Max] = {0};
os_file_read(file, r1u64(0, sizeof(identifier_maybe)), identifier_maybe);
file_read(file, r1u64(0, sizeof(identifier_maybe)), identifier_maybe);
B32 is_elf_magic = (identifier_maybe[ELF_Identifier_Mag0] == 0x7f &&
identifier_maybe[ELF_Identifier_Mag1] == 'E' &&
identifier_maybe[ELF_Identifier_Mag2] == 'L' &&
@@ -267,14 +267,14 @@ rb_thread_entry_point(void *p)
if(file_format == RB_FileFormat_Null)
{
RDI_Header rdi_header_maybe = {0};
os_file_read_struct(file, 0, &rdi_header_maybe);
file_read_struct(file, 0, &rdi_header_maybe);
if(rdi_header_maybe.magic == RDI_MAGIC_CONSTANT)
{
file_format = RB_FileFormat_RDI;
}
}
os_file_close(file);
file_close(file);
}
//////////////////////////
@@ -295,7 +295,7 @@ rb_thread_entry_point(void *p)
String8 file_data = {0};
if(file_format != RB_FileFormat_Null) ProfScope("load recognized file")
{
file_data = os_data_from_file_path(arena, input_file_path);
file_data = data_from_file_path(arena, input_file_path);
}
//////////////////////////
@@ -1593,7 +1593,7 @@ rb_thread_entry_point(void *p)
{
if(output_path.size != 0) ProfScope("write outputs [file]")
{
B32 is_written = os_write_data_list_to_file_path(output_path, output_blobs);
B32 is_written = write_data_list_to_file_path(output_path, output_blobs);
if(is_written)
{
log_infof("Results written to %S", output_path);
+2
View File
@@ -33,6 +33,7 @@
#include "pdb/pdb.h"
#include "pdb/pdb_parse.h"
#include "pdb/pdb_stringize.h"
#include "arch/arch_inc.h"
#include "rdi_from_coff/rdi_from_coff.h"
#include "rdi_from_elf/rdi_from_elf.h"
#include "rdi_from_pdb/rdi_from_pdb.h"
@@ -63,6 +64,7 @@
#include "pdb/pdb.c"
#include "pdb/pdb_parse.c"
#include "pdb/pdb_stringize.c"
#include "arch/arch_inc.c"
#include "rdi_from_coff/rdi_from_coff.c"
#include "rdi_from_elf/rdi_from_elf.c"
#include "rdi_from_pdb/rdi_from_pdb.c"

Some files were not shown because too many files have changed in this diff Show More