Revert "x64 does not belong in base - base is intended to be things we can assume everywhere, which explicitly disqualifies x64 by definition."

This reverts commit 4e4639c2a0.
This commit is contained in:
Nikita Smith committed 2026-09-21 14:05:13 -07:00
1 parent 4add147a09
commit f9950ef4e9
12 files changed
+164 -81

No files matched your search

-1
View File
@@ -21,7 +21,6 @@
#define STB_SPRINTF_DECORATE(name) raddbg_##name
#define STB_SPRINTF_STATIC
#include "third_party/stb/stb_sprintf.h"
#include "third_party/radsort/radsort.h"
////////////////////////////////
//~ rjf: Codebase Keywords
+3
View File
@@ -30,6 +30,9 @@
#include "base_test.c"
#include "base_entry_point.c"
// TODO: move x64 to base layer
#include "x64/x64.c"
#if OS_WINDOWS
# include "win32/base/win32_base.c"
#elif OS_LINUX
+1
View File
@@ -32,6 +32,7 @@
#include "base_test.h"
#include "base_entry_point.h"
#include "x64/x64.h"
#if OS_WINDOWS
# include "win32/base/win32_base.h"
#elif OS_LINUX
+35
View File
@@ -39,5 +39,40 @@ str8_lit_comp("MemoryExecute"),
str8_lit_comp("CppThrow"),
};
String8 dmn_event_kind_string_table[22] =
{
str8_lit_comp("Null"),
str8_lit_comp("Error"),
str8_lit_comp("HandshakeComplete"),
str8_lit_comp("CreateProcess"),
str8_lit_comp("ExitProcess"),
str8_lit_comp("CreateThread"),
str8_lit_comp("ExitThread"),
str8_lit_comp("LoadModule"),
str8_lit_comp("UnloadModule"),
str8_lit_comp("ModuleDebugInfo"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("Trap"),
str8_lit_comp("SingleStep"),
str8_lit_comp("Exception"),
str8_lit_comp("Halt"),
str8_lit_comp("Memory"),
str8_lit_comp("DebugString"),
str8_lit_comp("SetThreadName"),
str8_lit_comp("SetThreadColor"),
str8_lit_comp("SetBreakpoint"),
str8_lit_comp("UnsetBreakpoint"),
str8_lit_comp("SetVAddrRangeNote"),
};
String8 dmn_exception_kind_string_table[5] =
{
str8_lit_comp("Null"),
str8_lit_comp("MemoryRead"),
str8_lit_comp("MemoryWrite"),
str8_lit_comp("MemoryExecute"),
str8_lit_comp("CppThrow"),
};
C_LINKAGE_END
+58
View File
@@ -62,9 +62,67 @@ DMN_ExceptionKind_CppThrow,
DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind;
typedef enum DMN_EventKind
{
DMN_EventKind_Null,
DMN_EventKind_Error,
DMN_EventKind_HandshakeComplete,
DMN_EventKind_CreateProcess,
DMN_EventKind_ExitProcess,
DMN_EventKind_CreateThread,
DMN_EventKind_ExitThread,
DMN_EventKind_LoadModule,
DMN_EventKind_UnloadModule,
DMN_EventKind_ModuleDebugInfo,
DMN_EventKind_Breakpoint,
DMN_EventKind_Trap,
DMN_EventKind_SingleStep,
DMN_EventKind_Exception,
DMN_EventKind_Halt,
DMN_EventKind_Memory,
DMN_EventKind_DebugString,
DMN_EventKind_SetThreadName,
DMN_EventKind_SetThreadColor,
DMN_EventKind_SetBreakpoint,
DMN_EventKind_UnsetBreakpoint,
DMN_EventKind_SetVAddrRangeNote,
DMN_EventKind_COUNT,
} DMN_EventKind;
typedef enum DMN_ErrorKind
{
DMN_ErrorKind_Null,
DMN_ErrorKind_NotAttached,
DMN_ErrorKind_UnexpectedFailure,
DMN_ErrorKind_InvalidHandle,
DMN_ErrorKind_COUNT,
} DMN_ErrorKind;
typedef enum DMN_MemoryEventKind
{
DMN_MemoryEventKind_Null,
DMN_MemoryEventKind_Commit,
DMN_MemoryEventKind_Reserve,
DMN_MemoryEventKind_Decommit,
DMN_MemoryEventKind_Release,
DMN_MemoryEventKind_COUNT,
} DMN_MemoryEventKind;
typedef enum DMN_ExceptionKind
{
DMN_ExceptionKind_Null,
DMN_ExceptionKind_MemoryRead,
DMN_ExceptionKind_MemoryWrite,
DMN_ExceptionKind_MemoryExecute,
DMN_ExceptionKind_CppThrow,
DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind;
C_LINKAGE_BEGIN
extern String8 dmn_event_kind_string_table[22];
extern String8 dmn_exception_kind_string_table[5];
extern String8 dmn_event_kind_string_table[22];
extern String8 dmn_exception_kind_string_table[5];
C_LINKAGE_END
+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_ExceptionCode_PF) ||
if((state->uc_mcontext.gregs[REG_TRAPNO] != X64_Exception_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();
+7 -14
View File
@@ -35,13 +35,6 @@
#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);
@@ -53,13 +46,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; \
}))
////////////////////////////////
-2
View File
@@ -12,7 +12,6 @@
//- rjf: [h]
#include "base/base_inc.h"
#include "x64/x64.h"
#include "linker/hash_table.h"
#include "linker/base_ext/base_bit_array.h"
#include "rdi/rdi_local.h"
@@ -47,7 +46,6 @@
//- rjf: [c]
#include "base/base_inc.c"
#include "x64/x64.c"
#include "linker/hash_table.c"
#include "linker/base_ext/base_bit_array.c"
#include "rdi/rdi_local.c"
+2 -2
View File
@@ -376,8 +376,8 @@
//- rjf: [h]
#include "base/base_inc.h"
#include "x64/x64.h"
#include "win32/win32_inc.h"
#include "linker/hash_table.h"
#include "linker/base_ext/base_bit_array.h"
#include "artifact_cache/artifact_cache.h"
#include "rdi/rdi_local.h"
@@ -438,8 +438,8 @@
//- rjf: [c]
#include "base/base_inc.c"
#include "x64/x64.c"
#include "win32/win32_inc.c"
#include "linker/hash_table.c"
#include "linker/base_ext/base_bit_array.c"
#include "artifact_cache/artifact_cache.c"
#include "rdi/rdi_local.c"
+1 -1
View File
@@ -137,7 +137,7 @@ radsortmovesize( sizeof( (start)[0] ) ), \
//===================================================================================================
// small heap sort - this sort is around 200 bytes compiled - can use directly when size is important
static RSFORCEINLINE void radheapsortinteral( void * start, size_t len, size_t element_size, is_before_func * is_before, swap_func * swapper )
internal RSFORCEINLINE void radheapsortinteral( void * start, size_t len, size_t element_size, is_before_func * is_before, swap_func * swapper )
{
void * left;
void * right;
-2
View File
@@ -20,7 +20,6 @@
////////////////////////////////
#include "base/base_inc.h"
#include "x64/x64.h"
#include "linker/hash_table.h"
#include "linker/lf_hash_table.h"
#include "linker/base_ext/base_bit_array.h"
@@ -104,7 +103,6 @@
#include "torture.h"
#include "base/base_inc.c"
#include "x64/x64.c"
#include "linker/hash_table.c"
#include "linker/lf_hash_table.c"
#include "linker/base_ext/base_bit_array.c"
+30 -32
View File
@@ -212,40 +212,39 @@ X64_DebugControlFlags;
////////////////////////////////
//~ Exception Codes
typedef enum X64_ExceptionCode
typedef enum
{
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;
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;
////////////////////////////////
//~ Page Fault Flags
typedef enum X64_PageFaultError
typedef enum
{
X64_PageFaultError_Protection = (1u << 0),
X64_PageFaultError_Write = (1u << 1),
@@ -254,8 +253,7 @@ typedef enum X64_PageFaultError
X64_PageFaultError_InstructionFetch = (1u << 4),
X64_PageFaultError_ProtectionKey = (1u << 5),
X64_PageFaultError_ShadowStack = (1u << 6),
}
X64_PageFaultError;
} X64_PageFaultError;
////////////////////////////////
//~ rjf: Generated
@@ -282,4 +280,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 // X64_H
#endif // BASE_X64_H