Initial build skeleton

This commit is contained in:
Luke Street
2025-11-05 21:55:12 -07:00
commit 3778c69d3b
359 changed files with 181847 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
build/
*.lib
+11
View File
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.22)
project(winedll LANGUAGES C ASM)
set(CMAKE_C_STANDARD 11)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
add_subdirectory(libs/musl)
add_subdirectory(imports/kernel32)
add_subdirectory(dlls/msvcrt)
+26
View File
@@ -0,0 +1,26 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR i686)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET i686-pc-windows-gnu)
set(CMAKE_CXX_COMPILER_TARGET i686-pc-windows-gnu)
set(CMAKE_ASM_COMPILER_TARGET i686-pc-windows-gnu)
set(CMAKE_AR llvm-ar)
set(CMAKE_RANLIB llvm-ranlib)
set(CMAKE_LINKER lld)
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "")
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES "")
set(CMAKE_C_FLAGS_INIT "-nostdinc")
set(CMAKE_CXX_FLAGS_INIT "-nostdinc")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostdlib")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-nostdlib")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-nostdlib")
+99
View File
@@ -0,0 +1,99 @@
cmake_minimum_required(VERSION 3.22)
add_library(msvcrt SHARED
console.c
ctype.c
data.c
dir.c
environ.c
errno.c
exit.c
file.c
heap.c
iob.c
locale.c
lock.c
main.c
math.c
mathf.c
mbcs.c
misc.c
onexit.c
process.c
scanf.c
sincos.c
string.c
thread.c
time.c
undname.c
wcs.c
stubs.c
)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set_target_properties(msvcrt PROPERTIES OUTPUT_NAME msvcrt)
target_compile_definitions(msvcrt
PRIVATE
_CRTIMP=
_MSVCR_VER=90
_NTSYSTEM_ # stub ntdll calls
__WINE_PE_BUILD
)
target_compile_options(msvcrt
PRIVATE
-fno-builtin
-fno-strict-aliasing
-fno-omit-frame-pointer
-Wno-deprecated-declarations
-Wno-unused-parameter
-Wno-missing-braces
-Wno-ignored-qualifiers
)
target_include_directories(msvcrt
PRIVATE
${PROJECT_SOURCE_DIR}/dlls/msvcrt
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/include/msvcrt
${PROJECT_SOURCE_DIR}/include/wine
)
target_link_libraries(msvcrt
PRIVATE
musl
kernel32_import_lib
)
execute_process(
COMMAND ${CMAKE_C_COMPILER} -print-resource-dir
OUTPUT_VARIABLE CLANG_RESOURCE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(CLANG_RESOURCE_DIR)
target_include_directories(msvcrt
PRIVATE
${CLANG_RESOURCE_DIR}/include
)
set(CLANG_BUILTINS_LIB "${CLANG_RESOURCE_DIR}/lib/linux/libclang_rt.builtins-i386.a")
if(EXISTS "${CLANG_BUILTINS_LIB}")
target_link_libraries(msvcrt PRIVATE "${CLANG_BUILTINS_LIB}")
endif()
endif()
set(_toolchain_target ${CMAKE_C_COMPILER_TARGET})
if(NOT _toolchain_target)
set(_toolchain_target i686-pc-windows-gnu)
endif()
execute_process(
COMMAND ${CMAKE_C_COMPILER} --target=${_toolchain_target} -print-libgcc-file-name
OUTPUT_VARIABLE LIBGCC_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(LIBGCC_PATH AND EXISTS "${LIBGCC_PATH}")
target_link_libraries(msvcrt PRIVATE "${LIBGCC_PATH}")
endif()
+49
View File
@@ -0,0 +1,49 @@
EXTRADEFS = -D_CRTIMP=
MODULE = msvcrt.dll
IMPORTLIB = msvcrt
IMPORTS = $(MUSL_PE_LIBS) ntdll
DELAYIMPORTS = advapi32 user32
SOURCES = \
concurrency.c \
console.c \
cpp.c \
crt_gccmain.c \
crt_main.c \
crt_winmain.c \
crt_wmain.c \
crt_wwinmain.c \
ctype.c \
data.c \
dir.c \
environ.c \
errno.c \
except.c \
except_arm.c \
except_arm64.c \
except_arm64ec.c \
except_i386.c \
except_x86_64.c \
exception_ptr.c \
exit.c \
file.c \
handler4.c \
heap.c \
iob.c \
locale.c \
lock.c \
main.c \
math.c \
mathf.c \
mbcs.c \
misc.c \
onexit.c \
process.c \
rsrc.rc \
scanf.c \
sincos.c \
string.c \
thread.c \
time.c \
undname.c \
wcs.c
+137
View File
@@ -0,0 +1,137 @@
/*
* Copyright 2020 Piotr Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_BNUM_H
#define __WINE_BNUM_H
#define EXP_BITS 11
#define MANT_BITS 53
static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
#define LIMB_DIGITS 9 /* each DWORD stores up to 9 digits */
#define LIMB_MAX 1000000000 /* 10^9 */
#define BNUM_PREC64 128 /* data size needed to store 64-bit double */
#define BNUM_PREC80 2048 /* data size needed to store 80-bit double */
/* bnum represents real number with fixed decimal point */
struct bnum {
int b; /* least significant digit position */
int e; /* most significant digit position + 1 */
int size; /* data buffer size in DWORDS (power of 2) */
DWORD data[1]; /* circular buffer, base 10 number */
};
static inline int bnum_idx(struct bnum *b, int idx)
{
return idx & (b->size - 1);
}
/* Returns TRUE if new most significant limb was added */
static inline BOOL bnum_lshift(struct bnum *b, int shift)
{
DWORD rest = 0;
ULONGLONG tmp;
int i;
/* The limbs number can change by up to 1 so shift <= 29 */
assert(shift <= 29);
for(i=b->b; i<b->e; i++) {
tmp = ((ULONGLONG)b->data[bnum_idx(b, i)] << shift) + rest;
rest = tmp / LIMB_MAX;
b->data[bnum_idx(b, i)] = tmp % LIMB_MAX;
if(i == b->b && !b->data[bnum_idx(b, i)])
b->b++;
}
if(rest) {
b->data[bnum_idx(b, b->e)] = rest;
b->e++;
if(bnum_idx(b, b->b) == bnum_idx(b, b->e)) {
if(b->data[bnum_idx(b, b->b)]) b->data[bnum_idx(b, b->b+1)] |= 1;
b->b++;
}
return TRUE;
}
return FALSE;
}
/* Returns TRUE if most significant limb was removed */
static inline BOOL bnum_rshift(struct bnum *b, int shift)
{
DWORD tmp, rest = 0;
BOOL ret = FALSE;
int i;
/* Compute LIMB_MAX << shift without accuracy loss */
assert(shift <= 9);
for(i=b->e-1; i>=b->b; i--) {
tmp = b->data[bnum_idx(b, i)] & ((1<<shift)-1);
b->data[bnum_idx(b, i)] = (b->data[bnum_idx(b, i)] >> shift) + rest;
rest = (LIMB_MAX >> shift) * tmp;
if(i==b->e-1 && !b->data[bnum_idx(b, i)]) {
b->e--;
ret = TRUE;
}
}
if(rest) {
if(bnum_idx(b, b->b-1) == bnum_idx(b, b->e)) {
if(rest) b->data[bnum_idx(b, b->b)] |= 1;
} else {
b->b--;
b->data[bnum_idx(b, b->b)] = rest;
}
}
return ret;
}
static inline void bnum_mult(struct bnum *b, int mult)
{
DWORD rest = 0;
ULONGLONG tmp;
int i;
assert(mult <= LIMB_MAX);
for(i=b->b; i<b->e; i++) {
tmp = ((ULONGLONG)b->data[bnum_idx(b, i)] * mult) + rest;
rest = tmp / LIMB_MAX;
b->data[bnum_idx(b, i)] = tmp % LIMB_MAX;
if(i == b->b && !b->data[bnum_idx(b, i)])
b->b++;
}
if(rest) {
b->data[bnum_idx(b, b->e)] = rest;
b->e++;
if(bnum_idx(b, b->b) == bnum_idx(b, b->e)) {
if(b->data[bnum_idx(b, b->b)]) b->data[bnum_idx(b, b->b+1)] |= 1;
b->b++;
}
}
}
#endif /* __WINE_BNUM_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1104
View File
File diff suppressed because it is too large Load Diff
+373
View File
@@ -0,0 +1,373 @@
/*
* msvcrt C++ exception handling
*
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __MSVCRT_CPPEXCEPT_H
#define __MSVCRT_CPPEXCEPT_H
#include <fpieee.h>
#include "cxx.h"
#define CXX_FRAME_MAGIC_VC6 0x19930520
#define CXX_FRAME_MAGIC_VC7 0x19930521
#define CXX_FRAME_MAGIC_VC8 0x19930522
#define CXX_EXCEPTION 0xe06d7363
typedef struct
{
UINT ip;
int state;
} ipmap_info;
#ifndef CXX_USE_RVA
#define CXX_EXCEPTION_PARAMS 3
/* info about a single catch {} block */
typedef struct
{
UINT flags; /* flags (see below) */
const type_info *type_info; /* C++ type caught by this block */
int offset; /* stack offset to copy exception object to */
void * (*handler)(void);/* catch block handler code */
} catchblock_info;
/* info about a single try {} block */
typedef struct
{
int start_level; /* start trylevel of that block */
int end_level; /* end trylevel of that block */
int catch_level; /* initial trylevel of the catch block */
unsigned int catchblock_count; /* count of catch blocks in array */
const catchblock_info *catchblock; /* array of catch blocks */
} tryblock_info;
/* info about the unwind handler for a given trylevel */
typedef struct
{
int prev; /* prev trylevel unwind handler, to run after this one */
void * (*handler)(void);/* unwind handler */
} unwind_info;
/* descriptor of all try blocks of a given function */
typedef struct
{
UINT magic : 29; /* must be CXX_FRAME_MAGIC */
UINT bbt_flags : 3;
UINT unwind_count; /* number of unwind handlers */
const unwind_info *unwind_table; /* array of unwind handlers */
UINT tryblock_count; /* number of try blocks */
const tryblock_info *tryblock; /* array of try blocks */
UINT ipmap_count;
const ipmap_info *ipmap;
const void *expect_list; /* expected exceptions list when magic >= VC7 */
UINT flags; /* flags when magic >= VC8 */
} cxx_function_descr;
#else /* CXX_USE_RVA */
#define CXX_EXCEPTION_PARAMS 4
typedef struct
{
UINT flags;
UINT type_info;
int offset;
UINT handler;
#ifdef _WIN64
UINT frame;
#endif
} catchblock_info;
typedef struct
{
int start_level;
int end_level;
int catch_level;
UINT catchblock_count;
UINT catchblock;
} tryblock_info;
typedef struct
{
int prev;
UINT handler;
} unwind_info;
typedef struct
{
UINT magic : 29;
UINT bbt_flags : 3;
UINT unwind_count;
UINT unwind_table;
UINT tryblock_count;
UINT tryblock;
UINT ipmap_count;
UINT ipmap;
int unwind_help;
UINT expect_list;
UINT flags;
} cxx_function_descr;
#endif /* CXX_USE_RVA */
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */
#define FUNC_DESCR_NOEXCEPT 4 /* noexcept function */
#define CLASS_IS_SIMPLE_TYPE 1
#define CLASS_HAS_VIRTUAL_BASE_CLASS 4
#define TYPE_FLAG_CONST 1
#define TYPE_FLAG_VOLATILE 2
#define TYPE_FLAG_REFERENCE 8
void WINAPI DECLSPEC_NORETURN _CxxThrowException(void*,const cxx_exception_type*);
static inline BOOL is_cxx_exception( EXCEPTION_RECORD *rec )
{
if (rec->ExceptionCode != CXX_EXCEPTION) return FALSE;
if (rec->NumberParameters != CXX_EXCEPTION_PARAMS) return FALSE;
return (rec->ExceptionInformation[0] >= CXX_FRAME_MAGIC_VC6 &&
rec->ExceptionInformation[0] <= CXX_FRAME_MAGIC_VC8);
}
typedef struct
{
EXCEPTION_RECORD *rec;
LONG *ref; /* not binary compatible with native msvcr100 */
} exception_ptr;
void throw_exception(const char*);
void exception_ptr_from_record(exception_ptr*,EXCEPTION_RECORD*);
void __cdecl __ExceptionPtrCreate(exception_ptr*);
void __cdecl __ExceptionPtrDestroy(exception_ptr*);
void __cdecl __ExceptionPtrRethrow(const exception_ptr*);
BOOL __cdecl __uncaught_exception(void);
static inline const char *dbgstr_type_info( const type_info *info )
{
if (!info) return "{}";
return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}",
info->vtable, info->mangled, info->name ? info->name : "" );
}
/* compute the this pointer for a base class of a given type */
static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
{
if (!object) return NULL;
if (off->vbase_descr >= 0)
{
int *offset_ptr;
/* move this ptr to vbase descriptor */
object = (char *)object + off->vbase_descr;
/* and fetch additional offset from vbase descriptor */
offset_ptr = (int *)(*(char **)object + off->vbase_offset);
object = (char *)object + *offset_ptr;
}
object = (char *)object + off->this_offset;
return object;
}
#ifdef __ASM_USE_THISCALL_WRAPPER
extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
extern void call_dtor( void *func, void *this );
#else
static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
{
if (has_vbase)
((void (__thiscall*)(void*, void*, BOOL))func)(this, src, 1);
else
((void (__thiscall*)(void*, void*))func)(this, src);
}
static inline void call_dtor( void *func, void *this )
{
((void (__thiscall*)(void*))func)( this );
}
#endif
/* check if the exception type is caught by a given catch block, and return the type that matched */
static inline const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, uintptr_t base,
const type_info *catch_ti, UINT catch_flags )
{
const cxx_type_info_table *type_info_table = cxx_rva( exc_type->type_info_table, base );
UINT i;
for (i = 0; i < type_info_table->count; i++)
{
const cxx_type_info *type = cxx_rva( type_info_table->info[i], base );
const type_info *ti = cxx_rva( type->type_info, base );
if (!catch_ti) return type; /* catch(...) matches any type */
if (catch_ti != ti)
{
if (strcmp( catch_ti->mangled, ti->mangled )) continue;
}
/* type is the same, now check the flags */
if ((exc_type->flags & TYPE_FLAG_CONST) &&
!(catch_flags & TYPE_FLAG_CONST)) continue;
if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
!(catch_flags & TYPE_FLAG_VOLATILE)) continue;
return type; /* it matched */
}
return NULL;
}
/* copy the exception object where the catch block wants it */
static inline void copy_exception( void *object, void **dest, UINT catch_flags,
const cxx_type_info *type, uintptr_t base )
{
if (catch_flags & TYPE_FLAG_REFERENCE)
{
*dest = get_this_pointer( &type->offsets, object );
}
else if (type->flags & CLASS_IS_SIMPLE_TYPE)
{
memmove( dest, object, type->size );
/* if it is a pointer, adjust it */
if (type->size == sizeof(void*)) *dest = get_this_pointer( &type->offsets, *dest );
}
else /* copy the object */
{
if (type->copy_ctor)
call_copy_ctor( cxx_rva( type->copy_ctor, base ), dest,
get_this_pointer( &type->offsets, object ),
(type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) );
else
memmove( dest, get_this_pointer( &type->offsets, object ), type->size );
}
}
#define TRACE_EXCEPTION_TYPE(type,base) do { \
const cxx_type_info_table *table = cxx_rva( type->type_info_table, base ); \
unsigned int i; \
TRACE( "flags %x destr %p handler %p type info %p\n", \
type->flags, cxx_rva( type->destructor, base ), \
type->custom_handler ? cxx_rva( type->custom_handler, base ) : NULL, table ); \
for (i = 0; i < table->count; i++) \
{ \
const cxx_type_info *type = cxx_rva( table->info[i], base ); \
const type_info *info = cxx_rva( type->type_info, base ); \
TRACE( " %d: flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n", \
i, type->flags, info, dbgstr_type_info( info ), \
type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset, \
type->size, cxx_rva( type->copy_ctor, base )); \
} \
} while(0)
extern void dump_function_descr( const cxx_function_descr *descr, uintptr_t base );
extern void *find_catch_handler( void *object, uintptr_t frame, uintptr_t exc_base,
const tryblock_info *tryblock,
cxx_exception_type *exc_type, uintptr_t image_base );
extern int handle_fpieee_flt( __msvcrt_ulong exception_code, EXCEPTION_POINTERS *ep,
int (__cdecl *handler)(_FPIEEE_RECORD*) );
#ifndef __i386__
extern void *call_catch_handler( EXCEPTION_RECORD *rec );
extern void *call_unwind_handler( void *func, uintptr_t frame, DISPATCHER_CONTEXT *dispatch );
extern ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch );
#endif
#if _MSVCR_VER >= 80
#define EXCEPTION_MANGLED_NAME ".?AVexception@std@@"
#else
#define EXCEPTION_MANGLED_NAME ".?AVexception@@"
#endif
#define CREATE_EXCEPTION_OBJECT(exception_name) \
static exception* __exception_ctor(exception *this, const char *str, const vtable_ptr *vtbl) \
{ \
if (str) \
{ \
unsigned int len = strlen(str) + 1; \
this->name = malloc(len); \
memcpy(this->name, str, len); \
this->do_free = TRUE; \
} \
else \
{ \
this->name = NULL; \
this->do_free = FALSE; \
} \
this->vtable = vtbl; \
return this; \
} \
\
static exception* __exception_copy_ctor(exception *this, const exception *rhs, const vtable_ptr *vtbl) \
{ \
if (rhs->do_free) \
{ \
__exception_ctor(this, rhs->name, vtbl); \
} \
else \
{ \
*this = *rhs; \
this->vtable = vtbl; \
} \
return this; \
} \
extern const vtable_ptr exception_name ## _vtable; \
DEFINE_THISCALL_WRAPPER(exception_name ## _copy_ctor,8) \
exception* __thiscall exception_name ## _copy_ctor(exception *this, const exception *rhs) \
{ \
return __exception_copy_ctor(this, rhs, & exception_name ## _vtable); \
} \
\
DEFINE_THISCALL_WRAPPER(exception_name ## _dtor,4) \
void __thiscall exception_name ## _dtor(exception *this) \
{ \
if (this->do_free) free(this->name); \
} \
\
DEFINE_THISCALL_WRAPPER(exception_name ## _vector_dtor,8) \
void* __thiscall exception_name ## _vector_dtor(exception *this, unsigned int flags) \
{ \
if (flags & 2) \
{ \
INT_PTR i, *ptr = (INT_PTR *)this - 1; \
\
for (i = *ptr - 1; i >= 0; i--) exception_name ## _dtor(this + i); \
operator_delete(ptr); \
} \
else \
{ \
exception_name ## _dtor(this); \
if (flags & 1) operator_delete(this); \
} \
return this; \
} \
\
DEFINE_THISCALL_WRAPPER(exception_name ## _what,4) \
const char* __thiscall exception_name ## _what(exception *this) \
{ \
return this->name ? this->name : "Unknown exception"; \
} \
\
__ASM_BLOCK_BEGIN(exception_name ## _vtables) \
__ASM_VTABLE(exception_name, \
VTABLE_ADD_FUNC(exception_name ## _vector_dtor) \
VTABLE_ADD_FUNC(exception_name ## _what)); \
__ASM_BLOCK_END \
\
DEFINE_RTTI_DATA(exception_name, 0, EXCEPTION_MANGLED_NAME)
#endif /* __MSVCRT_CPPEXCEPT_H */
+31
View File
@@ -0,0 +1,31 @@
/*
* __main entry point
*
* Copyright 2019 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep implib
#endif
#ifdef __WINE_PE_BUILD
/* mingw compilers emit call to __main() when main() function is defined.
* it's used by crt to call global constructors and register global destructors. */
void __cdecl __main(void) {}
#endif
+62
View File
@@ -0,0 +1,62 @@
/*
* mainCRTStartup default entry point
*
* Copyright 2019 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep implib
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <process.h>
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
int __cdecl main(int argc, char **argv, char **env);
static const IMAGE_NT_HEADERS *get_nt_header( void )
{
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)NtCurrentTeb()->Peb->ImageBaseAddress;
return (const IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
}
int __cdecl mainCRTStartup(void)
{
int argc, ret;
char **argv, **env;
#ifdef _UCRT
_configure_narrow_argv(_crt_argv_unexpanded_arguments);
_initialize_narrow_environment();
argc = *__p___argc();
argv = *__p___argv();
env = _get_initial_narrow_environment();
#else
int new_mode = 0;
__getmainargs(&argc, &argv, &env, 0, &new_mode);
#endif
_set_app_type(get_nt_header()->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? _crt_gui_app : _crt_console_app);
ret = main(argc, argv, env);
exit(ret);
return ret;
}
+54
View File
@@ -0,0 +1,54 @@
/*
* main default entry point for exe files
*
* Copyright 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep implib
#endif
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
int __cdecl main( int argc, char *argv[] )
{
STARTUPINFOA info;
char *cmdline = GetCommandLineA();
int bcount = 0;
BOOL in_quotes = FALSE;
while (*cmdline)
{
if ((*cmdline == '\t' || *cmdline == ' ') && !in_quotes) break;
else if (*cmdline == '\\') bcount++;
else if (*cmdline == '\"')
{
if (!(bcount & 1)) in_quotes = !in_quotes;
bcount = 0;
}
else bcount = 0;
cmdline++;
}
while (*cmdline == '\t' || *cmdline == ' ') cmdline++;
GetStartupInfoA( &info );
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
return WinMain( GetModuleHandleA(0), 0, cmdline, info.wShowWindow );
}
+62
View File
@@ -0,0 +1,62 @@
/*
* wmainCRTStartup default entry point
*
* Copyright 2019 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep implib
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <process.h>
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
int __cdecl wmain(int argc, WCHAR **argv, WCHAR **env);
static const IMAGE_NT_HEADERS *get_nt_header( void )
{
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)NtCurrentTeb()->Peb->ImageBaseAddress;
return (const IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
}
int __cdecl wmainCRTStartup(void)
{
int argc, ret;
WCHAR **argv, **env;
#ifdef _UCRT
_configure_wide_argv(_crt_argv_unexpanded_arguments);
_initialize_wide_environment();
argc = *__p___argc();
argv = *__p___wargv();
env = _get_initial_wide_environment();
#else
int new_mode = 0;
__wgetmainargs(&argc, &argv, &env, 0, &new_mode);
#endif
_set_app_type(get_nt_header()->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? _crt_gui_app : _crt_console_app);
ret = wmain(argc, argv, env);
exit(ret);
return ret;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* main default entry point for Unicode exe files
*
* Copyright 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep implib
#endif
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
int WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,int);
int __cdecl wmain( int argc, WCHAR *argv[] )
{
STARTUPINFOW info;
WCHAR *cmdline = GetCommandLineW();
int bcount = 0;
BOOL in_quotes = FALSE;
while (*cmdline)
{
if ((*cmdline == '\t' || *cmdline == ' ') && !in_quotes) break;
else if (*cmdline == '\\') bcount++;
else if (*cmdline == '\"')
{
if (!(bcount & 1)) in_quotes = !in_quotes;
bcount = 0;
}
else bcount = 0;
cmdline++;
}
while (*cmdline == '\t' || *cmdline == ' ') cmdline++;
GetStartupInfoW( &info );
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
return wWinMain( GetModuleHandleW(0), 0, cmdline, info.wShowWindow );
}
+617
View File
File diff suppressed because it is too large Load Diff
+430
View File
@@ -0,0 +1,430 @@
/*
* Copyright 2012 Piotr Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "windef.h"
#include "winternl.h"
#include "rtlsupportapi.h"
#include "wine/asm.h"
#ifdef __i386__
#undef CXX_USE_RVA
#else
#define CXX_USE_RVA 1
#endif
#ifndef _WIN64
#undef RTTI_USE_RVA
#else
#define RTTI_USE_RVA 1
#endif
#ifdef _WIN64
#define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n"
#define __ASM_VTABLE(name,funcs) \
__asm__(".data\n" \
"\t.balign 8\n" \
"\t.quad " __ASM_NAME(#name "_rtti") "\n" \
__ASM_GLOBL(__ASM_NAME(#name "_vtable")) "\n" \
funcs "\n\t.text")
#else
#define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n"
#define __ASM_VTABLE(name,funcs) \
__asm__(".data\n" \
"\t.balign 4\n" \
"\t.long " __ASM_NAME(#name "_rtti") "\n" \
__ASM_GLOBL(__ASM_NAME(#name "_vtable")) "\n" \
funcs "\n\t.text")
#endif /* _WIN64 */
#ifndef RTTI_USE_RVA
#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \
static type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \
\
static const rtti_base_descriptor name ## _rtti_base_descriptor[1] = \
{ { &name ##_type_info, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { 0, -1, 0}, 64 } }; \
\
static const rtti_base_array name ## _rtti_base_array = \
{ { name ## _rtti_base_descriptor, __VA_ARGS__ } }; \
\
static const rtti_object_hierarchy name ## _hierarchy = \
{ 0, 0, ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })), &name ## _rtti_base_array }; \
\
const rtti_object_locator name ## _rtti = \
{ 0, off, 0, &name ## _type_info, &name ## _hierarchy };
#define INIT_RTTI(name,base) /* nothing to do */
#elif defined __WINE_PE_BUILD
#define DEFINE_RTTI_DATA2(name, off, mangled_name, ...) \
extern const rtti_object_locator name##_rtti; \
type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \
extern const rtti_base_descriptor name ## _rtti_base_descriptor[1]; \
void __asm_dummy_ ## name ## _rtti(void) \
{ \
asm( ".balign 4\n\t" \
__ASM_GLOBL(#name "_rtti_base_descriptor") "\n\t" \
".rva " #name "_type_info\n\t" \
".long %c0-1, 0, -1, 0, 64\n" \
#name "_rtti_base_array:\n\t" \
".rva " #__VA_ARGS__ "\n" \
#name "_rtti_hierarchy:\n\t" \
".long 0, 0, %c0\n\t" \
".rva " #name "_rtti_base_array\n\t" \
__ASM_GLOBL(#name "_rtti") "\n\t" \
".long 1, %c1, 0\n\t" \
".rva " #name "_type_info\n\t" \
".rva " #name "_rtti_hierarchy\n\t" \
".rva " #name "_rtti\n\t" \
:: "i"(ARRAY_SIZE(((const void *[]){ __VA_ARGS__ }))), "i"(off) ); \
}
#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \
DEFINE_RTTI_DATA2(name, off, mangled_name, name ## _rtti_base_descriptor, ##__VA_ARGS__)
#define INIT_RTTI(name,base) /* nothing to do */
#else /* RTTI_USE_RVA */
#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \
static type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \
\
static rtti_base_descriptor name ## _rtti_base_descriptor[1] = \
{ { 0xdeadbeef, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { 0, -1, 0}, 64 } }; \
\
static rtti_base_array name ## _rtti_base_array; \
\
static rtti_object_hierarchy name ## _hierarchy = \
{ 0, 0, ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })) }; \
\
rtti_object_locator name ## _rtti = \
{ 1, off, 0, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; \
\
static void init_ ## name ## _rtti(char *base) \
{ \
const void * const name ## _rtti_bases[] = { name ## _rtti_base_descriptor, __VA_ARGS__ }; \
name ## _rtti_base_descriptor[0].type_descriptor = (char*)&name ## _type_info - base; \
for (unsigned int i = 0; i < ARRAY_SIZE(name ## _rtti_bases); i++) \
name ## _rtti_base_array.bases[i] = (char*)name ## _rtti_bases[i] - base; \
name ## _hierarchy.base_classes = (char*)&name ## _rtti_base_array - base; \
name ## _rtti.type_descriptor = (char*)&name ## _type_info - base; \
name ## _rtti.type_hierarchy = (char*)&name ## _hierarchy - base; \
name ## _rtti.object_locator = (char*)&name ## _rtti - base; \
}
#define INIT_RTTI(name,base) init_ ## name ## _rtti((void *)(base))
#endif /* RTTI_USE_RVA */
#ifndef CXX_USE_RVA
#define DEFINE_CXX_TYPE(type, dtor, ...) \
static const cxx_type_info type ## _cxx_type_info[1] = \
{ { 0, &type ##_type_info, { 0, -1, 0 }, sizeof(type), THISCALL(type ##_copy_ctor) } }; \
\
static const cxx_type_info_table type ## _cxx_type_table = \
{ ARRAY_SIZE(((const void *[]){ NULL, __VA_ARGS__ })), { type ## _cxx_type_info, __VA_ARGS__ } }; \
\
static const cxx_exception_type type ## _exception_type = \
{ 0, THISCALL(dtor), NULL, & type ## _cxx_type_table };
#define INIT_CXX_TYPE(name,base) (void)name ## _exception_type
#elif defined __WINE_PE_BUILD
#define DEFINE_CXX_TYPE2(type, dtor, ...) \
extern const cxx_type_info type ## _cxx_type_info[1]; \
extern const cxx_exception_type type ## _exception_type; \
void __asm_dummy_ ## type ## _exception_type(void) \
{ \
asm( ".balign 4\n\t" \
__ASM_GLOBL(#type "_cxx_type_info") "\n\t" \
".long 0\n\t" \
".rva " #type "_type_info\n\t" \
".long 0, -1, 0, %c0\n\t" \
".rva " #type "_copy_ctor\n" \
#type "_type_table:\n\t" \
".long %c1\n\t" \
".rva " #__VA_ARGS__ "\n\t" \
__ASM_GLOBL(#type "_exception_type") "\n\t" \
".long 0\n\t" \
".rva " #dtor "\n\t" \
".long 0\n\t" \
".rva " #type "_type_table\n\t" \
:: "i"(sizeof(type)), "i"(ARRAY_SIZE(((const void *[]){ &__VA_ARGS__ }))) ); \
}
#define DEFINE_CXX_TYPE(type, dtor, ...) \
DEFINE_CXX_TYPE2(type, dtor, type ## _cxx_type_info, ##__VA_ARGS__)
#define INIT_CXX_TYPE(name,base) /* nothing to do */
#else /* CXX_USE_RVA */
#define DEFINE_CXX_TYPE(type, dtor, ...) \
static cxx_type_info type ## _cxx_type_info[1] = \
{ { 0, 0xdeadbeef, { 0, -1, 0 }, sizeof(type), 0xdeadbeef } }; \
\
static const void * const type ## _cxx_type_classes[] = { type ## _cxx_type_info, __VA_ARGS__ }; \
static cxx_type_info_table type ## _cxx_type_table = { ARRAY_SIZE(type ## _cxx_type_classes) }; \
static cxx_exception_type type ##_exception_type; \
\
static void init_ ## type ## _cxx(char *base) \
{ \
type ## _cxx_type_info[0].type_info = (char *)&type ## _type_info - base; \
type ## _cxx_type_info[0].copy_ctor = (char *)type ## _copy_ctor - base; \
for (unsigned int i = 0; i < ARRAY_SIZE(type ## _cxx_type_classes); i++) \
type ## _cxx_type_table.info[i] = (char *)type ## _cxx_type_classes[i] - base; \
type ## _exception_type.destructor = (char *)dtor - base; \
type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \
}
#define INIT_CXX_TYPE(name,base) init_ ## name ## _cxx((void *)(base))
#endif /* CXX_USE_RVA */
#ifdef __ASM_USE_THISCALL_WRAPPER
#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args
extern void *vtbl_wrapper_0;
extern void *vtbl_wrapper_4;
extern void *vtbl_wrapper_8;
extern void *vtbl_wrapper_12;
extern void *vtbl_wrapper_16;
extern void *vtbl_wrapper_20;
extern void *vtbl_wrapper_24;
extern void *vtbl_wrapper_28;
extern void *vtbl_wrapper_32;
extern void *vtbl_wrapper_36;
extern void *vtbl_wrapper_40;
extern void *vtbl_wrapper_44;
extern void *vtbl_wrapper_48;
extern void *vtbl_wrapper_52;
extern void *vtbl_wrapper_56;
#else
#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__thiscall***)type)this)[0][off/4]args
#endif
/* exception object */
typedef void (*vtable_ptr)(void);
typedef struct __exception
{
const vtable_ptr *vtable;
char *name; /* Name of this exception, always a new copy for each object */
int do_free; /* Whether to free 'name' in our dtor */
} exception;
/* rtti */
typedef struct __type_info
{
const vtable_ptr *vtable;
char *name; /* Unmangled name, allocated lazily */
char mangled[128]; /* Variable length, but we declare it large enough for static RTTI */
} type_info;
/* offsets for computing the this pointer */
typedef struct
{
int this_offset; /* offset of base class this pointer from start of object */
int vbase_descr; /* offset of virtual base class descriptor */
int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */
} this_ptr_offsets;
#ifndef RTTI_USE_RVA
typedef struct _rtti_base_descriptor
{
const type_info *type_descriptor;
int num_base_classes;
this_ptr_offsets offsets; /* offsets for computing the this pointer */
unsigned int attributes;
} rtti_base_descriptor;
typedef struct _rtti_base_array
{
const rtti_base_descriptor *bases[10]; /* First element is the class itself */
} rtti_base_array;
typedef struct _rtti_object_hierarchy
{
unsigned int signature;
unsigned int attributes;
int array_len; /* Size of the array pointed to by 'base_classes' */
const rtti_base_array *base_classes;
} rtti_object_hierarchy;
typedef struct _rtti_object_locator
{
unsigned int signature;
int base_class_offset;
unsigned int flags;
const type_info *type_descriptor;
const rtti_object_hierarchy *type_hierarchy;
} rtti_object_locator;
#else
typedef struct
{
unsigned int type_descriptor;
int num_base_classes;
this_ptr_offsets offsets; /* offsets for computing the this pointer */
unsigned int attributes;
} rtti_base_descriptor;
typedef struct
{
unsigned int bases[10]; /* First element is the class itself */
} rtti_base_array;
typedef struct
{
unsigned int signature;
unsigned int attributes;
int array_len; /* Size of the array pointed to by 'base_classes' */
unsigned int base_classes;
} rtti_object_hierarchy;
typedef struct
{
unsigned int signature;
int base_class_offset;
unsigned int flags;
unsigned int type_descriptor;
unsigned int type_hierarchy;
unsigned int object_locator;
} rtti_object_locator;
#endif /* RTTI_USE_RVA */
#ifndef CXX_USE_RVA
typedef struct
{
UINT flags;
const type_info *type_info;
this_ptr_offsets offsets;
unsigned int size;
void *copy_ctor;
} cxx_type_info;
typedef struct
{
UINT count;
const cxx_type_info *info[5];
} cxx_type_info_table;
typedef struct
{
UINT flags;
void *destructor;
void *custom_handler;
const cxx_type_info_table *type_info_table;
} cxx_exception_type;
#else
typedef struct
{
UINT flags;
unsigned int type_info;
this_ptr_offsets offsets;
unsigned int size;
unsigned int copy_ctor;
} cxx_type_info;
typedef struct
{
UINT count;
unsigned int info[5];
} cxx_type_info_table;
typedef struct
{
UINT flags;
unsigned int destructor;
unsigned int custom_handler;
unsigned int type_info_table;
} cxx_exception_type;
#endif /* CXX_USE_RVA */
extern const vtable_ptr type_info_vtable;
#ifdef CXX_USE_RVA
static inline uintptr_t cxx_rva_base( const void *ptr )
{
void *base;
return (uintptr_t)RtlPcToFileHeader( (void *)ptr, &base );
}
static inline void *cxx_rva( unsigned int rva, uintptr_t base )
{
return (void *)(base + rva);
}
#else
static inline uintptr_t cxx_rva_base( const void *ptr )
{
return 0;
}
static inline void *cxx_rva( const void *ptr, uintptr_t base )
{
return (void *)ptr;
}
#endif
#define CREATE_TYPE_INFO_VTABLE \
DEFINE_THISCALL_WRAPPER(type_info_vector_dtor,8) \
void * __thiscall type_info_vector_dtor(type_info * _this, unsigned int flags) \
{ \
if (flags & 2) \
{ \
/* we have an array, with the number of elements stored before the first object */ \
INT_PTR i, *ptr = (INT_PTR *)_this - 1; \
\
for (i = *ptr - 1; i >= 0; i--) free(_this[i].name); \
free(ptr); \
} \
else \
{ \
free(_this->name); \
if (flags & 1) free(_this); \
} \
return _this; \
} \
\
DEFINE_RTTI_DATA( type_info, 0, ".?AVtype_info@@" ) \
\
__ASM_BLOCK_BEGIN(type_info_vtables) \
__ASM_VTABLE(type_info, \
VTABLE_ADD_FUNC(type_info_vector_dtor)); \
__ASM_BLOCK_END
+735
View File
File diff suppressed because it is too large Load Diff
+1795
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More