From 7916cf71cc5703db58b9612de145d620c342442d Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 15 Apr 2023 09:54:23 +0200 Subject: [PATCH] tcc_error_noabort(): always use this unless compiling This avoids 'exit(1)' with errors outside of compilation (nasty in particular with libtcc usage) As a sideeffect multiple errors can be seen for linker errors (such as undefined symbols, relocation errors, ...) --- arm-link.c | 6 +-- arm64-link.c | 10 ++--- c67-link.c | 2 +- i386-link.c | 6 +-- libtcc.c | 103 ++++++++++++++++++++++++++----------------------- libtcc.h | 2 +- riscv64-link.c | 20 +++++----- tcc.c | 24 ++++++------ tcc.h | 9 +++-- tcccoff.c | 3 ++ tccelf.c | 98 +++++++++++++++++++++------------------------- tccgen.c | 3 +- tccmacho.c | 3 ++ tccpe.c | 25 ++++-------- tccrun.c | 30 ++++++++------ tcctools.c | 21 +++++----- x86_64-link.c | 6 +-- 17 files changed, 190 insertions(+), 181 deletions(-) diff --git a/arm-link.c b/arm-link.c index d58e620c..242bb945 100644 --- a/arm-link.c +++ b/arm-link.c @@ -214,7 +214,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t h = x & 2; th_ko = (x & 3) && (!blx_avail || !is_call); if (th_ko || x >= 0x2000000 || x < -0x2000000) - tcc_error("can't relocate value at %x,%d",addr, type); + tcc_error_noabort("can't relocate value at %x,%d",addr, type); x >>= 2; x &= 0xffffff; /* Only reached if blx is avail and it is a call */ @@ -303,7 +303,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t - instruction must be a call (bl) or a jump to PLT */ if (!to_thumb || x >= 0x1000000 || x < -0x1000000) if (to_thumb || (val & 2) || (!is_call && !to_plt)) - tcc_error("can't relocate value at %x,%d",addr, type); + tcc_error_noabort("can't relocate value at %x,%d",addr, type); /* Compute and store final offset */ s = (x >> 24) & 1; @@ -374,7 +374,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t x = (x * 2) / 2; x += val - addr; if((x^(x>>1))&0x40000000) - tcc_error("can't relocate value at %x,%d",addr, type); + tcc_error_noabort("can't relocate value at %x,%d",addr, type); (*(int *)ptr) |= x & 0x7fffffff; } return; diff --git a/arm64-link.c b/arm64-link.c index 8c345b29..568ac1fe 100644 --- a/arm64-link.c +++ b/arm64-link.c @@ -126,7 +126,7 @@ ST_FUNC void relocate_plt(TCCState *s1) uint64_t got = s1->got->sh_addr + 16; uint64_t off = (got >> 12) - (plt >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); + tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! write32le(p + 4, (0x90000010 | // adrp x16,... (off & 0x1ffffc) << 3 | (off & 3) << 29)); @@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1) uint64_t addr = got + read64le(p); uint64_t off = (addr >> 12) - (pc >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); + tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); write32le(p, (0x90000010 | // adrp x16,... (off & 0x1ffffc) << 3 | (off & 3) << 29)); write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] @@ -239,7 +239,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_AARCH64_ADR_PREL_PG_HI21: { uint64_t off = (val >> 12) - (addr >> 12); if ((off + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); + tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); write32le(ptr, ((read32le(ptr) & 0x9f00001f) | (off & 0x1ffffc) << 3 | (off & 3) << 29)); return; @@ -272,7 +272,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t (char *) symtab_section->link->data + sym->st_name); #endif if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) - tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed" + tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed" " (val=%lx, addr=%lx)", (long)val, (long)addr); write32le(ptr, (0x14000000 | (uint32_t)(type == R_AARCH64_CALL26) << 31 | @@ -283,7 +283,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t (((s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12)); if ((off + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); + tcc_error_noabort("R_AARCH64_ADR_GOT_PAGE relocation failed"); write32le(ptr, ((read32le(ptr) & 0x9f00001f) | (off & 0x1ffffc) << 3 | (off & 3) << 29)); return; diff --git a/c67-link.c b/c67-link.c index 514689c5..8e7a8b2f 100644 --- a/c67-link.c +++ b/c67-link.c @@ -67,7 +67,7 @@ int gotplt_entry_type (int reloc_type) ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) { - tcc_error("C67 got not implemented"); + tcc_error_noabort("C67 got not implemented"); return 0; } diff --git a/i386-link.c b/i386-link.c index ee344b93..2fb14637 100644 --- a/i386-link.c +++ b/i386-link.c @@ -227,7 +227,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_386_16: if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { output_file: - tcc_error("can only produce 16-bit binary files"); + tcc_error_noabort("can only produce 16-bit binary files"); } write16le(ptr, read16le(ptr) + val); return; @@ -274,7 +274,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t add32le(ptr + 5, -x); } else - tcc_error("unexpected R_386_TLS_GD pattern"); + tcc_error_noabort("unexpected R_386_TLS_GD pattern"); } return; case R_386_TLS_LDM: @@ -297,7 +297,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); } else - tcc_error("unexpected R_386_TLS_LDM pattern"); + tcc_error_noabort("unexpected R_386_TLS_LDM pattern"); } return; case R_386_TLS_LDO_32: diff --git a/libtcc.c b/libtcc.c index de8343f5..d6576b90 100644 --- a/libtcc.c +++ b/libtcc.c @@ -250,6 +250,12 @@ ST_FUNC char *tcc_load_text(int fd) #undef malloc #undef realloc +void mem_error(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit (1); +} + #ifndef MEM_DEBUG PUB_FUNC void tcc_free(void *ptr) @@ -262,7 +268,7 @@ PUB_FUNC void *tcc_malloc(unsigned long size) void *ptr; ptr = malloc(size); if (!ptr && size) - _tcc_error("memory full (malloc)"); + mem_error("memory full (malloc)"); return ptr; } @@ -280,7 +286,7 @@ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) void *ptr1; ptr1 = realloc(ptr, size); if (!ptr1 && size) - _tcc_error("memory full (realloc)"); + mem_error("memory full (realloc)"); return ptr1; } @@ -345,7 +351,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) header = malloc(sizeof(mem_debug_header_t) + size); if (!header) - _tcc_error("memory full (malloc)"); + mem_error("memory full (malloc)"); header->magic1 = MEM_DEBUG_MAGIC1; header->magic2 = MEM_DEBUG_MAGIC2; @@ -405,7 +411,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file mem_debug_chain_update = (header == mem_debug_chain); header = realloc(header, sizeof(mem_debug_header_t) + size); if (!header) - _tcc_error("memory full (realloc)"); + mem_error("memory full (realloc)"); header->size = size; write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); if (header->next) @@ -537,12 +543,6 @@ static void error1(int mode, const char *fmt, va_list ap) TCCState *s1 = tcc_state; CString cs; - cstr_new(&cs); - - if (s1 == NULL) - /* can happen only if called from tcc_malloc(): 'out of memory' */ - goto no_file; - tcc_exit_state(s1); if (mode == ERROR_WARN) { @@ -563,6 +563,7 @@ static void error1(int mode, const char *fmt, va_list ap) return; } + cstr_new(&cs); f = NULL; if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */ /* use upper file if inline ":asm:" or token ":paste:" */ @@ -578,8 +579,6 @@ static void error1(int mode, const char *fmt, va_list ap) } else if (s1->current_filename) { cstr_printf(&cs, "%s: ", s1->current_filename); } - -no_file: if (0 == cs.size) cstr_printf(&cs, "tcc: "); cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: "); @@ -595,15 +594,10 @@ no_file: s1->error_func(s1->error_opaque, (char*)cs.data); } cstr_free(&cs); - if (s1) { - if (mode != ERROR_WARN) - s1->nb_errors++; - if (mode != ERROR_ERROR) - return; - if (s1->error_set_jmp_enabled) - longjmp(s1->error_jmp_buf, 1); - } - exit(1); + if (mode != ERROR_WARN) + s1->nb_errors++; + if (mode == ERROR_ERROR && s1->error_set_jmp_enabled) + longjmp(s1->error_jmp_buf, 1); } LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func) @@ -623,20 +617,24 @@ LIBTCCAPI void *tcc_get_error_opaque(TCCState *s) } /* error without aborting current compilation */ -PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) +PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) { va_list ap; va_start(ap, fmt); error1(ERROR_NOABORT, fmt, ap); va_end(ap); + return -1; } +#undef _tcc_error PUB_FUNC void _tcc_error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - for (;;) error1(ERROR_ERROR, fmt, ap); + error1(ERROR_ERROR, fmt, ap); + exit(1); } +#define _tcc_error use_tcc_error_noabort PUB_FUNC void _tcc_warning(const char *fmt, ...) { @@ -646,6 +644,7 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...) va_end(ap); } + /********************************************************/ /* I/O layer */ @@ -855,6 +854,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->argv, &s1->argc); cstr_free(&s1->cmdline_defs); cstr_free(&s1->cmdline_incl); + cstr_free(&s1->linker_arg); #ifdef TCC_IS_NATIVE /* free runtime memory */ tcc_run_free(s1); @@ -1218,7 +1218,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename) { if (-1 == tcc_add_library_internal(s1, "%s/%s", filename, 0, s1->crt_paths, s1->nb_crt_paths)) - tcc_error_noabort("file '%s' not found", filename); + return tcc_error_noabort("file '%s' not found", filename); return 0; } #endif @@ -1505,7 +1505,7 @@ static int tcc_set_linker(TCCState *s, const char *option) return 0; } else { err: - tcc_error("unsupported linker option '%s'", option); + return tcc_error_noabort("unsupported linker option '%s'", option); } if (ignoring) tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option); @@ -1775,7 +1775,7 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv) } /* read list file */ -static void args_parser_listfile(TCCState *s, +static int args_parser_listfile(TCCState *s, const char *filename, int optind, int *pargc, char ***pargv) { TCCState *s1 = s; @@ -1786,7 +1786,7 @@ static void args_parser_listfile(TCCState *s, fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) - tcc_error("listfile '%s' not found", filename); + return tcc_error_noabort("listfile '%s' not found", filename); p = tcc_load_text(fd); for (i = 0; i < *pargc; ++i) @@ -1798,6 +1798,7 @@ static void args_parser_listfile(TCCState *s, tcc_free(p); dynarray_reset(&s->argv, &s->argc); *pargc = s->argc = argc, *pargv = s->argv = argv; + return 0; } #if defined TCC_TARGET_MACHO @@ -1815,7 +1816,7 @@ static uint32_t parse_version(TCCState *s1, const char *version) c = strtoul(&last[1], &last, 10); } if (*last || a > 0xffff || b > 0xff || c > 0xff) - tcc_error("version a.b.c not correct: %s", version); + tcc_error_noabort("version a.b.c not correct: %s", version); return (a << 16) | (b << 8) | c; } #endif @@ -1827,17 +1828,17 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) const char *optarg, *r; const char *run = NULL; int x; - CString linker_arg; /* collect -Wl options */ int tool = 0, arg_start = 0, noaction = optind; char **argv = *pargv; int argc = *pargc; - cstr_new(&linker_arg); + cstr_reset(&s->linker_arg); while (optind < argc) { r = argv[optind]; if (r[0] == '@' && r[1] != '\0') { - args_parser_listfile(s, r + 1, optind, &argc, &argv); + if (args_parser_listfile(s, r + 1, optind, &argc, &argv)) + return -1; continue; } optind++; @@ -1851,7 +1852,8 @@ reparse: if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ args_parser_add_file(s, r, s->filetype); if (run) { - tcc_set_options(s, run); + if (tcc_set_options(s, run)) + return -1; arg_start = optind - 1; break; } @@ -1863,7 +1865,7 @@ reparse: const char *p1 = popt->name; const char *r1 = r + 1; if (p1 == NULL) - tcc_error("invalid option -- '%s'", r); + return tcc_error_noabort("invalid option -- '%s'", r); if (!strstart(p1, &r1)) continue; optarg = r1; @@ -1871,7 +1873,7 @@ reparse: if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { if (optind >= argc) arg_err: - tcc_error("argument to '%s' is missing", r); + return tcc_error_noabort("argument to '%s' is missing", r); optarg = argv[optind++]; } } else if (*r1 != '\0') @@ -1994,11 +1996,12 @@ reparse: break; case TCC_OPTION_run: #ifndef TCC_IS_NATIVE - tcc_error("-run is not available in a cross compiler"); -#endif + return tcc_error_noabort("-run is not available in a cross compiler"); +#else run = optarg; x = TCC_OUTPUT_MEMORY; goto set_output_type; +#endif case TCC_OPTION_v: do ++s->verbose; while (*optarg++ == 'v'); ++noaction; @@ -2015,7 +2018,7 @@ reparse: } else if (!strcmp(optarg, "hard")) s->float_abi = ARM_HARD_FLOAT; else - tcc_error("unsupported float abi '%s'", optarg); + return tcc_error_noabort("unsupported float abi '%s'", optarg); break; #endif case TCC_OPTION_m: @@ -2039,11 +2042,14 @@ reparse: s->rdynamic = 1; break; case TCC_OPTION_Wl: - if (linker_arg.size) - --linker_arg.size, cstr_ccat(&linker_arg, ','); - cstr_cat(&linker_arg, optarg, 0); - if (tcc_set_linker(s, linker_arg.data)) - cstr_free(&linker_arg); + if (s->linker_arg.size) + ((char*)s->linker_arg.data)[s->linker_arg.size - 1] = ','; + cstr_cat(&s->linker_arg, optarg, 0); + x = tcc_set_linker(s, s->linker_arg.data); + if (x) + cstr_reset(&s->linker_arg); + if (x < 0) + return -1; break; case TCC_OPTION_Wp: r = optarg; @@ -2124,7 +2130,7 @@ reparse: extra_action: arg_start = optind - 1; if (arg_start != noaction) - tcc_error("cannot parse %s here", r); + return tcc_error_noabort("cannot parse %s here", r); tool = x; break; default: @@ -2133,8 +2139,8 @@ unsupported_option: break; } } - if (linker_arg.size) { - r = linker_arg.data; + if (s->linker_arg.size) { + r = s->linker_arg.data; goto arg_err; } *pargc = argc - arg_start; @@ -2150,13 +2156,14 @@ unsupported_option: return OPT_HELP; } -LIBTCCAPI void tcc_set_options(TCCState *s, const char *r) +LIBTCCAPI int tcc_set_options(TCCState *s, const char *r) { char **argv = NULL; - int argc = 0; + int argc = 0, ret; args_parser_make_argv(r, &argc, &argv); - tcc_parse_args(s, &argc, &argv, 0); + ret = tcc_parse_args(s, &argc, &argv, 0); dynarray_reset(&argv, &argc); + return ret < 0 ? ret : 0; } PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) diff --git a/libtcc.h b/libtcc.h index 5ddfda9d..8450ba8b 100644 --- a/libtcc.h +++ b/libtcc.h @@ -34,7 +34,7 @@ LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s); LIBTCCAPI void *tcc_get_error_opaque(TCCState *s); /* set options as from command line (multiple supported) */ -LIBTCCAPI void tcc_set_options(TCCState *s, const char *str); +LIBTCCAPI int tcc_set_options(TCCState *s, const char *str); /*****************************/ /* preprocessor */ diff --git a/riscv64-link.c b/riscv64-link.c index ba608c63..34bfeb04 100644 --- a/riscv64-link.c +++ b/riscv64-link.c @@ -127,7 +127,7 @@ ST_FUNC void relocate_plt(TCCState *s1) uint64_t got = s1->got->sh_addr; uint64_t off = (got - plt + 0x800) >> 12; if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); + tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got) write32le(p + 4, 0x41c30333); // sub t1, t1, t3 write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2) @@ -144,7 +144,7 @@ ST_FUNC void relocate_plt(TCCState *s1) uint64_t addr = got + read64le(p); uint64_t off = (addr - pc + 0x800) >> 12; if ((off + ((uint32_t)1 << 20)) >> 21) - tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); + tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got) write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3) | (((addr - pc) & 0xfff) << 20)); @@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, case R_RISCV_BRANCH: off64 = val - addr; if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe) - tcc_error("R_RISCV_BRANCH relocation failed" + tcc_error_noabort("R_RISCV_BRANCH relocation failed" " (val=%lx, addr=%lx)", (long)val, (long)addr); off32 = off64 >> 1; write32le(ptr, (read32le(ptr) & ~0xfe000f80) @@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, case R_RISCV_JAL: off64 = val - addr; if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2)) - tcc_error("R_RISCV_JAL relocation failed" + tcc_error_noabort("R_RISCV_JAL relocation failed" " (val=%lx, addr=%lx)", (long)val, (long)addr); off32 = off64; write32le(ptr, (read32le(ptr) & 0xfff) @@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, #endif off64 = (int64_t)(val - addr + 0x800) >> 12; if ((off64 + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", + tcc_error_noabort("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21), symtab_section->link->data + sym->st_name); write32le(ptr, (read32le(ptr) & 0xfff) @@ -225,7 +225,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset; off64 = (int64_t)(val - addr + 0x800) >> 12; if ((off64 + ((uint64_t)1 << 20)) >> 21) - tcc_error("R_RISCV_GOT_HI20 relocation failed"); + tcc_error_noabort("R_RISCV_GOT_HI20 relocation failed"); last_hi.addr = addr; last_hi.val = val; write32le(ptr, (read32le(ptr) & 0xfff) @@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr); #endif if (val != last_hi.addr) - tcc_error("unsupported hi/lo pcrel reloc scheme"); + tcc_error_noabort("unsupported hi/lo pcrel reloc scheme"); val = last_hi.val; addr = last_hi.addr; write32le(ptr, (read32le(ptr) & 0xfffff) @@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, return; case R_RISCV_PCREL_LO12_S: if (val != last_hi.addr) - tcc_error("unsupported hi/lo pcrel reloc scheme"); + tcc_error_noabort("unsupported hi/lo pcrel reloc scheme"); val = last_hi.val; addr = last_hi.addr; off32 = val - addr; @@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, case R_RISCV_RVC_BRANCH: off64 = (val - addr); if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe) - tcc_error("R_RISCV_RVC_BRANCH relocation failed" + tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed" " (val=%lx, addr=%lx)", (long)val, (long)addr); off32 = off64; write16le(ptr, (read16le(ptr) & 0xe383) @@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, case R_RISCV_RVC_JUMP: off64 = (val - addr); if ((off64 + (1 << 11)) & ~(uint64_t)0xffe) - tcc_error("R_RISCV_RVC_BRANCH relocation failed" + tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed" " (val=%lx, addr=%lx)", (long)val, (long)addr); off32 = off64; write16le(ptr, (read16le(ptr) & 0xe003) diff --git a/tcc.c b/tcc.c index 563662d0..5a7b76f6 100644 --- a/tcc.c +++ b/tcc.c @@ -286,6 +286,8 @@ redo: tcc_set_options(s, CONFIG_TCC_SWITCHES); #endif opt = tcc_parse_args(s, &argc, &argv, 1); + if (opt < 0) + return 1; if (n == 0) { if (opt == OPT_HELP) { @@ -299,7 +301,7 @@ redo: return 0; } if (opt == OPT_M32 || opt == OPT_M64) - tcc_tool_cross(s, argv, opt); /* never returns */ + return tcc_tool_cross(s, argv, opt); if (s->verbose) printf(version); if (opt == OPT_AR) @@ -318,22 +320,22 @@ redo: return 0; } - if (s->nb_files == 0) - tcc_error("no input files"); - - if (s->output_type == TCC_OUTPUT_PREPROCESS) { + if (s->nb_files == 0) { + tcc_error_noabort("no input files"); + } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { if (s->outfile && 0!=strcmp("-",s->outfile)) { ppfp = fopen(s->outfile, "w"); if (!ppfp) - tcc_error("could not write '%s'", s->outfile); + tcc_error_noabort("could not write '%s'", s->outfile); } } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { if (s->nb_libraries) - tcc_error("cannot specify libraries with -c"); - if (s->nb_files > 1 && s->outfile) - tcc_error("cannot specify output file with -c many files"); + tcc_error_noabort("cannot specify libraries with -c"); + else if (s->nb_files > 1 && s->outfile) + tcc_error_noabort("cannot specify output file with -c many files"); } - + if (s->nb_errors) + return 1; if (s->do_bench) start_time = getclock_ms(); } @@ -391,7 +393,7 @@ redo: if (!s->just_deps && tcc_output_file(s, s->outfile)) ret = 1; else if (s->gen_deps) - gen_makedeps(s, s->outfile, s->deps_outfile); + ret = gen_makedeps(s, s->outfile, s->deps_outfile); } } diff --git a/tcc.h b/tcc.h index 97024647..75ebfbca 100644 --- a/tcc.h +++ b/tcc.h @@ -1021,6 +1021,7 @@ struct TCCState { char *deps_outfile; /* option -MF */ int argc; char **argv; + CString linker_arg; /* collect -Wl options */ }; struct filespec { @@ -1239,7 +1240,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); #define realloc(p, s) use_tcc_realloc(p, s) #undef strdup #define strdup(s) use_tcc_strdup(s) -PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2); +PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2); PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2); PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2); #define tcc_internal_error(msg) tcc_error("internal compiler error\n"\ @@ -1787,8 +1788,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv); #ifdef TCC_TARGET_PE ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv); #endif -ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option); -ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename); +ST_FUNC int tcc_tool_cross(TCCState *s, char **argv, int option); +ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename); #endif /* ------------ tccdbg.c ------------ */ @@ -1915,7 +1916,9 @@ PUB_FUNC void tcc_exit_state(TCCState *s1); # define TCC_STATE_VAR(sym) tcc_state->sym # define TCC_SET_STATE(fn) fn # undef USING_GLOBALS +# undef _tcc_error #else # define TCC_STATE_VAR(sym) s1->sym # define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn) +# define _tcc_error use_tcc_error_noabort #endif diff --git a/tcccoff.c b/tcccoff.c index 651bbe82..56064cdd 100644 --- a/tcccoff.c +++ b/tcccoff.c @@ -21,6 +21,9 @@ #include "tcc.h" +/* XXX: this file uses tcc_error() to the effect of exit(1) */ +#undef _tcc_error + #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */ #define MAX_STR_TABLE 1000000 AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */ diff --git a/tccelf.c b/tccelf.c index ec317b31..b46ad4ca 100644 --- a/tccelf.c +++ b/tccelf.c @@ -506,7 +506,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index]; if (!sym_index || sym->st_shndx == SHN_UNDEF) { if (err) - tcc_error("%s not defined", name); + tcc_error_noabort("%s not defined", name); return (addr_t)-1; } return sym->st_value; @@ -759,7 +759,7 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, rel->r_addend = addend; #endif if (SHT_RELX != SHT_RELA && addend) - tcc_error("non-zero addend on REL architecture"); + tcc_error_noabort("non-zero addend on REL architecture"); } ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, @@ -953,7 +953,7 @@ static void update_gnu_hash(TCCState *s1, Section *gnu_hash) PTR_SIZE * bloom_size + nbuckets * 4 + (nb_syms - (q - new_syms)) * 4) - tcc_error ("gnu_hash size incorrect"); + tcc_error_noabort ("gnu_hash size incorrect"); /* find buckets */ for(i = 0; i < nbuckets; i++) @@ -1364,8 +1364,10 @@ redo: for_each_elem(s, 0, rel, ElfW_Rel) { type = ELFW(R_TYPE)(rel->r_info); gotplt_entry = gotplt_entry_type(type); - if (gotplt_entry == -1) - tcc_error ("Unknown relocation type for got: %d", type); + if (gotplt_entry == -1) { + tcc_error_noabort ("Unknown relocation type for got: %d", type); + continue; + } sym_index = ELFW(R_SYM)(rel->r_info); sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; @@ -1430,8 +1432,10 @@ redo: } #endif reloc_type = code_reloc(type); - if (reloc_type == -1) - tcc_error ("Unknown relocation type: %d", type); + if (reloc_type == -1) { + tcc_error_noabort ("Unknown relocation type: %d", type); + continue; + } if (reloc_type != 0) { jmp_slot: @@ -1862,7 +1866,7 @@ static void fill_local_got_entries(TCCState *s1) struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); unsigned offset = attr->got_offset; if (offset != rel->r_offset - s1->got->sh_addr) - tcc_error_noabort("huh"); + tcc_error_noabort("fill_local_got_entries: huh?"); rel->r_info = ELFW(R_INFO)(0, R_RELATIVE); #if SHT_RELX == SHT_RELA rel->r_addend = sym->st_value; @@ -2448,7 +2452,7 @@ static int tidy_section_headers(TCCState *s1, int *sec_order); /* Create an ELF file on disk. This function handle ELF specific layout requirements */ -static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, +static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, int file_offset, int *sec_order) { int i, shnum, offset, size, file_type; @@ -2507,6 +2511,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0); if (ehdr.e_entry == (addr_t)-1) ehdr.e_entry = text_section->sh_addr; + if (s1->nb_errors) + return -1; } ehdr.e_machine = EM_TCC_TARGET; @@ -2563,9 +2569,10 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, } fwrite(sh, 1, sizeof(ElfW(Shdr)), f); } + return 0; } -static void tcc_output_binary(TCCState *s1, FILE *f, +static int tcc_output_binary(TCCState *s1, FILE *f, const int *sec_order) { Section *s; @@ -2585,13 +2592,14 @@ static void tcc_output_binary(TCCState *s1, FILE *f, offset += size; } } + return 0; } /* Write an elf, coff or "binary" file */ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, ElfW(Phdr) *phdr, int file_offset, int *sec_order) { - int fd, mode, file_type; + int fd, mode, file_type, ret; FILE *f; file_type = s1->output_type; @@ -2601,25 +2609,22 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, mode = 0777; unlink(filename); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); - if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) { - tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno)); - return -1; - } + if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) + return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno)); if (s1->verbose) printf("<- %s\n", filename); - #ifdef TCC_TARGET_COFF if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) tcc_output_coff(s1, f); else #endif if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) - tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); + ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); else - tcc_output_binary(s1, f, sec_order); + ret = tcc_output_binary(s1, f, sec_order); fclose(f); - return 0; + return ret; } #ifndef ELF_OBJ_ONLY @@ -3016,13 +3021,12 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, lseek(fd, file_offset, SEEK_SET); if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL) - goto fail1; + goto invalid; /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || ehdr.e_machine != EM_TCC_TARGET) { - fail1: - tcc_error_noabort("invalid object file"); - return -1; +invalid: + return tcc_error_noabort("invalid object file"); } /* read sections */ shdr = load_data(fd, file_offset + ehdr.e_shoff, @@ -3040,14 +3044,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, nb_syms = 0; seencompressed = 0; stab_index = stabstr_index = 0; + ret = -1; for(i = 1; i < ehdr.e_shnum; i++) { sh = &shdr[i]; if (sh->sh_type == SHT_SYMTAB) { if (symtab) { tcc_error_noabort("object must contain only one symtab"); - fail: - ret = -1; goto the_end; } nb_syms = sh->sh_size / sizeof(ElfW(Sym)); @@ -3124,14 +3127,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, s->sh_entsize = sh->sh_entsize; sm_table[i].new_section = 1; found: - if (sh->sh_type != s->sh_type) { + if (sh->sh_type != s->sh_type #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD - if (strcmp (s->name, ".eh_frame")) + && strcmp (s->name, ".eh_frame") #endif - { - tcc_error_noabort("invalid section type"); - goto fail; - } + ) { + tcc_error_noabort("invalid section type"); + goto the_end; } /* align start of section */ s->data_offset += -s->data_offset & (sh->sh_addralign - 1); @@ -3255,7 +3257,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, invalid_reloc: tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", i, strsec + sh->sh_name, (int)rel->r_offset); - goto fail; + goto the_end; } rel->r_info = ELFW(R_INFO)(sym_index, type); /* offset the relocation offset */ @@ -3391,10 +3393,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte) len = read_ar_header(fd, file_offset, &hdr); if (len == 0) return 0; - if (len < 0) { - tcc_error_noabort("invalid archive"); - return -1; - } + if (len < 0) + return tcc_error_noabort("invalid archive"); file_offset += len; size = strtol(hdr.ar_size, NULL, 0); /* align to even */ @@ -3568,8 +3568,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || ehdr.e_machine != EM_TCC_TARGET) { - tcc_error_noabort("bad architecture"); - return -1; + return tcc_error_noabort("bad architecture"); } /* read sections */ @@ -3655,7 +3654,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) if (tcc_add_dllref(s1, name, -1)) continue; if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { - tcc_error_noabort("referenced dll '%s' not found", name); + ret = tcc_error_noabort("referenced dll '%s' not found", name); goto the_end; } } @@ -3830,24 +3829,21 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) s1->new_undef_sym = 0; t = ld_next(s1, filename, sizeof(filename)); if (t != '(') { - tcc_error_noabort("( expected"); - ret = -1; + ret = tcc_error_noabort("( expected"); goto lib_parse_error; } t = ld_next(s1, filename, sizeof(filename)); for(;;) { libname[0] = '\0'; if (t == LD_TOK_EOF) { - tcc_error_noabort("unexpected end of file"); - ret = -1; + ret = tcc_error_noabort("unexpected end of file"); goto lib_parse_error; } else if (t == ')') { break; } else if (t == '-') { t = ld_next(s1, filename, sizeof(filename)); if ((t != LD_TOK_NAME) || (filename[0] != 'l')) { - tcc_error_noabort("library name expected"); - ret = -1; + ret = tcc_error_noabort("library name expected"); goto lib_parse_error; } pstrcpy(libname, sizeof libname, &filename[1]); @@ -3857,8 +3853,7 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) snprintf(filename, sizeof filename, "lib%s.so", libname); } } else if (t != LD_TOK_NAME) { - tcc_error_noabort("filename expected"); - ret = -1; + ret = tcc_error_noabort("filename expected"); goto lib_parse_error; } if (!strcmp(filename, "AS_NEEDED")) { @@ -3922,15 +3917,12 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd) !strcmp(cmd, "TARGET")) { /* ignore some commands */ t = ld_next(s1, cmd, sizeof(cmd)); - if (t != '(') { - tcc_error_noabort("( expected"); - return -1; - } + if (t != '(') + return tcc_error_noabort("( expected"); for(;;) { t = ld_next(s1, filename, sizeof(filename)); if (t == LD_TOK_EOF) { - tcc_error_noabort("unexpected end of file"); - return -1; + return tcc_error_noabort("unexpected end of file"); } else if (t == ')') { break; } diff --git a/tccgen.c b/tccgen.c index b45a172b..bdbff99f 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2928,8 +2928,7 @@ redo: } goto redo; } else if (!combine_types(&combtype, vtop - 1, vtop, op)) { - tcc_error_noabort("invalid operand types for binary operation"); - vpop(); + tcc_error("invalid operand types for binary operation"); } else if (bt1 == VT_PTR || bt2 == VT_PTR) { /* at least one operand is a pointer */ /* relational op: must be both pointers */ diff --git a/tccmacho.c b/tccmacho.c index 1b730b0a..4d282ddb 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -35,6 +35,9 @@ #error Platform not supported #endif +/* XXX: this file uses tcc_error() to the effect of exit(1) */ +#undef _tcc_error + #define DEBUG_MACHO 0 #define dprintf if (DEBUG_MACHO) printf diff --git a/tccpe.c b/tccpe.c index 01969995..ab610af1 100644 --- a/tccpe.c +++ b/tccpe.c @@ -618,10 +618,8 @@ static int pe_write(struct pe_info *pe) TCCState *s1 = pe->s1; pf.op = fopen(pe->filename, "wb"); - if (NULL == pf.op) { - tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); - return -1; - } + if (NULL == pf.op) + return tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); pe->sizeofheaders = pe_file_align(pe, sizeof (struct pe_header) @@ -1337,9 +1335,8 @@ static int pe_check_symbols(struct pe_info *pe) if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) /* STB_WEAK undefined symbols are accepted */ continue; - tcc_error_noabort("undefined symbol '%s'%s", name, + ret = tcc_error_noabort("undefined symbol '%s'%s", name, imp_sym < 0 ? ", missing __declspec(dllimport)?":""); - ret = -1; } else if (pe->s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { @@ -1990,7 +1987,6 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe) ST_FUNC int pe_output_file(TCCState *s1, const char *filename) { - int ret; struct pe_info pe; memset(&pe, 0, sizeof pe); @@ -2005,9 +2001,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) pe_add_runtime(s1, &pe); resolve_common_syms(s1); pe_set_options(s1, &pe); + pe_check_symbols(&pe); - ret = pe_check_symbols(&pe); - if (ret) + if (s1->nb_errors) ; else if (filename) { pe_assign_addresses(&pe); @@ -2016,10 +2012,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) relocate_sections(s1); pe.start_addr = (DWORD) (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase); - if (s1->nb_errors) - ret = -1; - else - ret = pe_write(&pe); + if (0 == s1->nb_errors) + pe_write(&pe); dynarray_reset(&pe.sec_info, &pe.sec_count); } else { #ifdef TCC_IS_NATIVE @@ -2031,15 +2025,12 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) #endif #endif } - pe_free_imports(&pe); - #if PE_PRINT_SECTIONS if (s1->g_debug & 8) pe_print_sections(s1, "tcc.log"); #endif - return ret; + return s1->nb_errors ? -1 : 0; } /* ------------------------------------------------------------- */ - diff --git a/tccrun.c b/tccrun.c index a6a82b93..d373abca 100644 --- a/tccrun.c +++ b/tccrun.c @@ -63,7 +63,7 @@ static void rt_exit(int code); # include #endif -static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length); +static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length); static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff); #ifdef _WIN64 @@ -100,16 +100,17 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) ptr = mmap(NULL, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); /* mmap RX memory at a fixed distance */ prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0); - if (ptr == MAP_FAILED || prx == MAP_FAILED) - tcc_error("tccrun: could not map memory"); - ptr_diff = (char*)prx - (char*)ptr; close(fd); + if (ptr == MAP_FAILED || prx == MAP_FAILED) + return tcc_error_noabort("tccrun: could not map memory"); + ptr_diff = (char*)prx - (char*)ptr; //printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff); } #else ptr = tcc_malloc(size); #endif - tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */ + if (tcc_relocate_ex(s1, ptr, ptr_diff)) + return -1; dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); return 0; @@ -237,6 +238,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1); + if ((addr_t)-1 == (addr_t)prog_main) + return -1; #ifdef CONFIG_TCC_BACKTRACE memset(rc, 0, sizeof *rc); @@ -409,8 +412,10 @@ redo: #if DEBUG_RUNMEN printf("protect %d %p %04x\n", f, (void*)addr, n); #endif - if (n) - set_pages_executable(s1, f, (void*)addr, n); + if (n) { + if (set_pages_executable(s1, f, (void*)addr, n)) + return -1; + } } } @@ -440,7 +445,7 @@ redo: /* ------------------------------------------------------------- */ /* allow to run code in memory */ -static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length) +static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length) { #ifdef _WIN32 static const unsigned char protect[] = { @@ -450,7 +455,9 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon PAGE_EXECUTE_READWRITE }; DWORD old; - VirtualProtect(ptr, length, protect[mode], &old); + if (!VirtualProtect(ptr, length, protect[mode], &old)) + return -1; + return 0; #else static const unsigned char protect[] = { PROT_READ | PROT_EXEC, @@ -463,8 +470,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon end = (addr_t)ptr + length; end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); if (mprotect((void *)start, end - start, protect[mode])) - tcc_error("mprotect failed: did you mean to configure --with-selinux?"); - + return tcc_error_noabort("mprotect failed: did you mean to configure --with-selinux?"); /* XXX: BSD sometimes dump core with bad system call */ # if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64 if (mode == 0 || mode == 3) { @@ -472,7 +478,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon __clear_cache(ptr, (char *)ptr + length); } # endif - + return 0; #endif } diff --git a/tcctools.c b/tcctools.c index cc93b4c9..bef21ef6 100644 --- a/tcctools.c +++ b/tcctools.c @@ -490,9 +490,10 @@ the_end: #if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64 -ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int option) +ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option) { - tcc_error("-m%d not implemented.", option); + tcc_error_noabort("-m%d not implemented.", option); + return 1; } #else @@ -539,7 +540,7 @@ static int execvp_win32(const char *prog, char **argv) #define execvp execvp_win32 #endif /* _WIN32 */ -ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) +ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target) { char program[4096]; char *a0 = argv[0]; @@ -558,7 +559,8 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) if (strcmp(a0, program)) execvp(argv[0] = program, argv); - tcc_error("could not run '%s'", program); + tcc_error_noabort("could not run '%s'", program); + return 1; } #endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */ @@ -588,7 +590,7 @@ static char *escape_target_dep(const char *s) { return res; } -ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename) +ST_FUNC int gen_makedeps(TCCState *s1, const char *target, const char *filename) { FILE *depout; char buf[1024], *escaped_target; @@ -601,16 +603,16 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename filename = buf; } - if (s1->verbose) - printf("<- %s\n", filename); - if(!strcmp(filename, "-")) depout = fdopen(1, "w"); else /* XXX return err codes instead of error() ? */ depout = fopen(filename, "w"); if (!depout) - tcc_error("could not open '%s'", filename); + return tcc_error_noabort("could not open '%s'", filename); + if (s1->verbose) + printf("<- %s\n", filename); + fprintf(depout, "%s:", target); for (i = 0; inb_target_deps; ++i) { for (k = 0; k < i; ++k) @@ -623,6 +625,7 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename } fprintf(depout, "\n"); fclose(depout); + return 0; } /* -------------------------------------------------------------- */ diff --git a/x86_64-link.c b/x86_64-link.c index 8a840257..1b6aa092 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -251,7 +251,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t /* ignore overflow with undefined weak symbols */ if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) #endif - tcc_error("internal error: relocation failed"); + tcc_error_noabort("internal error: relocation failed"); } add32le(ptr, diff); } @@ -336,7 +336,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t add32le(ptr + 8, x); } else - tcc_error("unexpected R_X86_64_TLSGD pattern"); + tcc_error_noabort("unexpected R_X86_64_TLSGD pattern"); } break; case R_X86_64_TLSLD: @@ -356,7 +356,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t rel[1].r_info = ELFW(R_INFO)(0, R_X86_64_NONE); } else - tcc_error("unexpected R_X86_64_TLSLD pattern"); + tcc_error_noabort("unexpected R_X86_64_TLSLD pattern"); } break; case R_X86_64_DTPOFF32: