From 807dc7c8de2dcb0365c15b9c2a43ad0c195513dd Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 6 Jun 2013 09:26:31 +0800 Subject: tccpe: pstrcpy() will truncate .stabstr section name, use strncpy() instead. --- tccpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tccpe.c') diff --git a/tccpe.c b/tccpe.c index f7a200c..72c1572 100644 --- a/tccpe.c +++ b/tccpe.c @@ -663,7 +663,7 @@ static int pe_write(struct pe_info *pe) } } - pstrcpy((char*)psh->Name, sizeof psh->Name, sh_name); + strncpy((char*)psh->Name, sh_name, sizeof psh->Name); psh->Characteristics = pe_sec_flags[si->cls]; psh->VirtualAddress = addr; -- cgit v1.3.1 From 73faaea227a53e365dd75f1dba7a5071c7b5e541 Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 28 Aug 2013 22:55:05 +0200 Subject: i386-gen: preserve fp control word in gen_cvt_ftoi - Use runtime function for conversion - Also initialize fp with tcc -run on windows This fixes a bug where double x = 1.0; double y = 1.0000000000000001; double z = x < y ? 0 : sqrt (x*x - y*y); caused a bad sqrt because rounding precision for the x < y comparison was different to the one used within the sqrt function. This also fixes a bug where printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2)); would print 100, 99 Unrelated: win32: document relative include & lib lookup win32: normalize_slashes: do not mirror silly gcc behavior This reverts part of commit 8a81f9e1036637e21a47e14fb56bf64133546890 winapi: add missing WINAPI decl. for some functions --- i386-gen.c | 91 +++++++++++++----------------------------- lib/libtcc1.c | 23 ++++++++--- libtcc.c | 15 ++----- tcc.h | 1 + tccpe.c | 22 +++------- tccrun.c | 2 +- tcctok.h | 4 +- win32/include/winapi/winbase.h | 12 +++--- win32/lib/crt1.c | 6 +++ win32/lib/wincrt1.c | 2 +- win32/tcc-win32.txt | 6 +++ 11 files changed, 77 insertions(+), 107 deletions(-) (limited to 'tccpe.c') diff --git a/i386-gen.c b/i386-gen.c index 844a482..0a6d4d3 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -338,6 +338,15 @@ static void gadd_sp(int val) } } +static void gen_static_call(int v) +{ + Sym *sym; + + sym = external_global_sym(v, &func_old_type, 0); + oad(0xe8, -4); + greloc(cur_text_section, sym, ind-4, R_386_PC32); +} + /* 'is_jmp' is '1' if it is a jump */ static void gcall_or_jmp(int is_jmp) { @@ -570,6 +579,12 @@ ST_FUNC void gfunc_prolog(CType *func_type) func_bound_offset = lbounds_section->data_offset; } #endif + +#ifndef TCC_TARGET_PE + if (0 == strcmp(funcname, "main")) + gen_static_call(TOK___tcc_fpinit); +#endif + } /* generate function epilog */ @@ -582,7 +597,7 @@ ST_FUNC void gfunc_epilog(void) && func_bound_offset != lbounds_section->data_offset) { int saved_ind; int *bounds_ptr; - Sym *sym, *sym_data; + Sym *sym_data; /* add end of table info */ bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); *bounds_ptr = 0; @@ -594,20 +609,16 @@ ST_FUNC void gfunc_epilog(void) greloc(cur_text_section, sym_data, ind + 1, R_386_32); oad(0xb8, 0); /* mov %eax, xxx */ - sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_local_new); + ind = saved_ind; /* generate bound check local freeing */ o(0x5250); /* save returned value, if any */ greloc(cur_text_section, sym_data, ind + 1, R_386_32); oad(0xb8, 0); /* mov %eax, xxx */ - sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_local_delete); + o(0x585a); /* restore returned value, if any */ } #endif @@ -626,10 +637,8 @@ ST_FUNC void gfunc_epilog(void) ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; #ifdef TCC_TARGET_PE if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_386_PC32); + gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */ } else #endif { @@ -992,52 +1001,13 @@ ST_FUNC void gen_cvt_itof(int t) /* XXX: handle long long case */ ST_FUNC void gen_cvt_ftoi(int t) { - int r, r2, size; - Sym *sym; - CType ushort_type; - - ushort_type.t = VT_SHORT | VT_UNSIGNED; - ushort_type.ref = 0; - gv(RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; - - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_int_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 4) - o(0x1cdb); /* fistpl */ - else - o(0x3cdf); /* fistpll */ - o(0x24); - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - r = get_reg(RC_INT); - o(0x58 + r); /* pop r */ - if (size == 8) { - if (t == VT_LLONG) { - vtop->r = r; /* mark reg as used */ - r2 = get_reg(RC_INT); - o(0x58 + r2); /* pop r2 */ - vtop->r2 = r2; - } else { - o(0x04c483); /* add $4, %esp */ - } - } - vtop->r = r; + save_reg(TREG_EAX); + save_reg(TREG_EDX); + gen_static_call(TOK___tcc_cvt_ftol); + vtop->r = TREG_EAX; /* mark reg as used */ + if (t == VT_LLONG) + vtop->r2 = TREG_EDX; } /* convert from one floating point type to another */ @@ -1060,18 +1030,13 @@ ST_FUNC void ggoto(void) /* generate a bounded pointer addition */ ST_FUNC void gen_bounded_ptr_add(void) { - Sym *sym; - /* prepare fast i386 function call (args in eax and edx) */ gv2(RC_EAX, RC_EDX); /* save all temporary registers */ vtop -= 2; save_regs(0); /* do a fast function call */ - sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_ptr_add); /* returned pointer is in eax */ vtop++; vtop->r = TREG_EAX | VT_BOUNDED; diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 53dbec4..a94a82d 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -478,13 +478,24 @@ long long __ashldi3(long long a, int b) #endif } -#if defined(__i386__) -/* FPU control word for rounding to nearest mode */ -unsigned short __tcc_fpu_control = 0x137f; -/* FPU control word for round to zero mode for int conversion */ -unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00; +#ifndef _WIN32 +void __tcc_fpinit(void) +{ + unsigned c = 0x137F; + __asm__ __volatile__ ("fldcw %0" : "=m" (c)); +} #endif - +long long __tcc_cvt_ftol(long double x) +{ + unsigned c0, c1; + long long ret; + __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); + c1 = c0 | 0x0C00; + __asm__ __volatile__ ("fldcw %0" : "=m" (c1)); + __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); + __asm__ __volatile__ ("fldcw %0" : "=m" (c0)); + return ret; +} #endif /* !__x86_64__ */ /* XXX: fix tcc's code generator to do this instead */ diff --git a/libtcc.c b/libtcc.c index b10a2a7..3b018ae 100644 --- a/libtcc.c +++ b/libtcc.c @@ -78,21 +78,13 @@ ST_FUNC void asm_global_instr(void) #endif /********************************************************/ - #ifdef _WIN32 -// GCC appears to use '/' for relative paths and '\\' for absolute paths on Windows static char *normalize_slashes(char *path) { char *p; - if (path[1] == ':') { - for (p = path+2; *p; ++p) - if (*p == '/') - *p = '\\'; - } else { - for (p = path; *p; ++p) - if (*p == '\\') - *p = '/'; - } + for (p = path; *p; ++p) + if (*p == '\\') + *p = '/'; return path; } @@ -1036,6 +1028,7 @@ LIBTCCAPI TCCState *tcc_new(void) #ifdef TCC_TARGET_I386 s->seg_size = 32; #endif + s->runtime_main = "main"; return s; } diff --git a/tcc.h b/tcc.h index 859d4fd..c988e4f 100644 --- a/tcc.h +++ b/tcc.h @@ -665,6 +665,7 @@ struct TCCState { #endif #ifdef TCC_IS_NATIVE + const char *runtime_main; /* for tcc_relocate */ void *runtime_mem; # ifdef HAVE_SELINUX diff --git a/tccpe.c b/tccpe.c index 72c1572..05fed09 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1726,7 +1726,6 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) static void pe_add_runtime(TCCState *s1, struct pe_info *pe) { const char *start_symbol; - ADDR3264 addr = 0; int pe_type = 0; if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) @@ -1742,16 +1741,13 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) start_symbol = TCC_OUTPUT_MEMORY == s1->output_type - ? PE_GUI == pe_type ? "__runwinmain" : "_main" + ? PE_GUI == pe_type ? "__runwinmain" : "__runmain" : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") : PE_GUI == pe_type ? "__winstart" : "__start" ; - if (!s1->leading_underscore || strchr(start_symbol, '@')) { + if (!s1->leading_underscore || strchr(start_symbol, '@')) ++start_symbol; - if (start_symbol[0] != '_') - start_symbol = NULL; - } /* grab the startup code from libtcc1 */ if (start_symbol) @@ -1776,21 +1772,13 @@ 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; - - if (start_symbol) { - addr = get_elf_sym_addr(s1, start_symbol, 1); - if (PE_RUN == pe_type && addr) - /* for -run GUI's, put '_runwinmain' instead of 'main' */ - add_elf_sym(symtab_section, - addr, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "main"); + s1->runtime_main = start_symbol; } pe->type = pe_type; - pe->start_addr = addr; + pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); } ST_FUNC int pe_output_file(TCCState * s1, const char *filename) diff --git a/tccrun.c b/tccrun.c index d858ae6..b07ab0f 100644 --- a/tccrun.c +++ b/tccrun.c @@ -97,7 +97,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; - prog_main = tcc_get_symbol_err(s1, "main"); + prog_main = tcc_get_symbol_err(s1, s1->runtime_main); #ifdef CONFIG_TCC_BACKTRACE if (s1->do_debug) { diff --git a/tcctok.h b/tcctok.h index fde13dd..9b47a60 100644 --- a/tcctok.h +++ b/tcctok.h @@ -194,8 +194,8 @@ DEF(TOK__remu, "_remu") #endif #ifdef TCC_TARGET_I386 - DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") - DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") + DEF(TOK___tcc_fpinit, "__tcc_fpinit") + DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") #endif #ifdef TCC_ARM_EABI DEF(TOK___ashrdi3, "__aeabi_lasr") diff --git a/win32/include/winapi/winbase.h b/win32/include/winapi/winbase.h index a5d9b17..4a38006 100644 --- a/win32/include/winapi/winbase.h +++ b/win32/include/winapi/winbase.h @@ -968,15 +968,15 @@ extern "C" { LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand); #else - LONG InterlockedIncrement(LONG volatile *lpAddend); - LONG InterlockedDecrement(LONG volatile *lpAddend); - LONG InterlockedExchange(LONG volatile *Target,LONG Value); + LONG WINAPI InterlockedIncrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedDecrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedExchange(LONG volatile *Target,LONG Value); #define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value)) - LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); - LONG InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); - LONGLONG InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); + LONG WINAPI InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + LONG WINAPI InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); + LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) { LONGLONG Old; diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index 3e1d17f..cde3910 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -31,4 +31,10 @@ int _start(void) exit(ret); } +int _runmain(int argc, char **argv) +{ + _controlfp(0x10000, 0x30000); + return main(argc, argv, NULL); +} + // ============================================= diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c index 77e74b8..663fd33 100644 --- a/win32/lib/wincrt1.c +++ b/win32/lib/wincrt1.c @@ -59,6 +59,6 @@ int _runwinmain(int argc, char **argv) szCmd = ""; else if (szCmd > p && szCmd[-1] == '\"') --szCmd; + _controlfp(0x10000, 0x30000); return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT); } - diff --git a/win32/tcc-win32.txt b/win32/tcc-win32.txt index dc06b8f..1cb35c5 100644 --- a/win32/tcc-win32.txt +++ b/win32/tcc-win32.txt @@ -18,6 +18,12 @@ system PATH. + Include and library search paths + -------------------------------- + On windows, the standard "include" and "lib" directories are searched + relatively from the location of the executables (tcc.exe, libtcc.dll). + + Examples: --------- Open a console window (DOS box) and 'cd' to the examples directory. -- cgit v1.3.1 From 13b997668e32a4b451783fd80525cf221149c5b3 Mon Sep 17 00:00:00 2001 From: grischka Date: Tue, 10 Sep 2013 15:36:56 +0200 Subject: win32: fix libtcc support For "tcc -run file.c", I was trying to initialize the FP control in a function in libtcc1.a (_runmain) before calling main. Unfortunately that turned out to cause problems with for example libtcc_test since such usage doesn't necessarily define a 'main' function. So for tcc -run we're back to relying on the FP control word that is set in the startup code of tcc.exe rsp. libtcc.dll. This fixes part of commit 73faaea227a53e365dd75f1dba7a5071c7b5e541 --- tccpe.c | 7 ++++--- win32/lib/crt1.c | 6 ------ 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'tccpe.c') diff --git a/tccpe.c b/tccpe.c index 05fed09..19b20ab 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1741,7 +1741,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) start_symbol = TCC_OUTPUT_MEMORY == s1->output_type - ? PE_GUI == pe_type ? "__runwinmain" : "__runmain" + ? PE_GUI == pe_type ? "__runwinmain" : "_main" : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") : PE_GUI == pe_type ? "__winstart" : "__start" ; @@ -1750,7 +1750,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) ++start_symbol; /* grab the startup code from libtcc1 */ - if (start_symbol) + if (TCC_OUTPUT_MEMORY != s1->output_type || PE_GUI == pe_type) add_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, @@ -1775,10 +1775,11 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) if (TCC_OUTPUT_MEMORY == s1->output_type) { pe_type = PE_RUN; s1->runtime_main = start_symbol; + } else { + pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); } pe->type = pe_type; - pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); } ST_FUNC int pe_output_file(TCCState * s1, const char *filename) diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index cde3910..3e1d17f 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -31,10 +31,4 @@ int _start(void) exit(ret); } -int _runmain(int argc, char **argv) -{ - _controlfp(0x10000, 0x30000); - return main(argc, argv, NULL); -} - // ============================================= -- cgit v1.3.1 From 642b6d0f50c6b6a842c9239a102fe34d5619e931 Mon Sep 17 00:00:00 2001 From: YX Hao Date: Thu, 19 Sep 2013 21:50:38 +0800 Subject: Add the possibility to use noname functions by ordinal tcc.c: process.h:177:20: note: expected 'char * const*' but argument is of type 'char const*const*' tccpe.c: Add the possibility to use noname functions by ordinal. use def file: "AliasName @n" build-tcc.bat: 1. Enable 32 bits mode on 64 bits OS. 2. build doc. _parseLibs.bat: Convenient to use "*.def + *.c" instead of *.a, just use -l* _tcc.bat: a practice of _parseLibs.bat Signed-off-by: YX Hao --- tcc.c | 2 +- tccpe.c | 38 +++++++++++++++++++++---- win32/_parseLibs.bat | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ win32/_tcc.bat | 30 ++++++++++++++++++++ win32/build-tcc.bat | 9 +++++- 5 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 win32/_parseLibs.bat create mode 100644 win32/_tcc.bat (limited to 'tccpe.c') diff --git a/tcc.c b/tcc.c index b223d39..58f9007 100644 --- a/tcc.c +++ b/tcc.c @@ -79,7 +79,7 @@ static void help(void) #include static int execvp_win32(const char *prog, char **argv) { - int ret = spawnvp(P_NOWAIT, prog, (char const*const*)argv); + int ret = spawnvp(P_NOWAIT, prog, (char *const*)argv); if (-1 == ret) return ret; cwait(&ret, ret, WAIT_CHILD); diff --git a/tccpe.c b/tccpe.c index 19b20ab..bc1545e 100644 --- a/tccpe.c +++ b/tccpe.c @@ -813,6 +813,7 @@ static void pe_build_imports(struct pe_info *pe) hdr->Name = v + rva_base; for (k = 0, n = p->sym_count; k <= n; ++k) { + int ordinal = 0; if (k < n) { int iat_index = p->symbols[k]->iat_index; int sym_index = p->symbols[k]->sym_index; @@ -823,25 +824,31 @@ static void pe_build_imports(struct pe_info *pe) org_sym->st_value = thk_ptr; org_sym->st_shndx = pe->thunk->sh_num; v = pe->thunk->data_offset + rva_base; - section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ - put_elf_str(pe->thunk, name); + + /* ordinal or name */ + ordinal = imp_sym->st_value; /* from pe_load_def, temperary use */ + //if (ordinal) printf("ordinal: %d\n", ordinal); + if (!ordinal) { + section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ + put_elf_str(pe->thunk, name); + } #ifdef TCC_IS_NATIVE if (pe->type == PE_RUN) { v = imp_sym->st_value; if (dllref) { if ( !dllref->handle ) dllref->handle = LoadLibrary(dllref->name); - v = (ADDR3264)GetProcAddress(dllref->handle, name); + v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(LPCSTR)NULL+ordinal:name); } if (!v) - tcc_error_noabort("undefined symbol '%s'", name); + tcc_error_noabort("can't build symbol '%s'", name); } #endif } else { v = 0; /* last entry is zero */ } *(ADDR3264*)(pe->thunk->data+thk_ptr) = - *(ADDR3264*)(pe->thunk->data+ent_ptr) = v; + *(ADDR3264*)(pe->thunk->data+ent_ptr) = (ordinal && pe->type != PE_RUN)?(ADDR3264)1<<(sizeof(ADDR3264)*8-1)|ordinal:v; thk_ptr += sizeof (ADDR3264); ent_ptr += sizeof (ADDR3264); } @@ -1590,6 +1597,8 @@ static int pe_load_def(TCCState *s1, int fd) char line[400], dllname[80], *p; for (;;) { + int ord = 0; + char *x, *d, idxstr[8]; p = get_line(line, sizeof line, fd); if (NULL == p) break; @@ -1614,7 +1623,24 @@ static int pe_load_def(TCCState *s1, int fd) ++state; default: - pe_putimport(s1, dllindex, p, 0); + /* get ordianl and will store in sym->st_value */ + d = NULL; + x = strchr(line, ' '); + if (x) x = strchr(line, '@'); + while (x != NULL) { + d =x; + x = strchr(x+1, '@'); + } + if (d) { + ord = atoi(d+1); + itoa(ord, idxstr, 10); + if (strcmp(idxstr, d+1) == 0) { + memset(d, 0, 1); + trimback(p, d); + } else + ord = 0; + } + pe_putimport(s1, dllindex, p, ord); continue; } } diff --git a/win32/_parseLibs.bat b/win32/_parseLibs.bat new file mode 100644 index 0000000..19e8e64 --- /dev/null +++ b/win32/_parseLibs.bat @@ -0,0 +1,79 @@ +@echo off +setlocal enabledelayedexpansion + +pushd %~dp0 + +::Define as main parameters +set _Args_= +set _LIBs_= +set LIBi= + +set ARGSO=-IExt\include -LExt\lib %* + +::This is for the .def file also have a similar name .c file +::.a file will be larger than .def + .c +::*-uuid.c files are suitable to form libuuid.a +::w32api-3.17.2 +:GetRLib +for %%i in (%ARGSO%) do ( + set ARG=%%i + set OPT=!ARG:~0,2! + if "!OPT!"=="-l" ( + set LIB=!ARG:~2! + set LIBi= + if "!LIB!"=="uuid" ( + set LIBi= lib\*uid.c + ) else ( + if "!LIB!"=="vfw32" ( + set LIBi= lib\msvfw32.def lib\avifil32.def lib\avicap32.def + ) else ( + call :GetLibS + ) + ) + if "!LIBi!"=="" ( + set _Args_=!_Args_! %%i + ) else ( + set LIBi=!LIBi:%~dp0=! + set _LIBs_=!_LIBs_! !LIBi! + echo For lib !LIB! will use: + echo !LIBi! + echo. + ) + ) else ( + set _Args_=!_Args_! %%i + ) +) + +::GetRLib End +popd + +tcc.exe !_Args_! !_LIBs_! + +exit /b + +:::::::::: + +:GetLibS +for %%D in (-Llib %ARGSO%) do ( + set ARG_=%%D + set OPT_=!ARG_:~0,2! + set LIBD= + if "!OPT_!"=="-L" ( + set LIBD=!ARG_:~2! + if exist "!LIBD!" call :GetDLib + ) +) +set LIBD= +set OPT_= +set ARG_= +exit /b +::GetLibD End + +:GetDLib +pushd !LIBD! +for /f "usebackq delims=" %%I in (`"dir /b /s !LIB!.c !LIB!_*.c !LIB!.def !LIB!_*.def 2>nul"`) do ( + set LIBi=!LIBi! "%%I" +) +popd +exit /b +::GetDLib End diff --git a/win32/_tcc.bat b/win32/_tcc.bat new file mode 100644 index 0000000..65a7697 --- /dev/null +++ b/win32/_tcc.bat @@ -0,0 +1,30 @@ +@echo off +setlocal enabledelayedexpansion + +pushd %~dp0 + +path %~dp0;%path% + +set EXT=.exe +echo %*|findstr /R /C:"\<-c\>" >nul &&set EXT=.o +echo %*|findstr /R /C:"\<-shared\>" >nul &&set EXT=.dll + +::1st file found must be the main c file to get output file name +set OUTF= +call :FINDFN %* + +if "%OUTF%"=="" goto :EXIT + +call _parseLibs -vv -o "%OUTF%" %* + +:EXIT +popd +pause +exit /b + +:FINDFN +for %%i in (%*) do ( + if exist %%i set OUTF=%%~dpni%EXT%&goto :ENDFDF +) +:ENDFDF +exit /b diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat index 5bc5585..772ed26 100644 --- a/win32/build-tcc.bat +++ b/win32/build-tcc.bat @@ -5,7 +5,7 @@ @set /p VERSION= < ..\VERSION echo>..\config.h #define TCC_VERSION "%VERSION%" -@if _%PROCESSOR_ARCHITEW6432%_==_AMD64_ goto x86_64 +@rem @if _%PROCESSOR_ARCHITEW6432%_==_AMD64_ goto x86_64 @if _%PROCESSOR_ARCHITECTURE%_==_AMD64_ goto x86_64 @set target=-DTCC_TARGET_PE -DTCC_TARGET_I386 @@ -58,3 +58,10 @@ tiny_libmaker lib/libtcc1.a libtcc1.o alloca86_64.o crt1.o wincrt1.o dllcrt1.o d :the_end del *.o + +:makedoc +echo>..\config.texi @set VERSION %VERSION% +if not exist doc md doc +makeinfo --html --no-split -o doc\tcc-doc.html ../tcc-doc.texi +if exist tcc-win32.txt move tcc-win32.txt doc\ +copy ..\tests\libtcc_test.c examples\ -- cgit v1.3.1 From 4ad186c5ef61477030ca37372f9d6c6d03681015 Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 6 Jan 2014 19:07:08 +0100 Subject: i386: use __fixdfdi instead of __tcc_cvt_ftol Variants __fixsfdi/__fixxfdi are not needed for now because the value is converted to double always. Also: - remove __tcc_fpinit for unix as it seems redundant by the __setfpucw call in the startup code - avoid reference to s->runtime_main in cross compilers - configure: fix --with-libgcc help - tcctok.h: cleanup --- configure | 2 +- i386-gen.c | 28 ++++++++----------- lib/libtcc1.c | 39 ++++++++++++++------------ tccelf.c | 4 +-- tccpe.c | 2 ++ tcctok.h | 89 ++++++++++++++++++++++++++++++----------------------------- 6 files changed, 84 insertions(+), 80 deletions(-) mode change 100755 => 100644 configure (limited to 'tccpe.c') diff --git a/configure b/configure old mode 100755 new mode 100644 index cc8ca5a..8c44e5c --- a/configure +++ b/configure @@ -273,7 +273,7 @@ Advanced options (experts only): --strip-binaries strip symbol tables from resulting binaries --disable-static make libtcc.so instead of libtcc.a --disable-rpath disable use of -rpath with the above - --with-libgcc use libgcc_s.so.1 instead of libtcc.a in dynamic link + --with-libgcc use libgcc_s.so.1 instead of libtcc1.a in dynamic link --enable-mingw32 build windows version on linux with mingw32 --enable-cygwin build windows version on windows with cygwin --enable-cross build cross compilers diff --git a/i386-gen.c b/i386-gen.c index 2eb6922..4c4a54b 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -581,14 +581,6 @@ ST_FUNC void gfunc_prolog(CType *func_type) func_bound_offset = lbounds_section->data_offset; } #endif - -#ifndef CONFIG_USE_LIBGCC -#ifndef TCC_TARGET_PE - if (0 == strcmp(funcname, "main")) - gen_static_call(TOK___tcc_fpinit); -#endif -#endif - } /* generate function epilog */ @@ -988,16 +980,20 @@ ST_FUNC void gen_cvt_itof(int t) } /* convert fp to int 't' type */ -/* XXX: handle long long case */ ST_FUNC void gen_cvt_ftoi(int t) { - gv(RC_FLOAT); - save_reg(TREG_EAX); - save_reg(TREG_EDX); - gen_static_call(TOK___tcc_cvt_ftol); - vtop->r = TREG_EAX; /* mark reg as used */ - if (t == VT_LLONG) - vtop->r2 = TREG_EDX; + int bt = vtop->type.t & VT_BTYPE; + if (bt == VT_FLOAT) + vpush_global_sym(&func_old_type, TOK___fixsfdi); + else if (bt == VT_LDOUBLE) + vpush_global_sym(&func_old_type, TOK___fixxfdi); + else + vpush_global_sym(&func_old_type, TOK___fixdfdi); + vswap(); + gfunc_call(1); + vpushi(0); + vtop->r = REG_IRET; + vtop->r2 = REG_LRET; } /* convert from one floating point type to another */ diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 3103691..44208cd 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -478,24 +478,6 @@ long long __ashldi3(long long a, int b) #endif } -#ifndef _WIN32 -void __tcc_fpinit(void) -{ - unsigned c = 0x137F; - __asm__ __volatile__ ("fldcw %0" : : "m" (c)); -} -#endif -long long __tcc_cvt_ftol(long double x) -{ - unsigned c0, c1; - long long ret; - __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); - c1 = c0 | 0x0C00; - __asm__ __volatile__ ("fldcw %0" : : "m" (c1)); - __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); - __asm__ __volatile__ ("fldcw %0" : : "m" (c0)); - return ret; -} #endif /* !__x86_64__ */ /* XXX: fix tcc's code generator to do this instead */ @@ -616,6 +598,27 @@ unsigned long long __fixunsxfdi (long double a1) return 0; } +long long __fixsfdi (float a1) +{ + long long ret; int s; + ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +long long __fixdfdi (double a1) +{ + long long ret; int s; + ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +long long __fixxfdi (long double a1) +{ + long long ret; int s; + ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + #if defined(__x86_64__) && !defined(_WIN64) #ifndef __TINYC__ diff --git a/tccelf.c b/tccelf.c index caa8281..aa3daac 100644 --- a/tccelf.c +++ b/tccelf.c @@ -178,11 +178,11 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); } -#ifdef TCC_IS_NATIVE +#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE /* return elf symbol value or error */ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) { - return (void*)get_elf_sym_addr(s, name, 1); + return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); } #endif diff --git a/tccpe.c b/tccpe.c index bc1545e..62df865 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1800,7 +1800,9 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) 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)tcc_get_symbol_err(s1, start_symbol); } diff --git a/tcctok.h b/tcctok.h index 9b47a60..73b0cf9 100644 --- a/tcctok.h +++ b/tcctok.h @@ -143,23 +143,34 @@ #endif /* builtin functions or variables */ -#ifdef TCC_ARM_EABI - DEF(TOK_memcpy, "__aeabi_memcpy") - DEF(TOK_memcpy4, "__aeabi_memcpy4") - DEF(TOK_memcpy8, "__aeabi_memcpy8") - DEF(TOK_memset, "__aeabi_memset") - DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") - DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") -#else +#ifndef TCC_ARM_EABI DEF(TOK_memcpy, "memcpy") DEF(TOK_memset, "memset") DEF(TOK___divdi3, "__divdi3") DEF(TOK___moddi3, "__moddi3") DEF(TOK___udivdi3, "__udivdi3") DEF(TOK___umoddi3, "__umoddi3") + DEF(TOK___ashrdi3, "__ashrdi3") + DEF(TOK___lshrdi3, "__lshrdi3") + DEF(TOK___ashldi3, "__ashldi3") + DEF(TOK___floatundisf, "__floatundisf") + DEF(TOK___floatundidf, "__floatundidf") +# ifndef TCC_ARM_VFP + DEF(TOK___floatundixf, "__floatundixf") + DEF(TOK___fixunsxfdi, "__fixunsxfdi") +# endif + DEF(TOK___fixunssfdi, "__fixunssfdi") + DEF(TOK___fixunsdfdi, "__fixunsdfdi") #endif -#if defined(TCC_TARGET_ARM) -#ifdef TCC_ARM_EABI + +#if defined TCC_TARGET_ARM +# ifdef TCC_ARM_EABI + DEF(TOK_memcpy, "__aeabi_memcpy") + DEF(TOK_memcpy4, "__aeabi_memcpy4") + DEF(TOK_memcpy8, "__aeabi_memcpy8") + DEF(TOK_memset, "__aeabi_memset") + DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") + DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") DEF(TOK___aeabi_idivmod, "__aeabi_idivmod") DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod") DEF(TOK___divsi3, "__aeabi_idiv") @@ -168,24 +179,33 @@ DEF(TOK___floatdidf, "__aeabi_l2d") DEF(TOK___fixsfdi, "__aeabi_f2lz") DEF(TOK___fixdfdi, "__aeabi_d2lz") -#else + DEF(TOK___ashrdi3, "__aeabi_lasr") + DEF(TOK___lshrdi3, "__aeabi_llsr") + DEF(TOK___ashldi3, "__aeabi_llsl") + DEF(TOK___floatundisf, "__aeabi_ul2f") + DEF(TOK___floatundidf, "__aeabi_ul2d") + DEF(TOK___fixunssfdi, "__aeabi_f2ulz") + DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") +# else DEF(TOK___modsi3, "__modsi3") DEF(TOK___umodsi3, "__umodsi3") DEF(TOK___divsi3, "__divsi3") DEF(TOK___udivsi3, "__udivsi3") DEF(TOK___floatdisf, "__floatdisf") DEF(TOK___floatdidf, "__floatdidf") -#ifndef TCC_ARM_VFP +# ifndef TCC_ARM_VFP DEF(TOK___floatdixf, "__floatdixf") DEF(TOK___fixunssfsi, "__fixunssfsi") DEF(TOK___fixunsdfsi, "__fixunsdfsi") DEF(TOK___fixunsxfsi, "__fixunsxfsi") DEF(TOK___fixxfdi, "__fixxfdi") -#endif +# endif DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixdfdi, "__fixdfdi") +# endif #endif -#elif defined(TCC_TARGET_C67) + +#if defined TCC_TARGET_C67 DEF(TOK__divi, "_divi") DEF(TOK__divu, "_divu") DEF(TOK__divf, "_divf") @@ -193,32 +213,18 @@ DEF(TOK__remi, "_remi") DEF(TOK__remu, "_remu") #endif -#ifdef TCC_TARGET_I386 - DEF(TOK___tcc_fpinit, "__tcc_fpinit") - DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") -#endif -#ifdef TCC_ARM_EABI - DEF(TOK___ashrdi3, "__aeabi_lasr") - DEF(TOK___lshrdi3, "__aeabi_llsr") - DEF(TOK___ashldi3, "__aeabi_llsl") - DEF(TOK___floatundisf, "__aeabi_ul2f") - DEF(TOK___floatundidf, "__aeabi_ul2d") - DEF(TOK___fixunssfdi, "__aeabi_f2ulz") - DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") -#else - DEF(TOK___ashrdi3, "__ashrdi3") - DEF(TOK___lshrdi3, "__lshrdi3") - DEF(TOK___ashldi3, "__ashldi3") - DEF(TOK___floatundisf, "__floatundisf") - DEF(TOK___floatundidf, "__floatundidf") -#ifndef TCC_ARM_VFP - DEF(TOK___floatundixf, "__floatundixf") - DEF(TOK___fixunsxfdi, "__fixunsxfdi") + +#if defined TCC_TARGET_I386 + DEF(TOK___fixsfdi, "__fixsfdi") + DEF(TOK___fixdfdi, "__fixdfdi") + DEF(TOK___fixxfdi, "__fixxfdi") #endif - DEF(TOK___fixunssfdi, "__fixunssfdi") - DEF(TOK___fixunsdfdi, "__fixunsdfdi") + +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 + DEF(TOK_alloca, "alloca") #endif -#ifdef TCC_TARGET_PE + +#if defined TCC_TARGET_PE DEF(TOK___chkstk, "__chkstk") #endif @@ -233,20 +239,17 @@ DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") DEF(TOK___bound_local_new, "__bound_local_new") DEF(TOK___bound_local_delete, "__bound_local_delete") -#ifdef TCC_TARGET_PE +# ifdef TCC_TARGET_PE DEF(TOK_malloc, "malloc") DEF(TOK_free, "free") DEF(TOK_realloc, "realloc") DEF(TOK_memalign, "memalign") DEF(TOK_calloc, "calloc") -#endif +# endif DEF(TOK_memmove, "memmove") DEF(TOK_strlen, "strlen") DEF(TOK_strcpy, "strcpy") #endif -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - DEF(TOK_alloca, "alloca") -#endif /* Tiny Assembler */ DEF_ASM(byte) -- cgit v1.3.1 From d443644de360f68a84c05ab23f20f013b6e05b58 Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 6 Jan 2014 19:04:50 +0100 Subject: tccpe: cleanup "imports per ordinal" - tccpe.c: avoid conflict with imp_sym->st_value, cleanup - _parseLibs.bat, _tcc.bat: no instructions for usage, removed. from commit 642b6d0f50c6b6a842c9239a102fe34d5619e931 --- tccpe.c | 67 ++++++++++++++++++++++---------------------- win32/_parseLibs.bat | 79 ---------------------------------------------------- win32/_tcc.bat | 30 -------------------- 3 files changed, 33 insertions(+), 143 deletions(-) delete mode 100644 win32/_parseLibs.bat delete mode 100644 win32/_tcc.bat (limited to 'tccpe.c') diff --git a/tccpe.c b/tccpe.c index 62df865..ed7cb82 100644 --- a/tccpe.c +++ b/tccpe.c @@ -813,28 +813,24 @@ static void pe_build_imports(struct pe_info *pe) hdr->Name = v + rva_base; for (k = 0, n = p->sym_count; k <= n; ++k) { - int ordinal = 0; if (k < n) { int iat_index = p->symbols[k]->iat_index; int sym_index = p->symbols[k]->sym_index; ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index; ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index; const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name; + int ordinal; org_sym->st_value = thk_ptr; org_sym->st_shndx = pe->thunk->sh_num; - v = pe->thunk->data_offset + rva_base; - - /* ordinal or name */ - ordinal = imp_sym->st_value; /* from pe_load_def, temperary use */ - //if (ordinal) printf("ordinal: %d\n", ordinal); - if (!ordinal) { - section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ - put_elf_str(pe->thunk, name); - } + + if (dllref) + v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */ + else + ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */ + #ifdef TCC_IS_NATIVE if (pe->type == PE_RUN) { - v = imp_sym->st_value; if (dllref) { if ( !dllref->handle ) dllref->handle = LoadLibrary(dllref->name); @@ -842,13 +838,22 @@ static void pe_build_imports(struct pe_info *pe) } if (!v) tcc_error_noabort("can't build symbol '%s'", name); - } + } else #endif + if (ordinal) { + v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1); + } else { + v = pe->thunk->data_offset + rva_base; + section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ + put_elf_str(pe->thunk, name); + } + } else { v = 0; /* last entry is zero */ } + *(ADDR3264*)(pe->thunk->data+thk_ptr) = - *(ADDR3264*)(pe->thunk->data+ent_ptr) = (ordinal && pe->type != PE_RUN)?(ADDR3264)1<<(sizeof(ADDR3264)*8-1)|ordinal:v; + *(ADDR3264*)(pe->thunk->data+ent_ptr) = v; thk_ptr += sizeof (ADDR3264); ent_ptr += sizeof (ADDR3264); } @@ -1593,12 +1598,11 @@ static char *get_line(char *line, int size, int fd) /* ------------------------------------------------------------- */ static int pe_load_def(TCCState *s1, int fd) { - int state = 0, ret = -1, dllindex = 0; - char line[400], dllname[80], *p; + int state = 0, ret = -1, dllindex = 0, ord; + char line[400], dllname[80], *p, *x; for (;;) { - int ord = 0; - char *x, *d, idxstr[8]; + p = get_line(line, sizeof line, fd); if (NULL == p) break; @@ -1621,24 +1625,19 @@ static int pe_load_def(TCCState *s1, int fd) case 2: dllindex = add_dllref(s1, dllname); ++state; - + /* fall through */ default: - /* get ordianl and will store in sym->st_value */ - d = NULL; - x = strchr(line, ' '); - if (x) x = strchr(line, '@'); - while (x != NULL) { - d =x; - x = strchr(x+1, '@'); - } - if (d) { - ord = atoi(d+1); - itoa(ord, idxstr, 10); - if (strcmp(idxstr, d+1) == 0) { - memset(d, 0, 1); - trimback(p, d); - } else - ord = 0; + /* get ordinal and will store in sym->st_value */ + ord = 0; + x = strchr(p, ' '); + if (x) { + *x = 0, x = strrchr(x + 1, '@'); + if (x) { + char *d; + ord = (int)strtol(x + 1, &d, 10); + if (*d) + ord = 0; + } } pe_putimport(s1, dllindex, p, ord); continue; diff --git a/win32/_parseLibs.bat b/win32/_parseLibs.bat deleted file mode 100644 index 19e8e64..0000000 --- a/win32/_parseLibs.bat +++ /dev/null @@ -1,79 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -pushd %~dp0 - -::Define as main parameters -set _Args_= -set _LIBs_= -set LIBi= - -set ARGSO=-IExt\include -LExt\lib %* - -::This is for the .def file also have a similar name .c file -::.a file will be larger than .def + .c -::*-uuid.c files are suitable to form libuuid.a -::w32api-3.17.2 -:GetRLib -for %%i in (%ARGSO%) do ( - set ARG=%%i - set OPT=!ARG:~0,2! - if "!OPT!"=="-l" ( - set LIB=!ARG:~2! - set LIBi= - if "!LIB!"=="uuid" ( - set LIBi= lib\*uid.c - ) else ( - if "!LIB!"=="vfw32" ( - set LIBi= lib\msvfw32.def lib\avifil32.def lib\avicap32.def - ) else ( - call :GetLibS - ) - ) - if "!LIBi!"=="" ( - set _Args_=!_Args_! %%i - ) else ( - set LIBi=!LIBi:%~dp0=! - set _LIBs_=!_LIBs_! !LIBi! - echo For lib !LIB! will use: - echo !LIBi! - echo. - ) - ) else ( - set _Args_=!_Args_! %%i - ) -) - -::GetRLib End -popd - -tcc.exe !_Args_! !_LIBs_! - -exit /b - -:::::::::: - -:GetLibS -for %%D in (-Llib %ARGSO%) do ( - set ARG_=%%D - set OPT_=!ARG_:~0,2! - set LIBD= - if "!OPT_!"=="-L" ( - set LIBD=!ARG_:~2! - if exist "!LIBD!" call :GetDLib - ) -) -set LIBD= -set OPT_= -set ARG_= -exit /b -::GetLibD End - -:GetDLib -pushd !LIBD! -for /f "usebackq delims=" %%I in (`"dir /b /s !LIB!.c !LIB!_*.c !LIB!.def !LIB!_*.def 2>nul"`) do ( - set LIBi=!LIBi! "%%I" -) -popd -exit /b -::GetDLib End diff --git a/win32/_tcc.bat b/win32/_tcc.bat deleted file mode 100644 index 65a7697..0000000 --- a/win32/_tcc.bat +++ /dev/null @@ -1,30 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -pushd %~dp0 - -path %~dp0;%path% - -set EXT=.exe -echo %*|findstr /R /C:"\<-c\>" >nul &&set EXT=.o -echo %*|findstr /R /C:"\<-shared\>" >nul &&set EXT=.dll - -::1st file found must be the main c file to get output file name -set OUTF= -call :FINDFN %* - -if "%OUTF%"=="" goto :EXIT - -call _parseLibs -vv -o "%OUTF%" %* - -:EXIT -popd -pause -exit /b - -:FINDFN -for %%i in (%*) do ( - if exist %%i set OUTF=%%~dpni%EXT%&goto :ENDFDF -) -:ENDFDF -exit /b -- cgit v1.3.1 From 32a4962593d6a2006cdd725480124717e7f5377d Mon Sep 17 00:00:00 2001 From: grischka Date: Tue, 21 Jan 2014 13:25:14 +0100 Subject: tcctest: add back testXb (self compile with -b) - Thanks to Kirill "tcc -b itself" should work now (was removed in d5f4df09ff4a84dda5b03525285f03be7723376b) Also: - tests/Makefile: - fix spurious --I from 767410b8750b45d63805b45ca1a2cf34d7cb4923 - lookup boundtest.c via VPATH (for out-of-tree build) - test[123]b?: fail on diff error - Windows: test3 now works (from e31579b0769e1f9c0947d12e83316d1149307b1a) - abitest: a libtcc.a made by gcc is not usable for tcc on WIndows - using source instead (libtcc.c) - tccpe: - avoid gcc warning (x86_64) --- Makefile | 4 ++-- tccpe.c | 2 +- tests/Makefile | 40 ++++++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 21 deletions(-) (limited to 'tccpe.c') diff --git a/Makefile b/Makefile index 78e67f7..39f10ba 100644 --- a/Makefile +++ b/Makefile @@ -346,8 +346,8 @@ tcc-doc.info: tcc-doc.texi # in tests subdir export LIBTCC1 -%est: - $(MAKE) -C tests $@ "PROGS_CROSS=$(PROGS_CROSS)" +test test% %test : + $(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)' clean: rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF) diff --git a/tccpe.c b/tccpe.c index ed7cb82..f4a58f7 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1803,7 +1803,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) s1->runtime_main = start_symbol; #endif } else { - pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); + pe->start_addr = (DWORD)(uintptr_t)tcc_get_symbol_err(s1, start_symbol); } pe->type = pe_type; diff --git a/tests/Makefile b/tests/Makefile index 62e4f88..4d99a46 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,7 +5,7 @@ TOP = .. include $(TOP)/Makefile SRCDIR = $(top_srcdir)/tests -VPATH = $(SRCDIR) +VPATH = $(SRCDIR) $(top_srcdir) # what tests to run TESTS = \ @@ -13,27 +13,30 @@ TESTS = \ hello-run \ libtest \ test3 \ + $(BTESTS) \ abitest \ vla_test-run \ moretests + +BTESTS = test1b test3b btest + ifdef CONFIG_CROSS -TESTS += hello-cross + TESTS += hello-cross endif # test4 -- problem with -static # asmtest -- minor differences with gcc # btest -- works on i386 (including win32) -# test3 -- win32 does not know how to printf long doubles # bounds-checking is supported only on i386 ifneq ($(ARCH),i386) - TESTS := $(filter-out btest,$(TESTS)) + TESTS := $(filter-out $(BTESTS),$(TESTS)) endif ifdef CONFIG_WIN32 - TESTS := w32-prep $(filter-out test3,$(TESTS)) + TESTS := w32-prep $(filter-out $(BTESTS),$(TESTS)) endif ifeq ($(TARGETOS),Darwin) - TESTS := $(filter-out hello-exe test3 btest,$(TESTS)) + TESTS := $(filter-out hello-exe test3 $(BTESTS),$(TESTS)) endif ifeq ($(ARCH),i386) else ifneq ($(ARCH),x86-64) @@ -53,7 +56,7 @@ endif # run local version of tcc with local libraries and includes TCCFLAGS = -B$(TOP) -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include ifdef CONFIG_WIN32 - TCCFLAGS = -B$(top_srcdir)/win32 --I$(top_srcdir) -I$(top_srcdir)/include -I$(TOP) -L$(TOP) + TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/include -I$(TOP) -L$(TOP) endif XTCCFLAGS = -B$(TOP) -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include @@ -101,28 +104,29 @@ w32-prep: cp ../libtcc1.a ../lib # test.ref - generate using gcc -# copy only tcclib.h so GCC's stddef and stdarg will be used test.ref: tcctest.c gcc -o tcctest.gcc $< -I$(top_srcdir) $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS) ./tcctest.gcc > $@ # auto test -test1: tcctest.c test.ref +test1 test1b: tcctest.c test.ref @echo ------------ $@ ------------ $(TCC) -run $< > test.out1 - @if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi + @diff -u test.ref test.out1 && echo "Auto Test OK" # iterated test2 (compile tcc then compile tcctest.c !) -test2: tcctest.c test.ref +test2 test2b: tcctest.c test.ref @echo ------------ $@ ------------ $(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2 - @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi + @diff -u test.ref test.out2 && echo "Auto Test2 OK" # iterated test3 (compile tcc then compile tcc then compile tcctest.c !) -test3: tcctest.c test.ref +test3 test3b: tcctest.c test.ref @echo ------------ $@ ------------ $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3 - @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi + @diff -u test.ref test.out3 && echo "Auto Test3 OK" + +test%b : TCCFLAGS += -b # binary output test test4: tcctest.c test.ref @@ -153,7 +157,7 @@ btest: boundtest.c @echo ------------ $@ ------------ @for i in $(BOUNDS_OK); do \ echo ; echo --- boundtest $$i ---; \ - if $(TCC) -b -run boundtest.c $$i ; then \ + if $(TCC) -b -run $< $$i ; then \ echo succeded as expected; \ else\ echo Failed positive test $$i ; exit 1 ; \ @@ -161,7 +165,7 @@ btest: boundtest.c done ;\ for i in $(BOUNDS_FAIL); do \ echo ; echo --- boundtest $$i ---; \ - if $(TCC) -b -run boundtest.c $$i ; then \ + if $(TCC) -b -run $< $$i ; then \ echo Failed negative test $$i ; exit 1 ;\ else\ echo failed as expected; \ @@ -203,8 +207,8 @@ asmtest: asmtest.ref abitest-cc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC) $(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir) -abitest-tcc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC) - $(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir) +abitest-tcc$(EXESUF): abitest.c libtcc.c + $(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir) abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF) @echo ------------ $@ ------------ -- cgit v1.3.1 From 112148172b50c20acde6adf4f86fa0a32d3d5a6c Mon Sep 17 00:00:00 2001 From: grischka Date: Sun, 13 Apr 2014 20:30:46 +0200 Subject: tccpe: speed up .def file loading The fgets replacement meant to work with "int fd" was just too slow. --- tccpe.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'tccpe.c') diff --git a/tccpe.c b/tccpe.c index f4a58f7..6ee3865 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1583,31 +1583,20 @@ static char *trimback(char *a, char *e) return a; } -static char *get_line(char *line, int size, int fd) -{ - int n; - for (n = 0; n < size - 1; ) - if (read(fd, line + n, 1) < 1 || line[n++] == '\n') - break; - if (0 == n) - return NULL; - trimback(line, line + n); - return trimfront(line); -} - /* ------------------------------------------------------------- */ static int pe_load_def(TCCState *s1, int fd) { int state = 0, ret = -1, dllindex = 0, ord; char line[400], dllname[80], *p, *x; + FILE *fp; - for (;;) { - - p = get_line(line, sizeof line, fd); - if (NULL == p) - break; + fp = fdopen(dup(fd), "rb"); + while (fgets(line, sizeof line, fp)) + { + p = trimfront(trimback(line, strchr(line, 0))); if (0 == *p || ';' == *p) continue; + switch (state) { case 0: if (0 != strnicmp(p, "LIBRARY", 7)) @@ -1645,6 +1634,7 @@ static int pe_load_def(TCCState *s1, int fd) } ret = 0; quit: + fclose(fp); return ret; } -- cgit v1.3.1 From 2ac238fc507b64a8dd2d5d3d5c00210c1ffabea5 Mon Sep 17 00:00:00 2001 From: grischka Date: Thu, 17 Apr 2014 17:01:28 +0200 Subject: tccpe: adjust for new 'hidden' symbols feature in order to avoid conflicts with windows specific (ab)usage of the Elf32_Sym -> st_other field. --- libtcc.c | 12 +++++------- tcc.h | 4 ++++ tccpe.c | 16 ++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'tccpe.c') diff --git a/libtcc.c b/libtcc.c index 05abaef..deda7e6 100644 --- a/libtcc.c +++ b/libtcc.c @@ -491,22 +491,22 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, #ifdef TCC_TARGET_PE if (sym->type.t & VT_EXPORT) - other |= 1; + other |= ST_PE_EXPORT; if (sym_type == STT_FUNC && sym->type.ref) { Sym *ref = sym->type.ref; if (ref->a.func_export) - other |= 1; + other |= ST_PE_EXPORT; if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) { sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE); name = buf1; - other |= 2; + other |= ST_PE_STDCALL; can_add_underscore = 0; } } else { if (find_elf_sym(tcc_state->dynsymtab_section, name)) - other |= 4; + other |= ST_PE_IMPORT; if (sym->type.t & VT_IMPORT) - other |= 4; + other |= ST_PE_IMPORT; } #else if (! (sym->type.t & VT_STATIC)) @@ -1316,8 +1316,6 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) So it is handled here as if it were in a DLL. */ pe_putimport(s, 0, name, (uintptr_t)val); #else - /* XXX: Same problem on linux but currently "solved" elsewhere - via the rather dirty 'runtime_plt_and_got' hack. */ add_elf_sym(symtab_section, (uintptr_t)val, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, SHN_ABS, name); diff --git a/tcc.h b/tcc.h index ab14b38..c93cedf 100644 --- a/tcc.h +++ b/tcc.h @@ -1392,6 +1392,10 @@ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); #ifdef TCC_TARGET_X86_64 ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack); #endif +/* symbol properties stored in Elf32_Sym->st_other */ +# define ST_PE_EXPORT 0x10 +# define ST_PE_IMPORT 0x20 +# define ST_PE_STDCALL 0x40 #endif /* ------------ tccrun.c ----------------- */ diff --git a/tccpe.c b/tccpe.c index 6ee3865..b972d75 100644 --- a/tccpe.c +++ b/tccpe.c @@ -363,7 +363,7 @@ struct pe_info { static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym) { const char *name = symtab_section->link->data + sym->st_name; - if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2)) + if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL)) return name + 1; return name; } @@ -378,7 +378,7 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) s = pe_export_name(s1, sym); if (n) { /* second try: */ - if (sym->st_other & 2) { + if (sym->st_other & ST_PE_STDCALL) { /* try w/0 stdcall deco (windows API convention) */ p = strrchr(s, '@'); if (!p || s[0] != '_') @@ -899,7 +899,7 @@ static void pe_build_exports(struct pe_info *pe) for (sym_index = 1; sym_index < sym_end; ++sym_index) { sym = (ElfW(Sym)*)symtab_section->data + sym_index; name = pe_export_name(pe->s1, sym); - if ((sym->st_other & 1) + if ((sym->st_other & ST_PE_EXPORT) /* export only symbols from actually written sections */ && pe->s1->sections[sym->st_shndx]->sh_addr) { p = tcc_malloc(sizeof *p); @@ -908,9 +908,9 @@ static void pe_build_exports(struct pe_info *pe) dynarray_add((void***)&sorted, &sym_count, p); } #if 0 - if (sym->st_other & 1) + if (sym->st_other & ST_PE_EXPORT) printf("export: %s\n", name); - if (sym->st_other & 2) + if (sym->st_other & ST_PE_STDCALL) printf("stdcall: %s\n", name); #endif } @@ -1282,7 +1282,7 @@ static int pe_check_symbols(struct pe_info *pe) /* patch the original symbol */ sym->st_value = offset; sym->st_shndx = text_section->sh_num; - sym->st_other &= ~1; /* do not export */ + sym->st_other &= ~ST_PE_EXPORT; /* do not export */ continue; } @@ -1301,7 +1301,7 @@ static int pe_check_symbols(struct pe_info *pe) } else if (pe->s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { /* if -rdynamic option, then export all non local symbols */ - sym->st_other |= 1; + sym->st_other |= ST_PE_EXPORT; } } return ret; @@ -1463,7 +1463,7 @@ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) if (!sym->c) put_extern_sym(sym, NULL, 0, 0); esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - if (!(esym->st_other & 4)) + if (!(esym->st_other & ST_PE_IMPORT)) return sv; // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL)); -- cgit v1.3.1