only inc x64 into base by default on linux, where we actually apparently need it - ideally we do not just pull in all of x64 just for a few enum codes'

This commit is contained in:
Ryan Fleury committed 2026-09-21 09:43:28 -07:00
1 parent 4e4639c2a0
commit 9796328ffa
3 files changed
+73 -64

No files matched your search

+27 -27
View File
@@ -285,7 +285,7 @@ shared_memory_alloc(U64 size, String8 name)
SharedMemory result = { max_U64 };
if(size == 0 || size > max_S64) { return result; }
int id;
if(name.size == 0)
{
@@ -304,7 +304,7 @@ shared_memory_alloc(U64 size, String8 name)
if(ftruncate(id, size) == 0) { result.u64[0] = (U64)id; }
else { close(id); }
}
return result;
}
@@ -1107,15 +1107,15 @@ lnx_memory_fault_thread(void *unused)
{
LNX_MemoryFaultRequest *request = 0;
ssize_t count = LNX_RETRY_ON_EINTR(read(lnx_state.demand_memory.requests[0], &request, sizeof(request)));
if(count == 0) { break; }
if(count != sizeof(request)) { _exit(1); }
if(request == 0) { break; }
lnx_in_memory_fault_callback = 1;
B32 handled = lnx_state.demand_memory.fault(request->address, lnx_state.demand_memory.user_data);
lnx_in_memory_fault_callback = 0;
U32 *completion = &request->result;
ins_atomic_u32_eval_assign(completion, handled ? 2 : 1);
syscall(SYS_futex, completion, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0);
@@ -1148,25 +1148,25 @@ internal B32
lnx_dispatch_memory_read_fault(int sig, siginfo_t *info, void *context)
{
LNX_DemandMemory *memory = &lnx_state.demand_memory;
#if ARCH_X64 || ARCH_X86
if(sig != SIGSEGV || info == 0 || context == 0 ||
(info->si_code != SEGV_ACCERR && info->si_code != SEGV_MAPERR) ||
lnx_in_memory_fault_callback ||
ins_atomic_u32_eval(&memory->active) == 0)
(info->si_code != SEGV_ACCERR && info->si_code != SEGV_MAPERR) ||
lnx_in_memory_fault_callback ||
ins_atomic_u32_eval(&memory->active) == 0)
{
return 0;
}
ucontext_t *state = context;
if((state->uc_mcontext.gregs[REG_TRAPNO] != X64_Exception_PF) ||
if((state->uc_mcontext.gregs[REG_TRAPNO] != X64_ExceptionCode_PF) ||
(state->uc_mcontext.gregs[REG_ERR] & X64_PageFaultError_Write) ||
(state->uc_mcontext.gregs[REG_ERR] & X64_PageFaultError_InstructionFetch) ||
memory->owner_pid != getpid())
{
return 0;
}
int saved_errno = errno;
LNX_MemoryFaultRequest request = { .address = info->si_addr };
LNX_MemoryFaultRequest *ptr = &request;
@@ -1176,7 +1176,7 @@ lnx_dispatch_memory_read_fault(int sig, siginfo_t *info, void *context)
errno = saved_errno;
return 0;
}
// wait for the page fault handler to complete
while(!ins_atomic_u32_eval(&request.result))
{
@@ -1185,10 +1185,10 @@ lnx_dispatch_memory_read_fault(int sig, siginfo_t *info, void *context)
_exit(1);
}
}
B32 handled = request.result == 2;
errno = saved_errno;
return handled;
#else
NotImplemented;
@@ -1210,7 +1210,7 @@ memory_read_fault_handler_set(MemoryReadFaultFunction *func, void *user_data)
{
return 0;
}
memory->fault = func;
memory->user_data = user_data;
memory->owner_pid = getpid();
@@ -1229,7 +1229,7 @@ memory_read_fault_handler_set(MemoryReadFaultFunction *func, void *user_data)
}
memory->workers[memory->worker_count++] = worker;
}
ins_atomic_u32_eval_assign(&memory->active, 1);
}
else if(memory->worker_count)
@@ -1238,7 +1238,7 @@ memory_read_fault_handler_set(MemoryReadFaultFunction *func, void *user_data)
{
return 0;
}
ins_atomic_u32_eval_assign(&memory->active, 0);
return lnx_memory_fault_workers_stop(memory);
}
@@ -1605,7 +1605,7 @@ process_launch(ProcessLaunchParams *params)
posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP);
posix_spawnattr_setpgroup(&attr, 0);
}
// package argv
char **argv = push_array(scratch.arena, char *, params->cmd_line.node_count + 1);
{
@@ -1822,7 +1822,7 @@ lnx_signal_handler(int sig, siginfo_t *info, void *arg)
{
// page fault handler
if(lnx_dispatch_memory_read_fault(sig, info, arg)) { return; }
// crash handler
{
local_persist volatile U32 first = 0;
@@ -1833,10 +1833,10 @@ lnx_signal_handler(int sig, siginfo_t *info, void *arg)
sleep(UINT32_MAX);
}
}
local_persist void *ips[4096];
int ips_count = backtrace(ips, ArrayCount(ips));
fprintf(stderr, "A fatal signal was received: %s (%d). The process is terminating.\n", strsignal(sig), sig);
fprintf(stderr, "Create a new issue with this report at %s.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL);
fprintf(stderr, "Callstack:\n");
@@ -1844,7 +1844,7 @@ lnx_signal_handler(int sig, siginfo_t *info, void *arg)
{
Dl_info info = {0};
dladdr(ips[i], &info);
char cmd[2048];
snprintf(cmd, sizeof(cmd), "llvm-symbolizer --relative-address -f -e %s %lu", info.dli_fname, (unsigned long)ips[i] - (unsigned long)info.dli_fbase);
FILE *f = popen(cmd, "r");
@@ -1858,12 +1858,12 @@ lnx_signal_handler(int sig, siginfo_t *info, void *arg)
String8 module = str8_skip_last_slash(str8_cstring(info.dli_fname));
String8 file = str8_skip_last_slash(str8_cstring_capped(file_name, file_name + sizeof(file_name)));
if(file.size > 0) file.size -= 1;
B32 no_func = str8_match(func, str8_lit("??"), StringMatchFlag_RightSideSloppy);
B32 no_file = str8_match(file, str8_lit("??"), StringMatchFlag_RightSideSloppy);
if(no_func) { func = str8_zero(); }
if(no_file) { file = str8_zero(); }
fprintf(stderr, "%ld. [0x%016lx] %.*s%s%.*s %.*s\n", i+1, (unsigned long)ips[i], (int)module.size, module.str, (!no_func || !no_file) ? ", " : "", (int)func.size, func.str, (int)file.size, file.str);
}
pclose(f);
@@ -1874,7 +1874,7 @@ lnx_signal_handler(int sig, siginfo_t *info, void *arg)
}
}
fprintf(stderr, "\nVersion: %s%s\n\n", BUILD_VERSION_STRING_LITERAL, BUILD_GIT_HASH_STRING_LITERAL_APPEND);
_exit(1);
}
}
@@ -1902,7 +1902,7 @@ main(int argc, char **argv)
U64 pages = (U64)sysconf(_SC_PHYS_PAGES);
U64 page_size = (U64)sysconf(_SC_PAGESIZE);
U64 commit_size = (U64)sysconf(_SC_AVPHYS_PAGES);
SystemInfo *info = &lnx_state.system_info;
info->logical_processor_count = (U32)get_nprocs();
info->page_size = (U64)getpagesize();
+14 -7
View File
@@ -35,6 +35,13 @@
#include <unistd.h>
#include <ucontext.h>
// NOTE(rjf): this is required because we need to use architecture-specific code for "base"
// OS functionality - we may want to reevaluate if such things should be in base - but for
// now just pulling in the whole x64 layer, just for linux.
#if ARCH_X64 || ARCH_X86
# include "x64/x64.h"
#endif
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);
@@ -46,13 +53,13 @@ typedef struct timespec timespec;
//~ rjf: Linux Call Interruption Retry Helper
#define LNX_RETRY_ON_EINTR(expr) \
(__extension__({ \
__typeof__(expr) __ret; \
do { \
__ret = (expr); \
} while ((__ret == -1) && errno == EINTR); \
__ret; \
}))
(__extension__({ \
__typeof__(expr) __ret; \
do { \
__ret = (expr); \
} while ((__ret == -1) && errno == EINTR); \
__ret; \
}))
////////////////////////////////
+32 -30
View File
@@ -212,39 +212,40 @@ X64_DebugControlFlags;
////////////////////////////////
//~ Exception Codes
typedef enum
typedef enum X64_ExceptionCode
{
X64_Exception_DE = 0, // Divide error: division by zero or quotient overflow
X64_Exception_DB = 1, // Debug exception (single stepping, hardware breakpoint)
X64_Exception_NMI = 2, // Non-maskable interrupt
X64_Exception_BP = 3, // Breakpoint (int3)
X64_Exception_OF = 4, // Overflow
X64_Exception_BR = 5, // Bound range exceeded
X64_Exception_UD = 6, // Invalid opcode
X64_Exception_NM = 7, // Device not available
X64_Exception_DF = 8, // Double fault
X64_Exception_9 = 9, // Coprocessor segment overrun (obsolete)
X64_Exception_TS = 10, // Invalid task-state segment
X64_Exception_NP = 11, // Segment not present
X64_Exception_SS = 12, // Stack-segment fault
X64_Exception_GP = 13, // General-protection fault
X64_Exception_PF = 14, // Page fault
X64_Exception_15 = 15, // Reserved; Linux names it X86_TRAP_SPURIOUS
X64_Exception_MF = 16, // x87 floating-point exception
X64_Exception_AC = 17, // Alignment check
X64_Exception_MC = 18, // Machine check
X64_Exception_XF = 19, // SIMD floating-point exception
X64_Exception_VE = 20, // Virtualization exception
X64_Exception_CP = 21, // Control-protection exception
X64_Exception_Amd_HV = 28, // Hypervisor injection exception
X64_Exception_Amd_VC = 29, // VMM communication exception
X64_Exception_Amd_SX = 30, // Security exception
} X64_ExceptionCode;
X64_ExceptionCode_DE = 0, // Divide error: division by zero or quotient overflow
X64_ExceptionCode_DB = 1, // Debug exception (single stepping, hardware breakpoint)
X64_ExceptionCode_NMI = 2, // Non-maskable interrupt
X64_ExceptionCode_BP = 3, // Breakpoint (int3)
X64_ExceptionCode_OF = 4, // Overflow
X64_ExceptionCode_BR = 5, // Bound range exceeded
X64_ExceptionCode_UD = 6, // Invalid opcode
X64_ExceptionCode_NM = 7, // Device not available
X64_ExceptionCode_DF = 8, // Double fault
X64_ExceptionCode_9 = 9, // Coprocessor segment overrun (obsolete)
X64_ExceptionCode_TS = 10, // Invalid task-state segment
X64_ExceptionCode_NP = 11, // Segment not present
X64_ExceptionCode_SS = 12, // Stack-segment fault
X64_ExceptionCode_GP = 13, // General-protection fault
X64_ExceptionCode_PF = 14, // Page fault
X64_ExceptionCode_15 = 15, // Reserved; Linux names it X86_TRAP_SPURIOUS
X64_ExceptionCode_MF = 16, // x87 floating-point exception
X64_ExceptionCode_AC = 17, // Alignment check
X64_ExceptionCode_MC = 18, // Machine check
X64_ExceptionCode_XF = 19, // SIMD floating-point exception
X64_ExceptionCode_VE = 20, // Virtualization exception
X64_ExceptionCode_CP = 21, // Control-protection exception
X64_ExceptionCode_Amd_HV = 28, // Hypervisor injection exception
X64_ExceptionCode_Amd_VC = 29, // VMM communication exception
X64_ExceptionCode_Amd_SX = 30, // Security exception
}
X64_ExceptionCode;
////////////////////////////////
//~ Page Fault Flags
typedef enum
typedef enum X64_PageFaultError
{
X64_PageFaultError_Protection = (1u << 0),
X64_PageFaultError_Write = (1u << 1),
@@ -253,7 +254,8 @@ typedef enum
X64_PageFaultError_InstructionFetch = (1u << 4),
X64_PageFaultError_ProtectionKey = (1u << 5),
X64_PageFaultError_ShadowStack = (1u << 6),
} X64_PageFaultError;
}
X64_PageFaultError;
////////////////////////////////
//~ rjf: Generated
@@ -280,4 +282,4 @@ internal X64_XSaveLayout x64_get_xsave_layout(U64 xcr0);
internal void x64_set_debug_break(U64 *drs, U64 trap_idx, U64 addr, U64 size, X64_BreakpointType bp_type, X64_DebugBreakType break_type);
#endif // BASE_X64_H
#endif // X64_H