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)
master
grischka 2017-02-18 09:51:23 +01:00
parent 39b2afeb7c
commit 096125d963
11 changed files with 55 additions and 47 deletions

View File

@ -17,6 +17,7 @@ Platforms:
- provide a runtime library for ARM (Thomas Preud'homme)
- many x86-64 ABI fixes incl. XMM register passing and tests (James Lyon)
- ABI tests with native compiler using libtcc (James Lyon)
- UNICODE startup code supports wmain and wWinMain (YX Hao)
Features:
- VLA (variable length array) improved (James Lyon, Pip Cet)

View File

@ -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)
ARM_O = libtcc1.o armeabi.o alloca-arm.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"
OBJ = $(addprefix $(DIR)/,$(I386_O) $(WIN32_O))

View File

@ -743,9 +743,6 @@ LIBTCCAPI TCCState *tcc_new(void)
#endif
#ifdef TCC_TARGET_I386
s->seg_size = 32;
#endif
#ifdef TCC_IS_NATIVE
s->runtime_main = "main";
#endif
/* enable this if you want symbols with leading underscore on windows: */
#if 0 /* def TCC_TARGET_PE */

25
tccpe.c
View File

@ -358,6 +358,7 @@ struct pe_info {
int type;
DWORD sizeofheaders;
ADDR3264 imagebase;
const char *start_symbol;
DWORD start_addr;
DWORD imp_offs;
DWORD imp_size;
@ -638,7 +639,6 @@ static int pe_write(struct pe_info *pe)
switch (si->cls) {
case sec_text:
pe_header.opthdr.BaseOfCode = addr;
pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
break;
case sec_data:
@ -700,6 +700,7 @@ static int pe_write(struct pe_info *pe)
//pe_header.filehdr.TimeDateStamp = time(NULL);
pe_header.filehdr.NumberOfSections = pe->sec_count;
pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
pe_header.opthdr.ImageBase = pe->imagebase;
pe_header.opthdr.Subsystem = pe->subsystem;
@ -1309,6 +1310,9 @@ static int pe_check_symbols(struct pe_info *pe)
}
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);
ret = -1;
@ -1793,8 +1797,9 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
++start_symbol;
/* grab the startup code from libtcc1 */
/* only (PE_Dll == pe_type) doesn't need it,
(TCC_OUTPUT_MEMORY == s1->output_type && PE_Dll == pe_type) is illegal */
#ifdef TCC_IS_NATIVE
if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
#endif
set_elf_sym(symtab_section,
0, 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;
#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->start_symbol = start_symbol;
}
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.start_addr = (DWORD)
((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
- pe.imagebase);
if (s1->nb_errors)
ret = -1;
else
@ -1914,6 +1916,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
#ifdef TCC_IS_NATIVE
pe.thunk = data_section;
pe_build_imports(&pe);
s1->runtime_main = pe.start_symbol;
#endif
}

View File

@ -107,6 +107,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
{
int (*prog_main)(int, char **);
s1->runtime_main = "main";
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
return -1;
prog_main = tcc_get_symbol_err(s1, s1->runtime_main);

View File

@ -28,9 +28,6 @@ endif
ifeq (,$(filter i386 x86-64,$(ARCH)))
SKIP += 85_asm-outside-function.test
endif
ifeq ($(TARGETOS),Windows)
SKIP += 76_dollars_in_identifiers.test
endif
# Some tests might need arguments
ARGS =
@ -42,7 +39,8 @@ NORUN =
42_function_pointer.test : NORUN = true
# 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 = 2>&1 | sed 's,$(SRC)/,,g'
@ -57,9 +55,9 @@ all test: $(filter-out $(SKIP),$(TESTS))
@echo Test: $*...
# test -run
@if test -z "$(NORUN)"; then \
$(TCC) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \
$(TCC) $(FLAGS) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \
else \
$(TCC) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \
$(TCC) $(FLAGS) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \
./$*.exe $(ARGS) >>$*.output 2>&1 || true; \
fi
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe

View File

@ -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%
: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/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 -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/dllmain.c
.\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
.\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/crt1w.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/dllmain.c
.\tcc -m64 %D64% -c lib/chkstk.S

View File

@ -65,24 +65,23 @@ void _tstart(void)
exit(ret);
}
void _runtmain(int argc0, /* as tcc passed in */ char **argv0)
int _runtmain(int argc, /* as tcc passed in */ char **argv)
{
__TRY__
int argc, ret;
_TCHAR **argv;
_TCHAR **env;
_startupinfo start_info;
#ifdef UNICODE
int wargc;
_TCHAR **wargv, **wenv;
_startupinfo start_info = {0};
__set_app_type(_CONSOLE_APP);
__tgetmainargs(&wargc, &wargv, &wenv, _dowildcard, &start_info);
if (argc < wargc)
wargv += wargc - argc;
#define argv wargv
#endif
#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);
return _tmain(argc, argv, NULL);
}
// =============================================

View File

@ -0,0 +1,3 @@
#define _UNICODE 1
#define UNICODE 1
#include "crt1.c"

View File

@ -68,22 +68,25 @@ int _twinstart(void)
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;
int argc;
_TCHAR **argv;
_TCHAR **env;
_startupinfo start_info;
#ifdef UNICODE
int wargc;
_TCHAR **wargv, **wenv;
_startupinfo start_info = {0};
start_info.newmode = 0;
__tgetmainargs(&argc, &argv, &env, 0, &start_info);
__tgetmainargs(&wargc, &wargv, &wenv, 0, &start_info);
if (argc < wargc)
wargv += wargc - argc;
#define argv wargv
#endif
p = GetCommandLine();
szCmd = NULL;
if (argc0 > 1)
szCmd = _tcsstr(p, argv[argc - argc0 + 1]);
if (argc > 1)
szCmd = _tcsstr(p, argv[1]);
if (NULL == szCmd)
szCmd = __T("");
else if (szCmd > p && szCmd[-1] == __T('\"'))

View File

@ -0,0 +1,3 @@
#define _UNICODE 1
#define UNICODE 1
#include "wincrt1.c"