/*********************************************************** ** symbol_set - A public domain C modifier library ** by Allen Webster, "Mr. 4th", allenw@mr4th.com ** ** No warranty implied; use at your own risk ** ** Read README to get started. */ #ifndef SYMBOL_SET_H #define SYMBOL_SET_H /********************* ** Context Cracking ** *********************/ /* untangle compiler, os, & architecture */ #if defined(__clang__) # define SY__COMPILER_CLANG 1 # if defined(_WIN32) # define SY__OS_WINDOWS 1 # elif defined(__gnu_linux__) # define SY__OS_LINUX 1 # elif defined(__APPLE__) && defined(__MACH__) # define SY__OS_MAC 1 # else # error missing OS detection # endif # if defined(__amd64__) # define SY__ARCH_X64 1 # elif defined(__i386__) # define SY__ARCH_X86 1 # elif defined(__arm__) # define SY__ARCH_ARM 1 # elif defined(__aarch64__) # define SY__ARCH_ARM64 1 # else # error missing ARCH detection # endif #elif defined(_MSC_VER) # define SY__COMPILER_CL 1 # if defined(_WIN32) # define SY__OS_WINDOWS 1 # else # error missing OS detection # endif # if defined(_M_AMD64) # define SY__ARCH_X64 1 # elif defined(_M_I86) # define SY__ARCH_X86 1 # elif defined(_M_ARM) # define SY__ARCH_ARM 1 # else # error missing ARCH detection # endif #elif defined(__GNUC__) # define SY__COMPILER_GCC 1 # if defined(_WIN32) # define SY__OS_WINDOWS 1 # elif defined(__gnu_linux__) # define SY__OS_LINUX 1 # elif defined(__APPLE__) && defined(__MACH__) # define SY__OS_MAC 1 # else # error missing OS detection # endif # if defined(__amd64__) # define SY__ARCH_X64 1 # elif defined(__i386__) # define SY__ARCH_X86 1 # elif defined(__arm__) # define SY__ARCH_ARM 1 # elif defined(__aarch64__) # define SY__ARCH_ARM64 1 # else # error missing ARCH detection # endif #else # error no context cracking for this compiler #endif #if !defined(SY__COMPILER_CL) # define SY__COMPILER_CL 0 #endif #if !defined(SY__COMPILER_CLANG) # define SY__COMPILER_CLANG 0 #endif #if !defined(SY__COMPILER_GCC) # define SY__COMPILER_GCC 0 #endif #if !defined(SY__OS_WINDOWS) # define SY__OS_WINDOWS 0 #endif #if !defined(SY__OS_LINUX) # define SY__OS_LINUX 0 #endif #if !defined(SY__OS_MAC) # define SY__OS_MAC 0 #endif #if !defined(SY__ARCH_X64) # define SY__ARCH_X64 0 #endif #if !defined(SY__ARCH_X86) # define SY__ARCH_X86 0 #endif #if !defined(SY__ARCH_ARM) # define SY__ARCH_ARM 0 #endif #if !defined(SY__ARCH_ARM64) # define SY__ARCH_ARM64 0 #endif /* language */ #if defined(__cplusplus) # define SY__LANG_CXX 1 #else # define SY__LANG_C 1 #endif #if !defined(SY__LANG_CXX) # define SY__LANG_CXX 0 #endif #if !defined(SY__LANG_C) # define SY__LANG_C 0 #endif /********** ** Types ** **********/ #include typedef uint8_t Sy_U8; typedef uint16_t Sy_U16; typedef uint32_t Sy_U32; typedef uint64_t Sy_U64; #if SY__ARCH_X64 || SY__ARCH_ARM64 typedef Sy_U64 Sy_UAddress; #else typedef Sy_U32 Sy_UAddress; #endif /****************** ** Macro Helpers ** ******************/ #define SY__GLUE_(a,b) a##b #define SY__GLUE(a,b) SY__GLUE_(a,b) #define SY__STRIFY_(s) #s #define SY__STRIFY(s) SY__STRIFY_(s) /***************** ** Align Helper ** *****************/ #define SY__ALIGN_TO_POW2(x,a) (((x) + (a) - 1)&~((a) - 1)) /******************* ** Section Macros ** *******************/ /* IMPORTANT! On CL compiler add: #pragma section(
,read,write) */ #if SY__COMPILER_CLANG || SY__COMPILER_GCC # if SY__OS_MAC # define SY__SECTION_READONLY(N) __attribute__((__section__("__TEXT,"N))) const # define SY__SECTION_READWRITE(N) __attribute__((__section__("__READ,"N))) # else # define SY__SECTION_READONLY(N) __attribute__((__section__(N))) const # define SY__SECTION_READWRITE(N) __attribute__((__section__(N))) # endif #elif COMPILER_CL # define SY__SECTION_READONLY(N) __declspec(allocate(N)) const # define SY__SECTION_READWRITE(N) __declspec(allocate(N)) #else # error SY__SECTION_* not defined for this compiler/OS #endif /**************************** ** Do Not Mangle Qualifier ** ****************************/ #if SY__LANG_CXX # define SY__DO_NOT_MANGLE extern "C" #else # define SY__DO_NOT_MANGLE #endif /******************************* ** Do Not Eliminate Qualifier ** *******************************/ #if SY__OS_WINDOWS # define SY__DO_NOT_ELIMINATE__S0(N) __pragma(comment(linker,"/include:" #N)) # define SY__DO_NOT_ELIMINATE__S1(N) DO_NOT_ELIMINATE__S0(N) # define SY__DO_NOT_ELIMINATE(N) DO_NOT_ELIMINATE__S1(N) #else # define SY__DO_NOT_ELIMINATE(N) #endif /******************** ** Align Qualifier ** ********************/ #if SY__COMPILER_CL # define SY__ALIGN_VAR(z) __declspec(align(z)) #elif SY__COMPILER_CLANG || SY__COMPILER_GCC # define SY__ALIGN_VAR(z) __attribute__((__aligned__(z))) #else # error SY__ALIGN not defined for this compiler #endif /***************** ** Before Mains ** *****************/ #if SY__OS_WINDOWS # pragma section(".CRT$XCU", read) # define SY__BEFORE_MAIN__(n) \ static void n(void); \ SY__SECTIONREADWRITE(".CRT$XCU") \ SY__DO_NOT_ELIMINATE(n##__) \ SY__DO_NOT_MANGLE void (*n##__)(void); \ void (*n##__)(void) = n; \ static void n(void) #elif SY__OS_LINUX # define SY__BEFORE_MAIN__(n) __attribute__((constructor)) static void n(void) #else # error SY__BEFORE_MAIN__ missing for this OS #endif #define SY__BEFORE_MAIN_(n) SY__BEFORE_MAIN__(n) #define SY__BEFORE_MAIN(n) SY__BEFORE_MAIN_(n) /************************************* ** Symbol Set Programming Interface ** *************************************/ #define SyType(S) SY__GLUE(S,_Type) #define SyDeclare(S,N) SY__ALIGN_VAR(8) SY__SECTION_READWRITE(S##_section) SyType(S) SY__SYMBOL(S,N) #define SyDefine(S,N) SY__DO_NOT_ELIMINATE(SY__SYMBOL(S,N)) SyDeclare(S,N) #define SyDefineUnnamed(S) SyDefine(S,SY__GLUE(unnamed,__COUNTER__)) #define SyAddress(S,N) (&SY__SYMBOL(S,N)) #define SyID(S,N) SyIDFromAddress_Unchecked(S,SyAddress(S,N)) #define SyFlag(S,N) (1llu << SyID(S,N)) #define SyStride(S) SY__ALIGN_TO_POW2(sizeof(SyType(S)), 8) #if SY__OS_WINDOWS # define SyFirst(S) SY__FIRST(S) # define SyOpl(S) SY__OPL(S) #elif SY__OS_LINUX # define SyFirst(S) (&SY__FIRST(S)) # define SyOpl(S) (&SY__OPL(S)) #else # error missing implementation set locator for this OS #endif #define SyCount(S) (((Sy_U8*)SyOpl(S) - (Sy_U8*)SyFirst(S))/SyStride(S)) #define SyNext(S,addr) (SyType(S)*)((Sy_U8*)addr + SyStride(S)) #define SyEach(S,var) SyType(S)*var=SyFirst(S); var