re-slice linux/win32 backends, top-level folder is backend (demon/win32 -> win32/demon, etc.); os_gfx -> window_manager; fix linux / opengl builds for new apis/types

This commit is contained in:
Ryan Fleury
2026-05-08 15:21:22 -07:00
parent aea4a4ff9d
commit 9a7782de47
50 changed files with 12981 additions and 19517 deletions
+2 -2
View File
@@ -49,13 +49,13 @@ commands =
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .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 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: [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 = "build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "wsl ./build.sh 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, },
+2 -1
View File
@@ -28,7 +28,8 @@ struct ARCH_Info
global read_only Rng1U16 arch_reg_code_rng_nil = {0}; global read_only Rng1U16 arch_reg_code_rng_nil = {0};
global read_only String8 arch_reg_code_name_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 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}; global read_only B8 arch_reg_code_b8_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_b8_nil};
//////////////////////////////// ////////////////////////////////
//~ rjf: Abstracted Architecture Functions //~ rjf: Abstracted Architecture Functions
+2 -2
View File
@@ -4,9 +4,9 @@
#include "demon/demon_core.c" #include "demon/demon_core.c"
#if OS_WINDOWS #if OS_WINDOWS
# include "demon/win32/demon_core_win32.c" # include "win32/demon/win32_demon.c"
#elif OS_LINUX #elif OS_LINUX
# include "demon/linux/demon_core_linux.c" # include "linux/demon/linux_demon.c"
#else #else
# error Demon layer backend not defined for this operating system. # error Demon layer backend not defined for this operating system.
#endif #endif
+2 -2
View File
@@ -7,9 +7,9 @@
#include "demon/demon_core.h" #include "demon/demon_core.h"
#if OS_WINDOWS #if OS_WINDOWS
# include "demon/win32/demon_core_win32.h" # include "win32/demon/win32_demon.h"
#elif OS_LINUX #elif OS_LINUX
# include "demon/linux/demon_core_linux.h" # include "linux/demon/linux_demon.h"
#else #else
# error Demon layer backend not defined for this operating system. # error Demon layer backend not defined for this operating system.
#endif #endif
File diff suppressed because it is too large Load Diff
-222
View File
@@ -1,222 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_OS_LINUX_H
#define DEMON_OS_LINUX_H
// TODO(allen): Potential Upgrades:
//
// memory fd upgrade - Right now for each process we hold open a file
// descriptor for the process's memory (/proc/%d/mem) for the entire lifetime
// of the process; it could be opened and closed with some kind of LRU cache
// to put a finite cap on the number of handles the demon holds
//
////////////////////////////////
//~ NOTE(allen): Get The Linux Includes
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <elf.h>
#include <dirent.h>
#include <errno.h>
////////////////////////////////
//~ NOTE(allen): Linux Demon Types
//- entities
// Demon Linux Entity Extensions
// Process: ext_u64 set to memory file descriptor
// Thread : ext_u64 cast to DEMON_LNX_ThreadExt
// Module : ext_u64 set to U64 (address of name)
struct DEMON_LNX_ThreadExt{
B32 expecting_dummy_sigstop;
};
StaticAssert(sizeof(DEMON_LNX_ThreadExt) <= sizeof(Member(DEMON_Entity, ext_u64)), check_demon_lnx_thread_ext);
//- helpers
struct DEMON_LNX_AttachNode{
DEMON_LNX_AttachNode *next;
pid_t pid;
};
struct DEMON_LNX_ProcessAux{
B32 filled;
U64 phnum;
U64 phent;
U64 phdr;
U64 execfn;
};
struct DEMON_LNX_PhdrInfo{
Rng1U64 range;
U64 dynamic;
};
struct DEMON_LNX_ModuleNode{
DEMON_LNX_ModuleNode *next;
U64 vaddr;
U64 size;
U64 name;
U64 already_known;
};
struct DEMON_LNX_EntityNode{
DEMON_LNX_EntityNode *next;
DEMON_Entity *entity;
};
////////////////////////////////
//~ NOTE(allen): Linux Demon Register Layouts
// these are defined in <sys/user.h> but only for one architecture at a time
// (and we can't really trick it into giving us both in any obvious way)
// we define them here so that we have them all "at once"
struct DEMON_LNX_UserRegsX64{
U64 r15;
U64 r14;
U64 r13;
U64 r12;
U64 rbp;
U64 rbx;
U64 r11;
U64 r10;
U64 r9;
U64 r8;
U64 rax;
U64 rcx;
U64 rdx;
U64 rsi;
U64 rdi;
U64 orig_rax;
U64 rip;
U64 cs;
U64 rflags;
U64 rsp;
U64 ss;
U64 fsbase;
U64 gsbase;
U64 ds;
U64 es;
U64 fs;
U64 gs;
};
struct DEMON_LNX_UserX64{
DEMON_LNX_UserRegsX64 regs;
S32 u_fpvalid, _pad0;
SYMS_XSaveLegacy i387;
U64 u_tsize, u_dsize, u_ssize, start_code, start_stack;
U64 signal;
S32 reserved, _pad1;
U64 u_ar0, u_fpstate;
U64 magic;
U8 u_comm[32];
U64 u_debugreg[8];
};
struct DEMON_LNX_UserRegsX86{
U32 ebx;
U32 ecx;
U32 edx;
U32 esi;
U32 edi;
U32 ebp;
U32 eax;
U32 ds;
U32 es;
U32 fs;
U32 gs;
U32 orig_eax;
U32 eip;
U32 cs;
U32 eflags;
U32 sp;
U32 ss;
};
struct DEMON_LNX_UserX86{
DEMON_LNX_UserRegsX86 regs;
S32 u_fpvalid;
SYMS_FSave i387;
U32 u_tsize, u_dsize, u_ssize, start_code, start_stack;
S32 signal, reserved;
U32 u_ar0, u_fpstate;
U32 magic;
U8 u_comm[32];
U32 u_debugreg[8];
};
////////////////////////////////
enum
{
DEMON_LNX_PermFlags_Read = (1 << 0),
DEMON_LNX_PermFlags_Write = (1 << 1),
DEMON_LNX_PermFlags_Exec = (1 << 2),
DEMON_LNX_PermFlags_Private = (1 << 3)
};
typedef int DEMON_LNX_PermFlags;
enum
{
DEMON_LNX_MapsEntryType_Null,
DEMON_LNX_MapsEntryType_Path,
DEMON_LNX_MapsEntryType_Heap,
DEMON_LNX_MapsEntryType_Stack,
DEMON_LNX_MapsEntryType_VDSO,
};
typedef int DEMON_LNX_MapsEntryType;
struct DEMON_LNX_MapsEntry
{
U64 address_lo;
U64 address_hi;
DEMON_LNX_PermFlags perms;
U64 offset;
U32 dev_major;
U32 dev_minor;
U64 inode;
String8 pathname;
DEMON_LNX_MapsEntryType type;
pid_t stack_tid;
};
////////////////////////////////
//~ rjf: Helpers
internal DEMON_LNX_ThreadExt* demon_lnx_thread_ext(DEMON_Entity *entity);
internal B32 demon_lnx_attach_pid(Arena *arena, pid_t pid, DEMON_LNX_AttachNode **new_node);
internal String8 demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid);
internal int demon_lnx_open_memory_fd_for_pid(pid_t pid);
internal Arch demon_lnx_arch_from_pid(pid_t pid);
internal DEMON_LNX_ProcessAux demon_lnx_aux_from_pid(pid_t pid, Arch arch);
internal DEMON_LNX_PhdrInfo demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit,
U64 phvaddr, U64 phstride, U64 phcount);
internal DEMON_LNX_ModuleNode* demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process);
internal U64 demon_lnx_read_memory(int memory_fd, void *dst, U64 src, U64 size);
internal B32 demon_lnx_write_memory(int memory_fd, U64 dst, void *src, U64 size);
internal String8 demon_lnx_read_memory_str(Arena *arena, int memory_fd, U64 address);
internal void demon_lnx_regs_x64_from_usr_regs_x64(SYMS_RegX64 *dst, DEMON_LNX_UserRegsX64 *src);
internal void demon_lnx_usr_regs_x64_from_regs_x64(DEMON_LNX_UserRegsX64 *dst, SYMS_RegX64 *src);
internal String8 demon_lnx_read_int_string(int fd);
internal B32 demon_lnx_read_expect(int fd, char expect);
internal int demon_lnx_read_whitespace(int fd);
internal String8 demon_lnx_read_string(Arena *arena, int fd);
internal int demon_lnx_open_maps(pid_t pid);
internal B32 demon_lnx_next_map(Arena *arena, int maps, DEMON_LNX_MapsEntry *entry_out);
#endif //DEMON_OS_LINUX_H
-2
View File
@@ -17,7 +17,6 @@
// --- Code Base --------------------------------------------------------------- // --- Code Base ---------------------------------------------------------------
#include "base/base_inc.h" #include "base/base_inc.h"
#include "os/os_inc.h"
#include "hash_table.h" #include "hash_table.h"
#include "coff/coff.h" #include "coff/coff.h"
#include "coff/coff_parse.h" #include "coff/coff_parse.h"
@@ -37,7 +36,6 @@
#include "llvm/llvm.h" #include "llvm/llvm.h"
#include "base/base_inc.c" #include "base/base_inc.c"
#include "os/os_inc.c"
#include "hash_table.c" #include "hash_table.c"
#include "coff/coff.c" #include "coff/coff.c"
#include "coff/coff_parse.c" #include "coff/coff_parse.c"
File diff suppressed because it is too large Load Diff
+150
View File
@@ -4,4 +4,154 @@
#ifndef LINUX_BASE_H #ifndef LINUX_BASE_H
#define LINUX_BASE_H #define LINUX_BASE_H
////////////////////////////////
//~ rjf: Includes
#include <dirent.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <errno.h>
#include <execinfo.h>
#include <fcntl.h>
#include <features.h>
#include <linux/limits.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <spawn.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
pid_t gettid(void);
int pthread_setname_np(pthread_t thread, const char *name);
int pthread_getname_np(pthread_t thread, char *name, size_t size);
typedef struct tm tm;
typedef struct timespec timespec;
////////////////////////////////
//~ rjf: Linux Call Interruption Retry Helper
#define OS_LNX_RETRY_ON_EINTR(expr) \
(__extension__({ \
__typeof__(expr) __ret; \
do { \
__ret = (expr); \
} while ((__ret == -1) && errno == EINTR); \
__ret; \
}))
////////////////////////////////
//~ rjf: File Iterator
typedef struct OS_LNX_FileIter OS_LNX_FileIter;
struct OS_LNX_FileIter
{
DIR *dir;
struct dirent *dp;
String8 path;
};
StaticAssert(sizeof(Member(FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check);
////////////////////////////////
//~ rjf: Safe Call Handler Chain
typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
struct OS_LNX_SafeCallChain
{
OS_LNX_SafeCallChain *next;
ThreadEntryPointFunctionType *fail_handler;
void *ptr;
};
////////////////////////////////
//~ rjf: Entities
typedef enum OS_LNX_EntityKind
{
OS_LNX_EntityKind_Thread,
OS_LNX_EntityKind_Mutex,
OS_LNX_EntityKind_RWMutex,
OS_LNX_EntityKind_ConditionVariable,
OS_LNX_EntityKind_Barrier,
}
OS_LNX_EntityKind;
typedef struct OS_LNX_Entity OS_LNX_Entity;
struct OS_LNX_Entity
{
OS_LNX_Entity *next;
OS_LNX_EntityKind kind;
union
{
struct
{
pthread_t handle;
ThreadEntryPointFunctionType *func;
void *ptr;
} thread;
pthread_mutex_t mutex_handle;
pthread_rwlock_t rwmutex_handle;
struct
{
pthread_cond_t cond_handle;
pthread_mutex_t rwlock_mutex_handle;
} cv;
pthread_barrier_t barrier;
};
};
////////////////////////////////
//~ rjf: State
typedef struct OS_LNX_State OS_LNX_State;
struct OS_LNX_State
{
Arena *arena;
SystemInfo system_info;
ProcessInfo process_info;
pthread_mutex_t entity_mutex;
Arena *entity_arena;
OS_LNX_Entity *entity_free;
U64 default_env_count;
char **default_env;
};
////////////////////////////////
//~ rjf: Globals
global OS_LNX_State os_lnx_state = {0};
thread_static OS_LNX_SafeCallChain *os_lnx_safe_call_chain = 0;
////////////////////////////////
//~ rjf: Helpers
internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec);
internal tm os_lnx_tm_from_date_time(DateTime dt);
internal timespec os_lnx_timespec_from_date_time(DateTime dt);
internal DenseTime os_lnx_dense_time_from_timespec(timespec in);
internal FileProperties os_lnx_file_properties_from_stat(struct stat *s);
internal void os_lnx_safe_call_sig_handler(int x);
////////////////////////////////
//~ rjf: Entities
internal OS_LNX_Entity *os_lnx_entity_alloc(OS_LNX_EntityKind kind);
internal void os_lnx_entity_release(OS_LNX_Entity *entity);
////////////////////////////////
//~ rjf: Thread Entry Point
internal void *os_lnx_thread_entry_point(void *ptr);
#endif // LINUX_BASE_H #endif // LINUX_BASE_H
@@ -1163,13 +1163,12 @@ dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp)
internal B32 internal B32
dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread) dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
{ {
AssertAlways(thread->state == DMN_LNX_ThreadState_Stopped);
B32 is_reg_block_read = 0; B32 is_reg_block_read = 0;
if(thread->state == DMN_LNX_ThreadState_Stopped)
{
switch(thread->process->ctx->arch) switch(thread->process->ctx->arch)
{ {
case Arch_Null: {} break; default:{}break;
case Arch_x64: case Arch_x64:
{ {
DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx; DMN_LNX_ProcessCtx *process_ctx = thread->process->ctx;
@@ -1181,32 +1180,32 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_len = sizeof(src), .iov_base = &src })); int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_len = sizeof(src), .iov_base = &src }));
if(ptrace_result < 0) { goto exit; } if(ptrace_result < 0) { goto exit; }
dst->r15.u64 = src.r15; dst->r15 = src.r15;
dst->r14.u64 = src.r14; dst->r14 = src.r14;
dst->r13.u64 = src.r13; dst->r13 = src.r13;
dst->r12.u64 = src.r12; dst->r12 = src.r12;
dst->rbp.u64 = src.rbp; dst->rbp = src.rbp;
dst->rbx.u64 = src.rbx; dst->rbx = src.rbx;
dst->r11.u64 = src.r11; dst->r11 = src.r11;
dst->r10.u64 = src.r10; dst->r10 = src.r10;
dst->r9.u64 = src.r9; dst->r9 = src.r9;
dst->r8.u64 = src.r8; dst->r8 = src.r8;
dst->rax.u64 = src.rax; dst->rax = src.rax;
dst->rcx.u64 = src.rcx; dst->rcx = src.rcx;
dst->rdx.u64 = src.rdx; dst->rdx = src.rdx;
dst->rsi.u64 = src.rsi; dst->rsi = src.rsi;
dst->rdi.u64 = src.rdi; dst->rdi = src.rdi;
dst->rip.u64 = src.rip; dst->rip = src.rip;
dst->cs.u16 = src.cs; dst->cs = src.cs;
dst->rflags.u64 = src.rflags; dst->rflags = src.rflags;
dst->rsp.u64 = src.rsp; dst->rsp = src.rsp;
dst->ss.u16 = src.ss; dst->ss = src.ss;
dst->fsbase.u64 = src.fsbase; dst->fsbase = src.fsbase;
dst->gsbase.u64 = src.gsbase; dst->gsbase = src.gsbase;
dst->ds.u16 = src.ds; dst->ds = src.ds;
dst->es.u16 = src.es; dst->es = src.es;
dst->fs.u16 = src.fs; dst->fs = src.fs;
dst->gs.u16 = src.gs; dst->gs = src.gs;
thread->orig_rax = src.orig_rax; thread->orig_rax = src.orig_rax;
} }
@@ -1223,7 +1222,6 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
void *xsave_raw = push_array(scratch.arena, U8, process_ctx->xsave_size); void *xsave_raw = push_array(scratch.arena, U8, process_ctx->xsave_size);
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_X86_XSTATE, &(struct iovec){ .iov_len = process_ctx->xsave_size, .iov_base = xsave_raw })); int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_X86_XSTATE, &(struct iovec){ .iov_len = process_ctx->xsave_size, .iov_base = xsave_raw }));
if(ptrace_result < 0) { goto exit; } if(ptrace_result < 0) { goto exit; }
xsave = xsave_raw; xsave = xsave_raw;
fxsave = &xsave->fxsave; fxsave = &xsave->fxsave;
} }
@@ -1234,7 +1232,6 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
fxsave = push_array(scratch.arena, X64_FXSave, 1); fxsave = push_array(scratch.arena, X64_FXSave, 1);
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_FPREGSET, &(struct iovec){ .iov_len = sizeof(*fxsave), .iov_base = fxsave })); int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, thread->tid, (void *)NT_FPREGSET, &(struct iovec){ .iov_len = sizeof(*fxsave), .iov_base = fxsave }));
if(ptrace_result < 0) { goto exit; } if(ptrace_result < 0) { goto exit; }
fxsave = 0; fxsave = 0;
} }
@@ -1244,23 +1241,23 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
X64_FXSave *src = fxsave; X64_FXSave *src = fxsave;
// copy x87 registers // copy x87 registers
dst->fcw.u16 = src->fcw; dst->fcw = src->fcw;
dst->fsw.u16 = src->fsw; dst->fsw = src->fsw;
dst->ftw = src->ftw; dst->ftw = src->ftw;
dst->fop.u16 = src->fop; dst->fop = src->fop;
dst->fip.u64 = src->fip; dst->fip = src->fip;
dst->fdp.u64 = src->fdp; dst->fdp = src->fdp;
dst->mxcsr.u32 = src->mxcsr; dst->mxcsr = src->mxcsr;
dst->mxcsr_mask.u32 = src->mxcsr_mask; dst->mxcsr_mask = src->mxcsr_mask;
for EachIndex(i, 8) for EachIndex(i, 8)
{ {
MemoryCopy(&dst->st0 + i, src->st_space + i, sizeof(REGS_Reg80)); MemoryCopy(&dst->st0 + i, src->st_space + i, sizeof(U80));
} }
// SSE registers are always available in x64 // SSE registers are always available in x64
{ {
U128 *xmm_d = fxsave->xmm_space; U128 *xmm_d = fxsave->xmm_space;
REGS_Reg512 *zmm_s = &dst->zmm0; U512 *zmm_s = &dst->zmm0;
for EachIndex(i, 16) for EachIndex(i, 16)
{ {
MemoryCopy(&zmm_s[i], &xmm_d[i], sizeof(*xmm_d)); MemoryCopy(&zmm_s[i], &xmm_d[i], sizeof(*xmm_d));
@@ -1269,61 +1266,61 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
} }
// copy xsave registers // copy xsave registers
if(xsave) //
// compact register layout is not supported (xsave->header.xcomp_bv == 0)
//
if(xsave && xsave->header.xcomp_bv == 0)
{ {
// compact register layout is not supported if(xsave->header.xstate_bv & X64_XStateComponentFlag_AVX &&
AssertAlways(xsave->header.xcomp_bv == 0); process_ctx->xsave_layout.avx_offset + 16*sizeof(U128) <= process_ctx->xsave_size)
if(xsave->header.xstate_bv & X64_XStateComponentFlag_AVX)
{ {
AssertAlways(process_ctx->xsave_layout.avx_offset + 16*sizeof(REGS_Reg128) <= process_ctx->xsave_size); U128 *avx_s = (U128 *)((U8 *)xsave + process_ctx->xsave_layout.avx_offset);
REGS_Reg128 *avx_s = (REGS_Reg128 *)((U8 *)xsave + process_ctx->xsave_layout.avx_offset); U512 *zmm_d = &dst->zmm0;
REGS_Reg512 *zmm_d = &dst->zmm0;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&zmm_d[n].v[16], &avx_s[n], sizeof(REGS_Reg128)); MemoryCopy(&zmm_d[n].u8[16], &avx_s[n], sizeof(U128));
} }
} }
if(xsave->header.xstate_bv & X64_XStateComponentFlag_OPMASK) if(xsave->header.xstate_bv & X64_XStateComponentFlag_OPMASK &&
process_ctx->xsave_layout.opmask_offset + sizeof(U64) * 8 <= process_ctx->xsave_size)
{ {
AssertAlways(process_ctx->xsave_layout.opmask_offset + sizeof(REGS_Reg64) * 8 <= process_ctx->xsave_size); U64 *kmask_s = (U64 *)((U8 *)xsave + process_ctx->xsave_layout.opmask_offset);
REGS_Reg64 *kmask_s = (REGS_Reg64 *)((U8 *)xsave + process_ctx->xsave_layout.opmask_offset); U64 *kmask_d = &dst->k0;
REGS_Reg64 *kmask_d = &dst->k0;
for EachIndex(n, 8) for EachIndex(n, 8)
{ {
MemoryCopy(&kmask_d[n], &kmask_s[n], sizeof(REGS_Reg64)); MemoryCopy(&kmask_d[n], &kmask_s[n], sizeof(U64));
} }
} }
if(xsave->header.xstate_bv & X64_XStateComponentFlag_ZMM_H) if(xsave->header.xstate_bv & X64_XStateComponentFlag_ZMM_H &&
process_ctx->xsave_layout.zmm_h_offset + sizeof(U256) * 16 <= process_ctx->xsave_size)
{ {
AssertAlways(process_ctx->xsave_layout.zmm_h_offset + sizeof(REGS_Reg256) * 16 <= process_ctx->xsave_size); U256 *avx512h_s = (U256 *)((U8 *)xsave + process_ctx->xsave_layout.zmm_h_offset);
REGS_Reg256 *avx512h_s = (REGS_Reg256 *)((U8 *)xsave + process_ctx->xsave_layout.zmm_h_offset); U512 *zmmh_d = &dst->zmm0;
REGS_Reg512 *zmmh_d = &dst->zmm0;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&zmmh_d[n].v[32], &avx512h_s[n], sizeof(REGS_Reg256)); MemoryCopy(&zmmh_d[n].u8[32], &avx512h_s[n], sizeof(U256));
} }
} }
if(xsave->header.xstate_bv & X64_XStateComponentFlag_ZMM) if(xsave->header.xstate_bv & X64_XStateComponentFlag_ZMM &&
process_ctx->xsave_layout.zmm_offset + sizeof(U512) * 16 <= process_ctx->xsave_size)
{ {
AssertAlways(process_ctx->xsave_layout.zmm_offset + sizeof(REGS_Reg512) * 16 <= process_ctx->xsave_size); U512 *avx512_s = (U512 *)((U8 *)xsave + process_ctx->xsave_layout.zmm_offset);
REGS_Reg512 *avx512_s = (REGS_Reg512 *)((U8 *)xsave + process_ctx->xsave_layout.zmm_offset); U512 *zmm_d = &dst->zmm16;
REGS_Reg512 *zmm_d = &dst->zmm16;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&zmm_d[n], &avx512_s[n], sizeof(REGS_Reg512)); MemoryCopy(&zmm_d[n], &avx512_s[n], sizeof(U512));
} }
} }
if(xsave->header.xstate_bv & X64_XStateComponentFlag_CETU) if(xsave->header.xstate_bv & X64_XStateComponentFlag_CETU &&
process_ctx->xsave_layout.cet_u_offset + sizeof(U64)*2 <= process_ctx->xsave_size)
{ {
AssertAlways(process_ctx->xsave_layout.cet_u_offset + sizeof(U64)*2 <= process_ctx->xsave_size);
U64 *cet_u = (U64 *)((U8 *)xsave + process_ctx->xsave_layout.cet_u_offset); U64 *cet_u = (U64 *)((U8 *)xsave + process_ctx->xsave_layout.cet_u_offset);
dst->cetmsr.u64 = cet_u[0]; dst->cetmsr = cet_u[0];
dst->cetssp.u64 = cet_u[1]; dst->cetssp = cet_u[1];
} }
} }
@@ -1332,7 +1329,7 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
// debug registers // debug registers
{ {
REGS_Reg64 *dr_d = &dst->dr0; U64 *dr_d = &dst->dr0;
for EachIndex(n, 8) for EachIndex(n, 8)
{ {
if(n != 4 && n != 5) if(n != 4 && n != 5)
@@ -1341,19 +1338,15 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread)
errno = 0; errno = 0;
long peek_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_PEEKUSER, thread->tid, PtrFromInt(offset), 0)); long peek_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_PEEKUSER, thread->tid, PtrFromInt(offset), 0));
if(errno != 0) { goto exit; } if(errno != 0) { goto exit; }
dr_d[n].u64 = peek_result; dr_d[n] = peek_result;
} }
} }
} }
is_reg_block_read = 1; is_reg_block_read = 1;
}break; }break;
case Arch_x86:
case Arch_arm64:
case Arch_arm32: { NotImplemented; } break;
default: { InvalidPath; } break;
} }
}
exit:; exit:;
return is_reg_block_read; return is_reg_block_read;
} }
@@ -1376,33 +1369,33 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
// general purpose registers // general purpose registers
{ {
OS_LNX_GprsX64 dst; OS_LNX_GprsX64 dst;
dst.r15 = src->r15.u64; dst.r15 = src->r15;
dst.r14 = src->r14.u64; dst.r14 = src->r14;
dst.r13 = src->r13.u64; dst.r13 = src->r13;
dst.r12 = src->r12.u64; dst.r12 = src->r12;
dst.rbp = src->rbp.u64; dst.rbp = src->rbp;
dst.rbx = src->rbx.u64; dst.rbx = src->rbx;
dst.r11 = src->r11.u64; dst.r11 = src->r11;
dst.r10 = src->r10.u64; dst.r10 = src->r10;
dst.r9 = src->r9.u64; dst.r9 = src->r9;
dst.r8 = src->r8.u64; dst.r8 = src->r8;
dst.rax = src->rax.u64; dst.rax = src->rax;
dst.rcx = src->rcx.u64; dst.rcx = src->rcx;
dst.rdx = src->rdx.u64; dst.rdx = src->rdx;
dst.rsi = src->rsi.u64; dst.rsi = src->rsi;
dst.rdi = src->rdi.u64; dst.rdi = src->rdi;
dst.orig_rax = thread->orig_rax; dst.orig_rax = thread->orig_rax;
dst.rip = src->rip.u64; dst.rip = src->rip;
dst.cs = src->cs.u16; dst.cs = src->cs;
dst.rflags = src->rflags.u64; dst.rflags = src->rflags;
dst.rsp = src->rsp.u64; dst.rsp = src->rsp;
dst.ss = src->ss.u16; dst.ss = src->ss;
dst.fsbase = src->fsbase.u64; dst.fsbase = src->fsbase;
dst.gsbase = src->gsbase.u64; dst.gsbase = src->gsbase;
dst.ds = src->ds.u16; dst.ds = src->ds;
dst.es = src->es.u16; dst.es = src->es;
dst.fs = src->fs.u16; dst.fs = src->fs;
dst.gs = src->gs.u16; dst.gs = src->gs;
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_SETREGSET, thread->tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_base = &dst, .iov_len = sizeof(dst) })); int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_SETREGSET, thread->tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_base = &dst, .iov_len = sizeof(dst) }));
if(ptrace_result < 0) { goto exit; } if(ptrace_result < 0) { goto exit; }
} }
@@ -1413,27 +1406,27 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
X64_FXSave dst_fxsave = {0}; X64_FXSave dst_fxsave = {0};
{ {
dst_fxsave.fcw = src->fcw.u16; dst_fxsave.fcw = src->fcw;
dst_fxsave.fsw = src->fsw.u16; dst_fxsave.fsw = src->fsw;
dst_fxsave.ftw = src->ftw; dst_fxsave.ftw = src->ftw;
dst_fxsave.fop = src->fop.u16; dst_fxsave.fop = src->fop;
dst_fxsave.fip = src->fip.u64; dst_fxsave.fip = src->fip;
dst_fxsave.fdp = src->fdp.u64; dst_fxsave.fdp = src->fdp;
dst_fxsave.mxcsr = src->mxcsr.u32; dst_fxsave.mxcsr = src->mxcsr;
dst_fxsave.mxcsr_mask = src->mxcsr_mask.u32; dst_fxsave.mxcsr_mask = src->mxcsr_mask;
REGS_Reg128 *st_d = (REGS_Reg128 *)dst_fxsave.st_space; U128 *st_d = (U128 *)dst_fxsave.st_space;
REGS_Reg80 *st_s = &src->st0; U80 *st_s = &src->st0;
for EachIndex(n, 8) for EachIndex(n, 8)
{ {
MemoryCopy(&st_d[n], &st_s[n], sizeof(REGS_Reg80)); MemoryCopy(&st_d[n], &st_s[n], sizeof(U80));
} }
REGS_Reg128 *xmm_d = (REGS_Reg128 *)dst_fxsave.xmm_space; U128 *xmm_d = (U128 *)dst_fxsave.xmm_space;
REGS_Reg512 *xmm_s = &src->zmm0; U512 *xmm_s = &src->zmm0;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&xmm_d[n], &xmm_s[n], sizeof(REGS_Reg128)); MemoryCopy(&xmm_d[n], &xmm_s[n], sizeof(U128));
} }
} }
@@ -1447,13 +1440,13 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
if(process_ctx->xsave_layout.avx_offset) if(process_ctx->xsave_layout.avx_offset)
{ {
if(process_ctx->xsave_layout.avx_offset + sizeof(REGS_Reg128) * 16 <= process_ctx->xsave_size) if(process_ctx->xsave_layout.avx_offset + sizeof(U128) * 16 <= process_ctx->xsave_size)
{ {
REGS_Reg128 *avx_d = (REGS_Reg128 *)(xsave_raw + process_ctx->xsave_layout.avx_offset); U128 *avx_d = (U128 *)(xsave_raw + process_ctx->xsave_layout.avx_offset);
REGS_Reg512 *zmm_s = &src->zmm0; U512 *zmm_s = &src->zmm0;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&avx_d[n], &zmm_s[n].v[16], sizeof(REGS_Reg128)); MemoryCopy(&avx_d[n], &zmm_s[n].u8[16], sizeof(U128));
} }
dst->header.xstate_bv |= X64_XStateComponentFlag_AVX; dst->header.xstate_bv |= X64_XStateComponentFlag_AVX;
} }
@@ -1461,13 +1454,13 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
if(process_ctx->xsave_layout.opmask_offset) if(process_ctx->xsave_layout.opmask_offset)
{ {
if(process_ctx->xsave_layout.opmask_offset + sizeof(REGS_Reg64) * 8 <= process_ctx->xsave_size) if(process_ctx->xsave_layout.opmask_offset + sizeof(U64) * 8 <= process_ctx->xsave_size)
{ {
REGS_Reg64 *kmask_d = (REGS_Reg64 *)(xsave_raw + process_ctx->xsave_layout.opmask_offset); U64 *kmask_d = (U64 *)(xsave_raw + process_ctx->xsave_layout.opmask_offset);
REGS_Reg64 *kmask_s = &src->k0; U64 *kmask_s = &src->k0;
for EachIndex(n, 8) for EachIndex(n, 8)
{ {
MemoryCopy(&kmask_d[n], &kmask_s[n], sizeof(REGS_Reg64)); MemoryCopy(&kmask_d[n], &kmask_s[n], sizeof(U64));
} }
dst->header.xstate_bv |= X64_XStateComponentFlag_OPMASK; dst->header.xstate_bv |= X64_XStateComponentFlag_OPMASK;
} }
@@ -1476,13 +1469,13 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
if(process_ctx->xsave_layout.zmm_h_offset) if(process_ctx->xsave_layout.zmm_h_offset)
{ {
if(process_ctx->xsave_layout.zmm_h_offset + sizeof(REGS_Reg256) * 16 <= process_ctx->xsave_size) if(process_ctx->xsave_layout.zmm_h_offset + sizeof(U256) * 16 <= process_ctx->xsave_size)
{ {
REGS_Reg256 *avx512h_d = (REGS_Reg256 *)(xsave_raw + process_ctx->xsave_layout.zmm_h_offset); U256 *avx512h_d = (U256 *)(xsave_raw + process_ctx->xsave_layout.zmm_h_offset);
REGS_Reg512 *zmmh_s = &src->zmm0; U512 *zmmh_s = &src->zmm0;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&avx512h_d[n], &zmmh_s[n].v[32], sizeof(REGS_Reg256)); MemoryCopy(&avx512h_d[n], &zmmh_s[n].u8[32], sizeof(U256));
} }
dst->header.xstate_bv |= X64_XStateComponentFlag_ZMM_H; dst->header.xstate_bv |= X64_XStateComponentFlag_ZMM_H;
} }
@@ -1491,13 +1484,13 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
if(process_ctx->xsave_layout.zmm_offset) if(process_ctx->xsave_layout.zmm_offset)
{ {
if(process_ctx->xsave_layout.zmm_offset + sizeof(REGS_Reg512) * 16 <= process_ctx->xsave_size) if(process_ctx->xsave_layout.zmm_offset + sizeof(U512) * 16 <= process_ctx->xsave_size)
{ {
REGS_Reg512 *avx512_d = (REGS_Reg512 *)(xsave_raw + process_ctx->xsave_layout.zmm_offset); U512 *avx512_d = (U512 *)(xsave_raw + process_ctx->xsave_layout.zmm_offset);
REGS_Reg512 *zmm_s = &src->zmm16; U512 *zmm_s = &src->zmm16;
for EachIndex(n, 16) for EachIndex(n, 16)
{ {
MemoryCopy(&avx512_d[n], &zmm_s[n], sizeof(REGS_Reg512)); MemoryCopy(&avx512_d[n], &zmm_s[n], sizeof(U512));
} }
dst->header.xstate_bv |= X64_XStateComponentFlag_ZMM; dst->header.xstate_bv |= X64_XStateComponentFlag_ZMM;
} }
@@ -1506,9 +1499,9 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
if(process_ctx->xsave_layout.cet_u_offset) if(process_ctx->xsave_layout.cet_u_offset)
{ {
if(process_ctx->xsave_layout.cet_u_offset + sizeof(REGS_Reg64) * 2 <= process_ctx->xsave_size) if(process_ctx->xsave_layout.cet_u_offset + sizeof(U64) * 2 <= process_ctx->xsave_size)
{ {
REGS_Reg64 *cet_u = (REGS_Reg64 *)(xsave_raw + process_ctx->xsave_layout.cet_u_offset); U64 *cet_u = (U64 *)(xsave_raw + process_ctx->xsave_layout.cet_u_offset);
cet_u[0] = src->cetmsr; cet_u[0] = src->cetmsr;
cet_u[1] = src->cetssp; cet_u[1] = src->cetssp;
dst->header.xstate_bv |= X64_XStateComponentFlag_CETU; dst->header.xstate_bv |= X64_XStateComponentFlag_CETU;
@@ -1527,15 +1520,15 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread)
// debug registers // debug registers
{ {
src->dr7.u64 |= (1 << 10); src->dr7 |= (1 << 10);
REGS_Reg64 *dr_s = &src->dr0; U64 *dr_s = &src->dr0;
for EachIndex(n, 8) for EachIndex(n, 8)
{ {
if(n != 4 && n != 5) if(n != 4 && n != 5)
{ {
U64 offset = OffsetOf(OS_LNX_UserX64, u_debugreg[n]); U64 offset = OffsetOf(OS_LNX_UserX64, u_debugreg[n]);
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_POKEUSER, thread->tid, PtrFromInt(offset), (void*)(uintptr_t)dr_s[n].u64)); int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_POKEUSER, thread->tid, PtrFromInt(offset), (void*)(uintptr_t)dr_s[n]));
if(ptrace_result < 0) { goto exit; } if(ptrace_result < 0) { goto exit; }
} }
} }
@@ -1563,8 +1556,8 @@ dmn_lnx_set_single_step_flag(DMN_LNX_Thread *thread, B32 is_on)
case Arch_x64: case Arch_x64:
{ {
X64_RegBlock *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 |= X64_RFlag_Trap; }
else { reg_block->rflags.u64 &= ~X64_RFlag_Trap; } else { reg_block->rflags &= ~X64_RFlag_Trap; }
thread->is_reg_block_dirty = 1; thread->is_reg_block_dirty = 1;
is_flag_set = 1; is_flag_set = 1;
} break; } break;
@@ -2086,36 +2079,31 @@ dmn_lnx_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid)
U64 address = 0; U64 address = 0;
switch(thread->process->ctx->arch) switch(thread->process->ctx->arch)
{ {
case Arch_Null: {} break; default:{}break;
case Arch_x64: case Arch_x64:
{ {
X64_RegBlock *regs_x64 = thread->reg_block; X64_RegBlock *regs_x64 = thread->reg_block;
if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B0) if(regs_x64->dr6 & X64_DebugStatusFlag_B0)
{ {
address = regs_x64->dr0.u64; address = regs_x64->dr0;
} }
else if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B1) else if(regs_x64->dr6 & X64_DebugStatusFlag_B1)
{ {
address = regs_x64->dr1.u64; address = regs_x64->dr1;
} }
else if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B2) else if(regs_x64->dr6 & X64_DebugStatusFlag_B2)
{ {
address = regs_x64->dr2.u64; address = regs_x64->dr2;
} }
else if(regs_x64->dr6.u64 & X64_DebugStatusFlag_B3) else if(regs_x64->dr6 & X64_DebugStatusFlag_B3)
{ {
address = regs_x64->dr3.u64; address = regs_x64->dr3;
} }
else else
{ {
is_valid = 0; is_valid = 0;
} }
}break; }break;
case Arch_x86:
case Arch_arm32:
case Arch_arm64:
{ NotImplemented; } break;
default: { InvalidPath; } break;
} }
if(is_valid) if(is_valid)
@@ -2275,7 +2263,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);
@@ -2966,7 +2954,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)
{ {
} }
@@ -3030,7 +3018,7 @@ dmn_tls_root_vaddr_from_thread(DMN_Handle thread_handle)
{ {
X64_RegBlock *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 + 8, &dtv_pointer))
{ {
tls_root_vaddr = dtv_pointer; tls_root_vaddr = dtv_pointer;
} }
@@ -4,6 +4,66 @@
#ifndef DEMON_CORE_LINUX_H #ifndef DEMON_CORE_LINUX_H
#define DEMON_CORE_LINUX_H #define DEMON_CORE_LINUX_H
////////////////////////////////
//~ rjf: Register Layouts
//
// These are defined in <sys/user.h>, but only for one architecture at a time
typedef struct OS_LNX_GprsX64 OS_LNX_GprsX64;
struct OS_LNX_GprsX64
{
U64 r15;
U64 r14;
U64 r13;
U64 r12;
U64 rbp;
U64 rbx;
U64 r11;
U64 r10;
U64 r9;
U64 r8;
U64 rax;
U64 rcx;
U64 rdx;
U64 rsi;
U64 rdi;
U64 orig_rax;
U64 rip;
U64 cs;
U64 rflags;
U64 rsp;
U64 ss;
U64 fsbase;
U64 gsbase;
U64 ds;
U64 es;
U64 fs;
U64 gs;
};
typedef struct OS_LNX_UserX64 OS_LNX_UserX64;
struct OS_LNX_UserX64
{
OS_LNX_GprsX64 regs;
S32 u_fpvalid;
U32 _pad0;
X64_FXSave i387;
U64 u_tsize;
U64 u_dsize;
U64 u_ssize;
U64 start_code;
U64 start_stack;
U64 signal;
U32 reserved;
U32 _pad1;
U64 u_ar0;
U64 u_fpstate;
U64 magic;
U8 u_comm[32];
U64 u_debugreg[8];
};
StaticAssert(sizeof(OS_LNX_UserX64) == 912, g_os_lnx_user_x64_size_check);
//////////////////////////////// ////////////////////////////////
//~ TLS //~ TLS
@@ -98,7 +98,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)
{ {
Vec2F32 resolution = dim_2f32(rect); Vec2F32 resolution = dim_2f32(rect);
@@ -161,22 +161,22 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
scratch_end(scratch); scratch_end(scratch);
//- rjf: convert to handle & return //- rjf: convert to handle & return
OS_Handle handle = {(U64)w}; OS_Window handle = {(U64)w};
return handle; return handle;
} }
internal void internal void
os_window_close(OS_Handle handle) os_window_close(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XDestroyWindow(os_lnx_gfx_state->display, w->window); XDestroyWindow(os_lnx_gfx_state->display, w->window);
} }
internal void internal void
os_window_set_title(OS_Handle handle, String8 title) os_window_set_title(OS_Window handle, String8 title)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
String8 title_copy = push_str8_copy(scratch.arena, title); String8 title_copy = push_str8_copy(scratch.arena, title);
@@ -185,25 +185,25 @@ os_window_set_title(OS_Handle handle, String8 title)
} }
internal void internal void
os_window_first_paint(OS_Handle handle) os_window_first_paint(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XMapWindow(os_lnx_gfx_state->display, w->window); XMapWindow(os_lnx_gfx_state->display, w->window);
} }
internal void internal void
os_window_focus(OS_Handle handle) os_window_focus(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XSetInputFocus(os_lnx_gfx_state->display, w->window, RevertToNone, CurrentTime); XSetInputFocus(os_lnx_gfx_state->display, w->window, RevertToNone, CurrentTime);
} }
internal B32 internal B32
os_window_is_focused(OS_Handle handle) os_window_is_focused(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return 0;} if(os_window_match(handle, os_window_zero())) {return 0;}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
Window focused_window = 0; Window focused_window = 0;
int revert_to = 0; int revert_to = 0;
@@ -213,96 +213,96 @@ 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)
{ {
if(os_handle_match(handle, os_handle_zero())) {return 0;} if(os_window_match(handle, os_window_zero())) {return 0;}
// TODO(rjf) // TODO(rjf)
return 0; return 0;
} }
internal void internal void
os_window_set_fullscreen(OS_Handle handle, B32 fullscreen) os_window_set_fullscreen(OS_Window handle, B32 fullscreen)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal B32 internal B32
os_window_is_maximized(OS_Handle handle) os_window_is_maximized(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return 0;} if(os_window_match(handle, os_window_zero())) {return 0;}
// TODO(rjf) // TODO(rjf)
return 0; return 0;
} }
internal void internal void
os_window_set_maximized(OS_Handle handle, B32 maximized) os_window_set_maximized(OS_Window handle, B32 maximized)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal B32 internal B32
os_window_is_minimized(OS_Handle handle) os_window_is_minimized(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return 0;} if(os_window_match(handle, os_window_zero())) {return 0;}
// TODO(rjf) // TODO(rjf)
return 0; return 0;
} }
internal void internal void
os_window_set_minimized(OS_Handle handle, B32 minimized) os_window_set_minimized(OS_Window handle, B32 minimized)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal void internal void
os_window_bring_to_front(OS_Handle handle) os_window_bring_to_front(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal void internal void
os_window_set_monitor(OS_Handle handle, OS_Handle monitor) os_window_set_monitor(OS_Window handle, OS_Monitor monitor)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal void internal void
os_window_clear_custom_border_data(OS_Handle handle) os_window_clear_custom_border_data(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
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)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal void internal void
os_window_push_custom_edges(OS_Handle handle, F32 thickness) os_window_push_custom_edges(OS_Window handle, F32 thickness)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
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)
{ {
if(os_handle_match(handle, os_handle_zero())) {return;} if(os_window_match(handle, os_window_zero())) {return;}
// TODO(rjf) // TODO(rjf)
} }
internal Rng2F32 internal Rng2F32
os_rect_from_window(OS_Handle handle) os_rect_from_window(OS_Window handle)
{ {
if(os_handle_match(handle, os_handle_zero())) {return r2f32p(0, 0, 0, 0);} if(os_window_match(handle, os_window_zero())) {return r2f32p(0, 0, 0, 0);}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XWindowAttributes atts = {0}; XWindowAttributes atts = {0};
Status s = XGetWindowAttributes(os_lnx_gfx_state->display, w->window, &atts); Status s = XGetWindowAttributes(os_lnx_gfx_state->display, w->window, &atts);
@@ -311,7 +311,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)
{ {
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XWindowAttributes atts = {0}; XWindowAttributes atts = {0};
@@ -321,7 +321,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)
{ {
// TODO(rjf) // TODO(rjf)
return 96.f; return 96.f;
@@ -330,16 +330,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)
{ {
OS_Handle result = {0}; OS_ExternalWindow result = {0};
// TODO(rjf) // TODO(rjf)
return result; return result;
} }
internal void internal void
os_focus_external_window(OS_Handle handle) os_focus_external_window(OS_ExternalWindow handle)
{ {
// TODO(rjf) // TODO(rjf)
} }
@@ -347,46 +347,46 @@ 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)
{ {
OS_HandleArray result = {0}; OS_MonitorArray result = {0};
// TODO(rjf) // TODO(rjf)
return result; return result;
} }
internal OS_Handle internal OS_Monitor
os_primary_monitor(void) os_primary_monitor(void)
{ {
OS_Handle result = {0}; OS_Monitor result = {0};
// TODO(rjf) // TODO(rjf)
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_Handle result = {0}; OS_Monitor result = {0};
// TODO(rjf) // TODO(rjf)
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)
{ {
// TODO(rjf) // TODO(rjf)
return str8_zero(); return str8_zero();
} }
internal Vec2F32 internal Vec2F32
os_dim_from_monitor(OS_Handle monitor) os_dim_from_monitor(OS_Monitor monitor)
{ {
// TODO(rjf) // TODO(rjf)
return v2f32(0, 0); return v2f32(0, 0);
} }
internal F32 internal F32
os_dpi_from_monitor(OS_Handle monitor) os_dpi_from_monitor(OS_Monitor monitor)
{ {
// TODO(rjf) // TODO(rjf)
return 96.f; return 96.f;
@@ -652,9 +652,9 @@ 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)
{ {
if(os_handle_match(handle, os_handle_zero())) {return v2f32(0, 0);} if(os_window_match(handle, os_window_zero())) {return v2f32(0, 0);}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
Vec2F32 result = {0}; Vec2F32 result = {0};
{ {
File diff suppressed because it is too large Load Diff
-215
View File
@@ -1,215 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef OS_CORE_LINUX_H
#define OS_CORE_LINUX_H
////////////////////////////////
//~ rjf: Includes
#include <dirent.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <errno.h>
#include <execinfo.h>
#include <fcntl.h>
#include <features.h>
#include <linux/limits.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <spawn.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
pid_t gettid(void);
int pthread_setname_np(pthread_t thread, const char *name);
int pthread_getname_np(pthread_t thread, char *name, size_t size);
typedef struct tm tm;
typedef struct timespec timespec;
////////////////////////////////
#define OS_LNX_RETRY_ON_EINTR(expr) \
(__extension__({ \
__typeof__(expr) __ret; \
do { \
__ret = (expr); \
} while ((__ret == -1) && errno == EINTR); \
__ret; \
}))
////////////////////////////////
//~ rjf: Register Layouts
//
// These are defined in <sys/user.h>, but only for one architecture at a time
typedef struct OS_LNX_GprsX64 OS_LNX_GprsX64;
struct OS_LNX_GprsX64
{
U64 r15;
U64 r14;
U64 r13;
U64 r12;
U64 rbp;
U64 rbx;
U64 r11;
U64 r10;
U64 r9;
U64 r8;
U64 rax;
U64 rcx;
U64 rdx;
U64 rsi;
U64 rdi;
U64 orig_rax;
U64 rip;
U64 cs;
U64 rflags;
U64 rsp;
U64 ss;
U64 fsbase;
U64 gsbase;
U64 ds;
U64 es;
U64 fs;
U64 gs;
};
typedef struct OS_LNX_UserX64 OS_LNX_UserX64;
struct OS_LNX_UserX64
{
OS_LNX_GprsX64 regs;
S32 u_fpvalid;
U32 _pad0;
X64_FXSave i387;
U64 u_tsize;
U64 u_dsize;
U64 u_ssize;
U64 start_code;
U64 start_stack;
U64 signal;
U32 reserved;
U32 _pad1;
U64 u_ar0;
U64 u_fpstate;
U64 magic;
U8 u_comm[32];
U64 u_debugreg[8];
};
StaticAssert(sizeof(OS_LNX_UserX64) == 912, g_os_lnx_user_x64_size_check);
////////////////////////////////
//~ rjf: File Iterator
typedef struct OS_LNX_FileIter OS_LNX_FileIter;
struct OS_LNX_FileIter
{
DIR *dir;
struct dirent *dp;
String8 path;
};
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check);
////////////////////////////////
//~ rjf: Safe Call Handler Chain
typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
struct OS_LNX_SafeCallChain
{
OS_LNX_SafeCallChain *next;
ThreadEntryPointFunctionType *fail_handler;
void *ptr;
};
////////////////////////////////
//~ rjf: Entities
typedef enum OS_LNX_EntityKind
{
OS_LNX_EntityKind_Thread,
OS_LNX_EntityKind_Mutex,
OS_LNX_EntityKind_RWMutex,
OS_LNX_EntityKind_ConditionVariable,
OS_LNX_EntityKind_Barrier,
}
OS_LNX_EntityKind;
typedef struct OS_LNX_Entity OS_LNX_Entity;
struct OS_LNX_Entity
{
OS_LNX_Entity *next;
OS_LNX_EntityKind kind;
union
{
struct
{
pthread_t handle;
ThreadEntryPointFunctionType *func;
void *ptr;
} thread;
pthread_mutex_t mutex_handle;
pthread_rwlock_t rwmutex_handle;
struct
{
pthread_cond_t cond_handle;
pthread_mutex_t rwlock_mutex_handle;
} cv;
pthread_barrier_t barrier;
};
};
////////////////////////////////
//~ rjf: State
typedef struct OS_LNX_State OS_LNX_State;
struct OS_LNX_State
{
Arena *arena;
OS_SystemInfo system_info;
OS_ProcessInfo process_info;
pthread_mutex_t entity_mutex;
Arena *entity_arena;
OS_LNX_Entity *entity_free;
U64 default_env_count;
char **default_env;
};
////////////////////////////////
//~ rjf: Globals
global OS_LNX_State os_lnx_state = {0};
thread_static OS_LNX_SafeCallChain *os_lnx_safe_call_chain = 0;
////////////////////////////////
//~ rjf: Helpers
internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec);
internal tm os_lnx_tm_from_date_time(DateTime dt);
internal timespec os_lnx_timespec_from_date_time(DateTime dt);
internal DenseTime os_lnx_dense_time_from_timespec(timespec in);
internal FileProperties os_lnx_file_properties_from_stat(struct stat *s);
internal void os_lnx_safe_call_sig_handler(int x);
////////////////////////////////
//~ rjf: Entities
internal OS_LNX_Entity *os_lnx_entity_alloc(OS_LNX_EntityKind kind);
internal void os_lnx_entity_release(OS_LNX_Entity *entity);
////////////////////////////////
//~ rjf: Thread Entry Point
internal void *os_lnx_thread_entry_point(void *ptr);
#endif // OS_CORE_LINUX_H
File diff suppressed because it is too large Load Diff
-88
View File
@@ -1,88 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef LINUX_H
#define LINUX_H
////////////////////////////////
//~ NOTE(allen): Get all these linux includes
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <time.h>
#include <dirent.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <signal.h>
#include <errno.h>
#include <dlfcn.h>
#include <sys/sysinfo.h>
////////////////////////////////
//~ NOTE(allen): File Iterator
struct LNX_FileIter{
int fd;
DIR *dir;
};
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(LNX_FileIter), file_iter_memory_size);
////////////////////////////////
//~ NOTE(allen): Threading Entities
enum LNX_EntityKind{
LNX_EntityKind_Null,
LNX_EntityKind_Thread,
LNX_EntityKind_Mutex,
LNX_EntityKind_ConditionVariable,
};
struct LNX_Entity{
LNX_Entity *next;
LNX_EntityKind kind;
volatile U32 reference_mask;
union{
struct{
ThreadEntryPointFunctionType *func;
void *ptr;
pthread_t handle;
} thread;
pthread_mutex_t mutex;
pthread_cond_t cond;
};
};
////////////////////////////////
//~ NOTE(allen): Safe Call Chain
struct LNX_SafeCallChain{
LNX_SafeCallChain *next;
ThreadEntryPointFunctionType *fail_handler;
void *ptr;
};
////////////////////////////////
//~ NOTE(allen): Helpers
internal B32 lnx_write_list_to_file_descriptor(int fd, String8List list);
internal void lnx_date_time_from_tm(DateTime *out, struct tm *in, U32 msec);
internal void lnx_tm_from_date_time(struct tm *out, DateTime *in);
internal void lnx_dense_time_from_timespec(DenseTime *out, struct timespec *in);
internal void lnx_file_properties_from_stat(FileProperties *out, struct stat *in);
internal String8 lnx_string_from_signal(int signum);
internal String8 lnx_string_from_errno(int error_number);
internal LNX_Entity* lnx_alloc_entity(LNX_EntityKind kind);
internal void lnx_free_entity(LNX_Entity *entity);
internal void* lnx_thread_base(void *ptr);
internal void lnx_safe_call_sig_handler(int);
#endif //LINUX_H
-279
View File
@@ -1,279 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
internal OS_Handle
os_handle_zero(void)
{
OS_Handle handle = {0};
return handle;
}
internal B32
os_handle_match(OS_Handle a, OS_Handle b)
{
return a.u64[0] == b.u64[0];
}
internal void
os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle)
{
OS_HandleNode *n = push_array(arena, OS_HandleNode, 1);
n->v = handle;
SLLQueuePush(handles->first, handles->last, n);
handles->count += 1;
}
internal OS_HandleArray
os_handle_array_from_list(Arena *arena, OS_HandleList *list)
{
OS_HandleArray result = {0};
result.count = list->count;
result.v = push_array_no_zero(arena, OS_Handle, result.count);
U64 idx = 0;
for(OS_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
{
result.v[idx] = n->v;
}
return result;
}
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8
os_data_from_file_path(Arena *arena, String8 path)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
FileProperties props = os_properties_from_file(file);
String8 data = os_string_from_file_range(arena, file, r1u64(0, props.size));
os_file_close(file);
return data;
}
internal B32
os_write_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
if(!os_handle_match(file, os_handle_zero()))
{
U64 bytes_written = os_file_write(file, r1u64(0, data.size), data.str);
good = (bytes_written == data.size);
os_file_close(file);
}
return good;
}
internal B32
os_write_data_list_to_file_path(String8 path, String8List list)
{
B32 good = 0;
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
if(!os_handle_match(file, os_handle_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 = os_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 = os_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);
os_file_close(file);
scratch_end(scratch);
}
return good;
}
internal B32
os_append_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
if(data.size != 0)
{
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append, path);
if(!os_handle_match(file, os_handle_zero()))
{
U64 pos = os_properties_from_file(file).size;
U64 bytes_written = os_file_write(file, r1u64(pos, pos+data.size), data.str);
good = (bytes_written == data.size);
os_file_close(file);
}
}
return good;
}
internal OS_FileID
os_id_from_file_path(String8 path)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
OS_FileID id = os_id_from_file(file);
os_file_close(file);
return id;
}
internal S64
os_file_id_compare(OS_FileID a, OS_FileID b)
{
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
return cmp;
}
internal String8
os_string_from_file_range(Arena *arena, OS_Handle 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 = os_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
os_file_read_cstring(Arena *arena, OS_Handle 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 = os_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;
}
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal OS_Handle
os_cmd_line_launch(String8 string)
{
Temp scratch = scratch_begin(0, 0);
U8 split_chars[] = {' '};
String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0);
OS_Handle handle = {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 = os_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
OS_Handle stdout_handle = {0};
if(stdout_path.size != 0)
{
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path);
os_file_close(file);
stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_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
OS_ProcessLaunchParams params = {0};
params.cmd_line = cmdline;
params.path = exe_folder;
params.inherit_env = 1;
params.stdout_file = stdout_handle;
handle = os_process_launch(&params);
// rjf: close stdout handle
{
if(stdout_path.size != 0)
{
os_file_close(stdout_handle);
}
}
}
scratch_end(scratch);
return handle;
}
internal OS_Handle
os_cmd_line_launchf(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
OS_Handle result = os_cmd_line_launch(string);
va_end(args);
scratch_end(scratch);
return result;
}
-324
View File
@@ -1,324 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef OS_CORE_H
#define OS_CORE_H
////////////////////////////////
//~ rjf: System Info
typedef struct OS_SystemInfo OS_SystemInfo;
struct OS_SystemInfo
{
U32 logical_processor_count;
U64 page_size;
U64 large_page_size;
U64 allocation_granularity;
String8 machine_name;
};
////////////////////////////////
//~ rjf: Process Info
typedef struct OS_ProcessInfo OS_ProcessInfo;
struct OS_ProcessInfo
{
U32 pid;
B32 large_pages_allowed;
String8 binary_path;
String8 initial_path;
String8 user_program_data_path;
String8List module_load_paths;
String8List environment;
};
////////////////////////////////
//~ rjf: Access Flags
typedef U32 OS_AccessFlags;
enum
{
OS_AccessFlag_Read = (1<<0),
OS_AccessFlag_Write = (1<<1),
OS_AccessFlag_Execute = (1<<2),
OS_AccessFlag_Append = (1<<3),
OS_AccessFlag_ShareRead = (1<<4),
OS_AccessFlag_ShareWrite = (1<<5),
OS_AccessFlag_Inherited = (1<<6),
};
////////////////////////////////
//~ rjf: Files
typedef U32 OS_FileIterFlags;
enum
{
OS_FileIterFlag_SkipFolders = (1 << 0),
OS_FileIterFlag_SkipFiles = (1 << 1),
OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
OS_FileIterFlag_Done = (1 << 31),
};
typedef struct OS_FileIter OS_FileIter;
struct OS_FileIter
{
OS_FileIterFlags flags;
U8 memory[800];
};
typedef struct OS_FileInfo OS_FileInfo;
struct OS_FileInfo
{
String8 name;
FileProperties props;
};
// nick: on-disk file identifier
typedef struct OS_FileID OS_FileID;
struct OS_FileID
{
U64 v[3];
};
////////////////////////////////
//~ rjf: Handle Type
typedef struct OS_Handle OS_Handle;
struct OS_Handle
{
U64 u64[1];
};
typedef struct OS_HandleNode OS_HandleNode;
struct OS_HandleNode
{
OS_HandleNode *next;
OS_Handle v;
};
typedef struct OS_HandleList OS_HandleList;
struct OS_HandleList
{
OS_HandleNode *first;
OS_HandleNode *last;
U64 count;
};
typedef struct OS_HandleArray OS_HandleArray;
struct OS_HandleArray
{
OS_Handle *v;
U64 count;
};
////////////////////////////////
//~ rjf: Process Launch Parameters
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
struct OS_ProcessLaunchParams
{
String8List cmd_line;
String8 path;
String8List env;
B32 inherit_env;
B32 debug_subprocesses;
B32 consoleless;
OS_Handle stdout_file;
OS_Handle stderr_file;
OS_Handle stdin_file;
};
////////////////////////////////
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
internal OS_Handle os_handle_zero(void);
internal B32 os_handle_match(OS_Handle a, OS_Handle b);
internal void os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle);
internal OS_HandleArray os_handle_array_from_list(Arena *arena, OS_HandleList *list);
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8 os_data_from_file_path(Arena *arena, String8 path);
internal B32 os_write_data_to_file_path(String8 path, String8 data);
internal B32 os_write_data_list_to_file_path(String8 path, String8List list);
internal B32 os_append_data_to_file_path(String8 path, String8 data);
internal OS_FileID os_id_from_file_path(String8 path);
internal S64 os_file_id_compare(OS_FileID a, OS_FileID b);
internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range);
internal String8 os_file_read_cstring(Arena *arena, OS_Handle file, U64 off);
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal OS_Handle os_cmd_line_launch(String8 string);
internal OS_Handle os_cmd_line_launchf(char *fmt, ...);
////////////////////////////////
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
internal OS_SystemInfo *os_get_system_info(void);
internal OS_ProcessInfo *os_get_process_info(void);
internal String8 os_get_current_path(Arena *arena);
internal U32 os_get_process_start_time_unix(void);
////////////////////////////////
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
//- rjf: basic
internal void *os_reserve(U64 size);
internal B32 os_commit(void *ptr, U64 size);
internal void os_decommit(void *ptr, U64 size);
internal void os_release(void *ptr, U64 size);
//- rjf: large pages
internal void *os_reserve_large(U64 size);
internal B32 os_commit_large(void *ptr, U64 size);
////////////////////////////////
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
internal U32 os_tid(void);
internal void os_set_thread_name(String8 string);
////////////////////////////////
//~ rjf: @os_hooks Aborting (Implemented Per-OS)
internal void os_abort(S32 exit_code);
////////////////////////////////
//~ rjf: @os_hooks File System (Implemented Per-OS)
//- rjf: files
internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path);
internal void os_file_close(OS_Handle file);
internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data);
#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr))
internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data);
internal B32 os_file_set_times(OS_Handle file, DateTime time);
internal FileProperties os_properties_from_file(OS_Handle file);
internal OS_FileID os_id_from_file(OS_Handle file);
internal B32 os_file_reserve_size(OS_Handle file, U64 size);
internal B32 os_delete_file_at_path(String8 path);
internal B32 os_copy_file_path(String8 dst, String8 src);
internal B32 os_move_file_path(String8 dst, String8 src);
internal String8 os_full_path_from_path(Arena *arena, String8 path);
internal B32 os_file_path_exists(String8 path);
internal B32 os_folder_path_exists(String8 path);
internal FileProperties os_properties_from_file_path(String8 path);
//- rjf: file maps
internal OS_Handle os_file_map_open(OS_AccessFlags flags, OS_Handle file);
internal void os_file_map_close(OS_Handle map);
internal void * os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range);
internal void os_file_map_view_close(OS_Handle map, void *ptr, Rng1U64 range);
//- rjf: directory iteration
internal OS_FileIter *os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags);
internal B32 os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out);
internal void os_file_iter_end(OS_FileIter *iter);
//- rjf: directory creation
internal B32 os_make_directory(String8 path);
////////////////////////////////
//~ rjf: @os_hooks Shared Memory (Implemented Per-OS)
internal OS_Handle os_shared_memory_alloc(U64 size, String8 name);
internal OS_Handle os_shared_memory_open(String8 name);
internal void os_shared_memory_close(OS_Handle handle);
internal void * os_shared_memory_view_open(OS_Handle handle, Rng1U64 range);
internal void os_shared_memory_view_close(OS_Handle handle, void *ptr, Rng1U64 range);
////////////////////////////////
//~ rjf: @os_hooks Time (Implemented Per-OS)
internal U64 os_now_microseconds(void);
internal U32 os_now_unix(void);
internal DateTime os_now_universal_time(void);
internal DateTime os_universal_time_from_local(DateTime *local_time);
internal DateTime os_local_time_from_universal(DateTime *universal_time);
internal void os_sleep_milliseconds(U32 msec);
////////////////////////////////
//~ rjf: @os_hooks Child Processes (Implemented Per-OS)
internal OS_Handle os_process_launch(OS_ProcessLaunchParams *params);
internal B32 os_process_join(OS_Handle handle, U64 endt_us, U64 *exit_code_out);
internal void os_process_detach(OS_Handle handle);
internal B32 os_process_kill(OS_Handle handle);
////////////////////////////////
//~ rjf: @os_hooks Threads (Implemented Per-OS)
internal Thread os_thread_launch(ThreadEntryPointFunctionType *f, void *p);
internal B32 os_thread_join(Thread handle, U64 endt_us);
internal void os_thread_detach(Thread handle);
////////////////////////////////
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
//- rjf: recursive mutexes
internal Mutex os_mutex_alloc(void);
internal void os_mutex_release(Mutex mutex);
internal void os_mutex_take(Mutex mutex);
internal void os_mutex_drop(Mutex mutex);
//- rjf: reader/writer mutexes
internal RWMutex os_rw_mutex_alloc(void);
internal void os_rw_mutex_release(RWMutex mutex);
internal void os_rw_mutex_take(RWMutex mutex, B32 write_mode);
internal void os_rw_mutex_drop(RWMutex mutex, B32 write_mode);
//- rjf: condition variables
internal CondVar os_cond_var_alloc(void);
internal void os_cond_var_release(CondVar cv);
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
internal B32 os_cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us);
internal B32 os_cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us);
internal void os_cond_var_signal(CondVar cv);
internal void os_cond_var_broadcast(CondVar cv);
//- rjf: cross-process semaphores
internal Semaphore os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name);
internal void os_semaphore_release(Semaphore semaphore);
internal Semaphore os_semaphore_open(String8 name);
internal void os_semaphore_close(Semaphore semaphore);
internal B32 os_semaphore_take(Semaphore semaphore, U64 endt_us);
internal void os_semaphore_drop(Semaphore semaphore);
//- rjf: barriers
internal Barrier os_barrier_alloc(U64 count);
internal void os_barrier_release(Barrier barrier);
internal void os_barrier_wait(Barrier barrier);
////////////////////////////////
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
internal OS_Handle os_library_open(String8 path);
internal void os_library_close(OS_Handle lib);
internal VoidProc *os_library_load_proc(OS_Handle lib, String8 name);
////////////////////////////////
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
internal void os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr);
////////////////////////////////
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
internal Guid os_make_guid(void);
////////////////////////////////
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
// NOTE(rjf): The implementation of `os_core` will define low-level entry
// points if BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
// into the standard codebase program entry points, named "entry_point".
#if BUILD_ENTRY_DEFINING_UNIT
raddbg_entry_point(entry_point);
internal no_inline void entry_point(CmdLine *cmdline);
#endif
#endif // OS_CORE_H
File diff suppressed because it is too large Load Diff
-27
View File
@@ -1,27 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
// #include "os/core/os_core.c"
#if OS_FEATURE_GRAPHICAL
# include "os/gfx/os_gfx.c"
#endif
#if OS_WINDOWS
// # include "os/core/win32/os_core_win32.c"
#elif OS_LINUX
# include "os/core/linux/os_core_linux.c"
#else
# error OS core layer not implemented for this operating system.
#endif
#if OS_FEATURE_GRAPHICAL
# if OS_GFX_STUB
# include "os/gfx/stub/os_gfx_stub.c"
# elif OS_WINDOWS
# include "os/gfx/win32/os_gfx_win32.c"
# elif OS_LINUX
# include "os/gfx/linux/os_gfx_linux.c"
# else
# error OS graphical layer not implemented for this operating system.
# endif
#endif
-40
View File
@@ -1,40 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef OS_INC_H
#define OS_INC_H
#if !defined(OS_FEATURE_GRAPHICAL)
# define OS_FEATURE_GRAPHICAL 0
#endif
#if !defined(OS_GFX_STUB)
# define OS_GFX_STUB 0
#endif
// #include "os/core/os_core.h"
#if OS_FEATURE_GRAPHICAL
# include "os/gfx/os_gfx.h"
#endif
#if OS_WINDOWS
// # include "os/core/win32/os_core_win32.h"
#elif OS_LINUX
# include "os/core/linux/os_core_linux.h"
#else
# error OS core layer not implemented for this operating system.
#endif
#if OS_FEATURE_GRAPHICAL
# if OS_GFX_STUB
# include "os/gfx/stub/os_gfx_stub.h"
# elif OS_WINDOWS
# include "os/gfx/win32/os_gfx_win32.h"
# elif OS_LINUX
# include "os/gfx/linux/os_gfx_linux.h"
# else
# error OS graphical layer not implemented for this operating system.
# endif
#endif
#endif // OS_INC_H
-2
View File
@@ -16,7 +16,6 @@
#include "linker/hash_table.h" #include "linker/hash_table.h"
#include "linker/lf_hash_table.h" #include "linker/lf_hash_table.h"
#include "linker/base_ext/base_bit_array.h" #include "linker/base_ext/base_bit_array.h"
#include "os/os_inc.h"
#include "rdi/rdi_local.h" #include "rdi/rdi_local.h"
#include "rdi_make/rdi_make_local.h" #include "rdi_make/rdi_make_local.h"
#include "coff/coff_inc.h" #include "coff/coff_inc.h"
@@ -47,7 +46,6 @@
#include "linker/hash_table.c" #include "linker/hash_table.c"
#include "linker/lf_hash_table.c" #include "linker/lf_hash_table.c"
#include "linker/base_ext/base_bit_array.c" #include "linker/base_ext/base_bit_array.c"
#include "os/os_inc.c"
#include "rdi/rdi_local.c" #include "rdi/rdi_local.c"
#include "rdi_make/rdi_make_local.c" #include "rdi_make/rdi_make_local.c"
#include "coff/coff_inc.c" #include "coff/coff_inc.c"
+2 -2
View File
@@ -265,11 +265,11 @@
#include "linker/hash_table.h" #include "linker/hash_table.h"
#include "linker/lf_hash_table.h" #include "linker/lf_hash_table.h"
#include "linker/base_ext/base_bit_array.h" #include "linker/base_ext/base_bit_array.h"
#include "os/os_inc.h"
#include "artifact_cache/artifact_cache.h" #include "artifact_cache/artifact_cache.h"
#include "rdi/rdi_local.h" #include "rdi/rdi_local.h"
#include "rdi_make/rdi_make_local.h" #include "rdi_make/rdi_make_local.h"
#include "mdesk/mdesk.h" #include "mdesk/mdesk.h"
#include "window_manager/window_manager_inc.h"
#include "config/config_inc.h" #include "config/config_inc.h"
#include "content/content.h" #include "content/content.h"
#include "file_stream/file_stream.h" #include "file_stream/file_stream.h"
@@ -318,11 +318,11 @@
#include "linker/hash_table.c" #include "linker/hash_table.c"
#include "linker/lf_hash_table.c" #include "linker/lf_hash_table.c"
#include "linker/base_ext/base_bit_array.c" #include "linker/base_ext/base_bit_array.c"
#include "os/os_inc.c"
#include "artifact_cache/artifact_cache.c" #include "artifact_cache/artifact_cache.c"
#include "rdi/rdi_local.c" #include "rdi/rdi_local.c"
#include "rdi_make/rdi_make_local.c" #include "rdi_make/rdi_make_local.c"
#include "mdesk/mdesk.c" #include "mdesk/mdesk.c"
#include "window_manager/window_manager_inc.c"
#include "config/config_inc.c" #include "config/config_inc.c"
#include "content/content.c" #include "content/content.c"
#include "file_stream/file_stream.c" #include "file_stream/file_stream.c"
@@ -79,7 +79,7 @@ r_ogl_os_init(CmdLine *cmdln)
} }
internal R_Handle internal R_Handle
r_ogl_os_window_equip(OS_Handle window) r_ogl_os_window_equip(OS_Window window)
{ {
OS_LNX_Window *window_os = (OS_LNX_Window *)window.u64[0]; OS_LNX_Window *window_os = (OS_LNX_Window *)window.u64[0];
R_OGL_LNX_Window *w = r_ogl_lnx_state->free_window; R_OGL_LNX_Window *w = r_ogl_lnx_state->free_window;
@@ -163,7 +163,7 @@ r_ogl_os_window_equip(OS_Handle window)
} }
internal void internal void
r_ogl_os_window_unequip(OS_Handle os, R_Handle r) r_ogl_os_window_unequip(OS_Window os, R_Handle r)
{ {
R_OGL_LNX_Window *w = (R_OGL_LNX_Window *)r.u64[0]; R_OGL_LNX_Window *w = (R_OGL_LNX_Window *)r.u64[0];
{ {
@@ -173,7 +173,7 @@ r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
} }
internal void internal void
r_ogl_os_select_window(OS_Handle os, R_Handle r) r_ogl_os_select_window(OS_Window os, R_Handle r)
{ {
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0]; R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0];
@@ -181,7 +181,7 @@ r_ogl_os_select_window(OS_Handle os, R_Handle r)
} }
internal void internal void
r_ogl_os_window_swap(OS_Handle os, R_Handle r) r_ogl_os_window_swap(OS_Window os, R_Handle r)
{ {
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0]; R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0];
@@ -79,27 +79,27 @@ r_ogl_os_init(CmdLine *cmdln)
} }
internal R_Handle internal R_Handle
r_ogl_os_window_equip(OS_Handle window) r_ogl_os_window_equip(OS_Window window)
{ {
R_Handle result = {0}; R_Handle result = {0};
return result; return result;
} }
internal void internal void
r_ogl_os_window_unequip(OS_Handle os, R_Handle r) r_ogl_os_window_unequip(OS_Window os, R_Handle r)
{ {
} }
internal void internal void
r_ogl_os_select_window(OS_Handle os, R_Handle r) r_ogl_os_select_window(OS_Window os, R_Handle r)
{ {
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx); glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx);
} }
internal void internal void
r_ogl_os_window_swap(OS_Handle os, R_Handle r) r_ogl_os_window_swap(OS_Window os, R_Handle r)
{ {
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
glXSwapBuffers(os_lnx_gfx_state->display, w->window); glXSwapBuffers(os_lnx_gfx_state->display, w->window);
+5 -5
View File
@@ -201,14 +201,14 @@ r_init(CmdLine *cmdln)
//- rjf: window setup/teardown //- rjf: window setup/teardown
r_hook R_Handle r_hook R_Handle
r_window_equip(OS_Handle window) r_window_equip(OS_Window window)
{ {
R_Handle result = r_ogl_os_window_equip(window); R_Handle result = r_ogl_os_window_equip(window);
return result; return result;
} }
r_hook void r_hook void
r_window_unequip(OS_Handle window, R_Handle window_equip) r_window_unequip(OS_Window window, R_Handle window_equip)
{ {
r_ogl_os_window_unequip(window, window_equip); r_ogl_os_window_unequip(window, window_equip);
} }
@@ -341,7 +341,7 @@ r_end_frame(void)
} }
r_hook void r_hook void
r_window_begin_frame(OS_Handle os, R_Handle r) r_window_begin_frame(OS_Window os, R_Handle r)
{ {
r_ogl_os_select_window(os, r); r_ogl_os_select_window(os, r);
@@ -358,7 +358,7 @@ r_window_begin_frame(OS_Handle os, R_Handle r)
} }
r_hook void r_hook void
r_window_end_frame(OS_Handle os, R_Handle r) r_window_end_frame(OS_Window os, R_Handle r)
{ {
for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next) for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next)
{ {
@@ -372,7 +372,7 @@ r_window_end_frame(OS_Handle os, R_Handle r)
//- rjf: render pass submission //- rjf: render pass submission
r_hook void r_hook void
r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) r_window_submit(OS_Window window, R_Handle window_equip, R_PassList *passes)
{ {
Rng2F32 viewport_rect = os_client_rect_from_window(window); Rng2F32 viewport_rect = os_client_rect_from_window(window);
Vec2F32 viewport_dim = dim_2f32(viewport_rect); Vec2F32 viewport_dim = dim_2f32(viewport_rect);
+4 -4
View File
@@ -224,9 +224,9 @@ internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id
internal VoidProc *r_ogl_os_load_procedure(char *name); internal VoidProc *r_ogl_os_load_procedure(char *name);
internal void r_ogl_os_init(CmdLine *cmdln); internal void r_ogl_os_init(CmdLine *cmdln);
internal R_Handle r_ogl_os_window_equip(OS_Handle window); internal R_Handle r_ogl_os_window_equip(OS_Window window);
internal void r_ogl_os_window_unequip(OS_Handle os, R_Handle r); internal void r_ogl_os_window_unequip(OS_Window os, R_Handle r);
internal void r_ogl_os_select_window(OS_Handle os, R_Handle r); internal void r_ogl_os_select_window(OS_Window os, R_Handle r);
internal void r_ogl_os_window_swap(OS_Handle os, R_Handle r); internal void r_ogl_os_window_swap(OS_Window os, R_Handle r);
#endif // RENDER_OPENGL_H #endif // RENDER_OPENGL_H
@@ -101,7 +101,7 @@ r_ogl_os_init(CmdLine *cmdline)
} }
internal R_Handle internal R_Handle
r_ogl_os_window_equip(OS_Handle window) r_ogl_os_window_equip(OS_Window window)
{ {
//- rjf: unpack window //- rjf: unpack window
OS_W32_Window *w = os_w32_window_from_handle(window); OS_W32_Window *w = os_w32_window_from_handle(window);
@@ -155,12 +155,12 @@ r_ogl_os_window_equip(OS_Handle window)
} }
internal void internal void
r_ogl_os_window_unequip(OS_Handle os, R_Handle r) r_ogl_os_window_unequip(OS_Window os, R_Handle r)
{ {
} }
internal void internal void
r_ogl_os_select_window(OS_Handle os, R_Handle r) r_ogl_os_select_window(OS_Window os, R_Handle r)
{ {
OS_W32_Window *w = os_w32_window_from_handle(os); OS_W32_Window *w = os_w32_window_from_handle(os);
if(w != 0) if(w != 0)
@@ -172,7 +172,7 @@ r_ogl_os_select_window(OS_Handle os, R_Handle r)
} }
internal void internal void
r_ogl_os_window_swap(OS_Handle os, R_Handle r) r_ogl_os_window_swap(OS_Window os, R_Handle r)
{ {
OS_W32_Window *w = os_w32_window_from_handle(os); OS_W32_Window *w = os_w32_window_from_handle(os);
if(w != 0) if(w != 0)
-2
View File
@@ -12,7 +12,6 @@
//- rjf: [h] //- rjf: [h]
#include "base/base_inc.h" #include "base/base_inc.h"
#include "os/os_inc.h"
#include "content/content.h" #include "content/content.h"
#include "artifact_cache/artifact_cache.h" #include "artifact_cache/artifact_cache.h"
#include "file_stream/file_stream.h" #include "file_stream/file_stream.h"
@@ -21,7 +20,6 @@
//- rjf: [c] //- rjf: [c]
#include "base/base_inc.c" #include "base/base_inc.c"
#include "os/os_inc.c"
#include "content/content.c" #include "content/content.c"
#include "artifact_cache/artifact_cache.c" #include "artifact_cache/artifact_cache.c"
#include "file_stream/file_stream.c" #include "file_stream/file_stream.c"
-2
View File
@@ -12,7 +12,6 @@
//- rjf: [h] //- rjf: [h]
#include "base/base_inc.h" #include "base/base_inc.h"
#include "os/os_inc.h"
#include "render/render_inc.h" #include "render/render_inc.h"
#include "font_provider/font_provider_inc.h" #include "font_provider/font_provider_inc.h"
#include "font_cache/font_cache.h" #include "font_cache/font_cache.h"
@@ -20,7 +19,6 @@
//- rjf: [c] //- rjf: [c]
#include "base/base_inc.c" #include "base/base_inc.c"
#include "os/os_inc.c"
#include "render/render_inc.c" #include "render/render_inc.c"
#include "font_provider/font_provider_inc.c" #include "font_provider/font_provider_inc.c"
#include "font_cache/font_cache.c" #include "font_cache/font_cache.c"
+4 -21
View File
@@ -69,6 +69,7 @@ stap_list_from_string(Arena *arena, String8 string)
internal String8 internal String8
stap_parse_args_x64(String8 string, STAP_Arg *arg_out) stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
{ {
ARCH_Info *arch_info = arch_info_from_arch(Arch_x64);
String8 error = str8_lit("unknown parse error"); String8 error = str8_lit("unknown parse error");
U64 sep_pos = str8_find_needle(string, 0, str8_lit("@"), 0); U64 sep_pos = str8_find_needle(string, 0, str8_lit("@"), 0);
if (sep_pos < string.size) { if (sep_pos < string.size) {
@@ -200,14 +201,9 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
index_str = str8_skip(index_str, 1); index_str = str8_skip(index_str, 1);
// parse base // parse base
B8 base_is_alias = 0;
U32 base_reg_code = 0; U32 base_reg_code = 0;
if (base_str.size) { if (base_str.size) {
base_reg_code = regs_reg_code_from_name(Arch_x64, base_str); base_reg_code = arch_reg_code_from_name(arch_info, base_str);
if (base_reg_code == 0) {
base_reg_code = regs_alias_code_from_name(Arch_x64, base_str);
base_is_alias = base_reg_code != 0;
}
if (base_reg_code == 0) { if (base_reg_code == 0) {
error = str8_lit("unknown base register"); error = str8_lit("unknown base register");
goto operand_parse_exit; goto operand_parse_exit;
@@ -215,14 +211,9 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
} }
// parse index // parse index
B8 index_is_alias = 0;
U32 index_reg_code = 0; U32 index_reg_code = 0;
if (index_str.size) { if (index_str.size) {
index_reg_code = regs_reg_code_from_name(Arch_x64, index_str); index_reg_code = arch_reg_code_from_name(arch_info, index_str);
if (index_reg_code == 0) {
index_reg_code = regs_alias_code_from_name(Arch_x64, index_str);
index_is_alias = index_reg_code != 0;
}
if (index_reg_code == 0) { if (index_reg_code == 0) {
error = str8_lit("unknown index register"); error = str8_lit("unknown index register");
} }
@@ -247,9 +238,7 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
arg.type = STAP_ArgType_MemoryRef; arg.type = STAP_ArgType_MemoryRef;
arg.memory_ref.disp = disp; arg.memory_ref.disp = disp;
arg.memory_ref.base.reg_code = base_reg_code; arg.memory_ref.base.reg_code = base_reg_code;
arg.memory_ref.base.is_alias = base_is_alias;
arg.memory_ref.index.reg_code = index_reg_code; arg.memory_ref.index.reg_code = index_reg_code;
arg.memory_ref.index.is_alias = index_is_alias;
arg.memory_ref.scale = scale; arg.memory_ref.scale = scale;
} }
// $imm // $imm
@@ -296,19 +285,13 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
goto operand_parse_exit; goto operand_parse_exit;
} }
B8 is_reg_alias = 0; U32 reg_code = arch_reg_code_from_name(arch_info, reg_str);
U32 reg_code = regs_reg_code_from_name(Arch_x64, reg_str);
if (reg_code == 0) {
reg_code = regs_alias_code_from_name(Arch_x64, reg_str);
is_reg_alias = reg_code != 0;
}
if (reg_code == 0) { if (reg_code == 0) {
error = str8_lit("invalid register name"); error = str8_lit("invalid register name");
goto operand_parse_exit; goto operand_parse_exit;
} }
arg.type = STAP_ArgType_Reg; arg.type = STAP_ArgType_Reg;
arg.reg.is_alias = is_reg_alias;
arg.reg.reg_code = reg_code; arg.reg.reg_code = reg_code;
} else { } else {
goto operand_parse_exit; goto operand_parse_exit;
-3
View File
@@ -29,17 +29,14 @@ typedef struct STAP_Arg
U64 imm; U64 imm;
struct { struct {
U32 reg_code; U32 reg_code;
B8 is_alias;
} reg; } reg;
struct { struct {
S64 disp; S64 disp;
struct { struct {
U32 reg_code; U32 reg_code;
B8 is_alias;
} base; } base;
struct { struct {
U32 reg_code; U32 reg_code;
B8 is_alias;
} index; } index;
U64 scale; U64 scale;
} memory_ref; } memory_ref;
-2
View File
@@ -5,12 +5,10 @@
#define BUILD_CONSOLE_INTERFACE 1 #define BUILD_CONSOLE_INTERFACE 1
#include "base/base_inc.h" #include "base/base_inc.h"
#include "os/os_inc.h"
#include "arch/arch_inc.h" #include "arch/arch_inc.h"
#include "stap/stap_parse.h" #include "stap/stap_parse.h"
#include "base/base_inc.c" #include "base/base_inc.c"
#include "os/os_inc.c"
#include "arch/arch_inc.c" #include "arch/arch_inc.c"
#include "stap/stap_parse.c" #include "stap/stap_parse.c"
-2
View File
@@ -8,7 +8,6 @@
// Headers // Headers
#include "base/base_inc.h" #include "base/base_inc.h"
#include "os/os_inc.h"
#include "coff/coff.h" #include "coff/coff.h"
#include "coff/coff_parse.h" #include "coff/coff_parse.h"
@@ -16,7 +15,6 @@
// Implementations // Implementations
#include "base/base_inc.c" #include "base/base_inc.c"
#include "os/os_inc.c"
#include "coff/coff.c" #include "coff/coff.c"
#include "coff/coff_parse.c" #include "coff/coff_parse.c"
+2 -2
View File
@@ -24,11 +24,11 @@
#include "linker/hash_table.h" #include "linker/hash_table.h"
#include "linker/lf_hash_table.h" #include "linker/lf_hash_table.h"
#include "linker/base_ext/base_bit_array.h" #include "linker/base_ext/base_bit_array.h"
#include "os/os_inc.h"
#include "artifact_cache/artifact_cache.h" #include "artifact_cache/artifact_cache.h"
#include "rdi/rdi_local.h" #include "rdi/rdi_local.h"
#include "rdi_make/rdi_make_local.h" #include "rdi_make/rdi_make_local.h"
#include "mdesk/mdesk.h" #include "mdesk/mdesk.h"
#include "window_manager/window_manager_inc.h"
#include "config/config_inc.h" #include "config/config_inc.h"
#include "content/content.h" #include "content/content.h"
#include "file_stream/file_stream.h" #include "file_stream/file_stream.h"
@@ -98,11 +98,11 @@
#include "linker/hash_table.c" #include "linker/hash_table.c"
#include "linker/lf_hash_table.c" #include "linker/lf_hash_table.c"
#include "linker/base_ext/base_bit_array.c" #include "linker/base_ext/base_bit_array.c"
#include "os/os_inc.c"
#include "artifact_cache/artifact_cache.c" #include "artifact_cache/artifact_cache.c"
#include "rdi/rdi_local.c" #include "rdi/rdi_local.c"
#include "rdi_make/rdi_make_local.c" #include "rdi_make/rdi_make_local.c"
#include "mdesk/mdesk.c" #include "mdesk/mdesk.c"
#include "window_manager/window_manager_inc.c"
#include "config/config_inc.c" #include "config/config_inc.c"
#include "content/content.c" #include "content/content.c"
#include "file_stream/file_stream.c" #include "file_stream/file_stream.c"
@@ -1,8 +1,8 @@
// 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/)
#ifndef OS_GFX_WIN32_H #ifndef WIN32_WINDOW_MANAGER_H
#define OS_GFX_WIN32_H #define WIN32_WINDOW_MANAGER_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Includes / Libraries //~ rjf: Includes / Libraries
@@ -120,4 +120,4 @@ internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
internal BOOL os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr); internal BOOL os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
#endif // OS_GFX_WIN32_H #endif // WIN32_WINDOW_MANAGER_H
@@ -3,8 +3,8 @@
//- GENERATED CODE //- GENERATED CODE
#ifndef OS_GFX_META_H #ifndef WINDOW_MANAGER_META_H
#define OS_GFX_META_H #define WINDOW_MANAGER_META_H
typedef enum OS_Key typedef enum OS_Key
{ {
@@ -160,4 +160,4 @@ extern String8 os_g_key_cfg_string_table[143];
C_LINKAGE_END C_LINKAGE_END
#endif // OS_GFX_META_H #endif // WINDOW_MANAGER_META_H
@@ -4,7 +4,7 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Generated Code
#include "generated/os_gfx.meta.c" #include "window_manager/generated/window_manager.meta.c"
//////////////////////////////// ////////////////////////////////
//~ rjf: Handle Type Helpers //~ rjf: Handle Type Helpers
@@ -77,7 +77,7 @@ OS_Cursor;
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Generated Code
#include "os/gfx/generated/os_gfx.meta.h" #include "window_manager/generated/window_manager.meta.h"
//////////////////////////////// ////////////////////////////////
//~ rjf: Event Types //~ rjf: Event Types
+13
View File
@@ -0,0 +1,13 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "window_manager.c"
#if WM_STUB
# include "window_manager_stub.c"
#elif OS_WINDOWS
# include "win32/window_manager/win32_window_manager.c"
#elif OS_LINUX
# include "linux/window_manager/linux_window_manager.c"
#else
# error Window manager layer not implemented for this operating system.
#endif
+18
View File
@@ -0,0 +1,18 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef WINDOW_MANAGER_INC_H
#define WINDOW_MANAGER_INC_H
#include "window_manager.h"
#if WM_STUB
# include "window_manager_stub.h"
#elif OS_WINDOWS
# include "win32/window_manager/win32_window_manager.h"
#elif OS_LINUX
# include "linux/window_manager/linux_window_manager.h"
#else
# error Window manager layer not implemented for this operating system.
#endif
#endif // WINDOW_MANAGER_INC_H
+23 -15
View File
@@ -34,7 +34,8 @@ enum
//////////////////////////////// ////////////////////////////////
//~ fxsave/xsave //~ fxsave/xsave
typedef struct AlignType(16) X64_FXSave typedef struct X64_FXSave X64_FXSave;
struct AlignType(16) X64_FXSave
{ {
U16 fcw; U16 fcw;
U16 fsw; U16 fsw;
@@ -48,23 +49,25 @@ typedef struct AlignType(16) X64_FXSave
U128 st_space[8]; U128 st_space[8];
U128 xmm_space[16]; U128 xmm_space[16];
U8 padding[96]; U8 padding[96];
} X64_FXSave; };
StaticAssert(sizeof(X64_FXSave) == 512, g_x64_xsave_legacy_size_check); StaticAssert(sizeof(X64_FXSave) == 512, g_x64_xsave_legacy_size_check);
typedef struct X64_XSaveHeader typedef struct X64_XSaveHeader X64_XSaveHeader;
struct X64_XSaveHeader
{ {
U64 xstate_bv; U64 xstate_bv;
U64 xcomp_bv; U64 xcomp_bv;
U8 reserved[48]; U8 reserved[48];
} X64_XSaveHeader; };
StaticAssert(sizeof(X64_XSaveHeader) == 64, g_x64_xsave_header_size_check); StaticAssert(sizeof(X64_XSaveHeader) == 64, g_x64_xsave_header_size_check);
typedef struct AlignType(64) X64_XSave typedef struct X64_XSave X64_XSave;
struct AlignType(64) X64_XSave
{ {
X64_FXSave fxsave; X64_FXSave fxsave;
X64_XSaveHeader header; X64_XSaveHeader header;
// U8 ext_area[0]; // U8 ext_area[0];
} X64_XSave; };
StaticAssert(sizeof(X64_XSave) == 576, g_x64_xsave_size_check); StaticAssert(sizeof(X64_XSave) == 576, g_x64_xsave_size_check);
typedef U32 X64_XStateComponentIdx; typedef U32 X64_XStateComponentIdx;
@@ -90,7 +93,6 @@ enum
X64_XStateComponentIdx_TILECFG = 17, X64_XStateComponentIdx_TILECFG = 17,
X64_XStateComponentIdx_TILEDATA = 18, X64_XStateComponentIdx_TILEDATA = 18,
}; };
enum enum
{ {
X64_XStateComponentFlag_FP = (1 << X64_XStateComponentIdx_FP), X64_XStateComponentFlag_FP = (1 << X64_XStateComponentIdx_FP),
@@ -114,7 +116,8 @@ enum
X64_XStateComponentFlag_TILEDATA = (1 << X64_XStateComponentIdx_TILEDATA), X64_XStateComponentFlag_TILEDATA = (1 << X64_XStateComponentIdx_TILEDATA),
}; };
typedef struct typedef struct X64_XSaveLayout X64_XSaveLayout;
struct X64_XSaveLayout
{ {
U64 x87_offset; U64 x87_offset;
U64 sse_offset; U64 sse_offset;
@@ -135,12 +138,12 @@ typedef struct
U64 hwp_offset; U64 hwp_offset;
U64 tile_cfg_offset; U64 tile_cfg_offset;
U64 tile_data_offset; U64 tile_data_offset;
} X64_XSaveLayout; };
//////////////////////////////// ////////////////////////////////
//~ Debug Status Register //~ Debug Status Register
typedef enum typedef enum X64_DebugStatusFlags
{ {
X64_DebugStatusFlag_B0 = (1 << 0), X64_DebugStatusFlag_B0 = (1 << 0),
X64_DebugStatusFlag_B1 = (1 << 1), X64_DebugStatusFlag_B1 = (1 << 1),
@@ -151,16 +154,19 @@ typedef enum
X64_DebugStatusFlag_SingleStep = (1 << 14), X64_DebugStatusFlag_SingleStep = (1 << 14),
X64_DebugStatusFlag_TaskSwitch = (1 << 15), X64_DebugStatusFlag_TaskSwitch = (1 << 15),
X64_DebugStatusFlag_RTM = (1 << 16), X64_DebugStatusFlag_RTM = (1 << 16),
} X64_DebugStatusFlags; }
X64_DebugStatusFlags;
//////////////////////////////// ////////////////////////////////
//~ Debug Control Register //~ Debug Control Register
typedef enum X64_BreakpointType { typedef enum X64_BreakpointType
{
X64_BreakpointType_Null, X64_BreakpointType_Null,
X64_BreakpointType_Local, X64_BreakpointType_Local,
X64_BreakpointType_Global, X64_BreakpointType_Global,
} X64_BreakpointType; }
X64_BreakpointType;
typedef enum X64_DebugBreakType typedef enum X64_DebugBreakType
{ {
@@ -169,7 +175,8 @@ typedef enum X64_DebugBreakType
X64_DebugBreakType_Write, X64_DebugBreakType_Write,
X64_DebugBreakType_ReadWriteIO, X64_DebugBreakType_ReadWriteIO,
X64_DebugBreakType_ReadWriteNoFetch, X64_DebugBreakType_ReadWriteNoFetch,
} X64_DebugBreakType; }
X64_DebugBreakType;
typedef enum X64_DebugControlFlags typedef enum X64_DebugControlFlags
{ {
@@ -199,7 +206,8 @@ typedef enum X64_DebugControlFlags
X64_DebugControlFlag_LEN1 = (3 << 22), X64_DebugControlFlag_LEN1 = (3 << 22),
X64_DebugControlFlag_LEN2 = (3 << 26), X64_DebugControlFlag_LEN2 = (3 << 26),
X64_DebugControlFlag_LEN3 = (3 << 30), X64_DebugControlFlag_LEN3 = (3 << 30),
} X64_DebugControlFlags; }
X64_DebugControlFlags;
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated //~ rjf: Generated