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' */
|
/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
|
||||||
static inline char *config_tccdir_w32(char *path)
|
static inline char *config_tccdir_w32(char *path)
|
||||||
{
|
{
|
||||||
char temp[1024];
|
|
||||||
char try[1024];
|
|
||||||
char *p;
|
char *p;
|
||||||
int c;
|
|
||||||
GetModuleFileName(tcc_module, path, MAX_PATH);
|
GetModuleFileName(tcc_module, path, MAX_PATH);
|
||||||
p = tcc_basename(normalize_slashes(strlwr(path)));
|
p = tcc_basename(normalize_slashes(strlwr(path)));
|
||||||
if (p > path)
|
if (p > path)
|
||||||
--p;
|
--p;
|
||||||
|
|
||||||
*p = 0;
|
*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;
|
return path;
|
||||||
}
|
}
|
||||||
#define CONFIG_TCCDIR config_tccdir_w32(alloca(MAX_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 {
|
} else {
|
||||||
ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
|
ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
|
||||||
}
|
}
|
||||||
break;
|
goto check_success;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
const char *ext = tcc_fileextension(filename);
|
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"
|
" -Dsym[=val] define 'sym' with value 'val'\n"
|
||||||
" -Usym undefine 'sym'\n"
|
" -Usym undefine 'sym'\n"
|
||||||
" -E preprocess only\n"
|
" -E preprocess only\n"
|
||||||
" -C keep comments (not yet implemented)\n"
|
|
||||||
"Linker options:\n"
|
"Linker options:\n"
|
||||||
" -Ldir add library path 'dir'\n"
|
" -Ldir add library path 'dir'\n"
|
||||||
" -llib link with dynamic or static library 'lib'\n"
|
" -llib link with dynamic or static library 'lib'\n"
|
||||||
@ -303,7 +302,7 @@ redo:
|
|||||||
if (opt == OPT_M32 || opt == OPT_M64)
|
if (opt == OPT_M32 || opt == OPT_M64)
|
||||||
return tcc_tool_cross(s, argv, opt);
|
return tcc_tool_cross(s, argv, opt);
|
||||||
if (s->verbose)
|
if (s->verbose)
|
||||||
printf(version);
|
printf("%s", version);
|
||||||
if (opt == OPT_AR)
|
if (opt == OPT_AR)
|
||||||
return tcc_tool_ar(s, argc, argv);
|
return tcc_tool_ar(s, argc, argv);
|
||||||
#ifdef TCC_TARGET_PE
|
#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 */
|
/* library search paths */
|
||||||
#ifndef CONFIG_TCC_LIBPATHS
|
#ifndef CONFIG_TCC_LIBPATHS
|
||||||
# ifdef TCC_TARGET_PE
|
# if defined TCC_TARGET_PE || defined _WIN32
|
||||||
# define CONFIG_TCC_LIBPATHS "{B}/lib"
|
# define CONFIG_TCC_LIBPATHS "{B}/lib"
|
||||||
# else
|
# else
|
||||||
# define CONFIG_TCC_LIBPATHS \
|
# define CONFIG_TCC_LIBPATHS \
|
||||||
@ -496,7 +496,6 @@ typedef struct CString {
|
|||||||
int size; /* size in bytes */
|
int size; /* size in bytes */
|
||||||
int size_allocated;
|
int size_allocated;
|
||||||
void *data; /* either 'char *' or 'nwchar_t *' */
|
void *data; /* either 'char *' or 'nwchar_t *' */
|
||||||
struct CString *prev;
|
|
||||||
} CString;
|
} CString;
|
||||||
|
|
||||||
/* type definition */
|
/* 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
|
/* Bind symbols of executable: resolve undefined symbols from exported symbols
|
||||||
in shared libraries */
|
in shared libraries */
|
||||||
static void bind_exe_dynsyms(TCCState *s1)
|
static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
int sym_index, index;
|
int sym_index, index;
|
||||||
@ -1895,6 +1895,8 @@ static void bind_exe_dynsyms(TCCState *s1)
|
|||||||
name = (char *) symtab_section->link->data + sym->st_name;
|
name = (char *) symtab_section->link->data + sym->st_name;
|
||||||
sym_index = find_elf_sym(s1->dynsymtab_section, name);
|
sym_index = find_elf_sym(s1->dynsymtab_section, name);
|
||||||
if (sym_index) {
|
if (sym_index) {
|
||||||
|
if (is_PIE)
|
||||||
|
continue;
|
||||||
esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
|
esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
|
||||||
type = ELFW(ST_TYPE)(esym->st_info);
|
type = ELFW(ST_TYPE)(esym->st_info);
|
||||||
if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
|
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)) {
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
name = (char *)symtab_section->link->data + sym->st_name;
|
name = (char *)symtab_section->link->data + sym->st_name;
|
||||||
dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
|
dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
|
||||||
if (sym->st_shndx != SHN_UNDEF
|
if (sym->st_shndx != SHN_UNDEF) {
|
||||||
&& ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
|
||||||
if (dynsym_index || s1->rdynamic)
|
&& (dynsym_index || s1->rdynamic))
|
||||||
set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
||||||
sym->st_info, 0, sym->st_shndx, name);
|
sym->st_info, 0, sym->st_shndx, name);
|
||||||
} else if (dynsym_index) {
|
} else if (dynsym_index) {
|
||||||
@ -2797,8 +2799,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
dynamic->sh_entsize = sizeof(ElfW(Dyn));
|
dynamic->sh_entsize = sizeof(ElfW(Dyn));
|
||||||
|
|
||||||
got_sym = build_got(s1);
|
got_sym = build_got(s1);
|
||||||
if (file_type == TCC_OUTPUT_EXE) {
|
if (file_type & TCC_OUTPUT_EXE) {
|
||||||
bind_exe_dynsyms(s1);
|
bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
|
||||||
if (s1->nb_errors)
|
if (s1->nb_errors)
|
||||||
goto the_end;
|
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 */
|
/* generate a floating point operation with constant propagation */
|
||||||
static void gen_opif(int op)
|
static void gen_opif(int op)
|
||||||
{
|
{
|
||||||
int c1, c2, cast_int = 0;
|
int c1, c2, i, bt;
|
||||||
SValue *v1, *v2;
|
SValue *v1, *v2;
|
||||||
#if defined _MSC_VER && defined __x86_64__
|
#if defined _MSC_VER && defined __x86_64__
|
||||||
/* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
|
/* 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;
|
v2 = vtop;
|
||||||
if (op == TOK_NEG)
|
if (op == TOK_NEG)
|
||||||
v1 = v2;
|
v1 = v2;
|
||||||
|
bt = v1->type.t & VT_BTYPE;
|
||||||
|
|
||||||
/* currently, we cannot do computations with forward symbols */
|
/* currently, we cannot do computations with forward symbols */
|
||||||
c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||||
c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||||
if (c1 && c2) {
|
if (c1 && c2) {
|
||||||
if (v1->type.t == VT_FLOAT) {
|
if (bt == VT_FLOAT) {
|
||||||
f1 = v1->c.f;
|
f1 = v1->c.f;
|
||||||
f2 = v2->c.f;
|
f2 = v2->c.f;
|
||||||
} else if (v1->type.t == VT_DOUBLE) {
|
} else if (bt == VT_DOUBLE) {
|
||||||
f1 = v1->c.d;
|
f1 = v1->c.d;
|
||||||
f2 = v2->c.d;
|
f2 = v2->c.d;
|
||||||
} else {
|
} else {
|
||||||
@ -2533,41 +2534,39 @@ static void gen_opif(int op)
|
|||||||
f1 = -f1;
|
f1 = -f1;
|
||||||
goto unary_result;
|
goto unary_result;
|
||||||
case TOK_EQ:
|
case TOK_EQ:
|
||||||
f1 = f1 == f2;
|
i = f1 == f2;
|
||||||
make_int:
|
make_int:
|
||||||
cast_int = 1;
|
vtop -= 2;
|
||||||
break;
|
vpushi(i);
|
||||||
|
return;
|
||||||
case TOK_NE:
|
case TOK_NE:
|
||||||
f1 = f1 != f2;
|
i = f1 != f2;
|
||||||
goto make_int;
|
goto make_int;
|
||||||
case TOK_LT:
|
case TOK_LT:
|
||||||
f1 = f1 < f2;
|
i = f1 < f2;
|
||||||
goto make_int;
|
goto make_int;
|
||||||
case TOK_GE:
|
case TOK_GE:
|
||||||
f1 = f1 >= f2;
|
i = f1 >= f2;
|
||||||
goto make_int;
|
goto make_int;
|
||||||
case TOK_LE:
|
case TOK_LE:
|
||||||
f1 = f1 <= f2;
|
i = f1 <= f2;
|
||||||
goto make_int;
|
goto make_int;
|
||||||
case TOK_GT:
|
case TOK_GT:
|
||||||
f1 = f1 > f2;
|
i = f1 > f2;
|
||||||
goto make_int;
|
goto make_int;
|
||||||
/* XXX: also handles tests ? */
|
|
||||||
default:
|
default:
|
||||||
goto general_case;
|
goto general_case;
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
unary_result:
|
unary_result:
|
||||||
/* XXX: overflow test ? */
|
/* XXX: overflow test ? */
|
||||||
if (v1->type.t == VT_FLOAT) {
|
if (bt == VT_FLOAT) {
|
||||||
v1->c.f = f1;
|
v1->c.f = f1;
|
||||||
} else if (v1->type.t == VT_DOUBLE) {
|
} else if (bt == VT_DOUBLE) {
|
||||||
v1->c.d = f1;
|
v1->c.d = f1;
|
||||||
} else {
|
} else {
|
||||||
v1->c.ld = f1;
|
v1->c.ld = f1;
|
||||||
}
|
}
|
||||||
if (cast_int)
|
|
||||||
gen_cast_s(VT_INT);
|
|
||||||
} else {
|
} else {
|
||||||
general_case:
|
general_case:
|
||||||
if (op == TOK_NEG) {
|
if (op == TOK_NEG) {
|
||||||
@ -4029,10 +4028,18 @@ static Sym * find_field (CType *type, int v, int *cumofs)
|
|||||||
{
|
{
|
||||||
Sym *s = type->ref;
|
Sym *s = type->ref;
|
||||||
int v1 = v | SYM_FIELD;
|
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) {
|
while ((s = s->next) != NULL) {
|
||||||
if (s->v == v1) {
|
if (s->v == v1) {
|
||||||
*cumofs += s->c;
|
*cumofs = s->c;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
if ((s->type.t & VT_BTYPE) == VT_STRUCT
|
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))
|
||||||
if (!(v & SYM_FIELD)) { /* top-level call */
|
tcc_error("field not found: %s", get_tok_str(v, NULL));
|
||||||
s = type->ref;
|
return s;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_fields (CType *type, int check)
|
static void check_fields (CType *type, int check)
|
||||||
@ -6003,21 +6002,15 @@ special_math_val:
|
|||||||
if (tok == TOK_INC || tok == TOK_DEC) {
|
if (tok == TOK_INC || tok == TOK_DEC) {
|
||||||
inc(1, tok);
|
inc(1, tok);
|
||||||
next();
|
next();
|
||||||
} else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
|
} else if (tok == '.' || tok == TOK_ARROW) {
|
||||||
int qualifiers, cumofs = 0;
|
int qualifiers, cumofs;
|
||||||
/* field */
|
/* field */
|
||||||
if (tok == TOK_ARROW)
|
if (tok == TOK_ARROW)
|
||||||
indir();
|
indir();
|
||||||
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
||||||
test_lvalue();
|
test_lvalue();
|
||||||
/* expect pointer on structure */
|
/* expect pointer on structure */
|
||||||
if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
|
|
||||||
expect("struct or union");
|
|
||||||
if (tok == TOK_CDOUBLE)
|
|
||||||
expect("field name");
|
|
||||||
next();
|
next();
|
||||||
if (tok == TOK_CINT || tok == TOK_CUINT)
|
|
||||||
expect("field name");
|
|
||||||
s = find_field(&vtop->type, tok, &cumofs);
|
s = find_field(&vtop->type, tok, &cumofs);
|
||||||
/* add field offset to pointer */
|
/* add field offset to pointer */
|
||||||
gaddrof();
|
gaddrof();
|
||||||
@ -7494,9 +7487,6 @@ static int decl_designator(init_params *p, CType *type, unsigned long c,
|
|||||||
l = tok;
|
l = tok;
|
||||||
struct_field:
|
struct_field:
|
||||||
next();
|
next();
|
||||||
if ((type->t & VT_BTYPE) != VT_STRUCT)
|
|
||||||
expect("struct/union type");
|
|
||||||
cumofs = 0;
|
|
||||||
f = find_field(type, l, &cumofs);
|
f = find_field(type, l, &cumofs);
|
||||||
if (cur_field)
|
if (cur_field)
|
||||||
*cur_field = f;
|
*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) {
|
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
||||||
next(); /* do macro subst */
|
next(); /* do macro subst */
|
||||||
redo:
|
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();
|
next_nomacro();
|
||||||
t = tok;
|
t = tok;
|
||||||
if (t == '(')
|
if (t == '(')
|
||||||
@ -1489,7 +1492,7 @@ static int expr_preprocess(TCCState *s1)
|
|||||||
expect("')'");
|
expect("')'");
|
||||||
tok = TOK_CINT;
|
tok = TOK_CINT;
|
||||||
tokc.i = c;
|
tokc.i = c;
|
||||||
} else if (tok >= TOK_IDENT) {
|
} else {
|
||||||
/* if undefined macro, replace with zero, check for func-like */
|
/* if undefined macro, replace with zero, check for func-like */
|
||||||
t = tok;
|
t = tok;
|
||||||
tok = TOK_CINT;
|
tok = TOK_CINT;
|
||||||
|
@ -209,9 +209,8 @@ TF_TYPE(thread_test_complex, vn)
|
|||||||
sleep_ms(2);
|
sleep_ms(2);
|
||||||
ret = tcc_add_file(s, argv[0]);
|
ret = tcc_add_file(s, argv[0]);
|
||||||
sleep_ms(3);
|
sleep_ms(3);
|
||||||
if (ret < 0)
|
if (ret == 0)
|
||||||
exit(1);
|
tcc_run(s, argc, argv);
|
||||||
tcc_run(s, argc, argv);
|
|
||||||
tcc_delete(s);
|
tcc_delete(s);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 0;
|
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