mirror of
https://github.com/frida/tinycc
synced 2025-01-15 15:59:20 +03: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)
|
||||
- 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)
|
||||
|
@ -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))
|
||||
|
3
libtcc.c
3
libtcc.c
@ -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
25
tccpe.c
@ -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
|
||||
}
|
||||
|
||||
|
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 **);
|
||||
|
||||
s1->runtime_main = "main";
|
||||
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
||||
return -1;
|
||||
prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
// =============================================
|
||||
|
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);
|
||||
}
|
||||
|
||||
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('\"'))
|
||||
|
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