From cd75ca692a38466d1ff08ac9b60018695735d871 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 3 Jun 2023 21:20:48 +0200 Subject: [PATCH] stuff & fixes libtcc.c: - revert "Small patch to allow..." (someone's personal easteregg) (see da3a763e977a84edf43c5ca101deae768ae8480d) - check return value from macho_load_tbd/dylib tcc.c: - remove help for "not yet implemented" option tccelf.c: - check PIE's for "unresolved symbols" tccgen.c: - avoid int->double->int cast (see a46372e910710b9b00d4f4122ef6c1b00b2b909c) - fix constant propagation with pseudo long doubles (must mask out VT_LONG from type) - cleanup find_field() (again) tccpp.c: - disallow strings and double constants in #if expressions win32/include/uchar.h: - change file mode --- libtcc.c | 40 +---------------------------- tcc.c | 3 +-- tcc.h | 3 +-- tccelf.c | 14 +++++----- tccgen.c | 70 ++++++++++++++++++++++---------------------------- tccpp.c | 7 +++-- tests/libtcc_test_mt.c | 5 ++-- win32/include/uchar.h | 0 8 files changed, 48 insertions(+), 94 deletions(-) mode change 100755 => 100644 win32/include/uchar.h diff --git a/libtcc.c b/libtcc.c index d5ca6d46..85ed5d32 100644 --- a/libtcc.c +++ b/libtcc.c @@ -99,50 +99,12 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) /* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */ static inline char *config_tccdir_w32(char *path) { - char temp[1024]; - char try[1024]; char *p; - int c; GetModuleFileName(tcc_module, path, MAX_PATH); p = tcc_basename(normalize_slashes(strlwr(path))); if (p > path) --p; - *p = 0; - - /* - * See if we are perhaps in a "bin/" subfolder of the - * installation path, in which case the real root of - * the installation is one level up. We can test this - * by looking for the 'include' folder. - */ - strncpy(temp, path, sizeof(temp)-1); - strcat(temp, "/include"); - - if (_access(temp, 0) != 0) { - /* No 'include' folder found, so go up one level. */ - strncpy(temp, path, sizeof(temp)-1); - - /* Try this for several "levels" up. */ - for (c = 0; c < 4; c++) { - p = tcc_basename(temp); - if (p > temp) { - --p; - *p = '\0'; - } - - strncpy(try, temp, sizeof(try)-1); - strcat(try, "/include"); - - if (_access(try, 0) == 0) { - if (p != NULL) - p = '\0'; - strcpy(path, temp); - break; - } - } - } - return path; } #define CONFIG_TCCDIR config_tccdir_w32(alloca(MAX_PATH)) @@ -1174,7 +1136,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) } else { ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); } - break; + goto check_success; default: { const char *ext = tcc_fileextension(filename); diff --git a/tcc.c b/tcc.c index 0c6f6ac7..9d06a477 100644 --- a/tcc.c +++ b/tcc.c @@ -48,7 +48,6 @@ static const char help[] = " -Dsym[=val] define 'sym' with value 'val'\n" " -Usym undefine 'sym'\n" " -E preprocess only\n" - " -C keep comments (not yet implemented)\n" "Linker options:\n" " -Ldir add library path 'dir'\n" " -llib link with dynamic or static library 'lib'\n" @@ -303,7 +302,7 @@ redo: if (opt == OPT_M32 || opt == OPT_M64) return tcc_tool_cross(s, argv, opt); if (s->verbose) - printf(version); + printf("%s", version); if (opt == OPT_AR) return tcc_tool_ar(s, argc, argv); #ifdef TCC_TARGET_PE diff --git a/tcc.h b/tcc.h index ff75de14..b49b7f94 100644 --- a/tcc.h +++ b/tcc.h @@ -284,7 +284,7 @@ extern long double strtold (const char *__nptr, char **__endptr); /* library search paths */ #ifndef CONFIG_TCC_LIBPATHS -# ifdef TCC_TARGET_PE +# if defined TCC_TARGET_PE || defined _WIN32 # define CONFIG_TCC_LIBPATHS "{B}/lib" # else # define CONFIG_TCC_LIBPATHS \ @@ -496,7 +496,6 @@ typedef struct CString { int size; /* size in bytes */ int size_allocated; void *data; /* either 'char *' or 'nwchar_t *' */ - struct CString *prev; } CString; /* type definition */ diff --git a/tccelf.c b/tccelf.c index b46ad4ca..2e3d8aca 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1880,7 +1880,7 @@ static void fill_local_got_entries(TCCState *s1) /* Bind symbols of executable: resolve undefined symbols from exported symbols in shared libraries */ -static void bind_exe_dynsyms(TCCState *s1) +static void bind_exe_dynsyms(TCCState *s1, int is_PIE) { const char *name; int sym_index, index; @@ -1895,6 +1895,8 @@ static void bind_exe_dynsyms(TCCState *s1) name = (char *) symtab_section->link->data + sym->st_name; sym_index = find_elf_sym(s1->dynsymtab_section, name); if (sym_index) { + if (is_PIE) + continue; esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; type = ELFW(ST_TYPE)(esym->st_info); if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { @@ -1970,9 +1972,9 @@ static void bind_libs_dynsyms(TCCState *s1) for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { name = (char *)symtab_section->link->data + sym->st_name; dynsym_index = find_elf_sym(s1->dynsymtab_section, name); - if (sym->st_shndx != SHN_UNDEF - && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - if (dynsym_index || s1->rdynamic) + if (sym->st_shndx != SHN_UNDEF) { + if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL + && (dynsym_index || s1->rdynamic)) set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, 0, sym->st_shndx, name); } else if (dynsym_index) { @@ -2797,8 +2799,8 @@ static int elf_output_file(TCCState *s1, const char *filename) dynamic->sh_entsize = sizeof(ElfW(Dyn)); got_sym = build_got(s1); - if (file_type == TCC_OUTPUT_EXE) { - bind_exe_dynsyms(s1); + if (file_type & TCC_OUTPUT_EXE) { + bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN); if (s1->nb_errors) goto the_end; } diff --git a/tccgen.c b/tccgen.c index 529abe9c..8f259b8b 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2474,7 +2474,7 @@ void gen_negf(int op) /* generate a floating point operation with constant propagation */ static void gen_opif(int op) { - int c1, c2, cast_int = 0; + int c1, c2, i, bt; SValue *v1, *v2; #if defined _MSC_VER && defined __x86_64__ /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ @@ -2486,15 +2486,16 @@ static void gen_opif(int op) v2 = vtop; if (op == TOK_NEG) v1 = v2; + bt = v1->type.t & VT_BTYPE; /* currently, we cannot do computations with forward symbols */ c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; if (c1 && c2) { - if (v1->type.t == VT_FLOAT) { + if (bt == VT_FLOAT) { f1 = v1->c.f; f2 = v2->c.f; - } else if (v1->type.t == VT_DOUBLE) { + } else if (bt == VT_DOUBLE) { f1 = v1->c.d; f2 = v2->c.d; } else { @@ -2533,41 +2534,39 @@ static void gen_opif(int op) f1 = -f1; goto unary_result; case TOK_EQ: - f1 = f1 == f2; + i = f1 == f2; make_int: - cast_int = 1; - break; + vtop -= 2; + vpushi(i); + return; case TOK_NE: - f1 = f1 != f2; + i = f1 != f2; goto make_int; case TOK_LT: - f1 = f1 < f2; + i = f1 < f2; goto make_int; case TOK_GE: - f1 = f1 >= f2; + i = f1 >= f2; goto make_int; case TOK_LE: - f1 = f1 <= f2; + i = f1 <= f2; goto make_int; case TOK_GT: - f1 = f1 > f2; + i = f1 > f2; goto make_int; - /* XXX: also handles tests ? */ default: goto general_case; } vtop--; unary_result: /* XXX: overflow test ? */ - if (v1->type.t == VT_FLOAT) { + if (bt == VT_FLOAT) { v1->c.f = f1; - } else if (v1->type.t == VT_DOUBLE) { + } else if (bt == VT_DOUBLE) { v1->c.d = f1; } else { v1->c.ld = f1; } - if (cast_int) - gen_cast_s(VT_INT); } else { general_case: if (op == TOK_NEG) { @@ -4029,10 +4028,18 @@ static Sym * find_field (CType *type, int v, int *cumofs) { Sym *s = type->ref; int v1 = v | SYM_FIELD; - + if (!(v & SYM_FIELD)) { /* top-level call */ + if ((type->t & VT_BTYPE) != VT_STRUCT) + expect("struct or union"); + if (v < TOK_UIDENT) + expect("field name"); + if (s->c < 0) + tcc_error("dereferencing incomplete type '%s'", + get_tok_str(s->v & ~SYM_STRUCT, 0)); + } while ((s = s->next) != NULL) { if (s->v == v1) { - *cumofs += s->c; + *cumofs = s->c; return s; } if ((s->type.t & VT_BTYPE) == VT_STRUCT @@ -4045,17 +4052,9 @@ static Sym * find_field (CType *type, int v, int *cumofs) } } } - - if (!(v & SYM_FIELD)) { /* top-level call */ - s = type->ref; - if (s->c < 0) - tcc_error("dereferencing incomplete type '%s'", - get_tok_str(s->v & ~SYM_STRUCT, 0)); - else - tcc_error("field not found: %s", - get_tok_str(v, &tokc)); - } - return NULL; + if (!(v & SYM_FIELD)) + tcc_error("field not found: %s", get_tok_str(v, NULL)); + return s; } static void check_fields (CType *type, int check) @@ -6003,21 +6002,15 @@ special_math_val: if (tok == TOK_INC || tok == TOK_DEC) { inc(1, tok); next(); - } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) { - int qualifiers, cumofs = 0; + } else if (tok == '.' || tok == TOK_ARROW) { + int qualifiers, cumofs; /* field */ if (tok == TOK_ARROW) indir(); qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE); test_lvalue(); /* expect pointer on structure */ - if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) - expect("struct or union"); - if (tok == TOK_CDOUBLE) - expect("field name"); next(); - if (tok == TOK_CINT || tok == TOK_CUINT) - expect("field name"); s = find_field(&vtop->type, tok, &cumofs); /* add field offset to pointer */ gaddrof(); @@ -7494,9 +7487,6 @@ static int decl_designator(init_params *p, CType *type, unsigned long c, l = tok; struct_field: next(); - if ((type->t & VT_BTYPE) != VT_STRUCT) - expect("struct/union type"); - cumofs = 0; f = find_field(type, l, &cumofs); if (cur_field) *cur_field = f; diff --git a/tccpp.c b/tccpp.c index dee42712..43a616c0 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1457,7 +1457,10 @@ static int expr_preprocess(TCCState *s1) while (tok != TOK_LINEFEED && tok != TOK_EOF) { next(); /* do macro subst */ redo: - if (tok == TOK_DEFINED) { + if (tok < TOK_IDENT) { + if (tok >= TOK_STR && tok <= TOK_CLDOUBLE) + tcc_error("invalid constant in preprocessor expression"); + } else if (tok == TOK_DEFINED) { next_nomacro(); t = tok; if (t == '(') @@ -1489,7 +1492,7 @@ static int expr_preprocess(TCCState *s1) expect("')'"); tok = TOK_CINT; tokc.i = c; - } else if (tok >= TOK_IDENT) { + } else { /* if undefined macro, replace with zero, check for func-like */ t = tok; tok = TOK_CINT; diff --git a/tests/libtcc_test_mt.c b/tests/libtcc_test_mt.c index 1e5a3860..7af8f3e8 100644 --- a/tests/libtcc_test_mt.c +++ b/tests/libtcc_test_mt.c @@ -209,9 +209,8 @@ TF_TYPE(thread_test_complex, vn) sleep_ms(2); ret = tcc_add_file(s, argv[0]); sleep_ms(3); - if (ret < 0) - exit(1); - tcc_run(s, argc, argv); + if (ret == 0) + tcc_run(s, argc, argv); tcc_delete(s); fflush(stdout); return 0; diff --git a/win32/include/uchar.h b/win32/include/uchar.h old mode 100755 new mode 100644 -- 2.11.4.GIT