fixes & cleanups

- tccgen.c/tcc.h: allow function declaration after use:
      int f() { return g(); }
      int g() { return 1; }
  may be a warning but not an error
  see also 76cb1144ef

- tccgen.c: redundant code related to inline functions removed
  (functions used anywhere have sym->c set automatically)

- tccgen.c: make 32bit llop non-equal test portable
  (probably not on C67)

- dynarray_add: change prototype to possibly avoid aliasing
  problems or at least warnings

- lib/alloca*.S: ".section .note.GNU-stack,"",%progbits" removed
  (has no effect)

- tccpe: set SizeOfCode field (for correct upx decompression)

- libtcc.c: fixed alternative -run invocation
      tcc "-run -lxxx ..." file.c
  (meant to load the library after file).
  Also supported now:
      tcc files ... options ... -run @ arguments ...
This commit is contained in:
grischka 2017-02-13 18:23:43 +01:00
parent 9817204d8a
commit a4a20360e9
13 changed files with 61 additions and 90 deletions

View File

@ -341,7 +341,7 @@ void stuff_const_harder(uint32_t op, uint32_t v) {
}
}
ST_FUNC uint32_t encbranch(int pos, int addr, int fail)
uint32_t encbranch(int pos, int addr, int fail)
{
addr-=pos+8;
addr/=4;

View File

@ -70,9 +70,6 @@ enum {
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN 8
/* generate jmp to a label */
#define gjmp2(instr,lbl) oad(instr,lbl)
/******************************************************/
#else /* ! TARGET_DEFS_ONLY */
/******************************************************/
@ -148,7 +145,7 @@ ST_FUNC void gsym(int t)
}
/* instruction + 4 bytes data. Return the address of the data */
ST_FUNC int oad(int c, int s)
static int oad(int c, int s)
{
int t;
if (nocode_wanted)
@ -159,6 +156,9 @@ ST_FUNC int oad(int c, int s)
return t;
}
/* generate jmp to a label */
#define gjmp2(instr,lbl) oad(instr,lbl)
/* output constant with relocation if 'r & VT_SYM' is true */
ST_FUNC void gen_addr32(int r, Sym *sym, long c)
{

View File

@ -8,4 +8,3 @@ alloca:
mov r0, sp
mov pc, lr
.size alloca, .-alloca
.section .note.GNU-stack,"",%progbits

View File

@ -28,8 +28,4 @@ p3:
push %edx
ret
/* mark stack as nonexecutable */
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
#endif
/* ---------------------------------------------- */

View File

@ -53,8 +53,4 @@ p3:
ret
#endif
/* mark stack as nonexecutable */
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
#endif
/* ---------------------------------------------- */

View File

@ -35,8 +35,4 @@ p3:
push %rdx
ret
/* mark stack as nonexecutable */
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
#endif
/* ---------------------------------------------- */

View File

@ -403,13 +403,13 @@ PUB_FUNC void tcc_memstats(int bench)
/********************************************************/
/* dynarrays */
ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
{
int nb, nb_alloc;
void **pp;
nb = *nb_ptr;
pp = *ptab;
pp = *(void ***)ptab;
/* every power of two we double array size */
if ((nb & (nb - 1)) == 0) {
if (!nb)
@ -417,7 +417,7 @@ ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
else
nb_alloc = nb * 2;
pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
*ptab = pp;
*(void***)ptab = pp;
}
pp[nb++] = data;
*nb_ptr = nb;
@ -1013,7 +1013,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
}
/* update target deps */
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(filename));
parse_flags = 0;
@ -1586,7 +1586,7 @@ static void args_parser_add_file(TCCState *s, const char* filename, int filetype
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
f->type = filetype;
strcpy(f->name, filename);
dynarray_add((void ***)&s->files, &s->nb_files, f);
dynarray_add(&s->files, &s->nb_files, f);
}
/* read list file */
@ -1611,8 +1611,8 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
{
const TCCOption *popt;
const char *optarg, *r;
const char *run = NULL;
int optind = 0;
int run = 0;
int x;
int last_o = -1;
CString linker_arg; /* collect -Wl options */
@ -1631,8 +1631,10 @@ reparse:
}
if (r[0] != '-' || r[1] == '\0') {
args_parser_add_file(s, r, s->filetype);
if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
args_parser_add_file(s, r, s->filetype);
if (run) {
tcc_set_options(s, run);
optind--;
/* argv[0] will be this file */
break;
@ -1753,7 +1755,7 @@ reparse:
tcc_add_sysinclude_path(s, buf);
break;
case TCC_OPTION_include:
dynarray_add((void ***)&s->cmd_include_files,
dynarray_add(&s->cmd_include_files,
&s->nb_cmd_include_files, tcc_strdup(optarg));
break;
case TCC_OPTION_nostdinc:
@ -1769,8 +1771,7 @@ reparse:
#ifndef TCC_IS_NATIVE
tcc_error("-run is not available in a cross compiler");
#endif
tcc_set_options(s, optarg);
run = 1;
run = optarg;
x = TCC_OUTPUT_MEMORY;
goto set_output_type;
case TCC_OPTION_v:
@ -1903,7 +1904,7 @@ LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
}
cstr_ccat(&str, 0);
//printf("<%s>\n", str.data), fflush(stdout);
dynarray_add((void ***)&argv, &argc, tcc_strdup(str.data));
dynarray_add(&argv, &argc, tcc_strdup(str.data));
cstr_free(&str);
}
ret = tcc_parse_args(s, argc, argv);

6
tcc.h
View File

@ -388,7 +388,7 @@ struct Attribute {
func_export : 1,
func_import : 1,
func_args : 5,
func_proto : 1,
func_body : 1,
mode : 4,
weak : 1,
visibility : 2,
@ -1096,7 +1096,7 @@ PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
PUB_FUNC void tcc_warning(const char *fmt, ...);
/* other utilities */
ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
ST_FUNC void dynarray_reset(void *pp, int *n);
ST_INLN void cstr_ccat(CString *cstr, int ch);
ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
@ -1486,7 +1486,6 @@ static inline void add64le(unsigned char *p, int64_t x) {
/* ------------ i386-gen.c ------------ */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC void g(int c);
ST_FUNC int oad(int c, int s);
ST_FUNC void gen_le16(int c);
ST_FUNC void gen_le32(int c);
ST_FUNC void gen_addr32(int r, Sym *sym, long c);
@ -1510,7 +1509,6 @@ ST_FUNC void gen_opl(int op);
ST_FUNC char *default_elfinterp(struct TCCState *s);
#endif
ST_FUNC void arm_init(struct TCCState *s);
ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
ST_FUNC void gen_cvt_itof1(int t);
#endif

View File

@ -49,7 +49,7 @@ static int new_undef_sym = 0; /* Is there a new undefined sym since last new_und
ST_FUNC void tccelf_new(TCCState *s)
{
/* no section zero */
dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
dynarray_add(&s->sections, &s->nb_sections, NULL);
/* create standard sections */
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
@ -153,10 +153,10 @@ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh
}
if (sh_flags & SHF_PRIVATE) {
dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
} else {
sec->sh_num = s1->nb_sections;
dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
dynarray_add(&s1->sections, &s1->nb_sections, sec);
}
return sec;
@ -1896,7 +1896,7 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
static int elf_output_file(TCCState *s1, const char *filename)
{
int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
struct dyn_inf dyninf;
struct dyn_inf dyninf = {0};
ElfW(Phdr) *phdr;
ElfW(Sym) *sym;
Section *strsec, *interp, *dynamic, *dynstr;
@ -1912,7 +1912,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
phdr = NULL;
sec_order = NULL;
interp = dynamic = dynstr = NULL; /* avoid warning */
dyninf.dyn_rel_off = 0; /* avoid warning */
if (file_type != TCC_OUTPUT_OBJ) {
relocate_common_syms();
@ -2595,7 +2594,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
dllref->level = level;
strcpy(dllref->name, soname);
dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
/* add dynamic symbols in dynsym_section */
for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
@ -2825,9 +2824,9 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
goto lib_parse_error;
if (group) {
/* Add the filename *and* the libname to avoid future conversions */
dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
dynarray_add(&libs, &nblibs, tcc_strdup(filename));
if (libname[0] != '\0')
dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
dynarray_add(&libs, &nblibs, tcc_strdup(libname));
}
}
}

View File

@ -1608,23 +1608,15 @@ static void gen_opl(int op)
a = 0;
b = 0;
gen_op(op1);
if (op1 != TOK_NE) {
if (op == TOK_NE) {
b = gvtst(0, 0);
} else {
a = gvtst(1, 0);
}
if (op != TOK_EQ) {
/* generate non equal test */
/* XXX: NOT PORTABLE yet */
if (op1 == TOK_NE) {
if (op != TOK_EQ) {
/* generate non equal test */
vpushi(TOK_NE);
vtop->r = VT_CMP;
b = gvtst(0, 0);
} else {
#if defined(TCC_TARGET_I386)
b = gjmp2(0x850f, 0);
#elif defined(TCC_TARGET_ARM)
b = ind;
o(0x1A000000 | encbranch(ind, 0, 1));
#else
tcc_error("not implemented");
#endif
}
}
/* compare low. Always unsigned */
@ -4724,23 +4716,13 @@ ST_FUNC void unary(void)
tcc_warning("implicit declaration of function '%s'", name);
s = external_global_sym(t, &func_old_type, 0);
}
if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
(VT_STATIC | VT_INLINE | VT_FUNC)) {
/* if referencing an inline function, then we generate a
symbol to it if not already done. It will have the
effect to generate code for it at the end of the
compilation unit. Inline function as always
generated in the text section. */
if (!s->c && !nocode_wanted)
put_extern_sym(s, text_section, 0, 0);
r = VT_SYM | VT_CONST;
} else {
r = s->r;
/* A symbol that has a register is a local register variable,
which starts out as VT_LOCAL value. */
if ((r & VT_VALMASK) < VT_CONST)
r = (r & ~VT_VALMASK) | VT_LOCAL;
}
r = s->r;
/* A symbol that has a register is a local register variable,
which starts out as VT_LOCAL value. */
if ((r & VT_VALMASK) < VT_CONST)
r = (r & ~VT_VALMASK) | VT_LOCAL;
vset(&s->type, r, s->c);
/* Point to s as backpointer (even without r&VT_SYM).
Will be used by at least the x86 inline asm parser for
@ -4822,7 +4804,7 @@ ST_FUNC void unary(void)
s = vtop->type.ref;
next();
sa = s->next; /* first parameter */
nb_args = 0;
nb_args = regsize = 0;
ret.r2 = VT_CONST;
/* compute first implicit argument if a structure is returned */
if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
@ -5849,7 +5831,7 @@ static void block(int *bsym, int *csym, int is_expr)
tcc_warning("empty case range");
}
cr->sym = ind;
dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
dynarray_add(&cur_switch->p, &cur_switch->n, cr);
skip(':');
is_expr = 0;
goto block_after_label;
@ -6897,7 +6879,6 @@ static void gen_inline_functions(TCCState *s)
fn->sym = NULL;
if (file)
pstrcpy(file->filename, sizeof file->filename, fn->filename);
sym->r = VT_SYM | VT_CONST;
sym->type.t &= ~VT_INLINE;
begin_macro(fn->func_str, 1);
@ -7038,8 +7019,6 @@ static int decl0(int l, int is_for_loop_init)
goto func_error1;
ref = sym->type.ref;
if (0 == ref->a.func_proto)
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
/* use func_call from prototype if not defined */
if (ref->a.func_call != FUNC_CDECL
@ -7064,15 +7043,20 @@ static int decl0(int l, int is_for_loop_init)
tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL));
}
type.ref->a.func_proto = 0;
if (ref->a.func_body)
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
/* if symbol is already defined, then put complete type */
sym->type = type;
} else {
/* put function symbol */
sym = global_identifier_push(v, type.t, 0);
sym->type.ref = type.ref;
}
sym->type.ref->a.func_body = 1;
sym->r = VT_SYM | VT_CONST;
/* static inline functions are just recorded as a kind
of macro. Their code will be emitted at the end of
the compilation unit only if they are used */
@ -7106,14 +7090,13 @@ static int decl0(int l, int is_for_loop_init)
}
tok_str_add(fn->func_str, -1);
tok_str_add(fn->func_str, 0);
dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
} else {
/* compute text section */
cur_text_section = ad.section;
if (!cur_text_section)
cur_text_section = text_section;
sym->r = VT_SYM | VT_CONST;
gen_function(sym);
}
break;
@ -7138,7 +7121,6 @@ static int decl0(int l, int is_for_loop_init)
if ((type.t & VT_BTYPE) == VT_FUNC) {
/* external function definition */
/* specific case for func_call attribute */
ad.a.func_proto = 1;
type.ref->a = ad.a;
} else if (!(type.t & VT_ARRAY)) {
/* not lvalue if array */

12
tccpe.c
View File

@ -691,6 +691,10 @@ static int pe_write(struct pe_info *pe)
psh->PointerToRawData = file_offset;
file_offset = pe_file_align(pe, file_offset + si->data_size);
psh->SizeOfRawData = file_offset - psh->PointerToRawData;
if (si->cls == sec_text)
pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
else
pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
}
}
@ -753,7 +757,7 @@ static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
}
p = tcc_mallocz(sizeof *p);
p->dll_index = dll_index;
dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
dynarray_add(&pe->imp_info, &pe->imp_count, p);
found_dll:
i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index);
@ -761,7 +765,7 @@ found_dll:
return p->symbols[i];
s = tcc_mallocz(sizeof *s);
dynarray_add((void***)&p->symbols, &p->sym_count, s);
dynarray_add(&p->symbols, &p->sym_count, s);
s->sym_index = sym_index;
return s;
}
@ -904,7 +908,7 @@ static void pe_build_exports(struct pe_info *pe)
p = tcc_malloc(sizeof *p);
p->index = sym_index;
p->name = name;
dynarray_add((void***)&sorted, &sym_count, p);
dynarray_add(&sorted, &sym_count, p);
}
#if 0
if (sym->st_other & ST_PE_EXPORT)
@ -1515,7 +1519,7 @@ static int add_dllref(TCCState *s1, const char *dllname)
return i + 1;
dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
strcpy(dllref->name, dllname);
dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
return s1->nb_loaded_dlls;
}

View File

@ -1566,7 +1566,7 @@ static CachedInclude *search_cached_include(TCCState *s1, const char *filename,
e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
strcpy(e->filename, filename);
e->ifndef_macro = e->once = 0;
dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
/* add in hash table */
e->hash_next = s1->cached_includes_hash[h];
s1->cached_includes_hash[h] = s1->nb_cached_includes;
@ -1665,7 +1665,7 @@ static void pragma_parse(TCCState *s1)
if (tok != TOK_STR)
goto pragma_err;
file = tcc_strdup((char *)tokc.str.data);
dynarray_add((void ***)&s1->pragma_libs, &s1->nb_pragma_libs, file);
dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, file);
next();
if (tok != ')')
goto pragma_err;
@ -1820,7 +1820,7 @@ ST_FUNC void preprocess(int is_bof)
printf("%s: including %s\n", file->prev->filename, file->filename);
#endif
/* update target deps */
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(buf1));
/* push current file in stack */
++s1->include_stack_ptr;

View File

@ -224,7 +224,7 @@ static int is64_type(int t)
}
/* instruction + 4 bytes data. Return the address of the data */
ST_FUNC int oad(int c, int s)
static int oad(int c, int s)
{
int t;
if (nocode_wanted)