//////////////////////////////// // Context Cracking // untangle compiler, os, & architecture #if defined(__clang__) # define COMPILER_CLANG 1 # if defined(_WIN32) # define OS_WINDOWS 1 # elif defined(__gnu_linux__) # define OS_LINUX 1 # elif defined(__APPLE__) && defined(__MACH__) # define OS_MAC 1 # else # error missing OS detection # endif # if defined(__amd64__) # define ARCH_X64 1 // TODO(allen): verify this works on clang # elif defined(__i386__) # define ARCH_X86 1 // TODO(allen): verify this works on clang # elif defined(__arm__) # define ARCH_ARM 1 // TODO(allen): verify this works on clang # elif defined(__aarch64__) # define ARCH_ARM64 1 # else # error missing ARCH detection # endif #elif defined(_MSC_VER) # define COMPILER_CL 1 # if defined(_WIN32) # define OS_WINDOWS 1 # else # error missing OS detection # endif # if defined(_M_AMD64) # define ARCH_X64 1 # elif defined(_M_I86) # define ARCH_X86 1 # elif defined(_M_ARM) # define ARCH_ARM 1 // TODO(allen): ARM64? # else # error missing ARCH detection # endif #elif defined(__GNUC__) # define COMPILER_GCC 1 # if defined(_WIN32) # define OS_WINDOWS 1 # elif defined(__gnu_linux__) # define OS_LINUX 1 # elif defined(__APPLE__) && defined(__MACH__) # define OS_MAC 1 # else # error missing OS detection # endif # if defined(__amd64__) # define ARCH_X64 1 # elif defined(__i386__) # define ARCH_X86 1 # elif defined(__arm__) # define ARCH_ARM 1 # elif defined(__aarch64__) # define ARCH_ARM64 1 # else # error missing ARCH detection # endif #else # error no context cracking for this compiler #endif #if !defined(COMPILER_CL) # define COMPILER_CL 0 #endif #if !defined(COMPILER_CLANG) # define COMPILER_CLANG 0 #endif #if !defined(COMPILER_GCC) # define COMPILER_GCC 0 #endif #if !defined(OS_WINDOWS) # define OS_WINDOWS 0 #endif #if !defined(OS_LINUX) # define OS_LINUX 0 #endif #if !defined(OS_MAC) # define OS_MAC 0 #endif #if !defined(ARCH_X64) # define ARCH_X64 0 #endif #if !defined(ARCH_X86) # define ARCH_X86 0 #endif #if !defined(ARCH_ARM) # define ARCH_ARM 0 #endif #if !defined(ARCH_ARM64) # define ARCH_ARM64 0 #endif // language #if defined(__cplusplus) # define LANG_CXX 1 #else # define LANG_C 1 #endif #if !defined(LANG_CXX) # define LANG_CXX 0 #endif #if !defined(LANG_C) # define LANG_C 0 #endif //////////////////////////////// // GLUE(a,b) STRIFY(s) #define GLUE__(a,b) a##b #define GLUE_(a,b) GLUE__(a,b) #define GLUE(a,b) GLUE_(a,b) #define STRIFY__(s) #s #define STRIFY_(s) STRIFY__(s) #define STRIFY(s) STRIFY_(s) //////////////////////////////// // SECTION() #if COMPILER_CLANG || COMPILER_GCC # define SECTION(N) __attribute__((__section__(N))) #elif COMPILER_CL # define SECTION(N) __declspec(allocate(N)) #else # error SECTION not defined for this compiler #endif // for CL users: #pragma section(
,read,write) //////////////////////////////// // BEFORE_MAIN(){ <...> } #if OS_WINDOWS # pragma section(".CRT$XCU", read) # if LANG_CXX # define BEFORE_MAIN_NAMED(n) \ static void n(void); \ __declspec(allocate(".CRT$XCU")) \ __pragma(comment(linker,"/include:" #n "__")) \ extern "C" void (*n##__)(void); \ void (*n##__)(void) = n; \ static void n(void) # else # define BEFORE_MAIN_NAMED(n) \ static void n(void); \ __declspec(allocate(".CRT$XCU")) \ __pragma(comment(linker,"/include:" #n "__")) \ void (*n##__)(void) = n; \ static void n(void) # endif #elif OS_LINUX # define BEFORE_MAIN_NAMED(n) \ __attribute__((constructor)) static void n(void) #else # error BEFORE_MAIN missing for this OS #endif #define BEFORE_MAIN_(n) BEFORE_MAIN_NAMED(n) #define BEFORE_MAIN() BEFORE_MAIN_(GLUE(beforemain,__COUNTER__)) //////////////////////////////// // DO_NOT_ELIMINATE #if OS_WINDOWS # define DO_NOT_ELIMINATE__S0(N) __pragma(comment(linker,"/include:" #N)) # define DO_NOT_ELIMINATE__S1(N) DO_NOT_ELIMINATE__S0(N) # define DO_NOT_ELIMINATE(N) DO_NOT_ELIMINATE__S1(N) #else # define DO_NOT_ELIMINATE(N) #endif //////////////////////////////// // Types #include typedef int8_t S8; typedef int16_t S16; typedef int32_t S32; typedef int64_t S64; typedef uint8_t U8; typedef uint16_t U16; typedef uint32_t U32; typedef uint64_t U64; typedef S8 B8; typedef S16 B16; typedef S32 B32; typedef S64 B64; typedef float F32; typedef double F64; typedef struct RangePtr{ U8 *first; U8 *opl; } RangePtr; typedef struct String8{ U8 *str; U64 size; } String8; #define str8_lit(str) str8((U8*)(str), sizeof(str) - 1) #define str8_lit_const(str) { (U8*)(str), sizeof(str) - 1 } #define str8_expand(s) ((int)((s).size)), ((s).str) //////////////////////////////// // Functions static String8 str8(U8 *str, U64 size); static B32 str8_match(String8 a, String8 b, U32 flags); static void* os_this_image(void); static RangePtr self_img_get_section(void *image, String8 name);