stuff & fixes

libtcc.c:
- revert "Small patch to allow..." (someone's personal easteregg)
  (see da3a763e97)
- 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 a46372e910)
- 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
This commit is contained in:
grischka 2023-06-03 21:20:48 +02:00
parent 3f3cbb51ed
commit cd75ca692a
8 changed files with 48 additions and 94 deletions

View File

@ -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);

3
tcc.c
View File

@ -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

3
tcc.h
View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

0
win32/include/uchar.h Executable file → Normal file
View File