mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-10 08:50:07 +08:00
stuff & fixes
libtcc.c: - revert "Small patch to allow..." (someone's personal easteregg) (seeda3a763e97
) - 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 (seea46372e910
) - 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:
parent
3f3cbb51ed
commit
cd75ca692a
40
libtcc.c
40
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);
|
||||
|
3
tcc.c
3
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
|
||||
|
3
tcc.h
3
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 */
|
||||
|
14
tccelf.c
14
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;
|
||||
}
|
||||
|
70
tccgen.c
70
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;
|
||||
|
7
tccpp.c
7
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;
|
||||
|
@ -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
0
win32/include/uchar.h
Executable file → Normal file
Loading…
Reference in New Issue
Block a user