From a4a20360e9df90bb8a0ed23d113ed5564882de8a Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 13 Feb 2017 18:23:43 +0100 Subject: [PATCH] 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 76cb1144ef91924c53c57ea71e6f67ce73ce1cc6 - 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 ... --- arm-gen.c | 2 +- i386-gen.c | 8 +++--- lib/alloca-arm.S | 1 - lib/alloca86.S | 4 --- lib/alloca86_64-bt.S | 4 --- lib/alloca86_64.S | 4 --- libtcc.c | 23 ++++++++-------- tcc.h | 6 ++--- tccelf.c | 15 +++++------ tccgen.c | 64 ++++++++++++++++---------------------------- tccpe.c | 12 ++++++--- tccpp.c | 6 ++--- x86_64-gen.c | 2 +- 13 files changed, 61 insertions(+), 90 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index 8fec432f..5b923fae 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -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; diff --git a/i386-gen.c b/i386-gen.c index 759f33c9..a93d5a2d 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -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) { diff --git a/lib/alloca-arm.S b/lib/alloca-arm.S index 9deae630..02c554e1 100644 --- a/lib/alloca-arm.S +++ b/lib/alloca-arm.S @@ -8,4 +8,3 @@ alloca: mov r0, sp mov pc, lr .size alloca, .-alloca - .section .note.GNU-stack,"",%progbits diff --git a/lib/alloca86.S b/lib/alloca86.S index a17e07f2..ec1e1857 100644 --- a/lib/alloca86.S +++ b/lib/alloca86.S @@ -28,8 +28,4 @@ p3: push %edx ret -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif /* ---------------------------------------------- */ diff --git a/lib/alloca86_64-bt.S b/lib/alloca86_64-bt.S index 1f196bb2..9b6c3c6f 100644 --- a/lib/alloca86_64-bt.S +++ b/lib/alloca86_64-bt.S @@ -53,8 +53,4 @@ p3: ret #endif -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif /* ---------------------------------------------- */ diff --git a/lib/alloca86_64.S b/lib/alloca86_64.S index 4a741047..e4ca15eb 100644 --- a/lib/alloca86_64.S +++ b/lib/alloca86_64.S @@ -35,8 +35,4 @@ p3: push %rdx ret -/* mark stack as nonexecutable */ -#if defined __ELF__ && defined __linux__ - .section .note.GNU-stack,"",@progbits -#endif /* ---------------------------------------------- */ diff --git a/libtcc.c b/libtcc.c index c138277e..283d5a29 100644 --- a/libtcc.c +++ b/libtcc.c @@ -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); diff --git a/tcc.h b/tcc.h index d46ab0e0..c061c79a 100644 --- a/tcc.h +++ b/tcc.h @@ -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 diff --git a/tccelf.c b/tccelf.c index e2ba5a42..ec92bdba 100644 --- a/tccelf.c +++ b/tccelf.c @@ -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)); } } } diff --git a/tccgen.c b/tccgen.c index a0284ff1..1919c3cb 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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 */ diff --git a/tccpe.c b/tccpe.c index 44a823ec..f2dee396 100644 --- a/tccpe.c +++ b/tccpe.c @@ -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; } diff --git a/tccpp.c b/tccpp.c index 8cc9510b..0a2c09b7 100644 --- a/tccpp.c +++ b/tccpp.c @@ -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; diff --git a/x86_64-gen.c b/x86_64-gen.c index 7b61b48a..9f19e78a 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -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)