mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
win32: adjust new unicode support
- lib/Makefile: add (win)crt1_w.o - crt1.c/_runtmain: return to tcc & only use for UNICODE (because it might be not 100% reliable with for example wildcards (tcc *.c -run ...) - tccrun.c/tccpe.c: load -run startup_code only if called from tcc_run(). Otherwise main may not be defined. See libtcc_test.c - tests2/Makefile: pass extra options in FLAGS to allow overriding TCC Also: - tccpe.c: support weak attribute. (I first tried to solve the problem above by using it but then didn't)
This commit is contained in:
parent
39b2afeb7c
commit
096125d963
@ -17,6 +17,7 @@ Platforms:
|
|||||||
- provide a runtime library for ARM (Thomas Preud'homme)
|
- provide a runtime library for ARM (Thomas Preud'homme)
|
||||||
- many x86-64 ABI fixes incl. XMM register passing and tests (James Lyon)
|
- many x86-64 ABI fixes incl. XMM register passing and tests (James Lyon)
|
||||||
- ABI tests with native compiler using libtcc (James Lyon)
|
- ABI tests with native compiler using libtcc (James Lyon)
|
||||||
|
- UNICODE startup code supports wmain and wWinMain (YX Hao)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- VLA (variable length array) improved (James Lyon, Pip Cet)
|
- VLA (variable length array) improved (James Lyon, Pip Cet)
|
||||||
|
@ -41,7 +41,7 @@ I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
|
|||||||
X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BCHECK_O)
|
X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BCHECK_O)
|
||||||
ARM_O = libtcc1.o armeabi.o alloca-arm.o
|
ARM_O = libtcc1.o armeabi.o alloca-arm.o
|
||||||
ARM64_O = lib-arm64.o
|
ARM64_O = lib-arm64.o
|
||||||
WIN32_O = crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
|
WIN32_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o
|
||||||
|
|
||||||
ifeq "$(TARGET)" "i386-win32"
|
ifeq "$(TARGET)" "i386-win32"
|
||||||
OBJ = $(addprefix $(DIR)/,$(I386_O) $(WIN32_O))
|
OBJ = $(addprefix $(DIR)/,$(I386_O) $(WIN32_O))
|
||||||
|
3
libtcc.c
3
libtcc.c
@ -743,9 +743,6 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_I386
|
#ifdef TCC_TARGET_I386
|
||||||
s->seg_size = 32;
|
s->seg_size = 32;
|
||||||
#endif
|
|
||||||
#ifdef TCC_IS_NATIVE
|
|
||||||
s->runtime_main = "main";
|
|
||||||
#endif
|
#endif
|
||||||
/* enable this if you want symbols with leading underscore on windows: */
|
/* enable this if you want symbols with leading underscore on windows: */
|
||||||
#if 0 /* def TCC_TARGET_PE */
|
#if 0 /* def TCC_TARGET_PE */
|
||||||
|
25
tccpe.c
25
tccpe.c
@ -358,6 +358,7 @@ struct pe_info {
|
|||||||
int type;
|
int type;
|
||||||
DWORD sizeofheaders;
|
DWORD sizeofheaders;
|
||||||
ADDR3264 imagebase;
|
ADDR3264 imagebase;
|
||||||
|
const char *start_symbol;
|
||||||
DWORD start_addr;
|
DWORD start_addr;
|
||||||
DWORD imp_offs;
|
DWORD imp_offs;
|
||||||
DWORD imp_size;
|
DWORD imp_size;
|
||||||
@ -638,7 +639,6 @@ static int pe_write(struct pe_info *pe)
|
|||||||
switch (si->cls) {
|
switch (si->cls) {
|
||||||
case sec_text:
|
case sec_text:
|
||||||
pe_header.opthdr.BaseOfCode = addr;
|
pe_header.opthdr.BaseOfCode = addr;
|
||||||
pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sec_data:
|
case sec_data:
|
||||||
@ -700,6 +700,7 @@ static int pe_write(struct pe_info *pe)
|
|||||||
|
|
||||||
//pe_header.filehdr.TimeDateStamp = time(NULL);
|
//pe_header.filehdr.TimeDateStamp = time(NULL);
|
||||||
pe_header.filehdr.NumberOfSections = pe->sec_count;
|
pe_header.filehdr.NumberOfSections = pe->sec_count;
|
||||||
|
pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
|
||||||
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
||||||
pe_header.opthdr.ImageBase = pe->imagebase;
|
pe_header.opthdr.ImageBase = pe->imagebase;
|
||||||
pe_header.opthdr.Subsystem = pe->subsystem;
|
pe_header.opthdr.Subsystem = pe->subsystem;
|
||||||
@ -1309,6 +1310,9 @@ static int pe_check_symbols(struct pe_info *pe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
|
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||||
|
/* STB_WEAK undefined symbols are accepted */
|
||||||
|
continue;
|
||||||
tcc_error_noabort("undefined symbol '%s'", name);
|
tcc_error_noabort("undefined symbol '%s'", name);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
@ -1793,8 +1797,9 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
|||||||
++start_symbol;
|
++start_symbol;
|
||||||
|
|
||||||
/* grab the startup code from libtcc1 */
|
/* grab the startup code from libtcc1 */
|
||||||
/* only (PE_Dll == pe_type) doesn't need it,
|
#ifdef TCC_IS_NATIVE
|
||||||
(TCC_OUTPUT_MEMORY == s1->output_type && PE_Dll == pe_type) is illegal */
|
if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
|
||||||
|
#endif
|
||||||
set_elf_sym(symtab_section,
|
set_elf_sym(symtab_section,
|
||||||
0, 0,
|
0, 0,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||||
@ -1817,16 +1822,10 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TCC_OUTPUT_MEMORY == s1->output_type) {
|
if (TCC_OUTPUT_MEMORY == s1->output_type)
|
||||||
pe_type = PE_RUN;
|
pe_type = PE_RUN;
|
||||||
#ifdef TCC_IS_NATIVE
|
|
||||||
s1->runtime_main = start_symbol;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
pe->start_addr = (DWORD)(uintptr_t)tcc_get_symbol_err(s1, start_symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
pe->type = pe_type;
|
pe->type = pe_type;
|
||||||
|
pe->start_symbol = start_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pe_set_options(TCCState * s1, struct pe_info *pe)
|
static void pe_set_options(TCCState * s1, struct pe_info *pe)
|
||||||
@ -1905,6 +1904,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
|||||||
pe_relocate_rva(&pe, s);
|
pe_relocate_rva(&pe, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pe.start_addr = (DWORD)
|
||||||
|
((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
|
||||||
|
- pe.imagebase);
|
||||||
if (s1->nb_errors)
|
if (s1->nb_errors)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else
|
else
|
||||||
@ -1914,6 +1916,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
|||||||
#ifdef TCC_IS_NATIVE
|
#ifdef TCC_IS_NATIVE
|
||||||
pe.thunk = data_section;
|
pe.thunk = data_section;
|
||||||
pe_build_imports(&pe);
|
pe_build_imports(&pe);
|
||||||
|
s1->runtime_main = pe.start_symbol;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
tccrun.c
1
tccrun.c
@ -107,6 +107,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int (*prog_main)(int, char **);
|
int (*prog_main)(int, char **);
|
||||||
|
|
||||||
|
s1->runtime_main = "main";
|
||||||
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
|
prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
|
||||||
|
@ -28,9 +28,6 @@ endif
|
|||||||
ifeq (,$(filter i386 x86-64,$(ARCH)))
|
ifeq (,$(filter i386 x86-64,$(ARCH)))
|
||||||
SKIP += 85_asm-outside-function.test
|
SKIP += 85_asm-outside-function.test
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGETOS),Windows)
|
|
||||||
SKIP += 76_dollars_in_identifiers.test
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Some tests might need arguments
|
# Some tests might need arguments
|
||||||
ARGS =
|
ARGS =
|
||||||
@ -42,7 +39,8 @@ NORUN =
|
|||||||
42_function_pointer.test : NORUN = true
|
42_function_pointer.test : NORUN = true
|
||||||
|
|
||||||
# Some tests might need different flags
|
# Some tests might need different flags
|
||||||
76_dollars_in_identifiers.test : TCCFLAGS += -fdollars-in-identifiers
|
FLAGS =
|
||||||
|
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
|
||||||
|
|
||||||
# Filter source directory in warnings/errors (out-of-tree builds)
|
# Filter source directory in warnings/errors (out-of-tree builds)
|
||||||
FILTER = 2>&1 | sed 's,$(SRC)/,,g'
|
FILTER = 2>&1 | sed 's,$(SRC)/,,g'
|
||||||
@ -57,9 +55,9 @@ all test: $(filter-out $(SKIP),$(TESTS))
|
|||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
# test -run
|
# test -run
|
||||||
@if test -z "$(NORUN)"; then \
|
@if test -z "$(NORUN)"; then \
|
||||||
$(TCC) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \
|
$(TCC) $(FLAGS) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \
|
||||||
else \
|
else \
|
||||||
$(TCC) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \
|
$(TCC) $(FLAGS) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \
|
||||||
./$*.exe $(ARGS) >>$*.output 2>&1 || true; \
|
./$*.exe $(ARGS) >>$*.output 2>&1 || true; \
|
||||||
fi
|
fi
|
||||||
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe
|
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe
|
||||||
|
@ -137,12 +137,12 @@ copy>nul tiny_libmaker.exe tiny_libmaker-m%T%.exe
|
|||||||
%CC% -o tiny_libmaker-m%TX%.exe tools\tiny_libmaker.c %DX%
|
%CC% -o tiny_libmaker-m%TX%.exe tools\tiny_libmaker.c %DX%
|
||||||
|
|
||||||
:libtcc1.a
|
:libtcc1.a
|
||||||
@set O1=libtcc1.o crt1.o wincrt1.o crt1_w.o wincrt1_w.o dllcrt1.o dllmain.o chkstk.o bcheck.o
|
@set O1=libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o bcheck.o
|
||||||
.\tcc -m32 %D32% -c ../lib/libtcc1.c
|
.\tcc -m32 %D32% -c ../lib/libtcc1.c
|
||||||
.\tcc -m32 %D32% -c lib/crt1.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/crt1w.c
|
||||||
.\tcc -m32 %D32% -c lib/wincrt1.c
|
.\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/wincrt1w.c
|
||||||
.\tcc -m32 %D32% -c lib/dllcrt1.c
|
.\tcc -m32 %D32% -c lib/dllcrt1.c
|
||||||
.\tcc -m32 %D32% -c lib/dllmain.c
|
.\tcc -m32 %D32% -c lib/dllmain.c
|
||||||
.\tcc -m32 %D32% -c lib/chkstk.S
|
.\tcc -m32 %D32% -c lib/chkstk.S
|
||||||
@ -153,9 +153,9 @@ tiny_libmaker-m32 lib/32/libtcc1.a %O1% alloca86.o alloca86-bt.o
|
|||||||
@if errorlevel 1 goto :the_end
|
@if errorlevel 1 goto :the_end
|
||||||
.\tcc -m64 %D64% -c ../lib/libtcc1.c
|
.\tcc -m64 %D64% -c ../lib/libtcc1.c
|
||||||
.\tcc -m64 %D64% -c lib/crt1.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/crt1w.c
|
||||||
.\tcc -m64 %D64% -c lib/wincrt1.c
|
.\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/wincrt1w.c
|
||||||
.\tcc -m64 %D64% -c lib/dllcrt1.c
|
.\tcc -m64 %D64% -c lib/dllcrt1.c
|
||||||
.\tcc -m64 %D64% -c lib/dllmain.c
|
.\tcc -m64 %D64% -c lib/dllmain.c
|
||||||
.\tcc -m64 %D64% -c lib/chkstk.S
|
.\tcc -m64 %D64% -c lib/chkstk.S
|
||||||
|
@ -65,24 +65,23 @@ void _tstart(void)
|
|||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _runtmain(int argc0, /* as tcc passed in */ char **argv0)
|
int _runtmain(int argc, /* as tcc passed in */ char **argv)
|
||||||
{
|
{
|
||||||
__TRY__
|
#ifdef UNICODE
|
||||||
int argc, ret;
|
int wargc;
|
||||||
_TCHAR **argv;
|
_TCHAR **wargv, **wenv;
|
||||||
_TCHAR **env;
|
_startupinfo start_info = {0};
|
||||||
_startupinfo start_info;
|
|
||||||
|
|
||||||
__set_app_type(_CONSOLE_APP);
|
__tgetmainargs(&wargc, &wargv, &wenv, _dowildcard, &start_info);
|
||||||
|
if (argc < wargc)
|
||||||
|
wargv += wargc - argc;
|
||||||
|
#define argv wargv
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __i386
|
#ifdef __i386
|
||||||
_controlfp(_PC_53, _MCW_PC);
|
_controlfp(_PC_53, _MCW_PC);
|
||||||
#endif
|
#endif
|
||||||
|
return _tmain(argc, argv, NULL);
|
||||||
start_info.newmode = 0;
|
|
||||||
__tgetmainargs( &argc, &argv, &env, _dowildcard, &start_info);
|
|
||||||
ret = _tmain(argc0, argv + argc - argc0, env);
|
|
||||||
exit(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
|
3
win32/lib/crt1w.c
Normal file
3
win32/lib/crt1w.c
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#define _UNICODE 1
|
||||||
|
#define UNICODE 1
|
||||||
|
#include "crt1.c"
|
@ -68,22 +68,25 @@ int _twinstart(void)
|
|||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _runtwinmain(int argc0, /* as tcc passed in */ char **argv0)
|
int _runtwinmain(int argc, /* as tcc passed in */ char **argv)
|
||||||
{
|
{
|
||||||
_TCHAR *szCmd, *p;
|
_TCHAR *szCmd, *p;
|
||||||
|
|
||||||
int argc;
|
#ifdef UNICODE
|
||||||
_TCHAR **argv;
|
int wargc;
|
||||||
_TCHAR **env;
|
_TCHAR **wargv, **wenv;
|
||||||
_startupinfo start_info;
|
_startupinfo start_info = {0};
|
||||||
|
|
||||||
start_info.newmode = 0;
|
__tgetmainargs(&wargc, &wargv, &wenv, 0, &start_info);
|
||||||
__tgetmainargs(&argc, &argv, &env, 0, &start_info);
|
if (argc < wargc)
|
||||||
|
wargv += wargc - argc;
|
||||||
|
#define argv wargv
|
||||||
|
#endif
|
||||||
|
|
||||||
p = GetCommandLine();
|
p = GetCommandLine();
|
||||||
szCmd = NULL;
|
szCmd = NULL;
|
||||||
if (argc0 > 1)
|
if (argc > 1)
|
||||||
szCmd = _tcsstr(p, argv[argc - argc0 + 1]);
|
szCmd = _tcsstr(p, argv[1]);
|
||||||
if (NULL == szCmd)
|
if (NULL == szCmd)
|
||||||
szCmd = __T("");
|
szCmd = __T("");
|
||||||
else if (szCmd > p && szCmd[-1] == __T('\"'))
|
else if (szCmd > p && szCmd[-1] == __T('\"'))
|
||||||
|
3
win32/lib/wincrt1w.c
Normal file
3
win32/lib/wincrt1w.c
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#define _UNICODE 1
|
||||||
|
#define UNICODE 1
|
||||||
|
#include "wincrt1.c"
|
Loading…
Reference in New Issue
Block a user