mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 23:08:08 +00:00
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:
@@ -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 "%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 "%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 "%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 "%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 "%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
|
if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1
|
||||||
|
|||||||
+4
-3
@@ -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", .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 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 = "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]
|
//- rjf: [raddbg wsl]
|
||||||
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||||
|
|
||||||
//- rjf: [scratch]
|
//- 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]
|
//- 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, },
|
// .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, },
|
// .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
|
//- 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 = "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 = "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, },
|
// .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
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -108,7 +108,7 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
|
|||||||
{
|
{
|
||||||
RWMutexScope(stripe->rw_mutex, 1) for(;;)
|
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
|
// rjf: find node in cache
|
||||||
AC_Node *node = 0;
|
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->working_count = 1;
|
||||||
node->evict_threshold_us = params->evict_threshold_us;
|
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();
|
node->access_pt.last_update_idx_touched = update_tick_idx();
|
||||||
|
|
||||||
// rjf: request
|
// rjf: request
|
||||||
@@ -602,7 +602,7 @@ ac_cancel_thread_entry_point(void *p)
|
|||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
os_sleep_milliseconds(50);
|
sleep_ms(50);
|
||||||
semaphore_take(ac_shared->cancel_thread_semaphore, max_U64);
|
semaphore_take(ac_shared->cancel_thread_semaphore, max_U64);
|
||||||
{
|
{
|
||||||
for EachIndex(cache_slot_idx, ac_shared->cache_slots_count)
|
for EachIndex(cache_slot_idx, ac_shared->cache_slots_count)
|
||||||
|
|||||||
+14
-14
@@ -19,24 +19,24 @@ arena_alloc_(ArenaParams *params)
|
|||||||
// rjf: round up reserve/commit sizes
|
// rjf: round up reserve/commit sizes
|
||||||
if(params->flags & ArenaFlag_LargePages)
|
if(params->flags & ArenaFlag_LargePages)
|
||||||
{
|
{
|
||||||
reserve_size = AlignPow2(reserve_size, os_get_system_info()->large_page_size);
|
reserve_size = AlignPow2(reserve_size, get_system_info()->large_page_size);
|
||||||
commit_size = AlignPow2(commit_size, os_get_system_info()->large_page_size);
|
commit_size = AlignPow2(commit_size, get_system_info()->large_page_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reserve_size = AlignPow2(reserve_size, os_get_system_info()->page_size);
|
reserve_size = AlignPow2(reserve_size, get_system_info()->page_size);
|
||||||
commit_size = AlignPow2(commit_size, os_get_system_info()->page_size);
|
commit_size = AlignPow2(commit_size, get_system_info()->page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(params->flags & ArenaFlag_LargePages)
|
if(params->flags & ArenaFlag_LargePages)
|
||||||
{
|
{
|
||||||
base = os_reserve_large(reserve_size);
|
base = reserve_memory_large(reserve_size);
|
||||||
os_commit_large(base, commit_size);
|
commit_memory_large(base, commit_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
base = os_reserve(reserve_size);
|
base = reserve_memory(reserve_size);
|
||||||
os_commit(base, commit_size);
|
commit_memory(base, commit_size);
|
||||||
}
|
}
|
||||||
AsanPoisonMemoryRegion(base, commit_size);
|
AsanPoisonMemoryRegion(base, commit_size);
|
||||||
// TODO(rjf): we need to reintroduce this later when we have the ability to remove annotations...
|
// 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))
|
if(Unlikely(base == 0))
|
||||||
{
|
{
|
||||||
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||||
os_abort(1);
|
abort_self(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ arena_release(Arena *arena)
|
|||||||
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
|
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
|
||||||
{
|
{
|
||||||
prev = 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;
|
U8 *cmt_ptr = (U8 *)current + current->cmt;
|
||||||
if(current->flags & ArenaFlag_LargePages)
|
if(current->flags & ArenaFlag_LargePages)
|
||||||
{
|
{
|
||||||
os_commit_large(cmt_ptr, cmt_size);
|
commit_memory_large(cmt_ptr, cmt_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os_commit(cmt_ptr, cmt_size);
|
commit_memory(cmt_ptr, cmt_size);
|
||||||
}
|
}
|
||||||
AsanPoisonMemoryRegion(cmt_ptr, cmt_size);
|
AsanPoisonMemoryRegion(cmt_ptr, cmt_size);
|
||||||
current->cmt = cmt_pst_clamped;
|
current->cmt = cmt_pst_clamped;
|
||||||
@@ -213,7 +213,7 @@ arena_push(Arena *arena, U64 size, U64 align, B32 zero)
|
|||||||
if(Unlikely(result == 0))
|
if(Unlikely(result == 0))
|
||||||
{
|
{
|
||||||
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||||
os_abort(1);
|
abort_self(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ arena_pop_to(Arena *arena, U64 pos)
|
|||||||
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
|
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
|
||||||
{
|
{
|
||||||
prev = current->prev;
|
prev = current->prev;
|
||||||
os_release(current, current->res);
|
release_memory(current, current->res);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
arena->current = current;
|
arena->current = current;
|
||||||
|
|||||||
@@ -471,6 +471,8 @@ union U128
|
|||||||
U16 u16[8];
|
U16 u16[8];
|
||||||
U32 u32[4];
|
U32 u32[4];
|
||||||
U64 u64[2];
|
U64 u64[2];
|
||||||
|
F32 f32[4];
|
||||||
|
F64 f64[2];
|
||||||
};
|
};
|
||||||
typedef union U256 U256;
|
typedef union U256 U256;
|
||||||
union U256
|
union U256
|
||||||
@@ -480,6 +482,8 @@ union U256
|
|||||||
U32 u32[8];
|
U32 u32[8];
|
||||||
U64 u64[4];
|
U64 u64[4];
|
||||||
U128 u128[2];
|
U128 u128[2];
|
||||||
|
F32 f32[8];
|
||||||
|
F64 f64[4];
|
||||||
};
|
};
|
||||||
typedef union U512 U512;
|
typedef union U512 U512;
|
||||||
union U512
|
union U512
|
||||||
@@ -490,8 +494,19 @@ union U512
|
|||||||
U64 u64[8];
|
U64 u64[8];
|
||||||
U128 u128[4];
|
U128 u128[4];
|
||||||
U256 u256[2];
|
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
|
//~ rjf: Basic Type Structures
|
||||||
|
|
||||||
@@ -653,6 +668,21 @@ Compiler;
|
|||||||
# define Compiler_CURRENT Compiler_Null
|
# define Compiler_CURRENT Compiler_Null
|
||||||
#endif
|
#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
|
//~ 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_micro_seconds(U64 time);
|
||||||
internal DateTime date_time_from_unix_time(U64 unix_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
|
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Copyright (c) Epic Games Tools
|
||||||
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
@@ -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
|
||||||
@@ -11,6 +11,9 @@ global B32 async_loop_again_high_priority = 0;
|
|||||||
global B32 global_async_exit = 0;
|
global B32 global_async_exit = 0;
|
||||||
thread_static B32 is_async_thread = 0;
|
thread_static B32 is_async_thread = 0;
|
||||||
|
|
||||||
|
// NOTE(rjf): defined by target
|
||||||
|
internal void entry_point(CmdLine *cmdline);
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
main_thread_base_entry_point(int arguments_count, char **arguments)
|
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)
|
#if defined(DBG_ENGINE_CORE_H)
|
||||||
num_main_threads += 1;
|
num_main_threads += 1;
|
||||||
#endif
|
#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);
|
U64 num_main_threads_clamped = Min(num_async_threads, num_main_threads);
|
||||||
num_async_threads -= num_main_threads_clamped;
|
num_async_threads -= num_main_threads_clamped;
|
||||||
String8 num_async_threads_string = cmd_line_string(&cmdline, str8_lit("async_thread_count"));
|
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))
|
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, 0);
|
||||||
ins_atomic_u32_eval_assign(&async_loop_again_high_priority, 0);
|
ins_atomic_u32_eval_assign(&async_loop_again_high_priority, 0);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -9,14 +9,28 @@
|
|||||||
|
|
||||||
#include "base_core.c"
|
#include "base_core.c"
|
||||||
#include "base_profile.c"
|
#include "base_profile.c"
|
||||||
|
#include "base_memory.c"
|
||||||
#include "base_arena.c"
|
#include "base_arena.c"
|
||||||
#include "base_math.c"
|
#include "base_math.c"
|
||||||
#include "base_strings.c"
|
#include "base_strings.c"
|
||||||
#include "base_hash.c"
|
#include "base_hash.c"
|
||||||
|
#include "base_system.c"
|
||||||
#include "base_threads.c"
|
#include "base_threads.c"
|
||||||
#include "base_thread_context.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_command_line.c"
|
||||||
#include "base_markup.c"
|
#include "base_markup.c"
|
||||||
#include "base_meta.c"
|
#include "base_meta.c"
|
||||||
#include "base_log.c"
|
#include "base_log.c"
|
||||||
#include "base_entry_point.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
|
||||||
|
|||||||
@@ -11,16 +11,30 @@
|
|||||||
|
|
||||||
#include "base_core.h"
|
#include "base_core.h"
|
||||||
#include "base_profile.h"
|
#include "base_profile.h"
|
||||||
|
#include "base_memory.h"
|
||||||
#include "base_arena.h"
|
#include "base_arena.h"
|
||||||
#include "base_math.h"
|
#include "base_math.h"
|
||||||
#include "base_strings.h"
|
#include "base_strings.h"
|
||||||
#include "base_hash.h"
|
#include "base_hash.h"
|
||||||
|
#include "base_system.h"
|
||||||
#include "base_threads.h"
|
#include "base_threads.h"
|
||||||
#include "base_thread_context.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_command_line.h"
|
||||||
#include "base_markup.h"
|
#include "base_markup.h"
|
||||||
#include "base_meta.h"
|
#include "base_meta.h"
|
||||||
#include "base_log.h"
|
#include "base_log.h"
|
||||||
#include "base_entry_point.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
|
#endif // BASE_INC_H
|
||||||
|
|||||||
@@ -1,21 +1,2 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// 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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
# define LAYER_COLOR 0x404040ff
|
# define LAYER_COLOR 0x404040ff
|
||||||
#endif
|
#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))
|
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__), raddbg_thread_color_u32(LAYER_COLOR))
|
||||||
|
|
||||||
#endif // BASE_MARKUP_H
|
#endif // BASE_MARKUP_H
|
||||||
|
|||||||
@@ -407,6 +407,26 @@ transpose_4x4f32(Mat4x4F32 mat)
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Range Ops
|
//~ 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 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 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;}
|
internal Rng1U32 pad_1u32(Rng1U32 r, U32 x) {r.min -= x; r.max += x; return r;}
|
||||||
|
|||||||
@@ -177,6 +177,28 @@ struct Mat4x4F32
|
|||||||
|
|
||||||
//- rjf: 1-range
|
//- 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;
|
typedef union Rng1U32 Rng1U32;
|
||||||
union Rng1U32
|
union Rng1U32
|
||||||
{
|
{
|
||||||
@@ -546,6 +568,28 @@ internal Mat4x4F32 transpose_4x4f32(Mat4x4F32 mat);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Range Ops
|
//~ 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))
|
#define r1u32(min, max) rng_1u32((min), (max))
|
||||||
internal Rng1U32 rng_1u32(U32 min, U32 max);
|
internal Rng1U32 rng_1u32(U32 min, U32 max);
|
||||||
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x);
|
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x);
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Copyright (c) Epic Games Tools
|
||||||
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
@@ -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
|
||||||
@@ -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(¶ms);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -24,7 +24,7 @@ spall_begin(char *fmt, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
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);
|
va_end(args);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ thread_static U32 spall_pid = 0;
|
|||||||
internal inline void spall_begin(char *fmt, ...);
|
internal inline void spall_begin(char *fmt, ...);
|
||||||
# define ProfBegin(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
|
# define ProfBegin(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
|
||||||
# define ProfBeginDynamic(...) (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 ProfTick(...)
|
||||||
# define ProfIsCapturing(...) (!!spall_capturing)
|
# define ProfIsCapturing(...) (!!spall_capturing)
|
||||||
# define ProfBeginCapture(...) (spall_capturing = 1)
|
# define ProfBeginCapture(...) (spall_capturing = 1)
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Copyright (c) Epic Games Tools
|
||||||
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Copyright (c) Epic Games Tools
|
||||||
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
@@ -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
|
||||||
@@ -108,7 +108,7 @@ tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_sr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rjf: all cases: barrier
|
// 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
|
// rjf: doing broadcast -> copy from broadcast memory on destination lanes
|
||||||
if(broadcast_ptr != 0 && lane_idx() != broadcast_src_lane_idx)
|
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
|
// rjf: doing broadcast -> barrier on all lanes
|
||||||
if(broadcast_ptr != 0)
|
if(broadcast_ptr != 0)
|
||||||
{
|
{
|
||||||
os_barrier_wait(tctx->lane_ctx.barrier);
|
barrier_wait(tctx->lane_ctx.barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
@@ -202,7 +202,7 @@ internal void
|
|||||||
access_touch(Access *access, AccessPt *pt, CondVar cv)
|
access_touch(Access *access, AccessPt *pt, CondVar cv)
|
||||||
{
|
{
|
||||||
ins_atomic_u64_inc_eval(&pt->access_refcount);
|
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());
|
ins_atomic_u64_eval_assign(&pt->last_update_idx_touched, update_tick_idx());
|
||||||
Touch *touch = tctx_thread_local->free_touch;
|
Touch *touch = tctx_thread_local->free_touch;
|
||||||
if(touch != 0)
|
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_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);
|
U64 last_update_idx_touched = ins_atomic_u64_eval(&pt->last_update_idx_touched);
|
||||||
B32 result = (access_refcount == 0 &&
|
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());
|
last_update_idx_touched + params->update_idxs <= update_tick_idx());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-65
@@ -1,70 +1,6 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// 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
|
//~ rjf: Table Stripe Functions
|
||||||
|
|
||||||
@@ -72,7 +8,7 @@ internal StripeArray
|
|||||||
stripe_array_alloc(Arena *arena)
|
stripe_array_alloc(Arena *arena)
|
||||||
{
|
{
|
||||||
StripeArray array = {0};
|
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);
|
array.v = push_array(arena, Stripe, array.count);
|
||||||
for EachIndex(idx, 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];
|
Stripe *stripe = &stripes->v[slot_idx%stripes->count];
|
||||||
return stripe;
|
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
@@ -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 Thread thread_launch(ThreadEntryPointFunctionType *f, void *p);
|
||||||
internal B32 thread_join(Thread thread, U64 endt_us);
|
internal B32 thread_join(Thread thread, U64 endt_us);
|
||||||
internal void thread_detach(Thread thread);
|
internal void thread_detach(Thread thread);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Synchronization Primitive Functions
|
//~ rjf: @per_os_impl Synchronization Primitive Functions
|
||||||
|
|
||||||
//- rjf: recursive mutexes
|
//- rjf: recursive mutexes
|
||||||
internal Mutex mutex_alloc(void);
|
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)))
|
#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 safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr);
|
||||||
internal void stripe_array_release(StripeArray *stripes);
|
|
||||||
internal Stripe *stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx);
|
|
||||||
|
|
||||||
#endif // BASE_THREADS_H
|
#endif // BASE_THREADS_H
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ c_init(void)
|
|||||||
c_shared = push_array(arena, C_Shared, 1);
|
c_shared = push_array(arena, C_Shared, 1);
|
||||||
c_shared->arena = arena;
|
c_shared->arena = arena;
|
||||||
c_shared->blob_slots_count = 16384;
|
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_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 = 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);
|
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();
|
stripe->cv = cond_var_alloc();
|
||||||
}
|
}
|
||||||
c_shared->key_slots_count = 4096;
|
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_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 = 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);
|
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();
|
stripe->cv = cond_var_alloc();
|
||||||
}
|
}
|
||||||
c_shared->root_slots_count = 4096;
|
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_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 = 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);
|
c_shared->root_stripes_free_nodes = push_array(arena, C_RootNode *, c_shared->root_stripes_count);
|
||||||
|
|||||||
@@ -17,26 +17,20 @@ d_init(void)
|
|||||||
Arena *arena = arena_alloc();
|
Arena *arena = arena_alloc();
|
||||||
d_ctrl_state = push_array(arena, D_CtrlState, 1);
|
d_ctrl_state = push_array(arena, D_CtrlState, 1);
|
||||||
d_ctrl_state->arena = arena;
|
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);
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
U64 reg_count = regs_reg_code_count_from_arch(arch);
|
U64 reg_count = arch_info->reg_code_count;
|
||||||
String8 *alias_names = regs_alias_code_string_table_from_arch(arch);
|
String8 *reg_names = arch_info->reg_code_name_table;
|
||||||
U64 alias_count = regs_alias_code_count_from_arch(arch);
|
|
||||||
d_ctrl_state->arch_string2reg_tables[arch] = e_string2num_map_make(d_ctrl_state->arena, 256);
|
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)
|
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);
|
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_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.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);
|
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)
|
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_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.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);
|
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)
|
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();
|
d_ctrl_state->c2u_ring_cv = cond_var_alloc();
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
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);
|
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);
|
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);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
d_ctrl_state->ctrl_thread_entity_ctx_rw_mutex = rw_mutex_alloc();
|
d_ctrl_state->ctrl_thread_entity_ctx_rw_mutex = rw_mutex_alloc();
|
||||||
|
|||||||
+119
-130
@@ -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 *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);
|
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);
|
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);
|
d_entity_equip_string(store, local_machine, local_machine_name);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return store;
|
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_ThreadRegCache *cache = &d_ctrl_state->thread_reg_cache;
|
||||||
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
||||||
Arch arch = thread_entity->arch;
|
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 hash = d_hash_from_handle(handle);
|
||||||
U64 slot_idx = hash%cache->slots_count;
|
U64 slot_idx = hash%cache->slots_count;
|
||||||
U64 stripe_idx = slot_idx%cache->stripes_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);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
||||||
Arch arch = thread_entity->arch;
|
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);
|
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);
|
scratch_end(scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1555,8 +1557,9 @@ d_rsp_from_thread(D_EntityCtx *ctx, D_Handle handle)
|
|||||||
Temp scratch = scratch_begin(0, 0);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
D_Entity *thread_entity = d_entity_from_handle(ctx, handle);
|
||||||
Arch arch = thread_entity->arch;
|
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);
|
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);
|
scratch_end(scratch);
|
||||||
return result;
|
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]
|
//- rjf: [dwarf]
|
||||||
|
|
||||||
@@ -1716,7 +1719,7 @@ typedef struct D_MemoryReadContextDwarfX64 D_MemoryReadContextDwarfX64;
|
|||||||
struct D_MemoryReadContextDwarfX64
|
struct D_MemoryReadContextDwarfX64
|
||||||
{
|
{
|
||||||
D_Handle process_handle;
|
D_Handle process_handle;
|
||||||
U64 endt_us;
|
U64 endt_us;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal MACHINE_OP_MEM_READ(ctrl_machine_mem_read)
|
internal MACHINE_OP_MEM_READ(ctrl_machine_mem_read)
|
||||||
@@ -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)
|
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);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
D_UnwindStepResult result = { .flags = D_UnwindFlag_Error };
|
D_UnwindStepResult result = { .flags = D_UnwindFlag_Error };
|
||||||
|
|
||||||
// gather context for virtual stack unwinder
|
// gather context for virtual stack unwinder
|
||||||
@@ -1774,11 +1778,11 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
|
|||||||
EH_FrameHdr eh_frame_hdr = {0};
|
EH_FrameHdr eh_frame_hdr = {0};
|
||||||
EH_PtrCtx eh_ptr_ctx = {0};
|
EH_PtrCtx eh_ptr_ctx = {0};
|
||||||
{
|
{
|
||||||
U64 hash = d_hash_from_handle(module_handle);
|
U64 hash = d_hash_from_handle(module_handle);
|
||||||
U64 slot_idx = hash % d_ctrl_state->module_image_info_cache.slots_count;
|
U64 slot_idx = hash%d_ctrl_state->module_image_info_cache.slots_count;
|
||||||
U64 stripe_idx = slot_idx % d_ctrl_state->module_image_info_cache.stripes_count;
|
U64 stripe_idx = slot_idx%d_ctrl_state->module_image_info_cache.stripes_count;
|
||||||
D_ModuleImageInfoCacheSlot *slot = &d_ctrl_state->module_image_info_cache.slots[slot_idx];
|
D_ModuleImageInfoCacheSlot *slot = &d_ctrl_state->module_image_info_cache.slots[slot_idx];
|
||||||
D_ModuleImageInfoCacheStripe *stripe = &d_ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
D_ModuleImageInfoCacheStripe *stripe = &d_ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
||||||
MutexScopeR(stripe->rw_mutex) for EachNode(n, D_ModuleImageInfoCacheNode, slot->first)
|
MutexScopeR(stripe->rw_mutex) for EachNode(n, D_ModuleImageInfoCacheNode, slot->first)
|
||||||
{
|
{
|
||||||
if(d_handle_match(n->module, module_handle))
|
if(d_handle_match(n->module, module_handle))
|
||||||
@@ -1794,7 +1798,7 @@ d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D
|
|||||||
}
|
}
|
||||||
|
|
||||||
// grab IP
|
// 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
|
// use .eh_frame_hdr to quickly locate nearest FDE
|
||||||
U64 fde_addr = eh_find_nearest_fde(eh_frame_hdr, &eh_ptr_ctx, ip);
|
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
|
// setup machine ops
|
||||||
void *mem_read_ctx = 0;
|
void *mem_read_ctx = 0;
|
||||||
void *reg_read_ctx = 0;
|
|
||||||
MachineOp_MemRead *mem_read_func = 0;
|
MachineOp_MemRead *mem_read_func = 0;
|
||||||
MachineOp_RegRead *reg_read_func = 0;
|
|
||||||
switch(arch)
|
switch(arch)
|
||||||
{
|
{
|
||||||
case Arch_Null: break;
|
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);
|
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->process_handle = process_handle;
|
||||||
mem_read_ctx_x64->endt_us = endt_us;
|
mem_read_ctx_x64->endt_us = endt_us;
|
||||||
|
|
||||||
mem_read_ctx = mem_read_ctx_x64;
|
mem_read_ctx = mem_read_ctx_x64;
|
||||||
reg_read_ctx = regs;
|
|
||||||
|
|
||||||
mem_read_func = ctrl_machine_mem_read;
|
mem_read_func = ctrl_machine_mem_read;
|
||||||
reg_read_func = regs_read_dwarf_x64;
|
|
||||||
}break;
|
}break;
|
||||||
case Arch_x86:
|
case Arch_x86:
|
||||||
case Arch_arm64:
|
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
|
// compute CFA for the row
|
||||||
U64 cfa = 0;
|
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
|
// on success fill out output
|
||||||
if(unwind_status == MachineOpResult_Ok)
|
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_read_ctx = regs;
|
||||||
reg_write_ctx = regs;
|
reg_write_ctx = regs;
|
||||||
mem_read_func = ctrl_machine_mem_read;
|
mem_read_func = ctrl_machine_mem_read;
|
||||||
reg_read_func = regs_read_dwarf_x64;
|
|
||||||
reg_write_func = regs_write_dwarf_x64;
|
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply register rules to the context
|
// apply register rules to the context
|
||||||
MachineOpResult unwind_status = dw_cfi_apply_register_rules(arch,
|
MachineOpResult unwind_status = dw_cfi_apply_register_rules(arch, frame_ctx->cfa, frame_ctx->cfi_row, regs, mem_read_func, mem_read_ctx);
|
||||||
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);
|
|
||||||
|
|
||||||
// last frame typically has undefined rule for IP
|
// last frame typically has undefined rule for IP
|
||||||
if(frame_ctx->cfi_row->regs[frame_ctx->ret_addr_reg].rule == DW_CFI_RegisterRule_Undefined)
|
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
|
// translate unwind status code
|
||||||
@@ -2021,11 +2010,11 @@ d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwi
|
|||||||
|
|
||||||
//- rjf: [x64]
|
//- rjf: [x64]
|
||||||
|
|
||||||
internal REGS_Reg64 *
|
internal U64 *
|
||||||
d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg)
|
d_unwind_reg_from_pe_gpr_reg__pe_x64(X64_RegBlock *regs, PE_UnwindGprRegX64 gpr_reg)
|
||||||
{
|
{
|
||||||
local_persist REGS_Reg64 dummy = {0};
|
local_persist U64 dummy = {0};
|
||||||
REGS_Reg64 *result = &dummy;
|
U64 *result = &dummy;
|
||||||
switch(gpr_reg)
|
switch(gpr_reg)
|
||||||
{
|
{
|
||||||
case PE_UnwindGprRegX64_RAX:{result = ®s->rax;}break;
|
case PE_UnwindGprRegX64_RAX:{result = ®s->rax;}break;
|
||||||
@@ -2049,7 +2038,7 @@ d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal D_UnwindStepResult
|
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_stale = 0;
|
||||||
B32 is_good = 1;
|
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
|
//- 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
|
//- 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
|
//- rjf: set up parsing state
|
||||||
B32 is_epilog = 0;
|
B32 is_epilog = 0;
|
||||||
B32 keep_parsing = 1;
|
B32 keep_parsing = 1;
|
||||||
U64 read_vaddr = regs->rip.u64;
|
U64 read_vaddr = regs->rip;
|
||||||
U64 read_vaddr_opl = read_vaddr + 256;
|
U64 read_vaddr_opl = read_vaddr + 256;
|
||||||
|
|
||||||
//- rjf: check first instruction
|
//- 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")
|
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;)
|
for(B32 keep_parsing = 1;keep_parsing != 0;)
|
||||||
{
|
{
|
||||||
//- rjf: assume no more parsing after this instruction
|
//- 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:
|
case 0x5F:
|
||||||
{
|
{
|
||||||
// rjf: read value at rsp
|
// rjf: read value at rsp
|
||||||
U64 sp = regs->rsp.u64;
|
U64 sp = regs->rsp;
|
||||||
U64 value = 0;
|
U64 value = 0;
|
||||||
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &value, endt_us) ||
|
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &value, endt_us) ||
|
||||||
is_stale)
|
is_stale)
|
||||||
@@ -2318,9 +2307,9 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
|
|||||||
|
|
||||||
// rjf: modify registers
|
// rjf: modify registers
|
||||||
PE_UnwindGprRegX64 gpr_reg = (inst_byte - 0x58) + (rex & 1)*8;
|
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);
|
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
|
||||||
reg->u64 = value;
|
reg[0] = value;
|
||||||
regs->rsp.u64 = sp + 8;
|
regs->rsp = sp + 8;
|
||||||
|
|
||||||
// rjf: not a final instruction, so keep mparsing
|
// rjf: not a final instruction, so keep mparsing
|
||||||
keep_parsing = 1;
|
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;
|
read_vaddr += 4;
|
||||||
|
|
||||||
// rjf: update stack pointer
|
// 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
|
// rjf: not a final instruction; keep parsing
|
||||||
keep_parsing = 1;
|
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;
|
read_vaddr += 1;
|
||||||
|
|
||||||
// rjf: update stack pointer
|
// 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
|
// rjf: not a final instruction; keep parsing
|
||||||
keep_parsing = 1;
|
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;
|
read_vaddr += 1;
|
||||||
PE_UnwindGprRegX64 gpr_reg = (modrm & 7) + (rex & 1)*8;
|
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 = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, gpr_reg);
|
||||||
U64 reg_value = reg->u64;
|
U64 reg_value = reg[0];
|
||||||
|
|
||||||
// rjf: read immediate
|
// rjf: read immediate
|
||||||
S32 imm = 0;
|
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
|
// rjf: update stack pointer
|
||||||
regs->rsp.u64 = (U64)(reg_value + imm);
|
regs->rsp = (U64)(reg_value + imm);
|
||||||
|
|
||||||
// rjf: not a final instruction; keep parsing
|
// rjf: not a final instruction; keep parsing
|
||||||
keep_parsing = 1;
|
keep_parsing = 1;
|
||||||
@@ -2429,7 +2418,7 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
|
|||||||
case 0xC2:
|
case 0xC2:
|
||||||
{
|
{
|
||||||
// rjf: read new ip
|
// rjf: read new ip
|
||||||
U64 sp = regs->rsp.u64;
|
U64 sp = regs->rsp;
|
||||||
U64 new_ip = 0;
|
U64 new_ip = 0;
|
||||||
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
|
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||||
is_stale)
|
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;
|
U64 new_sp = sp + 8 + imm;
|
||||||
|
|
||||||
// rjf: commit registers
|
// rjf: commit registers
|
||||||
regs->rip.u64 = new_ip;
|
regs->rip = new_ip;
|
||||||
regs->rsp.u64 = new_sp;
|
regs->rsp = new_sp;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
// rjf: ret / rep; ret
|
// 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:
|
case 0xC3:
|
||||||
{
|
{
|
||||||
// rjf: read new ip
|
// rjf: read new ip
|
||||||
U64 sp = regs->rsp.u64;
|
U64 sp = regs->rsp;
|
||||||
U64 new_ip = 0;
|
U64 new_ip = 0;
|
||||||
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
|
if(!d_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||||
is_stale)
|
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;
|
U64 new_sp = sp + 8;
|
||||||
|
|
||||||
// rjf: commit registers
|
// rjf: commit registers
|
||||||
regs->rip.u64 = new_ip;
|
regs->rip = new_ip;
|
||||||
regs->rsp.u64 = new_sp;
|
regs->rsp = new_sp;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
// rjf: jmp nnnn
|
// 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
|
//- rjf: get frame reg
|
||||||
B32 bad_frame_reg_info = 0;
|
B32 bad_frame_reg_info = 0;
|
||||||
REGS_Reg64 *frame_reg = 0;
|
U64 *frame_reg = 0;
|
||||||
U64 frame_off = 0;
|
U64 frame_off = 0;
|
||||||
{
|
{
|
||||||
U64 unwind_info_off = first_pdata->voff_unwind_info;
|
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
|
//- rjf: unpack frame base
|
||||||
U64 frame_base = regs->rsp.u64;
|
U64 frame_base = regs->rsp;
|
||||||
if(frame_reg != 0)
|
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;
|
U64 adjusted_frame_base = raw_frame_base - frame_off*16;
|
||||||
frame_base = adjusted_frame_base;
|
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:
|
case PE_UnwindOpCode_PUSH_NONVOL:
|
||||||
{
|
{
|
||||||
// rjf: read value from stack pointer
|
// rjf: read value from stack pointer
|
||||||
U64 rsp = regs->rsp.u64;
|
U64 rsp = regs->rsp;
|
||||||
U64 value = 0;
|
U64 value = 0;
|
||||||
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &value, endt_us) ||
|
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &value, endt_us) ||
|
||||||
is_stale)
|
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;
|
U64 new_rsp = rsp + 8;
|
||||||
|
|
||||||
// rjf: commit registers
|
// rjf: commit registers
|
||||||
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
||||||
reg->u64 = value;
|
reg[0] = value;
|
||||||
regs->rsp.u64 = new_rsp;
|
regs->rsp = new_rsp;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_ALLOC_LARGE:
|
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
|
// rjf: advance stack pointer
|
||||||
U64 rsp = regs->rsp.u64;
|
U64 rsp = regs->rsp;
|
||||||
U64 new_rsp = rsp + size;
|
U64 new_rsp = rsp + size;
|
||||||
|
|
||||||
// rjf: advance stack pointer
|
// rjf: advance stack pointer
|
||||||
regs->rsp.u64 = new_rsp;
|
regs->rsp = new_rsp;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_ALLOC_SMALL:
|
case PE_UnwindOpCode_ALLOC_SMALL:
|
||||||
{
|
{
|
||||||
// rjf: advance stack pointer
|
// rjf: advance stack pointer
|
||||||
regs->rsp.u64 += op_info*8 + 8;
|
regs->rsp += op_info*8 + 8;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_SET_FPREG:
|
case PE_UnwindOpCode_SET_FPREG:
|
||||||
{
|
{
|
||||||
// rjf: put stack pointer back to the frame base
|
// rjf: put stack pointer back to the frame base
|
||||||
regs->rsp.u64 = frame_base;
|
regs->rsp = frame_base;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_SAVE_NONVOL:
|
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
|
// rjf: commit to register
|
||||||
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
||||||
reg->u64 = value;
|
reg[0] = value;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_SAVE_NONVOL_FAR:
|
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
|
// rjf: commit to register
|
||||||
REGS_Reg64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
U64 *reg = d_unwind_reg_from_pe_gpr_reg__pe_x64(regs, op_info);
|
||||||
reg->u64 = value;
|
reg[0] = value;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case PE_UnwindOpCode_EPILOG:
|
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
|
// rjf: read values
|
||||||
U64 sp_og = regs->rsp.u64;
|
U64 sp_og = regs->rsp;
|
||||||
U64 sp_adj = sp_og;
|
U64 sp_adj = sp_og;
|
||||||
if(op_info == 1)
|
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
|
// rjf: commit registers
|
||||||
regs->rip.u64 = ip_value;
|
regs->rip = ip_value;
|
||||||
regs->ss.u16 = ss_value;
|
regs->ss = ss_value;
|
||||||
regs->rflags.u64 = rflags_value;
|
regs->rflags = rflags_value;
|
||||||
regs->rsp.u64 = sp_value;
|
regs->rsp = sp_value;
|
||||||
|
|
||||||
// rjf: mark machine frame
|
// rjf: mark machine frame
|
||||||
xdata_unwind_did_machframe = 1;
|
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")
|
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
|
// rjf: read rip from stack pointer
|
||||||
U64 rsp = regs->rsp.u64;
|
U64 rsp = regs->rsp;
|
||||||
U64 new_rip = 0;
|
U64 new_rip = 0;
|
||||||
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &new_rip, endt_us) ||
|
if(!d_process_memory_read_struct(process_handle, rsp, &is_stale, &new_rip, endt_us) ||
|
||||||
is_stale)
|
is_stale)
|
||||||
@@ -2844,8 +2833,8 @@ d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 modul
|
|||||||
if(is_good)
|
if(is_good)
|
||||||
{
|
{
|
||||||
U64 new_rsp = rsp + 8;
|
U64 new_rsp = rsp + 8;
|
||||||
regs->rip.u64 = new_rip;
|
regs->rip = new_rip;
|
||||||
regs->rsp.u64 = new_rsp;
|
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 *thread_entity = d_entity_from_handle(ctx, thread);
|
||||||
D_Entity *process_entity = thread_entity->parent;
|
D_Entity *process_entity = thread_entity->parent;
|
||||||
Arch arch = thread_entity->arch;
|
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
|
//- rjf: grab initial register block
|
||||||
void *regs_block = d_reg_block_from_thread(scratch.arena, ctx, thread);
|
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;;)
|
for(unwind.flags = 0;;)
|
||||||
{
|
{
|
||||||
U64 rip = regs_rip_from_arch_block(arch, regs_block);
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
U64 rsp = regs_rsp_from_arch_block(arch, regs_block);
|
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)
|
// rjf: cancel on zero rip (except the top frame)
|
||||||
if(rip == 0 && frame_node_count > 0)
|
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
|
// stop unwinding on errors or stale data
|
||||||
unwind.flags |= step_result.flags;
|
unwind.flags |= step_result.flags;
|
||||||
if(unwind.flags & (D_UnwindFlag_Stale|D_UnwindFlag_Error) ||
|
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;
|
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)
|
for(U64 base_frame_idx = 0; base_frame_idx < base_unwind->frames.count; base_frame_idx += 1)
|
||||||
{
|
{
|
||||||
// rjf: unpack
|
// rjf: unpack
|
||||||
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
D_UnwindFrame *src = &base_unwind->frames.v[base_frame_idx];
|
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);
|
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
|
||||||
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
|
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
|
||||||
DI_Key dbgi_key = d_dbgi_key_from_module(module);
|
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];
|
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
|
//~ rjf: Control-Thread Functions
|
||||||
|
|
||||||
@@ -3178,7 +3164,7 @@ d_u2c_push_msgs(D_MsgList *msgs, U64 endt_us)
|
|||||||
good = 1;
|
good = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(os_now_microseconds() >= endt_us)
|
if(now_time_us() >= endt_us)
|
||||||
{
|
{
|
||||||
break;
|
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);
|
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;
|
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);
|
cond_var_broadcast(d_ctrl_state->c2u_ring_cv);
|
||||||
if(d_ctrl_state->wakeup_hook != 0)
|
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));
|
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;
|
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_Key new_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, new_dbgi_timestamp);
|
||||||
di_open(new_dbgi_key);
|
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_EntityCtx *entity_ctx = &d_ctrl_state->ctrl_thread_entity_store->ctx;
|
||||||
D_EntityArray threads = d_entity_array_from_kind(entity_ctx, D_EntityKind_Thread);
|
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)
|
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)
|
for(String8Node *n = dbg_path_candidates.first; n != 0; n = n->next)
|
||||||
{
|
{
|
||||||
String8 candidate_path = n->string;
|
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)
|
if(props.modified != 0 && props.size != 0)
|
||||||
{
|
{
|
||||||
initial_debug_info_path = push_str8_copy(arena, path_normalized_from_string(scratch.arena, candidate_path));
|
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));
|
D_Entity *thread = d_entity_from_handle(entity_ctx, d_handle_make(D_MachineID_Local, spoof->thread));
|
||||||
Arch arch = thread->arch;
|
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);
|
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)
|
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);
|
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_Handle module_handle = d_handle_make(D_MachineID_Local, event->module);
|
||||||
D_Event *out_evt1 = d_event_list_push(scratch.arena, &evts);
|
D_Event *out_evt1 = d_event_list_push(scratch.arena, &evts);
|
||||||
String8 module_path = path_normalized_from_string(scratch.arena, event->string);
|
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);
|
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->kind = D_EventKind_NewModule;
|
||||||
out_evt1->msg_id = msg->msg_id;
|
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;
|
out_evt1->tls_offset = event->tls_offset;
|
||||||
D_Event *out_evt2 = d_event_list_push(scratch.arena, &evts);
|
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);
|
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->kind = D_EventKind_ModuleDebugInfoPathChange;
|
||||||
out_evt2->msg_id = msg->msg_id;
|
out_evt2->msg_id = msg->msg_id;
|
||||||
out_evt2->entity = module_handle;
|
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);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
D_EntityCtx *entity_ctx = &d_ctrl_state->ctrl_thread_entity_store->ctx;
|
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);
|
void *regs = d_reg_block_from_thread(scratch.arena, entity_ctx, entity->handle);
|
||||||
Rng1U64 legal_range = r1u64(0, regs_size);
|
Rng1U64 legal_range = r1u64(0, regs_size);
|
||||||
Rng1U64 read_range = intersect_1u64(legal_range, range);
|
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")
|
else ProfScope("cache miss")
|
||||||
{
|
{
|
||||||
D_Entity *debug_info_path = d_entity_child_from_kind(mod, D_EntityKind_DebugInfoPath);
|
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))
|
ProfScope("determine if %.*s is necessary", str8_varg(debug_info_path->string))
|
||||||
{
|
{
|
||||||
//- rjf: determine if file is PDB
|
//- 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)
|
if(!file_is_pdb)
|
||||||
{
|
{
|
||||||
U8 msf70_magic_maybe[sizeof(msf_msf70_magic)] = {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)))
|
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
|
||||||
{
|
{
|
||||||
file_is_pdb = 1;
|
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)
|
if(!file_is_pdb)
|
||||||
{
|
{
|
||||||
U8 msf20_magic_maybe[sizeof(msf_msf20_magic)] = {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)))
|
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
|
||||||
{
|
{
|
||||||
file_is_pdb = 1;
|
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 any are found in the PDB, then this RDI is necessary.
|
||||||
if(file_is_pdb)
|
if(file_is_pdb)
|
||||||
{
|
{
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = properties_from_file(file);
|
||||||
OS_Handle map = os_file_map_open(OS_AccessFlag_Read, file);
|
FileMap map = file_map_open(AccessFlag_Read, file);
|
||||||
void *file_base = os_file_map_view_open(map, OS_AccessFlag_Read, r1u64(0, props.size));
|
void *file_base = file_map_view_open(map, AccessFlag_Read, r1u64(0, props.size));
|
||||||
String8 file_data = str8(file_base, 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);
|
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));
|
file_map_view_close(map, file_base, r1u64(0, props.size));
|
||||||
os_file_map_close(map);
|
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 = push_array(d_ctrl_state->ctrl_thread_msg_process_arena, D_ModuleReqCacheNode, 1);
|
||||||
node->next = slot;
|
node->next = slot;
|
||||||
d_ctrl_state->module_req_cache_slots[slot_idx] = node;
|
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;
|
E_IRCtx *ctx = &scope->ir_ctx;
|
||||||
ctx->regs_map = d_string2reg_from_arch(arch);
|
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->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->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);
|
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);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
LogScopeResult log = log_scope_end(scratch.arena);
|
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)
|
if(log.strings[LogMsgKind_UserError].size != 0)
|
||||||
{
|
{
|
||||||
D_EventList evts = {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);
|
String8 stderr_path = path_absolute_dst_from_relative_dst_src(scratch.arena, msg->stderr_path, msg->path);
|
||||||
|
|
||||||
//- rjf: obtain stdout/stderr/stdin handles
|
//- rjf: obtain stdout/stderr/stdin handles
|
||||||
OS_Handle stdout_handle = {0};
|
File stdout_handle = {0};
|
||||||
OS_Handle stderr_handle = {0};
|
File stderr_handle = {0};
|
||||||
OS_Handle stdin_handle = {0};
|
File stdin_handle = {0};
|
||||||
if(stdout_path.size != 0)
|
if(stdout_path.size != 0)
|
||||||
{
|
{
|
||||||
OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path);
|
File f = file_open(AccessFlag_Write|AccessFlag_Read, stdout_path);
|
||||||
os_file_close(f);
|
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);
|
stdout_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, msg->stdout_path);
|
||||||
}
|
}
|
||||||
if(stderr_path.size != 0)
|
if(stderr_path.size != 0)
|
||||||
{
|
{
|
||||||
OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stderr_path);
|
File f = file_open(AccessFlag_Write|AccessFlag_Read, stderr_path);
|
||||||
os_file_close(f);
|
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);
|
stderr_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, msg->stderr_path);
|
||||||
}
|
}
|
||||||
if(stdin_path.size != 0)
|
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
|
//- rjf: launch
|
||||||
OS_ProcessLaunchParams params = {0};
|
ProcessLaunchParams params = {0};
|
||||||
{
|
{
|
||||||
params.cmd_line = msg->cmd_line_string_list;
|
params.cmd_line = msg->cmd_line_string_list;
|
||||||
params.path = msg->path;
|
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, ¶ms);
|
U32 id = dmn_ctrl_launch(ctrl_ctx, ¶ms);
|
||||||
|
|
||||||
//- rjf: close stdout/stderr/stdin files
|
//- rjf: close stdout/stderr/stdin files
|
||||||
os_file_close(stdout_handle);
|
file_close(stdout_handle);
|
||||||
os_file_close(stderr_handle);
|
file_close(stderr_handle);
|
||||||
os_file_close(stdin_handle);
|
file_close(stdin_handle);
|
||||||
|
|
||||||
//- rjf: record (id -> entry points), so that we know custom entry points for this PID
|
//- 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;
|
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)
|
if(range_size != 0)
|
||||||
{
|
{
|
||||||
// rjf: set up arena
|
// 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);
|
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);
|
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.
|
// time.
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
U64 endt_us = os_now_microseconds()+10000;
|
U64 endt_us = now_time_us()+10000;
|
||||||
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
|
||||||
Rng1U64 page_range = r1u64(range.min/page_size, (range.max+page_size-1)/page_size);
|
Rng1U64 page_range = r1u64(range.min/page_size, (range.max+page_size-1)/page_size);
|
||||||
for EachInRange(page_idx, page_range)
|
for EachInRange(page_idx, page_range)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
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);
|
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);
|
scratch_end(scratch);
|
||||||
if(!slice.stale || os_now_microseconds() >= endt_us)
|
if(!slice.stale || now_time_us() >= endt_us)
|
||||||
{
|
{
|
||||||
break;
|
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_reg_gen = d_reg_gen();
|
||||||
pre_mem_gen = d_mem_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))
|
if(!(unwind.flags & D_UnwindFlag_Stale))
|
||||||
{
|
{
|
||||||
good = 1;
|
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 thread = threads[thread_idx];
|
||||||
D_Handle process = threads_processes[thread_idx];
|
D_Handle process = threads_processes[thread_idx];
|
||||||
Arch arch = threads_arches[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_CallStack call_stack = call_stacks[thread_idx];
|
||||||
D_CallStackTreeNode *thread_node = tree->root;
|
D_CallStackTreeNode *thread_node = tree->root;
|
||||||
for EachIndex(frame_idx, call_stack.frames_count)
|
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;
|
U64 depth = call_stack.frames[frame_idx].inline_depth;
|
||||||
D_CallStackTreeNode *next_node = &d_call_stack_tree_node_nil;
|
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)
|
for(D_CallStackTreeNode *child = thread_node->first; child != &d_call_stack_tree_node_nil; child = child->next)
|
||||||
|
|||||||
@@ -269,9 +269,8 @@ struct D_CtrlState
|
|||||||
Arena *arena;
|
Arena *arena;
|
||||||
D_WakeupFunctionType *wakeup_hook;
|
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_string2reg_tables[Arch_COUNT];
|
||||||
E_String2NumMap arch_string2alias_tables[Arch_COUNT];
|
|
||||||
|
|
||||||
// rjf: caches
|
// rjf: caches
|
||||||
D_ThreadRegCache thread_reg_cache;
|
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);
|
internal D_UnwindStepResult d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwindContext *frame_ctx, U64 endt_us);
|
||||||
|
|
||||||
//- rjf: [x64]
|
//- 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);
|
||||||
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 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
|
//- rjf: abstracted full unwind
|
||||||
internal D_Unwind d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us);
|
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
|
//- rjf: name -> register/alias hash tables, for eval
|
||||||
internal E_String2NumMap *d_string2reg_from_arch(Arch arch);
|
internal E_String2NumMap *d_string2reg_from_arch(Arch arch);
|
||||||
internal E_String2NumMap *d_string2alias_from_arch(Arch arch);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Control-Thread Functions
|
//~ rjf: Control-Thread Functions
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
|
|||||||
String8 machine_code = {0};
|
String8 machine_code = {0};
|
||||||
{
|
{
|
||||||
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
|
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;
|
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;
|
B32 good_machine_code = 0;
|
||||||
if(good_line_info)
|
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;
|
machine_code = machine_code_slice.data;
|
||||||
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
|
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
|
||||||
LogInfoNamedBlockF("machine_code_slice")
|
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;
|
B32 good_machine_code = 0;
|
||||||
if(good_line_info)
|
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;
|
machine_code = machine_code_slice.data;
|
||||||
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
|
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);
|
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, 0);
|
||||||
if(callstack.concrete_frames_count != 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);
|
access_close(access);
|
||||||
}
|
}
|
||||||
@@ -1648,7 +1649,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
|||||||
String8List env = target->env;
|
String8List env = target->env;
|
||||||
if(working_directory.size == 0)
|
if(working_directory.size == 0)
|
||||||
{
|
{
|
||||||
working_directory = os_get_current_path(scratch.arena);
|
working_directory = get_current_path(scratch.arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: build launch options
|
// rjf: build launch options
|
||||||
@@ -1811,12 +1812,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
|||||||
Access *access = access_open();
|
Access *access = access_open();
|
||||||
|
|
||||||
// rjf: thread => call stack
|
// 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
|
// rjf: use first unwind frame to generate trap
|
||||||
if(callstack.concrete_frames_count > 1)
|
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 trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr};
|
||||||
d_trap_list_push(scratch.arena, &trap_net.traps, &trap);
|
d_trap_list_push(scratch.arena, &trap_net.traps, &trap);
|
||||||
trap_net.good_read = 1;
|
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:
|
case D_CmdKind_SetThreadIP:
|
||||||
{
|
{
|
||||||
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
|
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;
|
U64 vaddr = params->vaddr;
|
||||||
void *block = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, thread->handle);
|
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);
|
B32 result = d_thread_write_reg_block(thread->handle, block);
|
||||||
(void)result;
|
(void)result;
|
||||||
}break;
|
}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_user_state->ctrl_soft_halt_issued = 1;
|
||||||
d_halt();
|
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);
|
MemoryZeroStruct(&d_user_state->ctrl_msgs);
|
||||||
arena_clear(d_user_state->ctrl_msg_arena);
|
arena_clear(d_user_state->ctrl_msg_arena);
|
||||||
|
|||||||
+40
-40
@@ -71,7 +71,7 @@ di_init(CmdLine *cmdline)
|
|||||||
if(!try_u64_from_str8_c_rules(signal_pid_string, &signal_pid))
|
if(!try_u64_from_str8_c_rules(signal_pid_string, &signal_pid))
|
||||||
{
|
{
|
||||||
has_parent = 0;
|
has_parent = 0;
|
||||||
signal_pid = os_get_process_info()->pid;
|
signal_pid = get_process_info()->pid;
|
||||||
}
|
}
|
||||||
U64 signal_code = 0;
|
U64 signal_code = 0;
|
||||||
String8 signal_code_string = cmd_line_string(cmdline, str8_lit("signal_code"));
|
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_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_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
|
else
|
||||||
{
|
{
|
||||||
di_shared->conversion_completion_lock_semaphore = semaphore_alloc(1, 1, di_shared->conversion_completion_lock_semaphore_name);
|
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_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_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_mutex = mutex_alloc();
|
||||||
di_shared->completion_arena = arena_alloc();
|
di_shared->completion_arena = arena_alloc();
|
||||||
di_shared->event_mutex = mutex_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
|
//- rjf: try to make key from file's contents
|
||||||
if(!made_key)
|
if(!made_key)
|
||||||
{
|
{
|
||||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = properties_from_file(file);
|
||||||
if(min_timestamp <= props.modified)
|
if(min_timestamp <= props.modified)
|
||||||
{
|
{
|
||||||
//- rjf: PDB magic => use GUID for key
|
//- 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";
|
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};
|
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)))
|
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
|
||||||
{
|
{
|
||||||
is_pdb = 1;
|
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";
|
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};
|
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)))
|
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
|
||||||
{
|
{
|
||||||
is_pdb = 1;
|
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
|
//- 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
|
//- rjf: decrement this key's node's refcount; remove if needed
|
||||||
B32 node_released = 0;
|
B32 node_released = 0;
|
||||||
OS_Handle file = {0};
|
File file = {0};
|
||||||
OS_Handle file_map = {0};
|
FileMap file_map = {0};
|
||||||
FileProperties file_props = {0};
|
FileProperties file_props = {0};
|
||||||
void *file_base = 0;
|
void *file_base = 0;
|
||||||
Arena *arena = 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_dec_eval(&di_shared->load_count);
|
||||||
ins_atomic_u64_inc_eval(&di_shared->load_gen);
|
ins_atomic_u64_inc_eval(&di_shared->load_gen);
|
||||||
os_file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
|
file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
|
||||||
os_file_map_close(file_map);
|
file_map_close(file_map);
|
||||||
os_file_close(file);
|
file_close(file);
|
||||||
if(arena != 0)
|
if(arena != 0)
|
||||||
{
|
{
|
||||||
arena_release(arena);
|
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
|
// rjf: found current results, or out-of-time? abort
|
||||||
if(grabbed || os_now_microseconds() >= endt_us)
|
if(grabbed || now_time_us() >= endt_us)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -681,16 +681,16 @@ di_async_tick(void)
|
|||||||
if(!t->og_analyzed)
|
if(!t->og_analyzed)
|
||||||
{
|
{
|
||||||
t->og_analyzed = 1;
|
t->og_analyzed = 1;
|
||||||
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, og_path);
|
File file = file_open(AccessFlag_ShareRead|AccessFlag_Read, og_path);
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = properties_from_file(file);
|
||||||
t->og_size = props.size;
|
t->og_size = props.size;
|
||||||
U64 rdi_magic_maybe = 0;
|
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)
|
rdi_magic_maybe == RDI_MAGIC_CONSTANT)
|
||||||
{
|
{
|
||||||
t->og_is_rdi = 1;
|
t->og_is_rdi = 1;
|
||||||
}
|
}
|
||||||
os_file_close(file);
|
file_close(file);
|
||||||
}
|
}
|
||||||
U64 og_size = t->og_size;
|
U64 og_size = t->og_size;
|
||||||
B32 og_is_rdi = t->og_is_rdi;
|
B32 og_is_rdi = t->og_is_rdi;
|
||||||
@@ -713,8 +713,8 @@ di_async_tick(void)
|
|||||||
if(!t->rdi_analyzed)
|
if(!t->rdi_analyzed)
|
||||||
{
|
{
|
||||||
t->rdi_analyzed = 1;
|
t->rdi_analyzed = 1;
|
||||||
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, rdi_path);
|
File file = file_open(AccessFlag_ShareRead|AccessFlag_Read, rdi_path);
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = properties_from_file(file);
|
||||||
if(props.modified < og_min_timestamp)
|
if(props.modified < og_min_timestamp)
|
||||||
{
|
{
|
||||||
t->rdi_is_stale = 1;
|
t->rdi_is_stale = 1;
|
||||||
@@ -723,12 +723,12 @@ di_async_tick(void)
|
|||||||
{
|
{
|
||||||
t->rdi_is_stale = 1;
|
t->rdi_is_stale = 1;
|
||||||
RDI_Header header = {0};
|
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);
|
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;
|
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)
|
if(!og_is_rdi && rdi_is_stale && t->thread_count == 0)
|
||||||
{
|
{
|
||||||
U64 thread_count = 1;
|
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)
|
if(priority_idx > 0)
|
||||||
{
|
{
|
||||||
max_thread_count = Max(1, max_thread_count/2);
|
max_thread_count = Max(1, max_thread_count/2);
|
||||||
@@ -756,7 +756,7 @@ di_async_tick(void)
|
|||||||
//- rjf: determine if there are threads available
|
//- rjf: determine if there are threads available
|
||||||
B32 threads_available = 0;
|
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 current_threads = di_shared->conversion_thread_count;
|
||||||
U64 needed_threads = (current_threads + t->thread_count);
|
U64 needed_threads = (current_threads + t->thread_count);
|
||||||
threads_available = (max_threads >= needed_threads);
|
threads_available = (max_threads >= needed_threads);
|
||||||
@@ -789,8 +789,8 @@ di_async_tick(void)
|
|||||||
if(og_is_good && ready_to_launch_conversion)
|
if(og_is_good && ready_to_launch_conversion)
|
||||||
{
|
{
|
||||||
B32 should_compress = 0;
|
B32 should_compress = 0;
|
||||||
OS_ProcessLaunchParams params = {0};
|
ProcessLaunchParams params = {0};
|
||||||
params.path = os_get_process_info()->binary_path;
|
params.path = get_process_info()->binary_path;
|
||||||
params.inherit_env = 1;
|
params.inherit_env = 1;
|
||||||
params.consoleless = 1;
|
params.consoleless = 1;
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "raddbg");
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "raddbg");
|
||||||
@@ -804,11 +804,11 @@ di_async_tick(void)
|
|||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--rdi");
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--rdi");
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--out:%S", rdi_path);
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--out:%S", rdi_path);
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--thread_count:%I64u", t->thread_count);
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--thread_count:%I64u", t->thread_count);
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--signal_pid:%I64u", (U64)os_get_process_info()->pid);
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--signal_pid:%I64u", (U64)get_process_info()->pid);
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--signal_code:%I64u", (U64)t);
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--signal_code:%I64u", (U64)t);
|
||||||
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "%S", og_path);
|
str8_list_pushf(scratch.arena, ¶ms.cmd_line, "%S", og_path);
|
||||||
ProfMsg("launch creation for %.*s", str8_varg(rdi_path));
|
ProfMsg("launch creation for %.*s", str8_varg(rdi_path));
|
||||||
t->process = os_process_launch(¶ms);
|
t->process = process_launch(¶ms);
|
||||||
t->status = DI_LoadTaskStatus_Active;
|
t->status = DI_LoadTaskStatus_Active;
|
||||||
di_shared->conversion_process_count += 1;
|
di_shared->conversion_process_count += 1;
|
||||||
di_shared->conversion_thread_count += t->thread_count;
|
di_shared->conversion_thread_count += t->thread_count;
|
||||||
@@ -840,7 +840,7 @@ di_async_tick(void)
|
|||||||
}
|
}
|
||||||
if(!task_is_done)
|
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)
|
if(task_is_done)
|
||||||
{
|
{
|
||||||
@@ -875,7 +875,7 @@ di_async_tick(void)
|
|||||||
//- rjf: if task is done, retire & recycle task; gather path to load
|
//- rjf: if task is done, retire & recycle task; gather path to load
|
||||||
if(t->status == DI_LoadTaskStatus_Done)
|
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);
|
DI_EventNode *n = push_array(di_shared->event_arena, DI_EventNode, 1);
|
||||||
SLLQueuePush(di_shared->events.first, di_shared->events.last, n);
|
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));
|
ProfBegin("parse %.*s", str8_varg(rdi_path));
|
||||||
|
|
||||||
//- rjf: open file
|
//- rjf: open file
|
||||||
OS_Handle file = {0};
|
File file = {0};
|
||||||
OS_Handle file_map = {0};
|
FileMap file_map = {0};
|
||||||
FileProperties file_props = {0};
|
FileProperties file_props = {0};
|
||||||
void *file_base = 0;
|
void *file_base = 0;
|
||||||
{
|
{
|
||||||
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, rdi_path);
|
file = file_open(AccessFlag_Read|AccessFlag_ShareRead|AccessFlag_ShareWrite, rdi_path);
|
||||||
file_map = os_file_map_open(OS_AccessFlag_Read, file);
|
file_map = file_map_open(AccessFlag_Read, file);
|
||||||
file_props = os_properties_from_file(file);
|
file_props = properties_from_file(file);
|
||||||
file_base = os_file_map_view_open(file_map, OS_AccessFlag_Read, r1u64(0, file_props.size));
|
file_base = file_map_view_open(file_map, AccessFlag_Read, r1u64(0, file_props.size));
|
||||||
}
|
}
|
||||||
|
|
||||||
//- rjf: do initial parse of rdi
|
//- rjf: do initial parse of rdi
|
||||||
@@ -1010,9 +1010,9 @@ di_async_tick(void)
|
|||||||
{
|
{
|
||||||
arena_release(rdi_parsed_arena);
|
arena_release(rdi_parsed_arena);
|
||||||
}
|
}
|
||||||
os_file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
|
file_map_view_close(file_map, file_base, r1u64(0, file_props.size));
|
||||||
os_file_map_close(file_map);
|
file_map_close(file_map);
|
||||||
os_file_close(file);
|
file_close(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cond_var_broadcast(stripe->cv);
|
cond_var_broadcast(stripe->cv);
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ struct DI_Node
|
|||||||
DI_Key key;
|
DI_Key key;
|
||||||
|
|
||||||
// rjf: value
|
// rjf: value
|
||||||
OS_Handle file;
|
File file;
|
||||||
OS_Handle file_map;
|
FileMap file_map;
|
||||||
void *file_base;
|
void *file_base;
|
||||||
FileProperties file_props;
|
FileProperties file_props;
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
@@ -145,7 +145,7 @@ struct DI_LoadTask
|
|||||||
B32 rdi_is_stale;
|
B32 rdi_is_stale;
|
||||||
|
|
||||||
U64 thread_count;
|
U64 thread_count;
|
||||||
OS_Handle process;
|
Process process;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DI_LoadCompletion DI_LoadCompletion;
|
typedef struct DI_LoadCompletion DI_LoadCompletion;
|
||||||
@@ -280,7 +280,7 @@ struct DI_Shared
|
|||||||
String8 conversion_completion_shared_memory_name;
|
String8 conversion_completion_shared_memory_name;
|
||||||
Semaphore conversion_completion_lock_semaphore;
|
Semaphore conversion_completion_lock_semaphore;
|
||||||
Semaphore conversion_completion_signal_semaphore;
|
Semaphore conversion_completion_signal_semaphore;
|
||||||
OS_Handle conversion_completion_shared_memory;
|
SharedMemory conversion_completion_shared_memory;
|
||||||
U64 *conversion_completion_shared_memory_base;
|
U64 *conversion_completion_shared_memory_base;
|
||||||
Thread conversion_completion_signal_receiver_thread;
|
Thread conversion_completion_signal_receiver_thread;
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -132,10 +132,11 @@ dmn_rip_from_thread(DMN_Handle thread)
|
|||||||
Temp scratch = scratch_begin(0, 0);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
{
|
{
|
||||||
Arch arch = dmn_arch_from_thread(thread);
|
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);
|
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
|
||||||
dmn_thread_read_reg_block(thread, reg_block);
|
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);
|
scratch_end(scratch);
|
||||||
return result;
|
return result;
|
||||||
@@ -148,10 +149,11 @@ dmn_rsp_from_thread(DMN_Handle thread)
|
|||||||
Temp scratch = scratch_begin(0, 0);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
{
|
{
|
||||||
Arch arch = dmn_arch_from_thread(thread);
|
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);
|
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
|
||||||
dmn_thread_read_reg_block(thread, reg_block);
|
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);
|
scratch_end(scratch);
|
||||||
return result;
|
return result;
|
||||||
@@ -165,11 +167,11 @@ dmn_process_read_cstring(Arena *arena, DMN_Handle process, U64 addr)
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
String8List block_list = {0};
|
String8List block_list = {0};
|
||||||
for(U64 cursor = addr, stride = 256; ; cursor += stride)
|
for(U64 cursor = addr, stride = 256;; cursor += stride)
|
||||||
{
|
{
|
||||||
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
|
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
|
||||||
U64 read_size = dmn_process_read(process, r1u64(cursor, cursor + stride), raw_block);
|
U64 read_size = dmn_process_read(process, r1u64(cursor, cursor + stride), raw_block);
|
||||||
String8 block = str8_cstring_capped(raw_block, raw_block + read_size);
|
String8 block = str8_cstring_capped(raw_block, raw_block + read_size);
|
||||||
str8_list_push(scratch.arena, &block_list, block);
|
str8_list_push(scratch.arena, &block_list, block);
|
||||||
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
|
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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_begin(void);
|
||||||
internal void dmn_ctrl_exclusive_access_end(void);
|
internal void dmn_ctrl_exclusive_access_end(void);
|
||||||
#define DMN_CtrlExclusiveAccessScope DeferLoop(dmn_ctrl_exclusive_access_begin(), dmn_ctrl_exclusive_access_end())
|
#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_attach(DMN_CtrlCtx *ctx, U32 pid);
|
||||||
internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code);
|
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);
|
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_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_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_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 U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
|
||||||
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
|
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)
|
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||||
|
|||||||
@@ -753,7 +753,8 @@ dmn_lnx_thread_alloc(DMN_LNX_Process *process, DMN_LNX_ThreadState thread_state,
|
|||||||
}
|
}
|
||||||
else
|
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);
|
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
|
internal U64
|
||||||
dmn_lnx_thread_read_ip(DMN_LNX_Thread *thread)
|
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
|
internal U64
|
||||||
dmn_lnx_thread_read_sp(DMN_LNX_Thread *thread)
|
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
|
internal void
|
||||||
dmn_lnx_thread_write_ip(DMN_LNX_Thread *thread, U64 ip)
|
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;
|
thread->is_reg_block_dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp)
|
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;
|
thread->is_reg_block_dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1166,7 +1173,7 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
|
|||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
|
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
|
||||||
REGS_RegBlockX64 *dst = thread->reg_block;
|
X64_RegBlock *dst = thread->reg_block;
|
||||||
|
|
||||||
// general purpose registers
|
// general purpose registers
|
||||||
{
|
{
|
||||||
@@ -1364,7 +1371,7 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
|
|||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
|
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
|
||||||
REGS_RegBlockX64 *src = thread->reg_block;
|
X64_RegBlock *src = thread->reg_block;
|
||||||
|
|
||||||
// general purpose registers
|
// 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_Null: {} break;
|
||||||
case Arch_x64:
|
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; }
|
if(is_on) { reg_block->rflags.u64 |= X64_RFlag_Trap; }
|
||||||
else { reg_block->rflags.u64 &= ~X64_RFlag_Trap; }
|
else { reg_block->rflags.u64 &= ~X64_RFlag_Trap; }
|
||||||
thread->is_reg_block_dirty = 1;
|
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_Null: {} break;
|
||||||
case Arch_x64:
|
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)
|
if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B0)
|
||||||
{
|
{
|
||||||
address = regs_x64->dr0.u64;
|
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_Null: {} break;
|
||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
REGS_RegBlockX64 *reg_block = thread->reg_block;
|
X64_RegBlock *reg_block = thread->reg_block;
|
||||||
U64 dtv_pointer = 0;
|
U64 dtv_pointer = 0;
|
||||||
if(dmn_lnx_read_struct(thread->process->fd, reg_block->fsbase.u64 + 8, &dtv_pointer))
|
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);
|
DMN_LNX_Thread *thread = dmn_lnx_thread_from_handle(thread_handle);
|
||||||
if(thread)
|
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);
|
MemoryCopy(reg_block, thread->reg_block, reg_block_size);
|
||||||
}
|
}
|
||||||
result = 1;
|
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);
|
DMN_LNX_Thread *thread = dmn_lnx_thread_from_handle(thread_handle);
|
||||||
if(thread)
|
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);
|
MemoryCopy(thread->reg_block, reg_block, reg_block_size);
|
||||||
thread->is_reg_block_dirty = 1;
|
thread->is_reg_block_dirty = 1;
|
||||||
result = 1;
|
result = 1;
|
||||||
@@ -3148,4 +3157,3 @@ dmn_process_iter_end(DMN_ProcessIter *iter)
|
|||||||
}
|
}
|
||||||
MemoryZeroStruct(iter);
|
MemoryZeroStruct(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+183
-173
@@ -606,7 +606,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
|||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
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
|
//- rjf: unpack info about available features
|
||||||
U32 feature_mask = GetEnabledXStateFeatures();
|
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;
|
DWORD64 xstate_mask = 0;
|
||||||
GetXStateFeaturesMask(ctx, &xstate_mask);
|
GetXStateFeaturesMask(ctx, &xstate_mask);
|
||||||
|
|
||||||
//- rjf: convert context -> REGS_RegBlockX64
|
//- rjf: convert context -> X64_RegBlock
|
||||||
XSAVE_FORMAT *xsave = &ctx->FltSave;
|
XSAVE_FORMAT *xsave = &ctx->FltSave;
|
||||||
dst->rax.u64 = ctx->Rax;
|
dst->rax = ctx->Rax;
|
||||||
dst->rcx.u64 = ctx->Rcx;
|
dst->rcx = ctx->Rcx;
|
||||||
dst->rdx.u64 = ctx->Rdx;
|
dst->rdx = ctx->Rdx;
|
||||||
dst->rbx.u64 = ctx->Rbx;
|
dst->rbx = ctx->Rbx;
|
||||||
dst->rsp.u64 = ctx->Rsp;
|
dst->rsp = ctx->Rsp;
|
||||||
dst->rbp.u64 = ctx->Rbp;
|
dst->rbp = ctx->Rbp;
|
||||||
dst->rsi.u64 = ctx->Rsi;
|
dst->rsi = ctx->Rsi;
|
||||||
dst->rdi.u64 = ctx->Rdi;
|
dst->rdi = ctx->Rdi;
|
||||||
dst->r8.u64 = ctx->R8;
|
dst->r8 = ctx->R8;
|
||||||
dst->r9.u64 = ctx->R9;
|
dst->r9 = ctx->R9;
|
||||||
dst->r10.u64 = ctx->R10;
|
dst->r10 = ctx->R10;
|
||||||
dst->r11.u64 = ctx->R11;
|
dst->r11 = ctx->R11;
|
||||||
dst->r12.u64 = ctx->R12;
|
dst->r12 = ctx->R12;
|
||||||
dst->r13.u64 = ctx->R13;
|
dst->r13 = ctx->R13;
|
||||||
dst->r14.u64 = ctx->R14;
|
dst->r14 = ctx->R14;
|
||||||
dst->r15.u64 = ctx->R15;
|
dst->r15 = ctx->R15;
|
||||||
dst->rip.u64 = ctx->Rip;
|
dst->rip = ctx->Rip;
|
||||||
dst->cs.u16 = ctx->SegCs;
|
dst->cs = ctx->SegCs;
|
||||||
dst->ds.u16 = ctx->SegDs;
|
dst->ds = ctx->SegDs;
|
||||||
dst->es.u16 = ctx->SegEs;
|
dst->es = ctx->SegEs;
|
||||||
dst->fs.u16 = ctx->SegFs;
|
dst->fs = ctx->SegFs;
|
||||||
dst->gs.u16 = ctx->SegGs;
|
dst->gs = ctx->SegGs;
|
||||||
dst->ss.u16 = ctx->SegSs;
|
dst->ss = ctx->SegSs;
|
||||||
dst->dr0.u64 = ctx->Dr0;
|
dst->dr0 = ctx->Dr0;
|
||||||
dst->dr1.u64 = ctx->Dr1;
|
dst->dr1 = ctx->Dr1;
|
||||||
dst->dr2.u64 = ctx->Dr2;
|
dst->dr2 = ctx->Dr2;
|
||||||
dst->dr3.u64 = ctx->Dr3;
|
dst->dr3 = ctx->Dr3;
|
||||||
dst->dr6.u64 = ctx->Dr6;
|
dst->dr6 = ctx->Dr6;
|
||||||
dst->dr7.u64 = ctx->Dr7;
|
dst->dr7 = ctx->Dr7;
|
||||||
// NOTE(rjf): this bit is "supposed to always be 1", according to old info.
|
// NOTE(rjf): this bit is "supposed to always be 1", according to old info.
|
||||||
// may need to be investigated.
|
// may need to be investigated.
|
||||||
dst->rflags.u64 = ctx->EFlags | 0x2;
|
dst->rflags = ctx->EFlags | 0x2;
|
||||||
dst->fcw.u16 = xsave->ControlWord;
|
dst->fcw = xsave->ControlWord;
|
||||||
dst->fsw.u16 = xsave->StatusWord;
|
dst->fsw = xsave->StatusWord;
|
||||||
dst->ftw = xsave->TagWord;
|
dst->ftw = xsave->TagWord;
|
||||||
dst->fop.u16 = xsave->ErrorOpcode;
|
dst->fop = xsave->ErrorOpcode;
|
||||||
MemoryCopy(&dst->fip.u64, &xsave->ErrorOffset, sizeof(U64));
|
MemoryCopy(&dst->fip, &xsave->ErrorOffset, sizeof(U64));
|
||||||
MemoryCopy(&dst->fdp.u64, &xsave->DataOffset, sizeof(U64));
|
MemoryCopy(&dst->fdp, &xsave->DataOffset, sizeof(U64));
|
||||||
dst->mxcsr.u32 = xsave->MxCsr;
|
dst->mxcsr = xsave->MxCsr;
|
||||||
dst->mxcsr_mask.u32 = xsave->MxCsr_Mask;
|
dst->mxcsr_mask = xsave->MxCsr_Mask;
|
||||||
{
|
{
|
||||||
M128A *float_s = xsave->FloatRegisters;
|
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)
|
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||||
{
|
{
|
||||||
MemoryCopy(float_d, float_s, sizeof(*float_d));
|
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
|
// SSE registers are always available in x64
|
||||||
{
|
{
|
||||||
M128A *xmm_s = xsave->XmmRegisters;
|
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)
|
for(U32 n = 0; n < 16; n += 1, xmm_s += 1, zmm_d += 1)
|
||||||
{
|
{
|
||||||
MemoryCopy(zmm_d, xmm_s, sizeof(*xmm_s));
|
MemoryCopy(zmm_d, xmm_s, sizeof(*xmm_s));
|
||||||
@@ -713,72 +713,77 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
|||||||
if(xstate_mask & XSTATE_MASK_AVX)
|
if(xstate_mask & XSTATE_MASK_AVX)
|
||||||
{
|
{
|
||||||
DWORD avx_length = 0;
|
DWORD avx_length = 0;
|
||||||
U8* avx_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
|
U8 *avx_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
|
||||||
Assert(avx_length == 16 * sizeof(REGS_Reg128));
|
if(avx_length == 16 * sizeof(U128))
|
||||||
|
|
||||||
REGS_Reg512 *zmm_d = &dst->zmm0;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, avx_s += sizeof(REGS_Reg128), zmm_d += 1)
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
REGS_Reg512 *zmm_d = &dst->zmm0;
|
U512 *zmm_d = &dst->zmm0;
|
||||||
for(U32 n = 0; n < 16; n += 1, zmm_d += 1)
|
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
|
// AVX-512
|
||||||
if(xstate_mask & XSTATE_MASK_AVX512)
|
if(xstate_mask & XSTATE_MASK_AVX512)
|
||||||
{
|
{
|
||||||
|
// rjf: kmask
|
||||||
DWORD kmask_length = 0;
|
DWORD kmask_length = 0;
|
||||||
U64* kmask_s = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
|
U64 *kmask_s = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
|
||||||
Assert(kmask_length == 8 * sizeof(U64));
|
if(kmask_length == 8 * sizeof(U64))
|
||||||
|
|
||||||
REGS_Reg64 *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));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rjf: zmmh
|
||||||
DWORD avx512h_length = 0;
|
DWORD avx512h_length = 0;
|
||||||
U8* avx512h_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
|
U8 *avx512h_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
|
||||||
Assert(avx512h_length == 16 * sizeof(REGS_Reg256));
|
if(avx512h_length == 16 * sizeof(U256))
|
||||||
|
|
||||||
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));
|
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;
|
DWORD avx512_length = 0;
|
||||||
U8* avx512_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
|
U8 *avx512_s = (U8 *)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
|
||||||
Assert(avx512_length == 16 * sizeof(REGS_Reg512));
|
if(avx512_length == 16 * sizeof(U512))
|
||||||
|
|
||||||
REGS_Reg512 *zmm_d = &dst->zmm16;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, avx512_s += sizeof(REGS_Reg512), zmm_d += 1)
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
REGS_Reg64 *kmask_d = &dst->k0;
|
U64 *kmask_d = &dst->k0;
|
||||||
for(U32 n = 0; n < 8; n += 1, kmask_d += 1)
|
for(U32 n = 0; n < 8; n += 1, kmask_d += 1)
|
||||||
{
|
{
|
||||||
MemoryZero(kmask_d, sizeof(*kmask_d));
|
MemoryZero(kmask_d, sizeof(*kmask_d));
|
||||||
}
|
}
|
||||||
|
U512 *zmmh_d = &dst->zmm0;
|
||||||
REGS_Reg512 *zmmh_d = &dst->zmm0;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, zmmh_d += 1)
|
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));
|
||||||
}
|
}
|
||||||
|
U512 *zmm_d = &dst->zmm16;
|
||||||
REGS_Reg512 *zmm_d = &dst->zmm16;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, zmm_d += 1)
|
for(U32 n = 0; n < 16; n += 1, zmm_d += 1)
|
||||||
{
|
{
|
||||||
MemoryZero(zmm_d, sizeof(*zmm_d));
|
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);
|
XSAVE_CET_U_FORMAT *cet = LocateXStateFeature(ctx, XSTATE_CET_U, &cet_length);
|
||||||
if (cet_length == sizeof(*cet))
|
if (cet_length == sizeof(*cet))
|
||||||
{
|
{
|
||||||
dst->cetmsr.u64 = cet->Ia32CetUMsr;
|
dst->cetmsr = cet->Ia32CetUMsr;
|
||||||
dst->cetssp.u64 = cet->Ia32Pl3SspMsr;
|
dst->cetssp = cet->Ia32Pl3SspMsr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,7 +833,7 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
|||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
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
|
//- rjf: unpack info about available features
|
||||||
U32 feature_mask = GetEnabledXStateFeatures();
|
U32 feature_mask = GetEnabledXStateFeatures();
|
||||||
@@ -860,49 +865,49 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- rjf: convert REGS_RegBlockX64 -> CONTEXT
|
//- rjf: convert X64_RegBlock -> CONTEXT
|
||||||
XSAVE_FORMAT *fxsave = &ctx->FltSave;
|
XSAVE_FORMAT *fxsave = &ctx->FltSave;
|
||||||
ctx->ContextFlags = ctx_flags;
|
ctx->ContextFlags = ctx_flags;
|
||||||
ctx->MxCsr = src->mxcsr.u32 & src->mxcsr_mask.u32;
|
ctx->MxCsr = src->mxcsr & src->mxcsr_mask;
|
||||||
ctx->Rax = src->rax.u64;
|
ctx->Rax = src->rax;
|
||||||
ctx->Rcx = src->rcx.u64;
|
ctx->Rcx = src->rcx;
|
||||||
ctx->Rdx = src->rdx.u64;
|
ctx->Rdx = src->rdx;
|
||||||
ctx->Rbx = src->rbx.u64;
|
ctx->Rbx = src->rbx;
|
||||||
ctx->Rsp = src->rsp.u64;
|
ctx->Rsp = src->rsp;
|
||||||
ctx->Rbp = src->rbp.u64;
|
ctx->Rbp = src->rbp;
|
||||||
ctx->Rsi = src->rsi.u64;
|
ctx->Rsi = src->rsi;
|
||||||
ctx->Rdi = src->rdi.u64;
|
ctx->Rdi = src->rdi;
|
||||||
ctx->R8 = src->r8.u64;
|
ctx->R8 = src->r8;
|
||||||
ctx->R9 = src->r9.u64;
|
ctx->R9 = src->r9;
|
||||||
ctx->R10 = src->r10.u64;
|
ctx->R10 = src->r10;
|
||||||
ctx->R11 = src->r11.u64;
|
ctx->R11 = src->r11;
|
||||||
ctx->R12 = src->r12.u64;
|
ctx->R12 = src->r12;
|
||||||
ctx->R13 = src->r13.u64;
|
ctx->R13 = src->r13;
|
||||||
ctx->R14 = src->r14.u64;
|
ctx->R14 = src->r14;
|
||||||
ctx->R15 = src->r15.u64;
|
ctx->R15 = src->r15;
|
||||||
ctx->Rip = src->rip.u64;
|
ctx->Rip = src->rip;
|
||||||
ctx->SegCs = src->cs.u16;
|
ctx->SegCs = src->cs;
|
||||||
ctx->SegDs = src->ds.u16;
|
ctx->SegDs = src->ds;
|
||||||
ctx->SegEs = src->es.u16;
|
ctx->SegEs = src->es;
|
||||||
ctx->SegFs = src->fs.u16;
|
ctx->SegFs = src->fs;
|
||||||
ctx->SegGs = src->gs.u16;
|
ctx->SegGs = src->gs;
|
||||||
ctx->SegSs = src->ss.u16;
|
ctx->SegSs = src->ss;
|
||||||
ctx->Dr0 = src->dr0.u64;
|
ctx->Dr0 = src->dr0;
|
||||||
ctx->Dr1 = src->dr1.u64;
|
ctx->Dr1 = src->dr1;
|
||||||
ctx->Dr2 = src->dr2.u64;
|
ctx->Dr2 = src->dr2;
|
||||||
ctx->Dr3 = src->dr3.u64;
|
ctx->Dr3 = src->dr3;
|
||||||
ctx->Dr6 = src->dr6.u64;
|
ctx->Dr6 = src->dr6;
|
||||||
ctx->Dr7 = src->dr7.u64;
|
ctx->Dr7 = src->dr7;
|
||||||
ctx->EFlags = src->rflags.u64;
|
ctx->EFlags = src->rflags;
|
||||||
fxsave->ControlWord = src->fcw.u16;
|
fxsave->ControlWord = src->fcw;
|
||||||
fxsave->StatusWord = src->fsw.u16;
|
fxsave->StatusWord = src->fsw;
|
||||||
fxsave->TagWord = src->ftw;
|
fxsave->TagWord = src->ftw;
|
||||||
fxsave->ErrorOpcode = src->fop.u16;
|
fxsave->ErrorOpcode = src->fop;
|
||||||
MemoryCopy(&fxsave->ErrorOffset, &src->fip.u64, sizeof(U64));
|
MemoryCopy(&fxsave->ErrorOffset, &src->fip, sizeof(U64));
|
||||||
MemoryCopy(&fxsave->DataOffset, &src->fdp.u64, sizeof(U64));
|
MemoryCopy(&fxsave->DataOffset, &src->fdp, sizeof(U64));
|
||||||
{
|
{
|
||||||
M128A *float_d = fxsave->FloatRegisters;
|
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)
|
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||||
{
|
{
|
||||||
MemoryCopy(float_d, float_s, 10);
|
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
|
// SSE registers are always available in x64
|
||||||
{
|
{
|
||||||
M128A *xmm_d = fxsave->XmmRegisters;
|
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)
|
for(U32 n = 0; n < 16; n += 1, xmm_d += 1, zmm_s += 1)
|
||||||
{
|
{
|
||||||
MemoryCopy(xmm_d, zmm_s, sizeof(*xmm_d));
|
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;
|
DWORD avx_length = 0;
|
||||||
U8* avx_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
|
U8* avx_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
|
||||||
Assert(avx_length == 16 * sizeof(REGS_Reg128));
|
if(avx_length == 16 * sizeof(U128))
|
||||||
|
|
||||||
REGS_Reg512 *zmm_s = &src->zmm0;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, avx_d += sizeof(REGS_Reg128), zmm_s += 1)
|
|
||||||
{
|
{
|
||||||
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;
|
DWORD kmask_length = 0;
|
||||||
U64* kmask_d = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
|
U64* kmask_d = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
|
||||||
Assert(kmask_length == 8 * sizeof(*kmask_d));
|
if(kmask_length == 8 * sizeof(*kmask_d))
|
||||||
|
|
||||||
REGS_Reg64 *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));
|
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;
|
DWORD avx512h_length = 0;
|
||||||
U8* avx512h_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
|
U8* avx512h_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
|
||||||
Assert(avx512h_length == 16 * sizeof(REGS_Reg256));
|
if(avx512h_length == 16 * sizeof(U256))
|
||||||
|
|
||||||
REGS_Reg512 *zmmh_s = &src->zmm0;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, avx512h_d += sizeof(REGS_Reg256), zmmh_s += 1)
|
|
||||||
{
|
{
|
||||||
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;
|
DWORD avx512_length = 0;
|
||||||
U8* avx512_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
|
U8* avx512_d = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
|
||||||
Assert(avx512_length == 16 * sizeof(REGS_Reg512));
|
if(avx512_length == 16 * sizeof(U512))
|
||||||
|
|
||||||
REGS_Reg512 *zmm_s = &src->zmm16;
|
|
||||||
for(U32 n = 0; n < 16; n += 1, avx512_d += sizeof(REGS_Reg512), zmm_s += 1)
|
|
||||||
{
|
{
|
||||||
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
|
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);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
U32 result = 0;
|
U32 result = 0;
|
||||||
@@ -1133,21 +1142,21 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
|
|||||||
}
|
}
|
||||||
BOOL inherit_handles = 0;
|
BOOL inherit_handles = 0;
|
||||||
STARTUPINFOW startup_info = {sizeof(startup_info)};
|
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];
|
HANDLE stdout_handle = (HANDLE)params->stdout_file.u64[0];
|
||||||
startup_info.hStdOutput = stdout_handle;
|
startup_info.hStdOutput = stdout_handle;
|
||||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
inherit_handles = 1;
|
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];
|
HANDLE stderr_handle = (HANDLE)params->stderr_file.u64[0];
|
||||||
startup_info.hStdError = stderr_handle;
|
startup_info.hStdError = stderr_handle;
|
||||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
inherit_handles = 1;
|
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];
|
HANDLE stdin_handle = (HANDLE)params->stdin_file.u64[0];
|
||||||
startup_info.hStdInput = stdin_handle;
|
startup_info.hStdInput = stdin_handle;
|
||||||
@@ -1502,7 +1511,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
//- rjf: x64
|
//- rjf: x64
|
||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
REGS_RegBlockX64 regs = {0};
|
X64_RegBlock regs = {0};
|
||||||
dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s);
|
dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s);
|
||||||
{
|
{
|
||||||
U64 trap_idx = 0;
|
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)
|
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];
|
DMN_Trap *trap = &n->v[n_idx];
|
||||||
REGS_Reg64 *addr_reg = ®s.dr0;
|
U64 *addr_reg = ®s.dr0;
|
||||||
switch(trap_idx)
|
switch(trap_idx)
|
||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
@@ -1520,12 +1529,12 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
case 2:{addr_reg = ®s.dr2;}break;
|
case 2:{addr_reg = ®s.dr2;}break;
|
||||||
case 3:{addr_reg = ®s.dr3;}break;
|
case 3:{addr_reg = ®s.dr3;}break;
|
||||||
}
|
}
|
||||||
addr_reg->u64 = trap->vaddr;
|
addr_reg[0] = trap->vaddr;
|
||||||
regs.dr7.u64 |= bit9|bit10|bit11;
|
regs.dr7 |= bit9|bit10|bit11;
|
||||||
regs.dr7.u64 |= (1ull << (trap_idx*2));
|
regs.dr7 |= (1ull << (trap_idx*2));
|
||||||
// NOTE(rjf): global-enable regs.dr7.u64 |= (1ull << (trap_idx*2+1));
|
// 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)(bit17|bit18|bit19|bit20) << (trap_idx*4));
|
||||||
regs.dr7.u64 &= ~((U64)(bit15|bit16));
|
regs.dr7 &= ~((U64)(bit15|bit16));
|
||||||
switch(trap->flags)
|
switch(trap->flags)
|
||||||
{
|
{
|
||||||
case DMN_TrapFlag_BreakOnExecute:
|
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:
|
||||||
case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
|
case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
|
||||||
{
|
{
|
||||||
regs.dr7.u64 |= ((U64)bit17) << (trap_idx*4);
|
regs.dr7 |= ((U64)bit17) << (trap_idx*4);
|
||||||
}break;
|
}break;
|
||||||
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
|
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
|
||||||
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite:
|
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite:
|
||||||
case DMN_TrapFlag_BreakOnRead:
|
case DMN_TrapFlag_BreakOnRead:
|
||||||
{
|
{
|
||||||
regs.dr7.u64 |= (((U64)bit17) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit17) << (trap_idx*4));
|
||||||
regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit18) << (trap_idx*4));
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
switch(trap->size)
|
switch(trap->size)
|
||||||
@@ -1549,16 +1558,16 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
default:{}break;
|
default:{}break;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit19) << (trap_idx*4));
|
||||||
}break;
|
}break;
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit19) << (trap_idx*4));
|
||||||
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit20) << (trap_idx*4));
|
||||||
}break;
|
}break;
|
||||||
case 8:
|
case 8:
|
||||||
{
|
{
|
||||||
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
|
regs.dr7 |= (((U64)bit20) << (trap_idx*4));
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1663,7 +1672,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
B32 do_threads_resume = 1;
|
B32 do_threads_resume = 1;
|
||||||
DMN_W32_EntityNode *first_ran_thread = 0;
|
DMN_W32_EntityNode *first_ran_thread = 0;
|
||||||
DMN_W32_EntityNode *last_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};
|
String8List debug_strings = {0};
|
||||||
DMN_Event *debug_strings_event = 0;
|
DMN_Event *debug_strings_event = 0;
|
||||||
for(B32 keep_going = 1; keep_going;)
|
for(B32 keep_going = 1; keep_going;)
|
||||||
@@ -2178,11 +2187,12 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Temp temp = temp_begin(scratch.arena);
|
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);
|
void *regs_block = push_array(scratch.arena, U8, regs_block_size);
|
||||||
if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block))
|
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);
|
dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block);
|
||||||
}
|
}
|
||||||
temp_end(temp);
|
temp_end(temp);
|
||||||
@@ -2287,16 +2297,16 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
default:{NotImplemented;}break;
|
default:{NotImplemented;}break;
|
||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
REGS_RegBlockX64 regs = {0};
|
X64_RegBlock regs = {0};
|
||||||
dmn_w32_thread_read_reg_block(thread->arch, thread->handle, ®s);
|
dmn_w32_thread_read_reg_block(thread->arch, thread->handle, ®s);
|
||||||
if(regs.dr6.u64 & 0xF)
|
if(regs.dr6 & 0xF)
|
||||||
{
|
{
|
||||||
e->kind = DMN_EventKind_Breakpoint;
|
e->kind = DMN_EventKind_Breakpoint;
|
||||||
if(0){}
|
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 & (1ull<<0) && regs.dr6 & (1ull<<0)) { flagged_trap_idx = 0; e->address = regs.dr0; }
|
||||||
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 & (1ull<<2) && regs.dr6 & (1ull<<1)) { flagged_trap_idx = 1; e->address = regs.dr1; }
|
||||||
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 & (1ull<<4) && regs.dr6 & (1ull<<2)) { flagged_trap_idx = 2; e->address = regs.dr2; }
|
||||||
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<<8) && regs.dr6 & (1ull<<3)) { flagged_trap_idx = 3; e->address = regs.dr3; }
|
||||||
}
|
}
|
||||||
}break;
|
}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
|
//- 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;
|
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->kind != DMN_W32_EntityKind_Thread) { continue; }
|
||||||
if(thread->thread.last_name_hash == 0 ||
|
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};
|
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->thread = dmn_w32_handle_from_entity(thread);
|
||||||
e->string = push_str8_copy(arena, name);
|
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;
|
thread->thread.last_name_hash = name_hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2684,9 +2694,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
//- rjf: x64
|
//- rjf: x64
|
||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
REGS_RegBlockX64 regs = {0};
|
X64_RegBlock regs = {0};
|
||||||
dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s);
|
dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s);
|
||||||
regs.dr7.u64 = 0;
|
regs.dr7 = 0;
|
||||||
dmn_w32_thread_write_reg_block(child->arch, child->handle, ®s);
|
dmn_w32_thread_write_reg_block(child->arch, child->handle, ®s);
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
@@ -2897,7 +2907,7 @@ dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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
|
DMN_AccessScope
|
||||||
{
|
{
|
||||||
@@ -2907,11 +2917,11 @@ dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFla
|
|||||||
switch(flags)
|
switch(flags)
|
||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
case OS_AccessFlag_Execute:{new_flags = PAGE_EXECUTE;}break;
|
case AccessFlag_Execute:{new_flags = PAGE_EXECUTE;}break;
|
||||||
case OS_AccessFlag_Execute|OS_AccessFlag_Read:{new_flags = PAGE_EXECUTE_READ;}break;
|
case AccessFlag_Execute|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 AccessFlag_Execute|AccessFlag_Read|AccessFlag_Write:{new_flags = PAGE_EXECUTE_READWRITE;}break;
|
||||||
case OS_AccessFlag_Read:{new_flags = PAGE_READONLY;}break;
|
case AccessFlag_Read:{new_flags = PAGE_READONLY;}break;
|
||||||
case OS_AccessFlag_Read|OS_AccessFlag_Write:{new_flags = PAGE_READWRITE;}break;
|
case AccessFlag_Read|AccessFlag_Write:{new_flags = PAGE_READWRITE;}break;
|
||||||
}
|
}
|
||||||
VirtualProtectEx(process_entity->handle, (void *)vaddr, size, new_flags, &old_flags);
|
VirtualProtectEx(process_entity->handle, (void *)vaddr, size, new_flags, &old_flags);
|
||||||
}
|
}
|
||||||
|
|||||||
+119
-127
@@ -294,150 +294,142 @@ dasm_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_o
|
|||||||
//- rjf: data * arch * addr * dbg -> decode artifacts
|
//- rjf: data * arch * addr * dbg -> decode artifacts
|
||||||
DASM_LineChunkList line_list = {0};
|
DASM_LineChunkList line_list = {0};
|
||||||
String8List inst_strings = {0};
|
String8List inst_strings = {0};
|
||||||
switch(params.arch)
|
|
||||||
{
|
{
|
||||||
default:{}break;
|
// rjf: disassemble
|
||||||
|
RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
|
||||||
//- rjf: x86/x64 decoding
|
RDI_Line *last_line = 0;
|
||||||
case Arch_x64:
|
for(U64 off = 0; off < data.size;)
|
||||||
case Arch_x86:
|
|
||||||
{
|
{
|
||||||
// rjf: disassemble
|
// rjf: disassemble one instruction
|
||||||
RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
|
DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax);
|
||||||
RDI_Line *last_line = 0;
|
if(inst.size == 0)
|
||||||
for(U64 off = 0; off < data.size;)
|
|
||||||
{
|
{
|
||||||
// rjf: disassemble one instruction
|
break;
|
||||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax);
|
}
|
||||||
if(inst.size == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rjf: push strings derived from voff -> line info
|
// rjf: push strings derived from voff -> line info
|
||||||
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines) &&
|
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines) &&
|
||||||
rdi != &rdi_parsed_nil)
|
rdi != &rdi_parsed_nil)
|
||||||
|
{
|
||||||
|
U64 voff = (params.vaddr+off) - params.base_vaddr;
|
||||||
|
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
|
||||||
|
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
|
||||||
|
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
|
||||||
|
RDI_ParsedLineTable unit_line_info = {0};
|
||||||
|
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
|
||||||
|
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff);
|
||||||
|
if(line_info_idx < unit_line_info.count)
|
||||||
{
|
{
|
||||||
U64 voff = (params.vaddr+off) - params.base_vaddr;
|
RDI_Line *line = &unit_line_info.lines[line_info_idx];
|
||||||
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
|
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
|
||||||
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
|
String8 file_normalized_full_path = {0};
|
||||||
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
|
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
|
||||||
RDI_ParsedLineTable unit_line_info = {0};
|
if(file != last_file)
|
||||||
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
|
|
||||||
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff);
|
|
||||||
if(line_info_idx < unit_line_info.count)
|
|
||||||
{
|
{
|
||||||
RDI_Line *line = &unit_line_info.lines[line_info_idx];
|
if(params.style_flags & DASM_StyleFlag_SourceFilesNames &&
|
||||||
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
|
file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0)
|
||||||
String8 file_normalized_full_path = {0};
|
|
||||||
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
|
|
||||||
if(file != last_file)
|
|
||||||
{
|
{
|
||||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames &&
|
String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path);
|
||||||
file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0)
|
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||||
{
|
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||||
String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path);
|
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
|
||||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
|
||||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
|
||||||
}
|
|
||||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0)
|
|
||||||
{
|
|
||||||
String8 inst_string = str8_lit(">");
|
|
||||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
|
||||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
|
||||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
|
||||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
|
||||||
}
|
|
||||||
last_file = file;
|
|
||||||
}
|
}
|
||||||
if(line && line != last_line && file->normal_full_path_string_idx != 0 &&
|
if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0)
|
||||||
params.style_flags & DASM_StyleFlag_SourceLines &&
|
|
||||||
file_normalized_full_path.size != 0)
|
|
||||||
{
|
{
|
||||||
FileProperties props = os_properties_from_file_path(file_normalized_full_path);
|
String8 inst_string = str8_lit(">");
|
||||||
if(props.modified != 0)
|
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||||
|
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||||
|
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||||
|
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||||
|
}
|
||||||
|
last_file = file;
|
||||||
|
}
|
||||||
|
if(line && line != last_line && file->normal_full_path_string_idx != 0 &&
|
||||||
|
params.style_flags & DASM_StyleFlag_SourceLines &&
|
||||||
|
file_normalized_full_path.size != 0)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
// need frontend to communicate path remapping info to this layer
|
||||||
|
C_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
|
||||||
|
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
|
||||||
|
U64 endt_us = max_U64;
|
||||||
|
U128 hash = {0};
|
||||||
|
TXT_TextInfo text_info = txt_text_info_from_key_lang(access, key, lang_kind, &hash);
|
||||||
|
stale = (stale || u128_match(hash, u128_zero()));
|
||||||
|
if(0 < line->line_num && line->line_num < text_info.lines_count)
|
||||||
{
|
{
|
||||||
// TODO(rjf): need redirection path - this may map to a different path on the local machine,
|
String8 data = c_data_from_hash(access, hash);
|
||||||
// need frontend to communicate path remapping info to this layer
|
String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1]));
|
||||||
C_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
|
if(line_text.size != 0)
|
||||||
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
|
|
||||||
U64 endt_us = max_U64;
|
|
||||||
U128 hash = {0};
|
|
||||||
TXT_TextInfo text_info = txt_text_info_from_key_lang(access, key, lang_kind, &hash);
|
|
||||||
stale = (stale || u128_match(hash, u128_zero()));
|
|
||||||
if(0 < line->line_num && line->line_num < text_info.lines_count)
|
|
||||||
{
|
{
|
||||||
String8 data = c_data_from_hash(access, hash);
|
String8 inst_string = push_str8f(scratch.arena, "> %S", line_text);
|
||||||
String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1]));
|
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||||
if(line_text.size != 0)
|
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||||
{
|
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||||
String8 inst_string = push_str8f(scratch.arena, "> %S", line_text);
|
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
|
||||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
|
||||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
|
||||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_line = line;
|
|
||||||
}
|
}
|
||||||
|
last_line = line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: push line
|
|
||||||
String8 addr_part = {0};
|
|
||||||
if(params.style_flags & DASM_StyleFlag_Addresses)
|
|
||||||
{
|
|
||||||
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off);
|
|
||||||
}
|
|
||||||
String8 code_bytes_part = {0};
|
|
||||||
if(params.style_flags & DASM_StyleFlag_CodeBytes)
|
|
||||||
{
|
|
||||||
String8List code_bytes_strings = {0};
|
|
||||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
|
|
||||||
for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1)
|
|
||||||
{
|
|
||||||
if(byte_idx < inst.size)
|
|
||||||
{
|
|
||||||
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : "");
|
|
||||||
}
|
|
||||||
else if(byte_idx < 8)
|
|
||||||
{
|
|
||||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
|
||||||
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
|
|
||||||
}
|
|
||||||
String8 symbol_part = {0};
|
|
||||||
if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
|
||||||
{
|
|
||||||
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr);
|
|
||||||
if(scope_idx != 0)
|
|
||||||
{
|
|
||||||
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
|
|
||||||
RDI_U32 procedure_idx = scope->proc_idx;
|
|
||||||
RDI_Symbol *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_idx);
|
|
||||||
String8 procedure_name = {0};
|
|
||||||
procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size);
|
|
||||||
if(procedure_name.size != 0)
|
|
||||||
{
|
|
||||||
symbol_part = push_str8f(scratch.arena, " (%S)", procedure_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part);
|
|
||||||
DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count,
|
|
||||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
|
||||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line);
|
|
||||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
|
||||||
|
|
||||||
// rjf: increment
|
|
||||||
off += inst.size;
|
|
||||||
}
|
}
|
||||||
}break;
|
|
||||||
|
// rjf: push line
|
||||||
|
String8 addr_part = {0};
|
||||||
|
if(params.style_flags & DASM_StyleFlag_Addresses)
|
||||||
|
{
|
||||||
|
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off);
|
||||||
|
}
|
||||||
|
String8 code_bytes_part = {0};
|
||||||
|
if(params.style_flags & DASM_StyleFlag_CodeBytes)
|
||||||
|
{
|
||||||
|
String8List code_bytes_strings = {0};
|
||||||
|
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
|
||||||
|
for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1)
|
||||||
|
{
|
||||||
|
if(byte_idx < inst.size)
|
||||||
|
{
|
||||||
|
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : "");
|
||||||
|
}
|
||||||
|
else if(byte_idx < 8)
|
||||||
|
{
|
||||||
|
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
||||||
|
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
|
||||||
|
}
|
||||||
|
String8 symbol_part = {0};
|
||||||
|
if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||||
|
{
|
||||||
|
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr);
|
||||||
|
if(scope_idx != 0)
|
||||||
|
{
|
||||||
|
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
|
||||||
|
RDI_U32 procedure_idx = scope->proc_idx;
|
||||||
|
RDI_Symbol *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_idx);
|
||||||
|
String8 procedure_name = {0};
|
||||||
|
procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size);
|
||||||
|
if(procedure_name.size != 0)
|
||||||
|
{
|
||||||
|
symbol_part = push_str8f(scratch.arena, " (%S)", procedure_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part);
|
||||||
|
DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||||
|
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||||
|
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line);
|
||||||
|
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||||
|
|
||||||
|
// rjf: increment
|
||||||
|
off += inst.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//- rjf: artifacts -> value bundle
|
//- rjf: artifacts -> value bundle
|
||||||
|
|||||||
+1
-1
@@ -226,7 +226,7 @@ dr_begin_frame(FNT_Tag icon_font)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
r_window_submit(os_window, r_window, &bucket->passes);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ internal Vec2F32 dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs);
|
|||||||
// (Frame boundaries & bucket submission)
|
// (Frame boundaries & bucket submission)
|
||||||
|
|
||||||
internal void dr_begin_frame(FNT_Tag icon_font);
|
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
|
//~ rjf: Bucket Construction & Selection API
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: Generated Code
|
||||||
|
|
||||||
|
#include "dwarf/generated/dwarf.meta.c"
|
||||||
|
|
||||||
internal DW_AttribClass
|
internal DW_AttribClass
|
||||||
dw_attrib_class_from_attrib_v2(DW_AttribKind k)
|
dw_attrib_class_from_attrib_v2(DW_AttribKind k)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1739,6 +1739,11 @@ typedef enum DW_RegX64Enum
|
|||||||
DW_RegX64_Last
|
DW_RegX64_Last
|
||||||
} DW_RegX64Enum;
|
} DW_RegX64Enum;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: Generated Code
|
||||||
|
|
||||||
|
#include "dwarf/generated/dwarf.meta.h"
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// Speced Encodings
|
// Speced Encodings
|
||||||
|
|
||||||
|
|||||||
@@ -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)`,
|
||||||
|
}
|
||||||
+899
-885
File diff suppressed because it is too large
Load Diff
@@ -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);
|
internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprValue v);
|
||||||
|
|
||||||
// evaluator
|
// 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
|
// encoder
|
||||||
internal String8 dw_encode_expr(Arena *arena, Arch arch, DW_Format format, DW_ExprEnc *encs, U64 encs_count);
|
internal String8 dw_encode_expr(Arena *arena, Arch arch, DW_Format format, DW_ExprEnc *encs, U64 encs_count);
|
||||||
|
|||||||
@@ -13,3 +13,6 @@
|
|||||||
#include "dwarf/dwarf_parse_2.c"
|
#include "dwarf/dwarf_parse_2.c"
|
||||||
#include "dwarf/eh_frame.c"
|
#include "dwarf/eh_frame.c"
|
||||||
#include "dwarf/eh_dump.c"
|
#include "dwarf/eh_dump.c"
|
||||||
|
#if defined(X64_H)
|
||||||
|
# include "dwarf/x64/dwarf_x64.c"
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -16,5 +16,8 @@
|
|||||||
#include "dwarf/dwarf_parse_2.h"
|
#include "dwarf/dwarf_parse_2.h"
|
||||||
#include "dwarf/eh_frame.h"
|
#include "dwarf/eh_frame.h"
|
||||||
#include "dwarf/eh_dump.h"
|
#include "dwarf/eh_dump.h"
|
||||||
|
#if defined(X64_H)
|
||||||
|
# include "dwarf/x64/dwarf_x64.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // DWARF_INC_H
|
#endif // DWARF_INC_H
|
||||||
|
|||||||
@@ -56,6 +56,43 @@ dw2_read_fmt_u64(String8 data, U64 off, DW_Format format, U64 *out)
|
|||||||
return bytes_read;
|
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
|
//~ rjf: Unit Header Parsing
|
||||||
|
|
||||||
|
|||||||
@@ -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_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);
|
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
|
//~ rjf: Unit Header Parsing
|
||||||
|
|
||||||
|
|||||||
+187
-165
@@ -91,101 +91,101 @@ dw_cfi_next_row(Arena *arena, DW_CFI_Unwind *uw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (inst->opcode) {
|
switch (inst->opcode) {
|
||||||
// Row Creation Instructions
|
// Row Creation Instructions
|
||||||
case DW_CFA_SetLoc: {
|
case DW_CFA_SetLoc: {
|
||||||
uw->pc = inst->operands[0].u64;
|
uw->pc = inst->operands[0].u64;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_AdvanceLoc:
|
case DW_CFA_AdvanceLoc:
|
||||||
case DW_CFA_AdvanceLoc1:
|
case DW_CFA_AdvanceLoc1:
|
||||||
case DW_CFA_AdvanceLoc2:
|
case DW_CFA_AdvanceLoc2:
|
||||||
case DW_CFA_AdvanceLoc4: {
|
case DW_CFA_AdvanceLoc4: {
|
||||||
uw->pc += inst->operands[0].u64;
|
uw->pc += inst->operands[0].u64;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// CFA Definition Instructions
|
// CFA Definition Instructions
|
||||||
case DW_CFA_DefCfa:
|
case DW_CFA_DefCfa:
|
||||||
case DW_CFA_DefCfaSf: {
|
case DW_CFA_DefCfaSf: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
S64 off = inst->operands[1].s64;
|
S64 off = inst->operands[1].s64;
|
||||||
uw->row->cfa.rule = DW_CFA_Rule_RegOff;
|
uw->row->cfa.rule = DW_CFA_Rule_RegOff;
|
||||||
uw->row->cfa.reg = reg;
|
uw->row->cfa.reg = reg;
|
||||||
uw->row->cfa.off = off;
|
uw->row->cfa.off = off;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_DefCfaRegister: {
|
case DW_CFA_DefCfaRegister: {
|
||||||
// TODO: report error: this operation is valid only if the current CFA rule is defined to register+offset
|
// TODO: report error: this operation is valid only if the current CFA rule is defined to register+offset
|
||||||
if (uw->row->cfa.rule != DW_CFA_Rule_RegOff) { goto exit; }
|
if (uw->row->cfa.rule != DW_CFA_Rule_RegOff) { goto exit; }
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->cfa.reg = reg;
|
uw->row->cfa.reg = reg;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_DefCfaOffset:
|
case DW_CFA_DefCfaOffset:
|
||||||
case DW_CFA_DefCfaOffsetSf: {
|
case DW_CFA_DefCfaOffsetSf: {
|
||||||
// TODO: report error: this operation is valid only if the current CFA rule is defined to register+offset
|
// TODO: report error: this operation is valid only if the current CFA rule is defined to register+offset
|
||||||
if (uw->row->cfa.rule != DW_CFA_Rule_RegOff) { goto exit; }
|
if (uw->row->cfa.rule != DW_CFA_Rule_RegOff) { goto exit; }
|
||||||
uw->row->cfa.off = inst->operands[0].s64;
|
uw->row->cfa.off = inst->operands[0].s64;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_DefCfaExpr: {
|
case DW_CFA_DefCfaExpr: {
|
||||||
uw->row->cfa.rule = DW_CFA_Rule_Expression;
|
uw->row->cfa.rule = DW_CFA_Rule_Expression;
|
||||||
uw->row->cfa.expr = inst->operands[0].block;
|
uw->row->cfa.expr = inst->operands[0].block;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Register Rule Instructions
|
// Register Rule Instructions
|
||||||
case DW_CFA_Undefined: {
|
case DW_CFA_Undefined: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Undefined;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Undefined;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_SameValue: {
|
case DW_CFA_SameValue: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_SameValue;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_SameValue;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_Offset:
|
case DW_CFA_Offset:
|
||||||
case DW_CFA_OffsetExt:
|
case DW_CFA_OffsetExt:
|
||||||
case DW_CFA_OffsetExtSf: {
|
case DW_CFA_OffsetExtSf: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Offset;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Offset;
|
||||||
uw->row->regs[reg].n = inst->operands[1].s64;
|
uw->row->regs[reg].n = inst->operands[1].s64;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_ValOffset:
|
case DW_CFA_ValOffset:
|
||||||
case DW_CFA_ValOffsetSf: {
|
case DW_CFA_ValOffsetSf: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_ValOffset;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_ValOffset;
|
||||||
uw->row->regs[reg].n = inst->operands[1].s64;
|
uw->row->regs[reg].n = inst->operands[1].s64;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_Register: {
|
case DW_CFA_Register: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Register;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Register;
|
||||||
uw->row->regs[reg].n = inst->operands[1].s64;
|
uw->row->regs[reg].n = inst->operands[1].s64;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_Expr: {
|
case DW_CFA_Expr: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Expression;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_Expression;
|
||||||
uw->row->regs[reg].expr = inst->operands[1].block;
|
uw->row->regs[reg].expr = inst->operands[1].block;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_ValExpr: {
|
case DW_CFA_ValExpr: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg].rule = DW_CFI_RegisterRule_ValExpression;
|
uw->row->regs[reg].rule = DW_CFI_RegisterRule_ValExpression;
|
||||||
uw->row->regs[reg].expr = inst->operands[1].block;
|
uw->row->regs[reg].expr = inst->operands[1].block;
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_Restore:
|
case DW_CFA_Restore:
|
||||||
case DW_CFA_RestoreExt: {
|
case DW_CFA_RestoreExt: {
|
||||||
U64 reg = inst->operands[0].u64;
|
U64 reg = inst->operands[0].u64;
|
||||||
uw->row->regs[reg] = uw->initial_row->regs[reg];
|
uw->row->regs[reg] = uw->initial_row->regs[reg];
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Row State Instructions
|
// Row State Instructions
|
||||||
case DW_CFA_RememberState: {
|
case DW_CFA_RememberState: {
|
||||||
DW_CFI_Row *new_row = dw_copy_cfi_row(arena, uw->row, uw->reg_count);
|
DW_CFI_Row *new_row = dw_copy_cfi_row(arena, uw->row, uw->reg_count);
|
||||||
SLLStackPush(uw->row, new_row);
|
SLLStackPush(uw->row, new_row);
|
||||||
} break;
|
} break;
|
||||||
case DW_CFA_RestoreState: {
|
case DW_CFA_RestoreState: {
|
||||||
if (uw->row == 0) { goto exit; } // TODO: report error: unbalanced number of pushes and pops
|
if (uw->row == 0) { goto exit; } // TODO: report error: unbalanced number of pushes and pops
|
||||||
DW_CFI_Row *free_row = uw->row;
|
DW_CFI_Row *free_row = uw->row;
|
||||||
SLLStackPop(uw->row);
|
SLLStackPop(uw->row);
|
||||||
SLLStackPush(uw->free_rows, free_row);
|
SLLStackPush(uw->free_rows, free_row);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_CFA_Nop: {} break;
|
case DW_CFA_Nop: {} break;
|
||||||
|
|
||||||
default: { NotImplemented; } break; // TODO: report error: unknown CFA opcode
|
default: { NotImplemented; } break; // TODO: report error: unknown CFA opcode
|
||||||
}
|
}
|
||||||
|
|
||||||
uw->curr_inst = uw->curr_inst->next;
|
uw->curr_inst = uw->curr_inst->next;
|
||||||
@@ -195,7 +195,7 @@ dw_cfi_next_row(Arena *arena, DW_CFI_Unwind *uw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
is_row_valid = row_inst != 0;
|
is_row_valid = row_inst != 0;
|
||||||
exit:;
|
exit:;
|
||||||
return is_row_valid;
|
return is_row_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,104 +237,126 @@ dw_cfi_row_from_pc(Arena *arena, Arch arch, DW_CIE *cie, DW_FDE *fde, DW_DecodeP
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal MachineOpResult
|
internal MachineOpResult
|
||||||
dw_compute_cfa(Arch arch,
|
dw_compute_cfa(Arch arch, DW_CFI_Row *row, void *reg_block, MachineOp_MemRead *mem_read_func, void *mem_read_ud, U64 *cfa_out)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
MachineOpResult unwind_status = MachineOpResult_Fail;
|
MachineOpResult unwind_status = MachineOpResult_Fail;
|
||||||
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
switch (row->cfa.rule) {
|
switch(row->cfa.rule)
|
||||||
case DW_CFA_Rule_Null: break;
|
{
|
||||||
case DW_CFA_Rule_RegOff: {
|
case DW_CFA_Rule_Null:{}break;
|
||||||
// TODO: report error (invalid register read)
|
case DW_CFA_Rule_RegOff:
|
||||||
U64 cfa_reg_value = 0;
|
{
|
||||||
U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
|
// TODO: report error (invalid register read)
|
||||||
AssertAlways(reg_size <= sizeof(cfa_reg_value));
|
U64 cfa_reg_value = 0;
|
||||||
unwind_status = reg_read_func(row->cfa.reg, &cfa_reg_value, reg_size, reg_read_ud);
|
U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
|
||||||
if (unwind_status != MachineOpResult_Ok) { break; }
|
AssertAlways(reg_size <= sizeof(cfa_reg_value));
|
||||||
*cfa_out = cfa_reg_value + row->cfa.off;
|
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, row->cfa.reg);
|
||||||
} break;
|
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
|
||||||
case DW_CFA_Rule_Expression: {
|
if(!arch_reg_block_read_range(arch_info, reg_block, reg_rng, &cfa_reg_value))
|
||||||
// TODO: evaluate expression
|
{
|
||||||
NotImplemented;
|
unwind_status = MachineOpResult_Fail;
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
*cfa_out = cfa_reg_value + row->cfa.off;
|
||||||
|
}break;
|
||||||
|
case DW_CFA_Rule_Expression:
|
||||||
|
{
|
||||||
|
// TODO: evaluate expression
|
||||||
|
NotImplemented;
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return unwind_status;
|
return unwind_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal MachineOpResult
|
internal MachineOpResult
|
||||||
dw_cfi_apply_register_rules(Arch arch,
|
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)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0,0);
|
Temp scratch = scratch_begin(0,0);
|
||||||
MachineOpResult unwind_status = MachineOpResult_Ok;
|
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);
|
U64 max_reg_size = dw_reg_max_size_from_arch(arch);
|
||||||
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size);
|
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size);
|
||||||
|
|
||||||
U64 reg_count = dw_reg_count_from_arch(arch);
|
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];
|
DW_CFI_Register *reg = &row->regs[reg_idx];
|
||||||
switch (reg->rule) {
|
ARCH_RegCode reg_code = arch_reg_code_from_dw(arch, reg_idx);
|
||||||
case DW_CFI_RegisterRule_Undefined: {} break;
|
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
|
||||||
case DW_CFI_RegisterRule_SameValue: {} break;
|
switch(reg->rule)
|
||||||
case DW_CFI_RegisterRule_Offset: {
|
{
|
||||||
// read register value from memory
|
default:{}break;
|
||||||
U64 addr = cfa + reg->n;
|
case DW_CFI_RegisterRule_Undefined: {} break;
|
||||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
case DW_CFI_RegisterRule_SameValue: {} break;
|
||||||
unwind_status = mem_read_func(addr, reg_buffer, reg_size, mem_read_ud);
|
case DW_CFI_RegisterRule_Offset:
|
||||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
{
|
||||||
|
// read register value from memory
|
||||||
|
U64 addr = cfa + reg->n;
|
||||||
|
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||||
|
unwind_status = mem_read_func(addr, reg_buffer, reg_size, mem_read_ud);
|
||||||
|
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||||
|
|
||||||
// write register value to the thread context
|
// 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))
|
||||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
{
|
||||||
} break;
|
unwind_status = MachineOpResult_Fail;
|
||||||
case DW_CFI_RegisterRule_ValOffset: {
|
goto exit;
|
||||||
// compute register value
|
}
|
||||||
U64 reg_value = cfa + reg->n;
|
}break;
|
||||||
|
case DW_CFI_RegisterRule_ValOffset:
|
||||||
|
{
|
||||||
|
// compute register value
|
||||||
|
U64 reg_value = cfa + reg->n;
|
||||||
|
|
||||||
// write register value to the thread context
|
// write register value to the thread context
|
||||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||||
unwind_status = reg_write_func(reg_idx, ®_value, reg_size, reg_write_ud);
|
if(!arch_reg_block_write_range(arch_info, reg_block, reg_rng, ®_value))
|
||||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
{
|
||||||
} break;
|
unwind_status = MachineOpResult_Fail;
|
||||||
case DW_CFI_RegisterRule_Register: {
|
goto exit;
|
||||||
// read register value from another register
|
}
|
||||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
}break;
|
||||||
unwind_status = reg_read_func(reg->n, reg_buffer, reg_size, reg_read_ud);
|
case DW_CFI_RegisterRule_Register:
|
||||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
{
|
||||||
|
// read register value from another register
|
||||||
|
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||||
|
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
|
// 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))
|
||||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
{
|
||||||
} break;
|
unwind_status = MachineOpResult_Fail;
|
||||||
case DW_CFI_RegisterRule_Expression: {
|
goto exit;
|
||||||
// TODO: evaluate expression
|
}
|
||||||
NotImplemented;
|
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||||
} break;
|
}break;
|
||||||
case DW_CFI_RegisterRule_ValExpression: {
|
case DW_CFI_RegisterRule_Expression:
|
||||||
// TODO: evaluate expression
|
{
|
||||||
NotImplemented;
|
// TODO: evaluate expression
|
||||||
} break;
|
NotImplemented;
|
||||||
case DW_CFI_RegisterRule_Architectural: {
|
}break;
|
||||||
NotImplemented;
|
case DW_CFI_RegisterRule_ValExpression:
|
||||||
} break;
|
{
|
||||||
default: { InvalidPath; } break;
|
// TODO: evaluate expression
|
||||||
|
NotImplemented;
|
||||||
|
}break;
|
||||||
|
case DW_CFI_RegisterRule_Architectural:
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update stack pointer
|
// update stack pointer
|
||||||
U64 sp = dw_sp_from_arch(arch);
|
arch_reg_block_write_sp(arch_info, reg_block, cfa);
|
||||||
reg_write_func(sp, &cfa, sizeof(cfa), reg_write_ud);
|
|
||||||
|
|
||||||
exit:;
|
exit:;
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return unwind_status;
|
return unwind_status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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 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
|
#endif // DWARF_UNWIND_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
|
|
||||||
#include "regs/rdi/generated/regs_rdi.meta.c"
|
//- GENERATED CODE
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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"
|
||||||
@@ -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
|
||||||
@@ -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)`
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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);
|
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
|
||||||
Arch arch = arch_from_rdi_arch(tli->arch);
|
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);
|
RDI_RegCode rdi_regcode = rdi_regcode_from_location(loc);
|
||||||
REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, rdi_regcode);
|
ARCH_RegCode reg_code = arch_reg_code_from_rdi(arch, rdi_regcode);
|
||||||
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code];
|
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
|
||||||
U64 byte_size = (U64)reg_rng.byte_size;
|
U64 byte_size = (U64)dim_1u16(reg_rng);
|
||||||
U64 byte_pos = 0;
|
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)));
|
e_oplist_push_op(arena, &result, RDI_EvalOp_RegRead, e_value_u64(RDI_EncodeRegReadParam(rdi_regcode, byte_size, byte_pos)));
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
@@ -830,7 +831,6 @@ internal void
|
|||||||
e_select_ir_ctx(E_IRCtx *ctx)
|
e_select_ir_ctx(E_IRCtx *ctx)
|
||||||
{
|
{
|
||||||
if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; }
|
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->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; }
|
||||||
if(ctx->member_map == 0) { ctx->member_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); }
|
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); }
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ typedef enum E_TypeKeyKind
|
|||||||
E_TypeKeyKind_Ext,
|
E_TypeKeyKind_Ext,
|
||||||
E_TypeKeyKind_Cons,
|
E_TypeKeyKind_Cons,
|
||||||
E_TypeKeyKind_Reg,
|
E_TypeKeyKind_Reg,
|
||||||
E_TypeKeyKind_RegAlias,
|
|
||||||
}
|
}
|
||||||
E_TypeKeyKind;
|
E_TypeKeyKind;
|
||||||
|
|
||||||
@@ -795,7 +794,6 @@ typedef struct E_IRCtx E_IRCtx;
|
|||||||
struct E_IRCtx
|
struct E_IRCtx
|
||||||
{
|
{
|
||||||
E_String2NumMap *regs_map;
|
E_String2NumMap *regs_map;
|
||||||
E_String2NumMap *reg_alias_map;
|
|
||||||
E_String2NumMap *locals_map; // (within `primary_module`)
|
E_String2NumMap *locals_map; // (within `primary_module`)
|
||||||
E_String2NumMap *member_map; // (within `primary_module`)
|
E_String2NumMap *member_map; // (within `primary_module`)
|
||||||
E_String2ExprMap *macro_map;
|
E_String2ExprMap *macro_map;
|
||||||
|
|||||||
@@ -280,13 +280,14 @@ e_interpret(String8 bytecode)
|
|||||||
U8 rdi_reg_code = (imm.u64&0x0000FF)>>0;
|
U8 rdi_reg_code = (imm.u64&0x0000FF)>>0;
|
||||||
U8 byte_size = (imm.u64&0x00FF00)>>8;
|
U8 byte_size = (imm.u64&0x00FF00)>>8;
|
||||||
U8 byte_off = (imm.u64&0xFF0000)>>16;
|
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);
|
Arch arch = e_interpret_ctx->reg_arch;
|
||||||
REGS_Rng *rng_table = regs_reg_code_rng_table_from_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;
|
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];
|
Rng1U16 rng = arch_info->reg_code_rng_table[base_reg_code];
|
||||||
U64 off = (U64)rng.byte_off + byte_off;
|
U64 off = (U64)rng.min + byte_off;
|
||||||
U64 size = (U64)byte_size;
|
U64 size = (U64)byte_size;
|
||||||
good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
|
good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-38
@@ -2016,49 +2016,25 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
|
|||||||
if(reg_num != 0)
|
if(reg_num != 0)
|
||||||
{
|
{
|
||||||
string_mapped = 1;
|
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 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 = e_bytecode_from_oplist(arena, &oplist);
|
||||||
mapped_bytecode_mode = E_Mode_Offset;
|
mapped_bytecode_mode = E_Mode_Offset;
|
||||||
mapped_bytecode_space = e_base_ctx->thread_reg_space;
|
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){}
|
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(!is_vector && reg_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(!is_vector && reg_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(!is_vector && reg_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 == 8) {mapped_type_key = e_type_key_basic(E_TypeKind_U64);}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num);
|
mapped_type_key = e_type_key_reg(arch, reg_code);
|
||||||
}
|
|
||||||
}
|
|
||||||
}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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}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);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
String8 file_path = expr->string;
|
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)
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
String8 folder_path = str8_chop_last_slash(file_path);
|
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))
|
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);
|
E_Space space = e_space_make(E_SpaceKind_FileSystem);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ typedef enum E_IdentifierResolutionPath
|
|||||||
E_IdentifierResolutionPath_BuiltInConstants,
|
E_IdentifierResolutionPath_BuiltInConstants,
|
||||||
E_IdentifierResolutionPath_BuiltInTypes,
|
E_IdentifierResolutionPath_BuiltInTypes,
|
||||||
E_IdentifierResolutionPath_Registers,
|
E_IdentifierResolutionPath_Registers,
|
||||||
E_IdentifierResolutionPath_RegisterAliases,
|
|
||||||
E_IdentifierResolutionPath_Macros,
|
E_IdentifierResolutionPath_Macros,
|
||||||
}
|
}
|
||||||
E_IdentifierResolutionPath;
|
E_IdentifierResolutionPath;
|
||||||
@@ -89,7 +88,6 @@ E_IdentifierResolutionPath e_default_identifier_resolution_paths[] =
|
|||||||
E_IdentifierResolutionPath_BuiltInTypes,
|
E_IdentifierResolutionPath_BuiltInTypes,
|
||||||
E_IdentifierResolutionPath_DebugInfoMatch,
|
E_IdentifierResolutionPath_DebugInfoMatch,
|
||||||
E_IdentifierResolutionPath_Registers,
|
E_IdentifierResolutionPath_Registers,
|
||||||
E_IdentifierResolutionPath_RegisterAliases,
|
|
||||||
E_IdentifierResolutionPath_Macros,
|
E_IdentifierResolutionPath_Macros,
|
||||||
};
|
};
|
||||||
E_IdentifierResolutionRule e_default_identifier_resolution_rule =
|
E_IdentifierResolutionRule e_default_identifier_resolution_rule =
|
||||||
@@ -110,7 +108,6 @@ E_IdentifierResolutionPath e_callable_identifier_resolution_paths[] =
|
|||||||
E_IdentifierResolutionPath_BuiltInTypes,
|
E_IdentifierResolutionPath_BuiltInTypes,
|
||||||
E_IdentifierResolutionPath_DebugInfoMatch,
|
E_IdentifierResolutionPath_DebugInfoMatch,
|
||||||
E_IdentifierResolutionPath_Registers,
|
E_IdentifierResolutionPath_Registers,
|
||||||
E_IdentifierResolutionPath_RegisterAliases,
|
|
||||||
};
|
};
|
||||||
E_IdentifierResolutionRule e_callable_identifier_resolution_rule =
|
E_IdentifierResolutionRule e_callable_identifier_resolution_rule =
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-27
@@ -288,7 +288,7 @@ e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal E_TypeKey
|
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};
|
E_TypeKey key = {E_TypeKeyKind_Reg};
|
||||||
key.u32[0] = (U32)arch;
|
key.u32[0] = (U32)arch;
|
||||||
@@ -296,15 +296,6 @@ e_type_key_reg(Arch arch, REGS_RegCode code)
|
|||||||
return key;
|
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
|
//- rjf: constructed type construction
|
||||||
|
|
||||||
internal U64
|
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_Ext: {kind = (E_TypeKind)key.u32[0];}break;
|
||||||
case E_TypeKeyKind_Cons: {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_Reg: {kind = E_TypeKind_Union;}break;
|
||||||
case E_TypeKeyKind_RegAlias:{kind = E_TypeKind_Union;}break;
|
|
||||||
}
|
}
|
||||||
return kind;
|
return kind;
|
||||||
}
|
}
|
||||||
@@ -1100,16 +1090,10 @@ e_push_type_from_key(Arena *arena, E_TypeKey key)
|
|||||||
case E_TypeKeyKind_Reg:
|
case E_TypeKeyKind_Reg:
|
||||||
{
|
{
|
||||||
Arch arch = (Arch)key.u32[0];
|
Arch arch = (Arch)key.u32[0];
|
||||||
REGS_RegCode code = (REGS_RegCode)key.u32[1];
|
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||||
REGS_Rng rng = regs_reg_code_rng_table_from_arch(arch)[code];
|
ARCH_RegCode code = (ARCH_RegCode)key.u32[1];
|
||||||
reg_byte_count = (U64)rng.byte_size;
|
Rng1U16 rng = arch_info->reg_code_rng_table[code];
|
||||||
}goto build_reg_type;
|
reg_byte_count = (U64)dim_1u16(rng);
|
||||||
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;
|
|
||||||
}goto build_reg_type;
|
}goto build_reg_type;
|
||||||
build_reg_type:
|
build_reg_type:
|
||||||
{
|
{
|
||||||
@@ -3117,23 +3101,23 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder)
|
|||||||
String8List folder_paths = {0};
|
String8List folder_paths = {0};
|
||||||
String8List file_paths = {0};
|
String8List file_paths = {0};
|
||||||
{
|
{
|
||||||
OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0);
|
FileIter *iter = file_iter_begin(scratch.arena, folder_path, 0);
|
||||||
for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);)
|
for(FileInfo info = {0}; file_iter_next(scratch.arena, iter, &info);)
|
||||||
{
|
{
|
||||||
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name);
|
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name);
|
||||||
if(matches.count == matches.needle_part_count)
|
if(matches.count == matches.needle_part_count)
|
||||||
{
|
{
|
||||||
if(info.props.flags & FilePropertyFlag_IsFolder)
|
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
|
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
|
//- rjf: build accelerator
|
||||||
@@ -3252,7 +3236,7 @@ E_TYPE_IREXT_FUNCTION_DEF(file)
|
|||||||
|
|
||||||
//- rjf: fill accel
|
//- rjf: fill accel
|
||||||
accel->file_path = push_str8_copy(arena, file_path);
|
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);
|
accel->fields = str8_array_from_list(arena, &fields);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
|
|||||||
@@ -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_zero(void);
|
||||||
internal E_TypeKey e_type_key_basic(E_TypeKind kind);
|
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_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(Arch arch, ARCH_RegCode code);
|
||||||
internal E_TypeKey e_type_key_reg_alias(Arch arch, REGS_AliasCode code);
|
|
||||||
|
|
||||||
//- rjf: constructed type construction
|
//- rjf: constructed type construction
|
||||||
internal U64 e_hash_from_cons_type_params(E_ConsTypeParams *params);
|
internal U64 e_hash_from_cons_type_params(E_ConsTypeParams *params);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
|
|||||||
FileProperties pre_props = {0};
|
FileProperties pre_props = {0};
|
||||||
if(lane_idx() == 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);
|
file_is_good = (pre_props.modified != 0);
|
||||||
}
|
}
|
||||||
lane_sync_u64(&file_is_good, 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
|
//- rjf: open file
|
||||||
OS_Handle file = {0};
|
File file = {0};
|
||||||
if(file_is_good)
|
if(file_is_good)
|
||||||
{
|
{
|
||||||
if(lane_idx() == 0)
|
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);
|
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
|
//- rjf: do read
|
||||||
U64 total_bytes_read = 0;
|
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)
|
ProfScope("read \"%.*s\" [0x%I64x, 0x%I64x)", str8_varg(path), range.min, range.max)
|
||||||
{
|
{
|
||||||
Rng1U64 lane_read_range = lane_range(data_buffer_size);
|
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);
|
ins_atomic_u64_add_eval(total_bytes_read_ptr, bytes_read);
|
||||||
}
|
}
|
||||||
lane_sync();
|
lane_sync();
|
||||||
@@ -116,7 +116,7 @@ fs_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out
|
|||||||
{
|
{
|
||||||
if(lane_idx() == 0)
|
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};
|
FileProperties post_props = {0};
|
||||||
if(lane_idx() == 0)
|
if(lane_idx() == 0)
|
||||||
{
|
{
|
||||||
post_props = os_properties_from_file_path(path);
|
post_props = properties_from_file_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- rjf: form content key
|
//- rjf: form content key
|
||||||
@@ -303,7 +303,7 @@ fs_async_tick(void)
|
|||||||
{
|
{
|
||||||
for(FS_Node *n = slot->first; n != 0; n = n->next)
|
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)
|
if(props.modified != n->last_modified_timestamp)
|
||||||
{
|
{
|
||||||
found_work = 1;
|
found_work = 1;
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ fp_font_open(String8 path)
|
|||||||
//- rjf: try to open font
|
//- rjf: try to open font
|
||||||
for(PathTask *t = first_task; t != 0 && font.file == 0; t = t->next)
|
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);
|
String16 path16 = str16_from_8(scratch.arena, t->path);
|
||||||
if(file_exists)
|
if(file_exists)
|
||||||
{
|
{
|
||||||
|
|||||||
+12
-12
@@ -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_PdbAltPath, "%%_RAD_PDB_PATH%%");
|
||||||
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
|
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)) {
|
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_TypeHashAlg, "BLAKE3");
|
||||||
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
|
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_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_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_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_DebugAltPath, "%%_RAD_RDI_PATH%%");
|
||||||
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MemoryMapFiles, "");
|
lnk_cmd_line_push_option_if_not_presentf(arena, &cmd_line, LNK_CmdSwitch_Rad_MemoryMapFiles, "");
|
||||||
if (BUILD_DEBUG) {
|
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");
|
str8_list_pushf(scratch.arena, &cmd_line, "-nologo");
|
||||||
|
|
||||||
// register input manifest files on command line
|
// 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;
|
for (String8Node *man_node = manifest_path_list.first;
|
||||||
man_node != 0;
|
man_node != 0;
|
||||||
man_node = man_node->next) {
|
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
|
// launch mt.exe with our command line
|
||||||
OS_ProcessLaunchParams launch_opts = {0};
|
ProcessLaunchParams launch_opts = {0};
|
||||||
launch_opts.cmd_line = cmd_line;
|
launch_opts.cmd_line = cmd_line;
|
||||||
launch_opts.inherit_env = 1;
|
launch_opts.inherit_env = 1;
|
||||||
launch_opts.consoleless = 0;
|
launch_opts.consoleless = 0;
|
||||||
OS_Handle mt_handle = os_process_launch(&launch_opts);
|
Process mt_handle = process_launch(&launch_opts);
|
||||||
if (os_handle_match(mt_handle, os_handle_zero())) {
|
if (process_match(mt_handle, process_zero())) {
|
||||||
lnk_error(LNK_Error_Mt, "unable to start process: %S", mt_path);
|
lnk_error(LNK_Error_Mt, "unable to start process: %S", mt_path);
|
||||||
} else {
|
} else {
|
||||||
os_process_join(mt_handle, max_U64, 0);
|
process_join(mt_handle, max_U64, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
@@ -447,8 +447,8 @@ lnk_manifest_from_inputs(Arena *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cleanup disk
|
// cleanup disk
|
||||||
os_delete_file_at_path(linker_manifest_path);
|
delete_file_at_path(linker_manifest_path);
|
||||||
os_delete_file_at_path(merged_manifest_path);
|
delete_file_at_path(merged_manifest_path);
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
} else {
|
} else {
|
||||||
@@ -804,7 +804,7 @@ lnk_make_res_obj(Arena *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// convert res to obj
|
// convert res to obj
|
||||||
OS_ProcessInfo *process_info = os_get_process_info();
|
ProcessInfo *process_info = get_process_info();
|
||||||
String8List exe_path_strs = {0};
|
String8List exe_path_strs = {0};
|
||||||
str8_list_push(scratch.arena, &exe_path_strs, process_info->binary_path);
|
str8_list_push(scratch.arena, &exe_path_strs, process_info->binary_path);
|
||||||
String8 exe_path = str8_list_first(&exe_path_strs);
|
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);
|
lnk_log(LNK_Log_InputObj, "Input Obj: %S", path);
|
||||||
Temp scratch = scratch_begin(0,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);
|
||||||
LNK_Input *input = lnk_inputer_push_thin(inputer->arena, &inputer->new_objs, inputer->objs_ht, full_path);
|
LNK_Input *input = lnk_inputer_push_thin(inputer->arena, &inputer->new_objs, inputer->objs_ht, full_path);
|
||||||
input->link_member = link_member;
|
input->link_member = link_member;
|
||||||
scratch_end(scratch);
|
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);
|
LNK_Input *input = hash_table_search_path_raw(load_ht, path);
|
||||||
if (input == 0) {
|
if (input == 0) {
|
||||||
Temp scratch = scratch_begin(0, 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);
|
input = hash_table_search_path_raw(load_ht, full_path);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-17
@@ -1115,7 +1115,7 @@ lnk_unwrap_rsp(Arena *arena, String8List arg_list)
|
|||||||
// remove "@"
|
// remove "@"
|
||||||
String8 name = str8_skip(curr->string, 1);
|
String8 name = str8_skip(curr->string, 1);
|
||||||
|
|
||||||
if (os_file_path_exists(name)) {
|
if (file_path_exists(name)) {
|
||||||
// read rsp from disk
|
// read rsp from disk
|
||||||
String8 file = lnk_read_data_from_file_path(scratch.arena, 0, name);
|
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: {
|
case LNK_CmdSwitch_LibPath: {
|
||||||
String8List lib_dir_list = str8_list_copy(config->arena, &value_strings);
|
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) {
|
for (String8Node *dir_n = lib_dir_list.first; dir_n != 0; dir_n = dir_n->next) {
|
||||||
if (!os_folder_path_exists(dir_n->string)) {
|
if (!folder_path_exists(dir_n->string)) {
|
||||||
String8 full_path = os_full_path_from_path(scratch.arena, 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);
|
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: {
|
case LNK_CmdSwitch_Rad_BuildInfo: {
|
||||||
lnk_print_build_info();
|
lnk_print_build_info();
|
||||||
os_abort(0);
|
abort_self(0);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll: {
|
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)) {
|
if (str8_match_lit("imageblake3", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
|
||||||
config->guid_type = Lnk_DebugInfoGuid_ImageBlake3;
|
config->guid_type = Lnk_DebugInfoGuid_ImageBlake3;
|
||||||
} else if (str8_match_lit("random", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
|
} else if (str8_match_lit("random", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
|
||||||
config->guid = os_make_guid();
|
config->guid = make_guid();
|
||||||
} else {
|
} else {
|
||||||
Guid guid;
|
Guid guid;
|
||||||
if (try_guid_from_string(value_strings.first->string, &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: {
|
case LNK_CmdSwitch_Rad_LargePages: {
|
||||||
if (value_strings.node_count == 0) {
|
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) {
|
if (process_info->large_pages_allowed) {
|
||||||
arena_default_flags |= ArenaFlag_LargePages;
|
arena_default_flags |= ArenaFlag_LargePages;
|
||||||
} else {
|
} 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) {
|
} else if (value_strings.node_count == 1) {
|
||||||
if (str8_match_lit("quiet", value_strings.first->string, StringMatchFlag_CaseInsensitive)) {
|
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) {
|
if (process_info->large_pages_allowed) {
|
||||||
arena_default_flags |= ArenaFlag_LargePages;
|
arena_default_flags |= ArenaFlag_LargePages;
|
||||||
}
|
}
|
||||||
@@ -2031,7 +2031,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers: {
|
case LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers: {
|
||||||
OS_SystemInfo *sysinfo = os_get_system_info();
|
SystemInfo *sysinfo = get_system_info();
|
||||||
if (value_strings.node_count == 0) {
|
if (value_strings.node_count == 0) {
|
||||||
config->max_worker_count = sysinfo->logical_processor_count;
|
config->max_worker_count = sysinfo->logical_processor_count;
|
||||||
} else {
|
} else {
|
||||||
@@ -2101,7 +2101,7 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
|
|||||||
|
|
||||||
case LNK_CmdSwitch_Rad_Version: {
|
case LNK_CmdSwitch_Rad_Version: {
|
||||||
lnk_fprintf(stdout, "%s\n", BUILD_TITLE_STRING_LITERAL);
|
lnk_fprintf(stdout, "%s\n", BUILD_TITLE_STRING_LITERAL);
|
||||||
os_abort(0);
|
abort_self(0);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case LNK_CmdSwitch_Rad_Workers: {
|
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: {
|
case LNK_CmdSwitch_Help: {
|
||||||
lnk_print_help();
|
lnk_print_help();
|
||||||
os_abort(0);
|
abort_self(0);
|
||||||
} break;
|
} 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);
|
LNK_Config *config = push_array(arena, LNK_Config, 1);
|
||||||
config->arena = arena;
|
config->arena = arena;
|
||||||
config->raw_cmd_line = str8_list_copy(arena, &raw_cmd_line);
|
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_imp_lib = 1;
|
||||||
config->build_exp = 1;
|
config->build_exp = 1;
|
||||||
config->heap_reserve = MB(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
|
// convert to full paths
|
||||||
config->out_path = os_full_path_from_path(arena, config->out_path);
|
config->out_path = full_path_from_path(arena, config->out_path);
|
||||||
config->pdb_name = os_full_path_from_path(arena, config->pdb_name);
|
config->pdb_name = full_path_from_path(arena, config->pdb_name);
|
||||||
config->rad_debug_name = os_full_path_from_path(arena, config->rad_debug_name);
|
config->rad_debug_name = full_path_from_path(arena, config->rad_debug_name);
|
||||||
config->imp_lib_name = os_full_path_from_path(arena, config->imp_lib_name);
|
config->imp_lib_name = full_path_from_path(arena, config->imp_lib_name);
|
||||||
config->manifest_name = os_full_path_from_path(arena, config->manifest_name);
|
config->manifest_name = full_path_from_path(arena, config->manifest_name);
|
||||||
|
|
||||||
// collect env vars
|
// collect env vars
|
||||||
HashTable *env_vars = hash_table_init(scratch.arena, 512);
|
HashTable *env_vars = hash_table_init(scratch.arena, 512);
|
||||||
{
|
{
|
||||||
#if OS_WINDOWS
|
#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) {
|
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);
|
String8List list = str8_split_by_string_chars(scratch.arena, node->string, str8_lit("="), 0);
|
||||||
|
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
|||||||
ProfBegin("Set up PCH");
|
ProfBegin("Set up PCH");
|
||||||
{
|
{
|
||||||
// hash_table<obj_path, obj_idx>
|
// 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);
|
HashTable *debug_p_ht = hash_table_init(scratch.arena, obj_count);
|
||||||
for EachIndex(i, input.debug_p_indices.count) {
|
for EachIndex(i, input.debug_p_indices.count) {
|
||||||
U64 obj_idx = input.debug_p_indices.v[i];
|
U64 obj_idx = input.debug_p_indices.v[i];
|
||||||
|
|||||||
+25
-25
@@ -1,41 +1,41 @@
|
|||||||
shared_function int
|
shared_function int
|
||||||
lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
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);
|
Assert(sizeof(handle) <= handle_buffer_max);
|
||||||
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
||||||
return !os_handle_match(handle, os_handle_zero());
|
return !file_match(handle, file_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_function int
|
shared_function int
|
||||||
lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max)
|
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);
|
Assert(sizeof(handle) <= handle_buffer_max);
|
||||||
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
MemoryCopy(handle_buffer, &handle, sizeof(handle));
|
||||||
return !os_handle_match(handle, os_handle_zero());
|
return !file_match(handle, file_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_function void
|
shared_function void
|
||||||
lnk_close_file(void *raw_handle)
|
lnk_close_file(void *raw_handle)
|
||||||
{
|
{
|
||||||
OS_Handle handle = *(OS_Handle *)raw_handle;
|
File handle = *(File *)raw_handle;
|
||||||
os_file_close(handle);
|
file_close(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_function uint64_t
|
shared_function uint64_t
|
||||||
lnk_size_from_file(void *raw_handle)
|
lnk_size_from_file(void *raw_handle)
|
||||||
{
|
{
|
||||||
OS_Handle handle = *(OS_Handle *)raw_handle;
|
File handle = *(File *)raw_handle;
|
||||||
FileProperties props = os_properties_from_file(handle);
|
FileProperties props = properties_from_file(handle);
|
||||||
return props.size;
|
return props.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_function uint64_t
|
shared_function uint64_t
|
||||||
lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max)
|
lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max)
|
||||||
{
|
{
|
||||||
OS_Handle handle = *(OS_Handle *)raw_handle;
|
File handle = *(File *)raw_handle;
|
||||||
U64 read_size = os_file_read(handle, rng_1u64(0, buffer_max), buffer);
|
U64 read_size = file_read(handle, rng_1u64(0, buffer_max), buffer);
|
||||||
Assert(read_size == buffer_max);
|
Assert(read_size == buffer_max);
|
||||||
return read_size;
|
return read_size;
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@ lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max)
|
|||||||
shared_function uint64_t
|
shared_function uint64_t
|
||||||
lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size)
|
lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size)
|
||||||
{
|
{
|
||||||
OS_Handle handle = *(OS_Handle*)raw_handle;
|
File handle = *(File*)raw_handle;
|
||||||
U64 write_size = os_file_write(handle, r1u64(offset, offset + buffer_size), buffer);
|
U64 write_size = file_write(handle, r1u64(offset, offset + buffer_size), buffer);
|
||||||
return write_size;
|
return write_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +54,10 @@ lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
|
|||||||
ProfBeginFunction();
|
ProfBeginFunction();
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
String8 result = {0};
|
String8 result = {0};
|
||||||
if (os_file_path_exists(path)) {
|
if (file_path_exists(path)) {
|
||||||
PathStyle path_style = path_style_from_str8(path);
|
PathStyle path_style = path_style_from_str8(path);
|
||||||
if (path_style == PathStyle_Relative) {
|
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};
|
String8List l = {0};
|
||||||
str8_list_push(scratch.arena, &l, current_path);
|
str8_list_push(scratch.arena, &l, current_path);
|
||||||
str8_list_push(scratch.arena, &l, 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);
|
String8 file_name = str8_skip_last_slash(path);
|
||||||
for EachNode(n, String8Node, dir_list.first) {
|
for EachNode(n, String8Node, dir_list.first) {
|
||||||
String8 full_path = push_str8f(scratch.arena, "%S/%S", n->string, file_name);
|
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);
|
result = push_str8_copy(arena, full_path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -80,10 +80,10 @@ lnk_find_first_file(Arena *arena, String8List dir_list, String8 path)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OS_Handle
|
internal File
|
||||||
lnk_file_open_with_rename_permissions(String8 path)
|
lnk_file_open_with_rename_permissions(String8 path)
|
||||||
{
|
{
|
||||||
OS_Handle file_handle = os_handle_zero();
|
File file_handle = file_zero();
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
Temp scratch = scratch_begin(0,0);
|
Temp scratch = scratch_begin(0,0);
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ lnk_file_open_with_rename_permissions(String8 path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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
|
#if OS_WINDOWS
|
||||||
FILE_DISPOSITION_INFO file_disposition = {0};
|
FILE_DISPOSITION_INFO file_disposition = {0};
|
||||||
@@ -122,7 +122,7 @@ lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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);
|
Temp scratch = scratch_begin(0,0);
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
@@ -167,7 +167,7 @@ THREAD_POOL_TASK_FUNC(lnk_data_size_from_file_path_task)
|
|||||||
LNK_DiskReader *task = raw_task;
|
LNK_DiskReader *task = raw_task;
|
||||||
String8 path = task->path_arr.v[task_id];
|
String8 path = task->path_arr.v[task_id];
|
||||||
|
|
||||||
OS_Handle handle = {0};
|
File handle = {0};
|
||||||
U64 size = 0;
|
U64 size = 0;
|
||||||
|
|
||||||
int is_open = lnk_open_file_read((char*)path.str, path.size, &handle, sizeof(handle));
|
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;
|
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];
|
U64 buffer_size = task->size_arr[task_id];
|
||||||
U8 *buffer = task->buffer + task->off_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);
|
Temp scratch = scratch_begin(&arena,1);
|
||||||
|
|
||||||
reader.path_arr = path_arr;
|
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);
|
reader.size_arr = push_array_no_zero(scratch.arena, U64, path_arr.count);
|
||||||
|
|
||||||
// open handles and get sizes
|
// 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);
|
ProfBeginV("Write %M to %S", data.total_size, path);
|
||||||
|
|
||||||
B32 open_with_rename = (temp_path.size > 0);
|
B32 open_with_rename = (temp_path.size > 0);
|
||||||
OS_Handle file_handle = {0};
|
File file_handle = {0};
|
||||||
String8 open_file_path = {0};
|
String8 open_file_path = {0};
|
||||||
if (open_with_rename) {
|
if (open_with_rename) {
|
||||||
file_handle = lnk_file_open_with_rename_permissions(temp_path);
|
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;
|
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
|
// 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);
|
lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", open_file_path, data.total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -11,7 +11,7 @@ typedef struct
|
|||||||
LNK_IO_Flags io_flags;
|
LNK_IO_Flags io_flags;
|
||||||
String8Array path_arr;
|
String8Array path_arr;
|
||||||
String8Array data_arr;
|
String8Array data_arr;
|
||||||
OS_Handle *handle_arr;
|
File *handle_arr;
|
||||||
U64 *size_arr;
|
U64 *size_arr;
|
||||||
U64 *off_arr;
|
U64 *off_arr;
|
||||||
U8 *buffer;
|
U8 *buffer;
|
||||||
@@ -28,9 +28,9 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void
|
|||||||
|
|
||||||
// --- IO Functions ------------------------------------------------------------
|
// --- IO Functions ------------------------------------------------------------
|
||||||
|
|
||||||
internal OS_Handle lnk_file_open_with_rename_permissions(String8 path);
|
internal File 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_set_delete_on_close(File handle, B32 delete_file);
|
||||||
internal B32 lnk_file_rename(OS_Handle handle, String8 new_name);
|
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 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);
|
internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, LNK_IO_Flags io_flags, String8Array path_arr);
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ global LNK_Timer g_timers[LNK_Timer_Count];
|
|||||||
internal void
|
internal void
|
||||||
lnk_timer_begin(LNK_TimerType timer)
|
lnk_timer_begin(LNK_TimerType timer)
|
||||||
{
|
{
|
||||||
g_timers[timer].begin = os_now_microseconds();
|
g_timers[timer].begin = now_time_us();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
lnk_timer_end(LNK_TimerType timer)
|
lnk_timer_end(LNK_TimerType timer)
|
||||||
{
|
{
|
||||||
g_timers[timer].end = os_now_microseconds();
|
g_timers[timer].end = now_time_us();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
|
|||||||
@@ -1613,7 +1613,7 @@ pdb_add_src(PDB_InfoContext *info, MSF_Context *msf, String8 file_path, String8
|
|||||||
if (comp == PDB_SrcComp_NULL) {
|
if (comp == PDB_SrcComp_NULL) {
|
||||||
// process path so it passes VS validity checks
|
// process path so it passes VS validity checks
|
||||||
String8 virt_path = file_path;
|
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 = path_absolute_dst_from_relative_dst_src(scratch.arena, virt_path, work_dir);
|
||||||
virt_path = lower_from_str8(scratch.arena, virt_path);
|
virt_path = lower_from_str8(scratch.arena, virt_path);
|
||||||
virt_path = path_convert_slashes(scratch.arena, virt_path, PathStyle_UnixAbsolute);
|
virt_path = path_convert_slashes(scratch.arena, virt_path, PathStyle_UnixAbsolute);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ tp_run_tasks(TP_Context *pool, TP_Worker *worker)
|
|||||||
// on last task ping main thread
|
// on last task ping main thread
|
||||||
U64 task_done = ins_atomic_u64_inc_eval(&pool->task_done);
|
U64 task_done = ins_atomic_u64_inc_eval(&pool->task_done);
|
||||||
if (task_done == task_count) {
|
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_Worker *worker = raw_worker;
|
||||||
TP_Context *pool = worker->pool;
|
TP_Context *pool = worker->pool;
|
||||||
for (; pool->is_live; ) {
|
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);
|
tp_run_tasks(pool, worker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,8 +46,8 @@ tp_worker_main_shared(void *raw_worker)
|
|||||||
TP_Worker *worker = raw_worker;
|
TP_Worker *worker = raw_worker;
|
||||||
TP_Context *pool = worker->pool;
|
TP_Context *pool = worker->pool;
|
||||||
for (; pool->is_live; ) {
|
for (; pool->is_live; ) {
|
||||||
if (os_semaphore_take(pool->exec_semaphore, max_U64)) {
|
if (semaphore_take(pool->exec_semaphore, max_U64)) {
|
||||||
if (os_semaphore_take(pool->task_semaphore, max_U64)) {
|
if (semaphore_take(pool->task_semaphore, max_U64)) {
|
||||||
tp_run_tasks(pool, worker);
|
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 task_semaphore = {0};
|
||||||
Semaphore exec_semaphore = {0};
|
Semaphore exec_semaphore = {0};
|
||||||
if (worker_count > 1) {
|
if (worker_count > 1) {
|
||||||
main_semaphore = os_semaphore_alloc(0, 1, str8_zero());
|
main_semaphore = semaphore_alloc(0, 1, str8_zero());
|
||||||
if (is_shared) {
|
if (is_shared) {
|
||||||
AssertAlways(worker_count <= max_worker_count);
|
AssertAlways(worker_count <= max_worker_count);
|
||||||
task_semaphore = os_semaphore_alloc(0, max_worker_count, name);
|
task_semaphore = semaphore_alloc(0, max_worker_count, name);
|
||||||
exec_semaphore = os_semaphore_alloc(0, worker_count, str8_zero());
|
exec_semaphore = semaphore_alloc(0, worker_count, str8_zero());
|
||||||
} else {
|
} 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 we are in shared mode ping local semaphore
|
||||||
if (pool->exec_semaphore.u64[0] != 0) {
|
if (pool->exec_semaphore.u64[0] != 0) {
|
||||||
for (U64 worker_idx = 0; worker_idx < drop_count; worker_idx +=1) {
|
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
|
// ping shared semaphore
|
||||||
for (U64 worker_idx = 0; worker_idx < drop_count; worker_idx += 1) {
|
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
|
// run tasks on main worker
|
||||||
tp_run_tasks(pool, &pool->worker_arr[0]);
|
tp_run_tasks(pool, &pool->worker_arr[0]);
|
||||||
|
|
||||||
// wait for workers to finish tasks
|
// wait for workers to finish tasks
|
||||||
os_semaphore_take(pool->main_semaphore, max_U64);
|
semaphore_take(pool->main_semaphore, max_U64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// Copyright (c) Epic Games Tools
|
||||||
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
@@ -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
|
||||||
@@ -14,7 +14,7 @@ mtx_init(void)
|
|||||||
mtx_shared = push_array(arena, MTX_Shared, 1);
|
mtx_shared = push_array(arena, MTX_Shared, 1);
|
||||||
mtx_shared->arena = arena;
|
mtx_shared->arena = arena;
|
||||||
mtx_shared->slots_count = 256;
|
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->slots = push_array(arena, MTX_Slot, mtx_shared->slots_count);
|
||||||
mtx_shared->stripes = push_array(arena, MTX_Stripe, mtx_shared->stripes_count);
|
mtx_shared->stripes = push_array(arena, MTX_Stripe, mtx_shared->stripes_count);
|
||||||
for(U64 idx = 0; idx < mtx_shared->stripes_count; idx += 1)
|
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].arena = arena_alloc();
|
||||||
mtx_shared->stripes[idx].rw_mutex = rw_mutex_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);
|
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)
|
for(U64 idx = 0; idx < mtx_shared->mut_threads_count; idx += 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -772,23 +772,13 @@ internal OS_Handle
|
|||||||
os_process_launch(OS_ProcessLaunchParams *params)
|
os_process_launch(OS_ProcessLaunchParams *params)
|
||||||
{
|
{
|
||||||
OS_Handle handle = {0};
|
OS_Handle handle = {0};
|
||||||
|
|
||||||
posix_spawn_file_actions_t file_actions = {0};
|
posix_spawn_file_actions_t file_actions = {0};
|
||||||
int file_actions_init_code = posix_spawn_file_actions_init(&file_actions);
|
int file_actions_init_code = posix_spawn_file_actions_init(&file_actions);
|
||||||
if(file_actions_init_code == 0)
|
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);
|
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);
|
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);
|
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};
|
posix_spawnattr_t attr = {0};
|
||||||
int attr_init_code = posix_spawnattr_init(&attr);
|
int attr_init_code = posix_spawnattr_init(&attr);
|
||||||
if(attr_init_code == 0)
|
if(attr_init_code == 0)
|
||||||
@@ -801,7 +791,6 @@ os_process_launch(OS_ProcessLaunchParams *params)
|
|||||||
String8List l = str8_split_path(scratch.arena, params->path);
|
String8List l = str8_split_path(scratch.arena, params->path);
|
||||||
str8_list_push(scratch.arena, &l, params->cmd_line.first->string);
|
str8_list_push(scratch.arena, &l, params->cmd_line.first->string);
|
||||||
String8 path_to_exe = str8_path_list_join_by_style(scratch.arena, &l, PathStyle_SystemAbsolute);
|
String8 path_to_exe = str8_path_list_join_by_style(scratch.arena, &l, PathStyle_SystemAbsolute);
|
||||||
|
|
||||||
argv[0] = (char *)path_to_exe.str;
|
argv[0] = (char *)path_to_exe.str;
|
||||||
U64 arg_idx = 1;
|
U64 arg_idx = 1;
|
||||||
for EachNode(n, String8Node, params->cmd_line.first->next)
|
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
|
// spawn process
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
int spawn_code = posix_spawn(&pid, argv[0], &file_actions, &attr, argv, envp);
|
int spawn_code = posix_spawn(&pid, argv[0], &file_actions, &attr, argv, envp);
|
||||||
|
|
||||||
if(spawn_code == 0)
|
if(spawn_code == 0)
|
||||||
{
|
{
|
||||||
handle.u64[0] = (U64)pid;
|
handle.u64[0] = (U64)pid;
|
||||||
@@ -850,16 +827,12 @@ os_process_launch(OS_ProcessLaunchParams *params)
|
|||||||
|
|
||||||
// clean up attributes
|
// clean up attributes
|
||||||
int attr_destroy_code = posix_spawnattr_destroy(&attr);
|
int attr_destroy_code = posix_spawnattr_destroy(&attr);
|
||||||
Assert(attr_destroy_code == 0);
|
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up file actions
|
// clean up file actions
|
||||||
int file_actions_destroy_code = posix_spawn_file_actions_destroy(&file_actions);
|
int file_actions_destroy_code = posix_spawn_file_actions_destroy(&file_actions);
|
||||||
Assert(file_actions_destroy_code == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,14 +846,12 @@ os_process_join(OS_Handle handle, U64 endt_us, U64 *exit_code_out)
|
|||||||
if(kill(pid, 0) >= 0)
|
if(kill(pid, 0) >= 0)
|
||||||
{
|
{
|
||||||
result = (errno == ENOENT);
|
result = (errno == ENOENT);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { Assert(0 && "failed to get status from pid"); }
|
|
||||||
}
|
}
|
||||||
else if(endt_us == max_U64)
|
else if(endt_us == max_U64)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,155 +1,6 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// 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)
|
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||||
|
|
||||||
|
|||||||
+31
-7
@@ -6,6 +6,30 @@
|
|||||||
|
|
||||||
#include "generated/os_gfx.meta.c"
|
#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)
|
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||||
|
|
||||||
@@ -182,12 +206,12 @@ os_eat_event(OS_EventList *events, OS_Event *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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;
|
B32 result = 0;
|
||||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
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)
|
event->kind == OS_EventKind_Press && event->key == key && event->modifiers == modifiers)
|
||||||
{
|
{
|
||||||
result = 1;
|
result = 1;
|
||||||
@@ -199,12 +223,12 @@ os_key_press(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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;
|
B32 result = 0;
|
||||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
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)
|
event->kind == OS_EventKind_Release && event->key == key && event->modifiers == modifiers)
|
||||||
{
|
{
|
||||||
result = 1;
|
result = 1;
|
||||||
@@ -216,12 +240,12 @@ os_key_release(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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;
|
B32 result = 0;
|
||||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
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)
|
event->kind == OS_EventKind_Text && event->character == character)
|
||||||
{
|
{
|
||||||
result = 1;
|
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);
|
OS_Event *evt = push_array(arena, OS_Event, 1);
|
||||||
DLLPushBack(evts->first, evts->last, evt);
|
DLLPushBack(evts->first, evts->last, evt);
|
||||||
evts->count += 1;
|
evts->count += 1;
|
||||||
evt->timestamp_us = os_now_microseconds();
|
evt->timestamp_us = now_time_us();
|
||||||
evt->kind = kind;
|
evt->kind = kind;
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|||||||
+72
-34
@@ -25,6 +25,37 @@ enum
|
|||||||
OS_WindowFlag_UseDefaultPosition = (1<<1),
|
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
|
//~ rjf: Cursor Types
|
||||||
|
|
||||||
@@ -81,7 +112,7 @@ struct OS_Event
|
|||||||
OS_Event *next;
|
OS_Event *next;
|
||||||
OS_Event *prev;
|
OS_Event *prev;
|
||||||
U64 timestamp_us;
|
U64 timestamp_us;
|
||||||
OS_Handle window;
|
OS_Window window;
|
||||||
OS_EventKind kind;
|
OS_EventKind kind;
|
||||||
OS_Modifiers modifiers;
|
OS_Modifiers modifiers;
|
||||||
OS_Key key;
|
OS_Key key;
|
||||||
@@ -107,6 +138,13 @@ struct OS_EventList
|
|||||||
|
|
||||||
internal B32 frame(void);
|
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)
|
//~ 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 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 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 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_press(OS_EventList *events, OS_Window 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_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
|
||||||
internal B32 os_text(OS_EventList *events, OS_Handle window, U32 character);
|
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 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 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);
|
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)
|
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_Handle os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
|
internal OS_Window os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
|
||||||
internal void os_window_close(OS_Handle window);
|
internal void os_window_close(OS_Window window);
|
||||||
internal void os_window_set_title(OS_Handle window, String8 title);
|
internal void os_window_set_title(OS_Window window, String8 title);
|
||||||
internal void os_window_first_paint(OS_Handle window);
|
internal void os_window_first_paint(OS_Window window);
|
||||||
internal void os_window_focus(OS_Handle window);
|
internal void os_window_focus(OS_Window window);
|
||||||
internal B32 os_window_is_focused(OS_Handle window);
|
internal B32 os_window_is_focused(OS_Window window);
|
||||||
internal B32 os_window_is_fullscreen(OS_Handle window);
|
internal B32 os_window_is_fullscreen(OS_Window window);
|
||||||
internal void os_window_set_fullscreen(OS_Handle window, B32 fullscreen);
|
internal void os_window_set_fullscreen(OS_Window window, B32 fullscreen);
|
||||||
internal B32 os_window_is_maximized(OS_Handle window);
|
internal B32 os_window_is_maximized(OS_Window window);
|
||||||
internal void os_window_set_maximized(OS_Handle window, B32 maximized);
|
internal void os_window_set_maximized(OS_Window window, B32 maximized);
|
||||||
internal B32 os_window_is_minimized(OS_Handle window);
|
internal B32 os_window_is_minimized(OS_Window window);
|
||||||
internal void os_window_set_minimized(OS_Handle window, B32 minimized);
|
internal void os_window_set_minimized(OS_Window window, B32 minimized);
|
||||||
internal void os_window_bring_to_front(OS_Handle window);
|
internal void os_window_bring_to_front(OS_Window window);
|
||||||
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
|
internal void os_window_set_monitor(OS_Window window, OS_Monitor monitor);
|
||||||
internal void os_window_clear_custom_border_data(OS_Handle handle);
|
internal void os_window_clear_custom_border_data(OS_Window handle);
|
||||||
internal void os_window_push_custom_title_bar(OS_Handle handle, F32 thickness);
|
internal void os_window_push_custom_title_bar(OS_Window handle, F32 thickness);
|
||||||
internal void os_window_push_custom_edges(OS_Handle 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_Handle handle, Rng2F32 rect);
|
internal void os_window_push_custom_title_bar_client_area(OS_Window handle, Rng2F32 rect);
|
||||||
internal Rng2F32 os_rect_from_window(OS_Handle window);
|
internal Rng2F32 os_rect_from_window(OS_Window window);
|
||||||
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
|
internal Rng2F32 os_client_rect_from_window(OS_Window window);
|
||||||
internal F32 os_dpi_from_window(OS_Handle window);
|
internal F32 os_dpi_from_window(OS_Window window);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_Handle os_focused_external_window(void);
|
internal OS_ExternalWindow os_focused_external_window(void);
|
||||||
internal void os_focus_external_window(OS_Handle handle);
|
internal void os_focus_external_window(OS_ExternalWindow ext_window);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_HandleArray os_push_monitors_array(Arena *arena);
|
internal OS_MonitorArray os_push_monitors_array(Arena *arena);
|
||||||
internal OS_Handle os_primary_monitor(void);
|
internal OS_Monitor os_primary_monitor(void);
|
||||||
internal OS_Handle os_monitor_from_window(OS_Handle window);
|
internal OS_Monitor os_monitor_from_window(OS_Window window);
|
||||||
internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor);
|
internal String8 os_name_from_monitor(Arena *arena, OS_Monitor monitor);
|
||||||
internal Vec2F32 os_dim_from_monitor(OS_Handle monitor);
|
internal Vec2F32 os_dim_from_monitor(OS_Monitor monitor);
|
||||||
internal F32 os_dpi_from_monitor(OS_Handle monitor);
|
internal F32 os_dpi_from_monitor(OS_Monitor monitor);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
//~ 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_EventList os_get_events(Arena *arena, B32 wait);
|
||||||
internal OS_Modifiers os_get_modifiers(void);
|
internal OS_Modifiers os_get_modifiers(void);
|
||||||
internal B32 os_key_is_down(OS_Key key);
|
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)
|
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||||
|
|||||||
@@ -32,15 +32,15 @@ os_w32_rng2f32_from_rect(RECT rect)
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Windows
|
//~ rjf: Windows
|
||||||
|
|
||||||
internal OS_Handle
|
internal OS_Window
|
||||||
os_w32_handle_from_window(OS_W32_Window *window)
|
os_w32_handle_from_window(OS_W32_Window *window)
|
||||||
{
|
{
|
||||||
OS_Handle handle = {(U64)window};
|
OS_Window handle = {(U64)window};
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OS_W32_Window *
|
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];
|
OS_W32_Window *window = (OS_W32_Window *)handle.u64[0];
|
||||||
return window;
|
return window;
|
||||||
@@ -342,7 +342,7 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||||||
if(good)
|
if(good)
|
||||||
{
|
{
|
||||||
OS_W32_Window *window = os_w32_window_from_hwnd(hwnd);
|
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;
|
B32 release = 0;
|
||||||
|
|
||||||
switch(uMsg)
|
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_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr)
|
||||||
{
|
{
|
||||||
OS_W32_MonitorGatherBundle *bundle = (OS_W32_MonitorGatherBundle *)bundle_ptr;
|
OS_W32_MonitorGatherBundle *bundle = (OS_W32_MonitorGatherBundle *)bundle_ptr;
|
||||||
OS_Handle handle = {(U64)monitor};
|
OS_Monitor m = {(U64)monitor};
|
||||||
os_handle_list_push(bundle->arena, bundle->list, handle);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1052,7 +1055,7 @@ os_get_clipboard_text(Arena *arena)
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_Handle
|
internal OS_Window
|
||||||
os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
|
os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
|
||||||
{
|
{
|
||||||
B32 custom_border = !!(flags & OS_WindowFlag_CustomBorder);
|
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
|
//- 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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 *window = os_w32_window_from_handle(handle);
|
||||||
os_w32_window_release(window);
|
os_w32_window_release(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
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
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
|
||||||
window->first_paint_done = 1;
|
window->first_paint_done = 1;
|
||||||
@@ -1150,7 +1153,7 @@ os_window_first_paint(OS_Handle window_handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
os_window_focus(OS_Handle handle)
|
os_window_focus(OS_Window handle)
|
||||||
{
|
{
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
SetForegroundWindow(window->hwnd);
|
SetForegroundWindow(window->hwnd);
|
||||||
@@ -1158,7 +1161,7 @@ os_window_focus(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
HWND active_hwnd = GetActiveWindow();
|
HWND active_hwnd = GetActiveWindow();
|
||||||
@@ -1166,7 +1169,7 @@ os_window_is_focused(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
|
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
|
||||||
@@ -1174,7 +1177,7 @@ os_window_is_fullscreen(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
|
DWORD window_style = GetWindowLong(window->hwnd, GWL_STYLE);
|
||||||
@@ -1208,7 +1211,7 @@ os_window_set_fullscreen(OS_Handle handle, B32 fullscreen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
internal B32
|
||||||
os_window_is_maximized(OS_Handle handle)
|
os_window_is_maximized(OS_Window handle)
|
||||||
{
|
{
|
||||||
B32 result = 0;
|
B32 result = 0;
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
@@ -1220,7 +1223,7 @@ os_window_is_maximized(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
if(window != 0)
|
if(window != 0)
|
||||||
@@ -1242,7 +1245,7 @@ os_window_set_maximized(OS_Handle handle, B32 maximized)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
internal B32
|
||||||
os_window_is_minimized(OS_Handle handle)
|
os_window_is_minimized(OS_Window handle)
|
||||||
{
|
{
|
||||||
B32 result = 0;
|
B32 result = 0;
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
@@ -1254,7 +1257,7 @@ os_window_is_minimized(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
if(window != 0 && minimized != os_window_is_minimized(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
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
if(window != 0)
|
if(window != 0)
|
||||||
@@ -1279,7 +1282,7 @@ os_window_bring_to_front(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
|
||||||
HMONITOR hmonitor = (HMONITOR)monitor.u64[0];
|
HMONITOR hmonitor = (HMONITOR)monitor.u64[0];
|
||||||
@@ -1300,7 +1303,7 @@ os_window_set_monitor(OS_Handle window_handle, OS_Handle monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
if(window->custom_border)
|
if(window->custom_border)
|
||||||
@@ -1313,21 +1316,21 @@ os_window_clear_custom_border_data(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
window->custom_border_title_thickness = thickness;
|
window->custom_border_title_thickness = thickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
window->custom_border_edge_thickness = thickness;
|
window->custom_border_edge_thickness = thickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
if(window->custom_border)
|
if(window->custom_border)
|
||||||
@@ -1342,7 +1345,7 @@ os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal Rng2F32
|
internal Rng2F32
|
||||||
os_rect_from_window(OS_Handle handle)
|
os_rect_from_window(OS_Window handle)
|
||||||
{
|
{
|
||||||
Rng2F32 r = {0};
|
Rng2F32 r = {0};
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
@@ -1356,7 +1359,7 @@ os_rect_from_window(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal Rng2F32
|
internal Rng2F32
|
||||||
os_client_rect_from_window(OS_Handle handle)
|
os_client_rect_from_window(OS_Window handle)
|
||||||
{
|
{
|
||||||
Rng2F32 r = {0};
|
Rng2F32 r = {0};
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
@@ -1370,7 +1373,7 @@ os_client_rect_from_window(OS_Handle handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal F32
|
internal F32
|
||||||
os_dpi_from_window(OS_Handle handle)
|
os_dpi_from_window(OS_Window handle)
|
||||||
{
|
{
|
||||||
F32 result = 96.f;
|
F32 result = 96.f;
|
||||||
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
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)
|
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_Handle
|
internal OS_ExternalWindow
|
||||||
os_focused_external_window(void)
|
os_focused_external_window(void)
|
||||||
{
|
{
|
||||||
HWND hwnd = GetForegroundWindow();
|
HWND hwnd = GetForegroundWindow();
|
||||||
OS_Handle result = {(U64)hwnd};
|
OS_ExternalWindow result = {(U64)hwnd};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
os_focus_external_window(OS_Handle handle)
|
os_focus_external_window(OS_ExternalWindow handle)
|
||||||
{
|
{
|
||||||
HWND hwnd = (HWND)handle.u64[0];
|
HWND hwnd = (HWND)handle.u64[0];
|
||||||
if(hwnd != 0)
|
if(hwnd != 0)
|
||||||
@@ -1406,40 +1409,47 @@ os_focus_external_window(OS_Handle handle)
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||||
|
|
||||||
internal OS_HandleArray
|
internal OS_MonitorArray
|
||||||
os_push_monitors_array(Arena *arena)
|
os_push_monitors_array(Arena *arena)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
OS_HandleList list = {0};
|
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);
|
||||||
{
|
{
|
||||||
OS_W32_MonitorGatherBundle bundle = {arena, &list};
|
U64 idx = 0;
|
||||||
EnumDisplayMonitors(0, 0, os_w32_monitor_gather_enum_proc, (LPARAM)&bundle);
|
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);
|
scratch_end(scratch);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OS_Handle
|
internal OS_Monitor
|
||||||
os_primary_monitor(void)
|
os_primary_monitor(void)
|
||||||
{
|
{
|
||||||
POINT zero_pt = {0, 0};
|
POINT zero_pt = {0, 0};
|
||||||
HMONITOR monitor = MonitorFromPoint(zero_pt, MONITOR_DEFAULTTOPRIMARY);
|
HMONITOR monitor = MonitorFromPoint(zero_pt, MONITOR_DEFAULTTOPRIMARY);
|
||||||
OS_Handle result = {(U64)monitor};
|
OS_Monitor result = {(U64)monitor};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OS_Handle
|
internal OS_Monitor
|
||||||
os_monitor_from_window(OS_Handle window)
|
os_monitor_from_window(OS_Window window)
|
||||||
{
|
{
|
||||||
OS_W32_Window *w = os_w32_window_from_handle(window);
|
OS_W32_Window *w = os_w32_window_from_handle(window);
|
||||||
HMONITOR handle = MonitorFromWindow(w->hwnd, MONITOR_DEFAULTTOPRIMARY);
|
HMONITOR handle = MonitorFromWindow(w->hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
OS_Handle result = {(U64)handle};
|
OS_Monitor result = {(U64)handle};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
os_name_from_monitor(Arena *arena, OS_Monitor monitor)
|
||||||
{
|
{
|
||||||
String8 result = {0};
|
String8 result = {0};
|
||||||
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
||||||
@@ -1454,7 +1464,7 @@ os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal Vec2F32
|
internal Vec2F32
|
||||||
os_dim_from_monitor(OS_Handle monitor)
|
os_dim_from_monitor(OS_Monitor monitor)
|
||||||
{
|
{
|
||||||
Vec2F32 result = {0};
|
Vec2F32 result = {0};
|
||||||
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
||||||
@@ -1469,7 +1479,7 @@ os_dim_from_monitor(OS_Handle monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal F32
|
internal F32
|
||||||
os_dpi_from_monitor(OS_Handle monitor)
|
os_dpi_from_monitor(OS_Monitor monitor)
|
||||||
{
|
{
|
||||||
F32 result = 96.f;
|
F32 result = 96.f;
|
||||||
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
HMONITOR monitor_handle = (HMONITOR)monitor.u64[0];
|
||||||
@@ -1546,7 +1556,7 @@ os_key_is_down(OS_Key key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal Vec2F32
|
internal Vec2F32
|
||||||
os_mouse_from_window(OS_Handle handle)
|
os_mouse_from_window(OS_Window handle)
|
||||||
{
|
{
|
||||||
ProfBeginFunction();
|
ProfBeginFunction();
|
||||||
Vec2F32 v = {0};
|
Vec2F32 v = {0};
|
||||||
|
|||||||
@@ -54,11 +54,20 @@ struct OS_W32_Window
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Monitor Gathering Bundle
|
//~ 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;
|
typedef struct OS_W32_MonitorGatherBundle OS_W32_MonitorGatherBundle;
|
||||||
struct OS_W32_MonitorGatherBundle
|
struct OS_W32_MonitorGatherBundle
|
||||||
{
|
{
|
||||||
Arena *arena;
|
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
|
//~ rjf: Windows
|
||||||
|
|
||||||
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window);
|
internal OS_Window os_w32_handle_from_window(OS_W32_Window *window);
|
||||||
internal OS_W32_Window * os_w32_window_from_handle(OS_Handle 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 OS_W32_Window * os_w32_window_from_hwnd(HWND hwnd);
|
||||||
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
|
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
|
||||||
internal OS_W32_Window * os_w32_window_alloc(void);
|
internal OS_W32_Window * os_w32_window_alloc(void);
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// 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
|
#if OS_FEATURE_GRAPHICAL
|
||||||
# include "os/gfx/os_gfx.c"
|
# include "os/gfx/os_gfx.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
# include "os/core/win32/os_core_win32.c"
|
// # include "os/core/win32/os_core_win32.c"
|
||||||
#elif OS_LINUX
|
#elif OS_LINUX
|
||||||
# include "os/core/linux/os_core_linux.c"
|
# include "os/core/linux/os_core_linux.c"
|
||||||
#else
|
#else
|
||||||
|
|||||||
+2
-2
@@ -12,13 +12,13 @@
|
|||||||
# define OS_GFX_STUB 0
|
# define OS_GFX_STUB 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os/core/os_core.h"
|
// #include "os/core/os_core.h"
|
||||||
#if OS_FEATURE_GRAPHICAL
|
#if OS_FEATURE_GRAPHICAL
|
||||||
# include "os/gfx/os_gfx.h"
|
# include "os/gfx/os_gfx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
# include "os/core/win32/os_core_win32.h"
|
// # include "os/core/win32/os_core_win32.h"
|
||||||
#elif OS_LINUX
|
#elif OS_LINUX
|
||||||
# include "os/core/linux/os_core_linux.h"
|
# include "os/core/linux/os_core_linux.h"
|
||||||
#else
|
#else
|
||||||
|
|||||||
-21
@@ -520,10 +520,6 @@ pe_bin_info_from_data(Arena *arena, String8 data)
|
|||||||
reported_data_dir_offset = sizeof(*pe_optional);
|
reported_data_dir_offset = sizeof(*pe_optional);
|
||||||
reported_data_dir_count = pe_optional->data_dir_count;
|
reported_data_dir_count = pe_optional->data_dir_count;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert(!"unable to read PE Optional Header");
|
|
||||||
}
|
|
||||||
}break;
|
}break;
|
||||||
case PE_PE32PLUS_MAGIC:
|
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_offset = sizeof(*pe_optional);
|
||||||
reported_data_dir_count = pe_optional->data_dir_count;
|
reported_data_dir_count = pe_optional->data_dir_count;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert(!"unable to read PE Optional Plus Header");
|
|
||||||
}
|
|
||||||
}break;
|
}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);
|
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);
|
data_dir_franges[dir_idx] = r1u64(file_off, file_off+dir.virt_size);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert(!"unable to read data directory");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// export virtual directory ranges
|
// 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);
|
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
|
// 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.zero_fill_size = (U64)tls_header32.zero_fill_size;
|
||||||
tls_header.characteristics = (U64)tls_header32.characteristics;
|
tls_header.characteristics = (U64)tls_header32.characteristics;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert(!"unable to read TLS Header 32");
|
|
||||||
}
|
|
||||||
}break;
|
}break;
|
||||||
case COFF_MachineType_X64:
|
case COFF_MachineType_X64:
|
||||||
{
|
{
|
||||||
if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header) != sizeof(tls_header))
|
if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header) != sizeof(tls_header))
|
||||||
{
|
{
|
||||||
MemoryZeroStruct(&tls_header);
|
MemoryZeroStruct(&tls_header);
|
||||||
Assert(!"unable to read TLS Header 64");
|
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -13,7 +13,7 @@ internal void
|
|||||||
rb_entry_point(CmdLine *cmdline)
|
rb_entry_point(CmdLine *cmdline)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(0, 0);
|
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"));
|
String8 threads_count_from_cmdline_string = cmd_line_string(cmdline, str8_lit("thread_count"));
|
||||||
if(threads_count_from_cmdline_string.size != 0)
|
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)
|
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);
|
String8List input_file_path_tasks = str8_list_copy(arena, &cmdline->inputs);
|
||||||
for(String8Node *n = input_file_path_tasks.first; n != 0; n = n->next)
|
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;
|
RB_FileFormatFlags file_format_flags = 0;
|
||||||
ProfScope("do thin analysis of file")
|
ProfScope("do thin analysis of file")
|
||||||
{
|
{
|
||||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, input_file_path);
|
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, input_file_path);
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = properties_from_file(file);
|
||||||
|
|
||||||
//- rjf: PDB magic -> PDB input
|
//- rjf: PDB magic -> PDB input
|
||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
U8 msf20_magic_maybe[sizeof(msf_msf20_magic)] = {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)))
|
if(MemoryMatch(msf20_magic_maybe, msf_msf20_magic, sizeof(msf20_magic_maybe)))
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_PDB;
|
file_format = RB_FileFormat_PDB;
|
||||||
@@ -109,7 +109,7 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
U8 msf70_magic_maybe[sizeof(msf_msf70_magic)] = {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)))
|
if(MemoryMatch(msf70_magic_maybe, msf_msf70_magic, sizeof(msf70_magic_maybe)))
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_PDB;
|
file_format = RB_FileFormat_PDB;
|
||||||
@@ -120,11 +120,11 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
PE_DosHeader dos_header_maybe = {0};
|
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)
|
if(dos_header_maybe.magic == PE_DOS_MAGIC)
|
||||||
{
|
{
|
||||||
U32 pe_magic_maybe = 0;
|
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)
|
if(pe_magic_maybe == PE_MAGIC)
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_PE;
|
file_format = RB_FileFormat_PE;
|
||||||
@@ -136,7 +136,7 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
U8 coff_archive_sig_maybe[sizeof(g_coff_archive_sig)] = {0};
|
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)))
|
if(MemoryMatch(coff_archive_sig_maybe, g_coff_archive_sig, sizeof(g_coff_archive_sig)))
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_COFF_Archive;
|
file_format = RB_FileFormat_COFF_Archive;
|
||||||
@@ -145,7 +145,7 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
U8 coff_thin_archive_sig_maybe[sizeof(g_coff_thin_archive_sig)] = {0};
|
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)))
|
if(MemoryMatch(coff_thin_archive_sig_maybe, g_coff_thin_archive_sig, sizeof(g_coff_thin_archive_sig)))
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_COFF_ThinArchive;
|
file_format = RB_FileFormat_COFF_ThinArchive;
|
||||||
@@ -156,7 +156,7 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
COFF_BigObjHeader header_maybe = {0};
|
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 &&
|
if(header_maybe.sig1 == COFF_MachineType_Unknown &&
|
||||||
header_maybe.sig2 == max_U16 &&
|
header_maybe.sig2 == max_U16 &&
|
||||||
header_maybe.version >= 2 &&
|
header_maybe.version >= 2 &&
|
||||||
@@ -169,7 +169,7 @@ rb_thread_entry_point(void *p)
|
|||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
COFF_FileHeader header_maybe = {0};
|
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_count = header_maybe.section_count;
|
||||||
U64 section_hdr_opl_off = sizeof(header_maybe) + section_count*sizeof(COFF_SectionHeader);
|
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)
|
if(props.size >= section_hdr_opl_off)
|
||||||
{
|
{
|
||||||
COFF_SectionHeader *section_hdrs = push_array(scratch.arena, COFF_SectionHeader, section_count);
|
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;
|
B32 section_ranges_valid = 1;
|
||||||
for EachIndex(section_hdr_idx, section_count)
|
for EachIndex(section_hdr_idx, section_count)
|
||||||
{
|
{
|
||||||
@@ -252,7 +252,7 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
U8 identifier_maybe[ELF_Identifier_Max] = {0};
|
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 &&
|
B32 is_elf_magic = (identifier_maybe[ELF_Identifier_Mag0] == 0x7f &&
|
||||||
identifier_maybe[ELF_Identifier_Mag1] == 'E' &&
|
identifier_maybe[ELF_Identifier_Mag1] == 'E' &&
|
||||||
identifier_maybe[ELF_Identifier_Mag2] == 'L' &&
|
identifier_maybe[ELF_Identifier_Mag2] == 'L' &&
|
||||||
@@ -267,14 +267,14 @@ rb_thread_entry_point(void *p)
|
|||||||
if(file_format == RB_FileFormat_Null)
|
if(file_format == RB_FileFormat_Null)
|
||||||
{
|
{
|
||||||
RDI_Header rdi_header_maybe = {0};
|
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)
|
if(rdi_header_maybe.magic == RDI_MAGIC_CONSTANT)
|
||||||
{
|
{
|
||||||
file_format = RB_FileFormat_RDI;
|
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};
|
String8 file_data = {0};
|
||||||
if(file_format != RB_FileFormat_Null) ProfScope("load recognized file")
|
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]")
|
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)
|
if(is_written)
|
||||||
{
|
{
|
||||||
log_infof("Results written to %S", output_path);
|
log_infof("Results written to %S", output_path);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "pdb/pdb.h"
|
#include "pdb/pdb.h"
|
||||||
#include "pdb/pdb_parse.h"
|
#include "pdb/pdb_parse.h"
|
||||||
#include "pdb/pdb_stringize.h"
|
#include "pdb/pdb_stringize.h"
|
||||||
|
#include "arch/arch_inc.h"
|
||||||
#include "rdi_from_coff/rdi_from_coff.h"
|
#include "rdi_from_coff/rdi_from_coff.h"
|
||||||
#include "rdi_from_elf/rdi_from_elf.h"
|
#include "rdi_from_elf/rdi_from_elf.h"
|
||||||
#include "rdi_from_pdb/rdi_from_pdb.h"
|
#include "rdi_from_pdb/rdi_from_pdb.h"
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
#include "pdb/pdb.c"
|
#include "pdb/pdb.c"
|
||||||
#include "pdb/pdb_parse.c"
|
#include "pdb/pdb_parse.c"
|
||||||
#include "pdb/pdb_stringize.c"
|
#include "pdb/pdb_stringize.c"
|
||||||
|
#include "arch/arch_inc.c"
|
||||||
#include "rdi_from_coff/rdi_from_coff.c"
|
#include "rdi_from_coff/rdi_from_coff.c"
|
||||||
#include "rdi_from_elf/rdi_from_elf.c"
|
#include "rdi_from_elf/rdi_from_elf.c"
|
||||||
#include "rdi_from_pdb/rdi_from_pdb.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
Reference in New Issue
Block a user