253 lines
4.9 KiB
C
253 lines
4.9 KiB
C
////////////////////////////////
|
|
// 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(<section-name>) <Decl>
|
|
|
|
#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(<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 <stdint.h>
|
|
|
|
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);
|