1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00
Beef/BeefRT/MinRT/MinRT.cpp

518 lines
14 KiB
C++
Raw Normal View History

2019-08-23 11:56:54 -07:00
#define SUPPORT_TLS
#ifdef _WIN64
typedef unsigned __int64 size_t;
typedef __int64 ptrdiff_t;
typedef __int64 intptr_t;
#else
typedef unsigned int size_t;
typedef int ptrdiff_t;
typedef int intptr_t;
#endif
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef char* LPSTR;
typedef char* LPBYTE;
typedef void* HINSTANCE;
typedef void* HANDLE;
typedef void* HMODULE;
#define WINAPI __stdcall
#define NTAPI __stdcall
typedef int BOOL;
#define FALSE 0
#define TRUE 1
#define NULL 0
#define _CONSOLE_APP 1
#define _GUI_APP 2
#define _O_RDONLY 0x0000 // open for reading only
#define _O_WRONLY 0x0001 // open for writing only
#define STD_INPUT_HANDLE -10
#define STD_OUTPUT_HANDLE -11
#define STD_ERROR_HANDLE -12
#define SW_SHOWDEFAULT 10
#define STARTF_USESHOWWINDOW 0x00000001
#define DLL_THREAD_ATTACH 2
#define _MCW_PC 0x00030000 // Precision Control
#define _PC_53 0x00010000 // 53 bits
struct FILE;
typedef char* va_list;
typedef int errno_t;
struct _startupinfo
{
int newmode;
};
struct STARTUPINFOA
{
DWORD cb;
LPSTR lpReserved;
LPSTR lpDesktop;
LPSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
};
typedef void(__cdecl* VoidFunc)();
typedef int(__cdecl* IntFunc)();
char** gArgV = NULL;
char** gEnv = NULL;
int gArgC = 0;
bool gIsGUIApp = false;
_startupinfo gStartupInfo = { 0 };
extern "C" int _fltused = 0;
extern "C" int _tls_index = 0;
extern "C"
{
extern char* _acmdln;
extern wchar_t* _wcmdln;
}
//extern "C" extern void* _image_base;
extern "C" extern void* __ImageBase;
extern "C" int main(int argc, char** argv, char** env);
extern "C" int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow);
extern "C" int __getmainargs(int* _Argc, char*** _Argv, char *** _Env, int _DoWildCard, _startupinfo* _StartInfo);
extern "C" void __set_app_type(int at);
extern "C" void exit(int exitCode);
extern "C" void _exit(int exitCode);
extern "C" void _cexit();
extern "C" char* _strdup(const char* str);
extern "C" int _open_osfhandle(intptr_t osfhandle, int flags);
extern "C" intptr_t __stdcall GetStdHandle(int nStdHandle);
extern "C" FILE* _fdopen(int fd, const char *mode);
extern "C" void setbuf(FILE *stream, char *buffer);
extern "C" int printf_s(const char* str, va_list arglist);
extern "C" int fprintf_s(FILE* fp, const char* str, va_list arglist);
extern "C" void free(void* ptr);
extern "C" void _clearfp();
void __cdecl terminate();
extern "C" float floorf(float val);
extern "C" double floor(double val);
extern "C" int _finite(double val);
extern "C" int _finitef(float val);
extern "C" void _initterm(VoidFunc* begin, VoidFunc* end);
extern "C" int _initterm_e(IntFunc* begin, IntFunc * end);
extern "C" errno_t _controlfp_s(unsigned int *currentControl, unsigned int newControl, unsigned int mask);
extern "C" char* __stdcall GetCommandLineA();
extern "C" wchar_t* __stdcall GetCommandLineW();
extern "C" void __stdcall GetStartupInfoA(STARTUPINFOA* lpStartupInfo);
extern "C" HMODULE LoadLibraryA(char* lpFileName);
extern "C" void* GetProcAddress(HMODULE mod, const char* name);
//extern "C" void __stdcall OutputDebugStringA(char* ptr);
#pragma section(".CRT$XCA", long, read) // First C++ Initializer
#pragma section(".CRT$XCAA", long, read) // Startup C++ Initializer
#pragma section(".CRT$XCZ", long, read) // Last C++ Initializer
#pragma section(".CRT$XDA", long, read) // First Dynamic TLS Initializer
#pragma section(".CRT$XDZ", long, read) // Last Dynamic TLS Initializer
#pragma section(".CRT$XIA", long, read) // First C Initializer
#pragma section(".CRT$XIAA", long, read) // Startup C Initializer
#pragma section(".CRT$XIAB", long, read) // PGO C Initializer
#pragma section(".CRT$XIAC", long, read) // Post-PGO C Initializer
#pragma section(".CRT$XIC", long, read) // CRT C Initializers
#pragma section(".CRT$XIYA", long, read) // VCCorLib Threading Model Initializer
#pragma section(".CRT$XIYAA", long, read) // XAML Designer Threading Model Override Initializer
#pragma section(".CRT$XIYB", long, read) // VCCorLib Main Initializer
#pragma section(".CRT$XIZ", long, read) // Last C Initializer
#pragma section(".CRT$XLA", long, read) // First Loader TLS Callback
#pragma section(".CRT$XLC", long, read) // CRT TLS Constructor
#pragma section(".CRT$XLD", long, read) // CRT TLS Terminator
#pragma section(".CRT$XLZ", long, read) // Last Loader TLS Callback
#pragma section(".CRT$XPA", long, read) // First Pre-Terminator
#pragma section(".CRT$XPB", long, read) // CRT ConcRT Pre-Terminator
#pragma section(".CRT$XPX", long, read) // CRT Pre-Terminators
#pragma section(".CRT$XPXA", long, read) // CRT stdio Pre-Terminator
#pragma section(".CRT$XPZ", long, read) // Last Pre-Terminator
#pragma section(".CRT$XTA", long, read) // First Terminator
#pragma section(".CRT$XTZ", long, read) // Last Terminator
#pragma section(".CRTMA$XCA", long, read) // First Managed C++ Initializer
#pragma section(".CRTMA$XCZ", long, read) // Last Managed C++ Initializer
#pragma section(".CRTVT$XCA", long, read) // First Managed VTable Initializer
#pragma section(".CRTVT$XCZ", long, read) // Last Managed VTable Initializer
#pragma section(".rdata$T", long, read)
#pragma section(".rtc$IAA", long, read) // First RTC Initializer
#pragma section(".rtc$IZZ", long, read) // Last RTC Initializer
#pragma section(".rtc$TAA", long, read) // First RTC Terminator
#pragma section(".rtc$TZZ", long, read) // Last RTC Terminator
#ifdef SUPPORT_TLS
#pragma section(".tls",long,read,write)
#pragma section(".tls$",long,read,write)
#pragma section(".tls$ZZZ",long,read,write)
#endif
static int __cdecl pre_c_initialization()
{
#ifdef MINRT_CONSOLE
__set_app_type(_CONSOLE_APP);
#else
__set_app_type(_GUI_APP);
#endif
#ifdef _M_IX86
_clearfp();
#endif
//__setusermatherr
#ifdef _M_IX86
_controlfp_s(nullptr, _PC_53, _MCW_PC); // _initialize_default_precision()
#endif
return 0;
}
typedef void (NTAPI* PIMAGE_TLS_CALLBACK)(void* DllHandle, DWORD Reason, void* Reserved);
#define _CRTALLOC(x) __declspec(allocate(x))
_CRTALLOC(".CRT$XIAA") static IntFunc pre_c_initializer = pre_c_initialization;
extern "C" _CRTALLOC(".CRT$XIA") IntFunc __xi_a[] = { nullptr }; // C initializers (first)
extern "C" _CRTALLOC(".CRT$XIZ") IntFunc __xi_z[] = { nullptr }; // C initializers (last)
extern "C" _CRTALLOC(".CRT$XCA") VoidFunc __xc_a[] = { nullptr }; // C++ initializers (first)
extern "C" _CRTALLOC(".CRT$XCZ") VoidFunc __xc_z[] = { nullptr }; // C++ initializers (last)
extern "C" _CRTALLOC(".CRT$XPA") VoidFunc __xp_a[] = { nullptr }; // C pre-terminators (first)
extern "C" _CRTALLOC(".CRT$XPZ") VoidFunc __xp_z[] = { nullptr }; // C pre-terminators (last)
extern "C" _CRTALLOC(".CRT$XTA") VoidFunc __xt_a[] = { nullptr }; // C terminators (first)
extern "C" _CRTALLOC(".CRT$XTZ") VoidFunc __xt_z[] = { nullptr }; // C terminators (last)
extern "C" _CRTALLOC(".CRT$XDA") VoidFunc __xd_a = { nullptr };
extern "C" _CRTALLOC(".CRT$XDZ") VoidFunc __xd_z = { nullptr };
/* TLS raw template data start and end.
We use here pointer-types for start/end so that tls-data remains
aligned on pointer-size-width. This seems to be required for
pe-loader. */
#ifdef SUPPORT_TLS
extern "C" _CRTALLOC(".tls$") char* _tls_start = NULL;
extern "C" _CRTALLOC(".tls$ZZZ") char* _tls_end = NULL;
#endif
struct IMAGE_TLS_DIRECTORY
{
void* StartAddressOfRawData;
void* EndAddressOfRawData;
void* AddressOfIndex; // PDWORD
void* AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
DWORD SizeOfZeroFill;
union {
DWORD Characteristics;
struct {
DWORD Reserved0 : 20;
DWORD Alignment : 4;
DWORD Reserved1 : 8;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
};
#ifdef SUPPORT_TLS
BOOL WINAPI __dyn_tls_init(HANDLE hDllHandle, DWORD dwReason, void* lpreserved)
{
VoidFunc* ps = &__xd_a;
ps++;
for (; ps != &__xd_z; ps++)
{
if (*ps != NULL)
(*ps)();
}
return TRUE;
}
const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK)__dyn_tls_init;
extern "C" _CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK)__dyn_tls_init;
extern "C" _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
extern "C" _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
//extern "C" _CRTALLOC(".tls") IMAGE_TLS_DIRECTORY _tls_used = {
extern "C" IMAGE_TLS_DIRECTORY _tls_used = {
&_tls_start, &_tls_end,
&_tls_index, (&__xl_a + 1),
0, 0
};
#endif
#pragma comment(linker, "/merge:.CRT=.rdata")
FILE* gStdFiles[3];
FILE* GetStdFile(int stdHandleId, bool isIn)
{
// int fd = _open_osfhandle(GetStdHandle(stdHandleId), 0);
// if (fd == -1)
// return NULL;
// FILE* fp = _fdopen(fd, isIn ? "r" : "w");
FILE* fp = _fdopen(stdHandleId, isIn ? "r" : "w");
setbuf(fp, NULL);
return fp;
}
int Init()
{
/*gStdFiles[0] = GetStdFile(STD_INPUT_HANDLE, true);
gStdFiles[1] = GetStdFile(STD_OUTPUT_HANDLE, false);
gStdFiles[2] = GetStdFile(STD_ERROR_HANDLE, false);*/
gStdFiles[0] = GetStdFile(0, true);
gStdFiles[1] = GetStdFile(1, false);
gStdFiles[2] = GetStdFile(2, false);
int result = _initterm_e(__xi_a, __xi_z);
if (result != 0)
return result;
_initterm(__xc_a, __xc_z);
#ifdef __dyn_tls_init
if (__dyn_tls_init_callback != NULL)
__dyn_tls_init(NULL, DLL_THREAD_ATTACH, NULL);
#endif
return 0;
}
void Finish(int result)
{
_initterm(__xp_a, __xp_z);
_initterm(__xt_a, __xt_z);
exit(result);
_cexit();
}
#ifdef MINRT_CONSOLE
extern "C" int mainCRTStartup()
{
gIsGUIApp = false;
int result = Init();
if (result != 0)
return result;
__getmainargs(&gArgC, &gArgV, &gEnv, 0, &gStartupInfo);
result = main(gArgC, gArgV, gEnv);
Finish(result);
return result;
}
#else
extern "C" int WinMainCRTStartup()
{
STARTUPINFOA startupInfo;
GetStartupInfoA(&startupInfo);
int result = Init();
if (result != 0)
return result;
HINSTANCE hInstance = (HINSTANCE)&__ImageBase;
char* cmdLine = GetCommandLineA();
if (cmdLine)
{
bool inDoubleQuote = false;
while (*cmdLine > ' ' || (*cmdLine && inDoubleQuote))
{
if (*cmdLine == '"')
inDoubleQuote = !inDoubleQuote;
++cmdLine;
}
while (*cmdLine && (*cmdLine <= ' '))
cmdLine++;
}
result = WinMain(hInstance, NULL, cmdLine, startupInfo.dwFlags & STARTF_USESHOWWINDOW ?
startupInfo.wShowWindow : SW_SHOWDEFAULT);
Finish(result);
return result;
}
#endif
void __cdecl operator delete(void* val, unsigned __int64 size)
{
free(val);
}
void __cdecl operator delete(void* val, int a, const char* name, int line)
{
free(val);
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) void* __cdecl _set_purecall_handler(void* _Handler)
2019-08-23 11:56:54 -07:00
{
return 0;
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) void* __cdecl _set_invalid_parameter_handler(void* _Handler)
2019-08-23 11:56:54 -07:00
{
return 0;
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) unsigned int __cdecl _set_abort_behavior(unsigned int _Flags, unsigned int _Mask)
2019-08-23 11:56:54 -07:00
{
return 0;
}
extern "C" int _vsnprintf_s_l(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format,
void* locale,
va_list argptr
);
typedef int (PROC_vsnprintf_s_l)(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format,
void* locale,
va_list argptr
);
typedef int (PROC_vfprintf_l)(
FILE *stream,
const char *format,
void* locale,
va_list argptr
);
static HMODULE gCrtLib = NULL;
void* GetCrtProc(const char* name)
{
if (gCrtLib == NULL)
gCrtLib = ::LoadLibraryA("msvcrt.dll");
return ::GetProcAddress(gCrtLib, name);
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) int __cdecl __stdio_common_vsprintf(
2019-08-23 11:56:54 -07:00
unsigned __int64 const options,
char* const buffer,
size_t const buffer_count,
char const* const format,
void* const locale,
va_list const arglist
)
{
static PROC_vsnprintf_s_l* p_vsnprintf_s_l = (PROC_vsnprintf_s_l*)GetCrtProc("_vsnprintf_s_l");
return p_vsnprintf_s_l(buffer, buffer_count, -1, format, locale, arglist);
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) int __cdecl __stdio_common_vfprintf(
2019-08-23 11:56:54 -07:00
unsigned __int64 const options,
FILE* const stream,
char const* const format,
void* const locale,
va_list const arglist
)
{
static PROC_vfprintf_l* p_vfprintf_l = (PROC_vfprintf_l*)GetCrtProc("_vfprintf_l");
return p_vfprintf_l(stream, format, locale, arglist);
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) FILE* __cdecl __acrt_iob_func(unsigned const id)
2019-08-23 11:56:54 -07:00
{
return gStdFiles[id];
}
extern "C" __declspec(noreturn) void __cdecl __std_terminate()
{
terminate();
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) float roundf(float val)
2019-08-23 11:56:54 -07:00
{
if (!_finitef(val))
{
return val;
}
else if (val >= 0)
{
float result = floorf(val);
if (result - val <= -0.5f)
result += 1.0f;
return result;
}
else
{
float result = floorf(-val);
if (result + val <= -0.5f)
result += 1.0f;
return -result;
}
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) double round(double val)
2019-08-23 11:56:54 -07:00
{
if (!_finite(val))
{
return val;
}
else if (val >= 0)
{
double result = floor(val);
if (result - val <= -0.5)
result += 1.0;
return result;
}
else
{
double result = floor(-val);
if (result + val <= -0.5)
result += 1.0;
return -result;
}
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) char* strdup(const char* str)
2019-08-23 11:56:54 -07:00
{
return _strdup(str);
}
2022-03-23 16:49:00 -07:00
extern "C" __declspec(dllexport) void __CxxFrameHandler4()
2020-10-28 10:02:08 -07:00
{
}
2019-08-23 11:56:54 -07:00
// if (TSS > _Init_thread_epoch) {
// _Init_thread_header(&TSS);
// Test our bit from the guard variable.
// if (TSS == -1) {
// ... initialize the object ...;
// _Init_thread_footer(&TSS);
// }
// }