aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tccpe.c28
-rw-r--r--win32/build-tcc.bat6
-rw-r--r--win32/lib/crt1.c49
-rw-r--r--win32/lib/wincrt1.c59
4 files changed, 111 insertions, 31 deletions
diff --git a/tccpe.c b/tccpe.c
index 8d29070..8bb3d85 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -1759,34 +1759,46 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
{
const char *start_symbol;
int pe_type = 0;
+ int unicode_entry = 0;
if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
pe_type = PE_GUI;
else
+ if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
+ pe_type = PE_GUI;
+ unicode_entry = PE_GUI;
+ }
+ else
if (TCC_OUTPUT_DLL == s1->output_type) {
pe_type = PE_DLL;
/* need this for 'tccelf.c:relocate_section()' */
s1->output_type = TCC_OUTPUT_EXE;
}
- else
+ else {
pe_type = PE_EXE;
+ if (find_elf_sym(symtab_section, "wmain"))
+ unicode_entry = PE_EXE;
+ }
start_symbol =
TCC_OUTPUT_MEMORY == s1->output_type
- ? PE_GUI == pe_type ? "__runwinmain" : "_main"
+ ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
+ : (unicode_entry ? "__runwmain" : "__runmain")
: PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
- : PE_GUI == pe_type ? "__winstart" : "__start"
+ : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
+ : (unicode_entry ? "__wstart" : "__start")
;
if (!s1->leading_underscore || strchr(start_symbol, '@'))
++start_symbol;
/* grab the startup code from libtcc1 */
- if (TCC_OUTPUT_MEMORY != s1->output_type || PE_GUI == pe_type)
- set_elf_sym(symtab_section,
- 0, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
- SHN_UNDEF, start_symbol);
+ /* only (PE_Dll == pe_type) doesn't need it,
+ (TCC_OUTPUT_MEMORY == s1->output_type && PE_Dll == pe_type) is illegal */
+ set_elf_sym(symtab_section,
+ 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ SHN_UNDEF, start_symbol);
tcc_add_pragma_libs(s1);
diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat
index 09117b4..8da1404 100644
--- a/win32/build-tcc.bat
+++ b/win32/build-tcc.bat
@@ -137,10 +137,12 @@ copy>nul tiny_libmaker.exe tiny_libmaker-m%T%.exe
%CC% -o tiny_libmaker-m%TX%.exe tools\tiny_libmaker.c %DX%
:libtcc1.a
-@set O1=libtcc1.o crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o bcheck.o
+@set O1=libtcc1.o crt1.o wincrt1.o crt1_w.o wincrt1_w.o dllcrt1.o dllmain.o chkstk.o bcheck.o
.\tcc -m32 %D32% -c ../lib/libtcc1.c
.\tcc -m32 %D32% -c lib/crt1.c
+.\tcc -m32 %D32% -c lib/crt1.c -D_UNICODE -DUNICODE -o crt1_w.o
.\tcc -m32 %D32% -c lib/wincrt1.c
+.\tcc -m32 %D32% -c lib/wincrt1.c -D_UNICODE -DUNICODE -o wincrt1_w.o
.\tcc -m32 %D32% -c lib/dllcrt1.c
.\tcc -m32 %D32% -c lib/dllmain.c
.\tcc -m32 %D32% -c lib/chkstk.S
@@ -151,7 +153,9 @@ tiny_libmaker-m32 lib/32/libtcc1.a %O1% alloca86.o alloca86-bt.o
@if errorlevel 1 goto :the_end
.\tcc -m64 %D64% -c ../lib/libtcc1.c
.\tcc -m64 %D64% -c lib/crt1.c
+.\tcc -m64 %D64% -c lib/crt1.c -D_UNICODE -DUNICODE -o crt1_w.o
.\tcc -m64 %D64% -c lib/wincrt1.c
+.\tcc -m64 %D64% -c lib/wincrt1.c -D_UNICODE -DUNICODE -o wincrt1_w.o
.\tcc -m64 %D64% -c lib/dllcrt1.c
.\tcc -m64 %D64% -c lib/dllmain.c
.\tcc -m64 %D64% -c lib/chkstk.S
diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c
index 7a2d765..1e2bd17 100644
--- a/win32/lib/crt1.c
+++ b/win32/lib/crt1.c
@@ -1,6 +1,9 @@
// =============================================
// crt1.c
+// _UNICODE for tchar.h, UNICODE for API
+#include <tchar.h>
+
#include <stdio.h>
#include <stdlib.h>
@@ -18,20 +21,32 @@ typedef struct
int newmode;
} _startupinfo;
-int __cdecl __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*);
+#ifdef _UNICODE
+#define __tgetmainargs __wgetmainargs
+#define _tstart _wstart
+#define _tmain wmain
+#define _runtmain _runwmain
+#else
+#define __tgetmainargs __getmainargs
+#define _tstart _start
+#define _tmain main
+#define _runtmain _runmain
+#endif
+
+int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
void __cdecl __set_app_type(int apptype);
unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
-int main(int argc, char * argv[], char * env[]);
+extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]);
/* Allow command-line globbing with "int _dowildcard = 1;" in the user source */
int _dowildcard;
-void _start(void)
+void _tstart(void)
{
__TRY__
int argc, ret;
- char **argv;
- char **env;
+ _TCHAR **argv;
+ _TCHAR **env;
_startupinfo start_info;
// Sets the current application type
@@ -45,8 +60,28 @@ void _start(void)
#endif
start_info.newmode = 0;
- __getmainargs( &argc, &argv, &env, _dowildcard, &start_info);
- ret = main(argc, argv, env);
+ __tgetmainargs( &argc, &argv, &env, _dowildcard, &start_info);
+ ret = _tmain(argc, argv, env);
+ exit(ret);
+}
+
+void _runtmain(int argc0, /* as tcc passed in */ char **argv0)
+{
+ __TRY__
+ int argc, ret;
+ _TCHAR **argv;
+ _TCHAR **env;
+ _startupinfo start_info;
+
+ __set_app_type(_CONSOLE_APP);
+
+#ifdef __i386
+ _controlfp(_PC_53, _MCW_PC);
+#endif
+
+ start_info.newmode = 0;
+ __tgetmainargs( &argc, &argv, &env, _dowildcard, &start_info);
+ ret = _tmain(argc0, argv + argc - argc0, env);
exit(ret);
}
diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c
index 663fd33..06f42f0 100644
--- a/win32/lib/wincrt1.c
+++ b/win32/lib/wincrt1.c
@@ -1,5 +1,8 @@
//+---------------------------------------------------------------------------
+// _UNICODE for tchar.h, UNICODE for API
+#include <tchar.h>
+
#include <windows.h>
#include <stdlib.h>
@@ -9,10 +12,28 @@
void __set_app_type(int);
void _controlfp(unsigned a, unsigned b);
-int _winstart(void)
+#ifdef _UNICODE
+#define __tgetmainargs __wgetmainargs
+#define _twinstart _wwinstart
+#define _runtwinmain _runwwinmain
+int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
+#else
+#define __tgetmainargs __getmainargs
+#define _twinstart _winstart
+#define _runtwinmain _runwinmain
+#endif
+
+typedef struct
+{
+ int newmode;
+} _startupinfo; // CLI Vs GUI
+
+int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
+
+int _twinstart(void)
{
__TRY__
- char *szCmd;
+ _TCHAR *szCmd;
STARTUPINFO startinfo;
int fShow;
int ret;
@@ -22,19 +43,19 @@ int _winstart(void)
szCmd = GetCommandLine();
if (szCmd) {
- while (' ' == *szCmd)
+ while (__T(' ') == *szCmd)
szCmd++;
- if ('\"' == *szCmd) {
+ if (__T('\"') == *szCmd) {
while (*++szCmd)
- if ('\"' == *szCmd) {
+ if (__T('\"') == *szCmd) {
szCmd++;
break;
}
} else {
- while (*szCmd && ' ' != *szCmd)
+ while (*szCmd && __T(' ') != *szCmd)
szCmd++;
}
- while (' ' == *szCmd)
+ while (__T(' ') == *szCmd)
szCmd++;
}
@@ -43,22 +64,30 @@ int _winstart(void)
if (0 == (startinfo.dwFlags & STARTF_USESHOWWINDOW))
fShow = SW_SHOWDEFAULT;
- ret = WinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
+ ret = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
exit(ret);
}
-int _runwinmain(int argc, char **argv)
+int _runtwinmain(int argc0, /* as tcc passed in */ char **argv0)
{
- char *szCmd, *p;
+ _TCHAR *szCmd, *p;
+
+ int argc;
+ _TCHAR **argv;
+ _TCHAR **env;
+ _startupinfo start_info;
+
+ start_info.newmode = 0;
+ __tgetmainargs(&argc, &argv, &env, 0, &start_info);
p = GetCommandLine();
szCmd = NULL;
- if (argc > 1)
- szCmd = strstr(p, argv[1]);
+ if (argc0 > 1)
+ szCmd = _tcsstr(p, argv[argc - argc0 + 1]);
if (NULL == szCmd)
- szCmd = "";
- else if (szCmd > p && szCmd[-1] == '\"')
+ szCmd = __T("");
+ else if (szCmd > p && szCmd[-1] == __T('\"'))
--szCmd;
_controlfp(0x10000, 0x30000);
- return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT);
+ return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT);
}