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, ...)
Unified · Split
| @@ -214,7 +214,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 213 unmodified lines | ||
| 214 | 214 | h = x & 2; |
| 215 | 215 | th_ko = (x & 3) && (!blx_avail || !is_call); |
| 216 | 216 | if (th_ko || x >= 0x2000000 || x < -0x2000000) |
| 217 | − tcc_error("can't relocate value at %x,%d",addr, type); | |
| 217 | + tcc_error_noabort("can't relocate value at %x,%d",addr, type); | |
| 218 | 218 | x >>= 2; |
| 219 | 219 | x &= 0xffffff; |
| 220 | 220 | /* 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 · 82 unmodified lines | ||
| 303 | 303 | - instruction must be a call (bl) or a jump to PLT */ |
| 304 | 304 | if (!to_thumb || x >= 0x1000000 || x < -0x1000000) |
| 305 | 305 | if (to_thumb || (val & 2) || (!is_call && !to_plt)) |
| 306 | − tcc_error("can't relocate value at %x,%d",addr, type); | |
| 306 | + tcc_error_noabort("can't relocate value at %x,%d",addr, type); | |
| 307 | 307 | |
| 308 | 308 | /* Compute and store final offset */ |
| 309 | 309 | s = (x >> 24) & 1; |
| @@ -374,7 +374,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 64 unmodified lines | ||
| 374 | 374 | x = (x * 2) / 2; |
| 375 | 375 | x += val - addr; |
| 376 | 376 | if((x^(x>>1))&0x40000000) |
| 377 | − tcc_error("can't relocate value at %x,%d",addr, type); | |
| 377 | + tcc_error_noabort("can't relocate value at %x,%d",addr, type); | |
| 378 | 378 | (*(int *)ptr) |= x & 0x7fffffff; |
| 379 | 379 | } |
| 380 | 380 | return; |
| @@ -126,7 +126,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 125 unmodified lines | ||
| 126 | 126 | uint64_t got = s1->got->sh_addr + 16; |
| 127 | 127 | uint64_t off = (got >> 12) - (plt >> 12); |
| 128 | 128 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 129 | − tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | |
| 129 | + tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | |
| 130 | 130 | write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! |
| 131 | 131 | write32le(p + 4, (0x90000010 | // adrp x16,... |
| 132 | 132 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| @@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 12 unmodified lines | ||
| 145 | 145 | uint64_t addr = got + read64le(p); |
| 146 | 146 | uint64_t off = (addr >> 12) - (pc >> 12); |
| 147 | 147 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 148 | − tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | |
| 148 | + tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | |
| 149 | 149 | write32le(p, (0x90000010 | // adrp x16,... |
| 150 | 150 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 151 | 151 | 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 · 87 unmodified lines | ||
| 239 | 239 | case R_AARCH64_ADR_PREL_PG_HI21: { |
| 240 | 240 | uint64_t off = (val >> 12) - (addr >> 12); |
| 241 | 241 | if ((off + ((uint64_t)1 << 20)) >> 21) |
| 242 | − tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); | |
| 242 | + tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); | |
| 243 | 243 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | |
| 244 | 244 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 245 | 245 | return; |
| @@ -272,7 +272,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 26 unmodified lines | ||
| 272 | 272 | (char *) symtab_section->link->data + sym->st_name); |
| 273 | 273 | #endif |
| 274 | 274 | if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) |
| 275 | − tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed" | |
| 275 | + tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed" | |
| 276 | 276 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 277 | 277 | write32le(ptr, (0x14000000 | |
| 278 | 278 | (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 · 4 unmodified lines | ||
| 283 | 283 | (((s1->got->sh_addr + |
| 284 | 284 | get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12)); |
| 285 | 285 | if ((off + ((uint64_t)1 << 20)) >> 21) |
| 286 | − tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); | |
| 286 | + tcc_error_noabort("R_AARCH64_ADR_GOT_PAGE relocation failed"); | |
| 287 | 287 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | |
| 288 | 288 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 289 | 289 | return; |
| @@ -67,7 +67,7 @@ int gotplt_entry_type (int reloc_type) · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) |
| 69 | 69 | { |
| 70 | − tcc_error("C67 got not implemented"); | |
| 70 | + tcc_error_noabort("C67 got not implemented"); | |
| 71 | 71 | return 0; |
| 72 | 72 | } |
| 73 | 73 | |
| @@ -227,7 +227,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 226 unmodified lines | ||
| 227 | 227 | case R_386_16: |
| 228 | 228 | if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { |
| 229 | 229 | output_file: |
| 230 | − tcc_error("can only produce 16-bit binary files"); | |
| 230 | + tcc_error_noabort("can only produce 16-bit binary files"); | |
| 231 | 231 | } |
| 232 | 232 | write16le(ptr, read16le(ptr) + val); |
| 233 | 233 | return; |
| @@ -274,7 +274,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 40 unmodified lines | ||
| 274 | 274 | add32le(ptr + 5, -x); |
| 275 | 275 | } |
| 276 | 276 | else |
| 277 | − tcc_error("unexpected R_386_TLS_GD pattern"); | |
| 277 | + tcc_error_noabort("unexpected R_386_TLS_GD pattern"); | |
| 278 | 278 | } |
| 279 | 279 | return; |
| 280 | 280 | case R_386_TLS_LDM: |
| @@ -297,7 +297,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 16 unmodified lines | ||
| 297 | 297 | rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); |
| 298 | 298 | } |
| 299 | 299 | else |
| 300 | − tcc_error("unexpected R_386_TLS_LDM pattern"); | |
| 300 | + tcc_error_noabort("unexpected R_386_TLS_LDM pattern"); | |
| 301 | 301 | } |
| 302 | 302 | return; |
| 303 | 303 | case R_386_TLS_LDO_32: |
| @@ -250,6 +250,12 @@ ST_FUNC char *tcc_load_text(int fd) · 249 unmodified lines | ||
| 250 | 250 | #undef malloc |
| 251 | 251 | #undef realloc |
| 252 | 252 | |
| 253 | +void mem_error(const char *msg) | |
| 254 | +{ | |
| 255 | + fprintf(stderr, "%s\n", msg); | |
| 256 | + exit (1); | |
| 257 | +} | |
| 258 | + | |
| 253 | 259 | #ifndef MEM_DEBUG |
| 254 | 260 | |
| 255 | 261 | PUB_FUNC void tcc_free(void *ptr) |
| @@ -262,7 +268,7 @@ PUB_FUNC void *tcc_malloc(unsigned long size) · 6 unmodified lines | ||
| 262 | 268 | void *ptr; |
| 263 | 269 | ptr = malloc(size); |
| 264 | 270 | if (!ptr && size) |
| 265 | − _tcc_error("memory full (malloc)"); | |
| 271 | + mem_error("memory full (malloc)"); | |
| 266 | 272 | return ptr; |
| 267 | 273 | } |
| 268 | 274 | |
| @@ -280,7 +286,7 @@ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) · 11 unmodified lines | ||
| 280 | 286 | void *ptr1; |
| 281 | 287 | ptr1 = realloc(ptr, size); |
| 282 | 288 | if (!ptr1 && size) |
| 283 | − _tcc_error("memory full (realloc)"); | |
| 289 | + mem_error("memory full (realloc)"); | |
| 284 | 290 | return ptr1; |
| 285 | 291 | } |
| 286 | 292 | |
| @@ -345,7 +351,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 58 unmodified lines | ||
| 345 | 351 | |
| 346 | 352 | header = malloc(sizeof(mem_debug_header_t) + size); |
| 347 | 353 | if (!header) |
| 348 | − _tcc_error("memory full (malloc)"); | |
| 354 | + mem_error("memory full (malloc)"); | |
| 349 | 355 | |
| 350 | 356 | header->magic1 = MEM_DEBUG_MAGIC1; |
| 351 | 357 | header->magic2 = MEM_DEBUG_MAGIC2; |
| @@ -405,7 +411,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 53 unmodified lines | ||
| 405 | 411 | mem_debug_chain_update = (header == mem_debug_chain); |
| 406 | 412 | header = realloc(header, sizeof(mem_debug_header_t) + size); |
| 407 | 413 | if (!header) |
| 408 | − _tcc_error("memory full (realloc)"); | |
| 414 | + mem_error("memory full (realloc)"); | |
| 409 | 415 | header->size = size; |
| 410 | 416 | write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); |
| 411 | 417 | if (header->next) |
| @@ -537,12 +543,6 @@ static void error1(int mode, const char *fmt, va_list ap) · 125 unmodified lines | ||
| 537 | 543 | TCCState *s1 = tcc_state; |
| 538 | 544 | CString cs; |
| 539 | 545 | |
| 540 | − cstr_new(&cs); | |
| 541 | − | |
| 542 | − if (s1 == NULL) | |
| 543 | − /* can happen only if called from tcc_malloc(): 'out of memory' */ | |
| 544 | − goto no_file; | |
| 545 | − | |
| 546 | 546 | tcc_exit_state(s1); |
| 547 | 547 | |
| 548 | 548 | if (mode == ERROR_WARN) { |
| @@ -563,6 +563,7 @@ static void error1(int mode, const char *fmt, va_list ap) · 14 unmodified lines | ||
| 563 | 563 | return; |
| 564 | 564 | } |
| 565 | 565 | |
| 566 | + cstr_new(&cs); | |
| 566 | 567 | f = NULL; |
| 567 | 568 | if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */ |
| 568 | 569 | /* use upper file if inline ":asm:" or token ":paste:" */ |
| @@ -578,8 +579,6 @@ static void error1(int mode, const char *fmt, va_list ap) · 9 unmodified lines | ||
| 578 | 579 | } else if (s1->current_filename) { |
| 579 | 580 | cstr_printf(&cs, "%s: ", s1->current_filename); |
| 580 | 581 | } |
| 581 | − | |
| 582 | −no_file: | |
| 583 | 582 | if (0 == cs.size) |
| 584 | 583 | cstr_printf(&cs, "tcc: "); |
| 585 | 584 | cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: "); |
| @@ -595,15 +594,10 @@ no_file: · 9 unmodified lines | ||
| 595 | 594 | s1->error_func(s1->error_opaque, (char*)cs.data); |
| 596 | 595 | } |
| 597 | 596 | cstr_free(&cs); |
| 598 | − if (s1) { | |
| 599 | − if (mode != ERROR_WARN) | |
| 600 | − s1->nb_errors++; | |
| 601 | − if (mode != ERROR_ERROR) | |
| 602 | − return; | |
| 603 | − if (s1->error_set_jmp_enabled) | |
| 604 | − longjmp(s1->error_jmp_buf, 1); | |
| 605 | − } | |
| 606 | − exit(1); | |
| 597 | + if (mode != ERROR_WARN) | |
| 598 | + s1->nb_errors++; | |
| 599 | + if (mode == ERROR_ERROR && s1->error_set_jmp_enabled) | |
| 600 | + longjmp(s1->error_jmp_buf, 1); | |
| 607 | 601 | } |
| 608 | 602 | |
| 609 | 603 | 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) · 13 unmodified lines | ||
| 623 | 617 | } |
| 624 | 618 | |
| 625 | 619 | /* error without aborting current compilation */ |
| 626 | −PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) | |
| 620 | +PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) | |
| 627 | 621 | { |
| 628 | 622 | va_list ap; |
| 629 | 623 | va_start(ap, fmt); |
| 630 | 624 | error1(ERROR_NOABORT, fmt, ap); |
| 631 | 625 | va_end(ap); |
| 626 | + return -1; | |
| 632 | 627 | } |
| 633 | 628 | |
| 629 | +#undef _tcc_error | |
| 634 | 630 | PUB_FUNC void _tcc_error(const char *fmt, ...) |
| 635 | 631 | { |
| 636 | 632 | va_list ap; |
| 637 | 633 | va_start(ap, fmt); |
| 638 | − for (;;) error1(ERROR_ERROR, fmt, ap); | |
| 634 | + error1(ERROR_ERROR, fmt, ap); | |
| 635 | + exit(1); | |
| 639 | 636 | } |
| 637 | +#define _tcc_error use_tcc_error_noabort | |
| 640 | 638 | |
| 641 | 639 | PUB_FUNC void _tcc_warning(const char *fmt, ...) |
| 642 | 640 | { |
| @@ -646,6 +644,7 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...) · 3 unmodified lines | ||
| 646 | 644 | va_end(ap); |
| 647 | 645 | } |
| 648 | 646 | |
| 647 | + | |
| 649 | 648 | /********************************************************/ |
| 650 | 649 | /* I/O layer */ |
| 651 | 650 | |
| @@ -855,6 +854,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 203 unmodified lines | ||
| 855 | 854 | dynarray_reset(&s1->argv, &s1->argc); |
| 856 | 855 | cstr_free(&s1->cmdline_defs); |
| 857 | 856 | cstr_free(&s1->cmdline_incl); |
| 857 | + cstr_free(&s1->linker_arg); | |
| 858 | 858 | #ifdef TCC_IS_NATIVE |
| 859 | 859 | /* free runtime memory */ |
| 860 | 860 | tcc_run_free(s1); |
| @@ -1218,7 +1218,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename) · 357 unmodified lines | ||
| 1218 | 1218 | { |
| 1219 | 1219 | if (-1 == tcc_add_library_internal(s1, "%s/%s", |
| 1220 | 1220 | filename, 0, s1->crt_paths, s1->nb_crt_paths)) |
| 1221 | − tcc_error_noabort("file '%s' not found", filename); | |
| 1221 | + return tcc_error_noabort("file '%s' not found", filename); | |
| 1222 | 1222 | return 0; |
| 1223 | 1223 | } |
| 1224 | 1224 | #endif |
| @@ -1505,7 +1505,7 @@ static int tcc_set_linker(TCCState *s, const char *option) · 280 unmodified lines | ||
| 1505 | 1505 | return 0; |
| 1506 | 1506 | } else { |
| 1507 | 1507 | err: |
| 1508 | − tcc_error("unsupported linker option '%s'", option); | |
| 1508 | + return tcc_error_noabort("unsupported linker option '%s'", option); | |
| 1509 | 1509 | } |
| 1510 | 1510 | if (ignoring) |
| 1511 | 1511 | 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) · 263 unmodified lines | ||
| 1775 | 1775 | } |
| 1776 | 1776 | |
| 1777 | 1777 | /* read list file */ |
| 1778 | −static void args_parser_listfile(TCCState *s, | |
| 1778 | +static int args_parser_listfile(TCCState *s, | |
| 1779 | 1779 | const char *filename, int optind, int *pargc, char ***pargv) |
| 1780 | 1780 | { |
| 1781 | 1781 | TCCState *s1 = s; |
| @@ -1786,7 +1786,7 @@ static void args_parser_listfile(TCCState *s, · 4 unmodified lines | ||
| 1786 | 1786 | |
| 1787 | 1787 | fd = open(filename, O_RDONLY | O_BINARY); |
| 1788 | 1788 | if (fd < 0) |
| 1789 | − tcc_error("listfile '%s' not found", filename); | |
| 1789 | + return tcc_error_noabort("listfile '%s' not found", filename); | |
| 1790 | 1790 | |
| 1791 | 1791 | p = tcc_load_text(fd); |
| 1792 | 1792 | for (i = 0; i < *pargc; ++i) |
| @@ -1798,6 +1798,7 @@ static void args_parser_listfile(TCCState *s, · 5 unmodified lines | ||
| 1798 | 1798 | tcc_free(p); |
| 1799 | 1799 | dynarray_reset(&s->argv, &s->argc); |
| 1800 | 1800 | *pargc = s->argc = argc, *pargv = s->argv = argv; |
| 1801 | + return 0; | |
| 1801 | 1802 | } |
| 1802 | 1803 | |
| 1803 | 1804 | #if defined TCC_TARGET_MACHO |
| @@ -1815,7 +1816,7 @@ static uint32_t parse_version(TCCState *s1, const char *version) · 11 unmodified lines | ||
| 1815 | 1816 | c = strtoul(&last[1], &last, 10); |
| 1816 | 1817 | } |
| 1817 | 1818 | if (*last || a > 0xffff || b > 0xff || c > 0xff) |
| 1818 | − tcc_error("version a.b.c not correct: %s", version); | |
| 1819 | + tcc_error_noabort("version a.b.c not correct: %s", version); | |
| 1819 | 1820 | return (a << 16) | (b << 8) | c; |
| 1820 | 1821 | } |
| 1821 | 1822 | #endif |
| @@ -1827,17 +1828,17 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) · 5 unmodified lines | ||
| 1827 | 1828 | const char *optarg, *r; |
| 1828 | 1829 | const char *run = NULL; |
| 1829 | 1830 | int x; |
| 1830 | − CString linker_arg; /* collect -Wl options */ | |
| 1831 | 1831 | int tool = 0, arg_start = 0, noaction = optind; |
| 1832 | 1832 | char **argv = *pargv; |
| 1833 | 1833 | int argc = *pargc; |
| 1834 | 1834 | |
| 1835 | − cstr_new(&linker_arg); | |
| 1835 | + cstr_reset(&s->linker_arg); | |
| 1836 | 1836 | |
| 1837 | 1837 | while (optind < argc) { |
| 1838 | 1838 | r = argv[optind]; |
| 1839 | 1839 | if (r[0] == '@' && r[1] != '\0') { |
| 1840 | − args_parser_listfile(s, r + 1, optind, &argc, &argv); | |
| 1840 | + if (args_parser_listfile(s, r + 1, optind, &argc, &argv)) | |
| 1841 | + return -1; | |
| 1841 | 1842 | continue; |
| 1842 | 1843 | } |
| 1843 | 1844 | optind++; |
| @@ -1851,7 +1852,8 @@ reparse: · 7 unmodified lines | ||
| 1851 | 1852 | if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ |
| 1852 | 1853 | args_parser_add_file(s, r, s->filetype); |
| 1853 | 1854 | if (run) { |
| 1854 | − tcc_set_options(s, run); | |
| 1855 | + if (tcc_set_options(s, run)) | |
| 1856 | + return -1; | |
| 1855 | 1857 | arg_start = optind - 1; |
| 1856 | 1858 | break; |
| 1857 | 1859 | } |
| @@ -1863,7 +1865,7 @@ reparse: · 5 unmodified lines | ||
| 1863 | 1865 | const char *p1 = popt->name; |
| 1864 | 1866 | const char *r1 = r + 1; |
| 1865 | 1867 | if (p1 == NULL) |
| 1866 | − tcc_error("invalid option -- '%s'", r); | |
| 1868 | + return tcc_error_noabort("invalid option -- '%s'", r); | |
| 1867 | 1869 | if (!strstart(p1, &r1)) |
| 1868 | 1870 | continue; |
| 1869 | 1871 | optarg = r1; |
| @@ -1871,7 +1873,7 @@ reparse: · 1 unmodified line | ||
| 1871 | 1873 | if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { |
| 1872 | 1874 | if (optind >= argc) |
| 1873 | 1875 | arg_err: |
| 1874 | − tcc_error("argument to '%s' is missing", r); | |
| 1876 | + return tcc_error_noabort("argument to '%s' is missing", r); | |
| 1875 | 1877 | optarg = argv[optind++]; |
| 1876 | 1878 | } |
| 1877 | 1879 | } else if (*r1 != '\0') |
| @@ -1994,11 +1996,12 @@ reparse: · 116 unmodified lines | ||
| 1994 | 1996 | break; |
| 1995 | 1997 | case TCC_OPTION_run: |
| 1996 | 1998 | #ifndef TCC_IS_NATIVE |
| 1997 | − tcc_error("-run is not available in a cross compiler"); | |
| 1998 | −#endif | |
| 1999 | + return tcc_error_noabort("-run is not available in a cross compiler"); | |
| 2000 | +#else | |
| 1999 | 2001 | run = optarg; |
| 2000 | 2002 | x = TCC_OUTPUT_MEMORY; |
| 2001 | 2003 | goto set_output_type; |
| 2004 | +#endif | |
| 2002 | 2005 | case TCC_OPTION_v: |
| 2003 | 2006 | do ++s->verbose; while (*optarg++ == 'v'); |
| 2004 | 2007 | ++noaction; |
| @@ -2015,7 +2018,7 @@ reparse: · 10 unmodified lines | ||
| 2015 | 2018 | } else if (!strcmp(optarg, "hard")) |
| 2016 | 2019 | s->float_abi = ARM_HARD_FLOAT; |
| 2017 | 2020 | else |
| 2018 | − tcc_error("unsupported float abi '%s'", optarg); | |
| 2021 | + return tcc_error_noabort("unsupported float abi '%s'", optarg); | |
| 2019 | 2022 | break; |
| 2020 | 2023 | #endif |
| 2021 | 2024 | case TCC_OPTION_m: |
| @@ -2039,11 +2042,14 @@ reparse: · 17 unmodified lines | ||
| 2039 | 2042 | s->rdynamic = 1; |
| 2040 | 2043 | break; |
| 2041 | 2044 | case TCC_OPTION_Wl: |
| 2042 | − if (linker_arg.size) | |
| 2043 | − --linker_arg.size, cstr_ccat(&linker_arg, ','); | |
| 2044 | − cstr_cat(&linker_arg, optarg, 0); | |
| 2045 | − if (tcc_set_linker(s, linker_arg.data)) | |
| 2046 | − cstr_free(&linker_arg); | |
| 2045 | + if (s->linker_arg.size) | |
| 2046 | + ((char*)s->linker_arg.data)[s->linker_arg.size - 1] = ','; | |
| 2047 | + cstr_cat(&s->linker_arg, optarg, 0); | |
| 2048 | + x = tcc_set_linker(s, s->linker_arg.data); | |
| 2049 | + if (x) | |
| 2050 | + cstr_reset(&s->linker_arg); | |
| 2051 | + if (x < 0) | |
| 2052 | + return -1; | |
| 2047 | 2053 | break; |
| 2048 | 2054 | case TCC_OPTION_Wp: |
| 2049 | 2055 | r = optarg; |
| @@ -2124,7 +2130,7 @@ reparse: · 74 unmodified lines | ||
| 2124 | 2130 | extra_action: |
| 2125 | 2131 | arg_start = optind - 1; |
| 2126 | 2132 | if (arg_start != noaction) |
| 2127 | − tcc_error("cannot parse %s here", r); | |
| 2133 | + return tcc_error_noabort("cannot parse %s here", r); | |
| 2128 | 2134 | tool = x; |
| 2129 | 2135 | break; |
| 2130 | 2136 | default: |
| @@ -2133,8 +2139,8 @@ unsupported_option: · 2 unmodified lines | ||
| 2133 | 2139 | break; |
| 2134 | 2140 | } |
| 2135 | 2141 | } |
| 2136 | − if (linker_arg.size) { | |
| 2137 | − r = linker_arg.data; | |
| 2142 | + if (s->linker_arg.size) { | |
| 2143 | + r = s->linker_arg.data; | |
| 2138 | 2144 | goto arg_err; |
| 2139 | 2145 | } |
| 2140 | 2146 | *pargc = argc - arg_start; |
| @@ -2150,13 +2156,14 @@ unsupported_option: · 9 unmodified lines | ||
| 2150 | 2156 | return OPT_HELP; |
| 2151 | 2157 | } |
| 2152 | 2158 | |
| 2153 | −LIBTCCAPI void tcc_set_options(TCCState *s, const char *r) | |
| 2159 | +LIBTCCAPI int tcc_set_options(TCCState *s, const char *r) | |
| 2154 | 2160 | { |
| 2155 | 2161 | char **argv = NULL; |
| 2156 | − int argc = 0; | |
| 2162 | + int argc = 0, ret; | |
| 2157 | 2163 | args_parser_make_argv(r, &argc, &argv); |
| 2158 | − tcc_parse_args(s, &argc, &argv, 0); | |
| 2164 | + ret = tcc_parse_args(s, &argc, &argv, 0); | |
| 2159 | 2165 | dynarray_reset(&argv, &argc); |
| 2166 | + return ret < 0 ? ret : 0; | |
| 2160 | 2167 | } |
| 2161 | 2168 | |
| 2162 | 2169 | PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) |
| @@ -34,7 +34,7 @@ LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s); · 33 unmodified lines | ||
| 34 | 34 | LIBTCCAPI void *tcc_get_error_opaque(TCCState *s); |
| 35 | 35 | |
| 36 | 36 | /* set options as from command line (multiple supported) */ |
| 37 | −LIBTCCAPI void tcc_set_options(TCCState *s, const char *str); | |
| 37 | +LIBTCCAPI int tcc_set_options(TCCState *s, const char *str); | |
| 38 | 38 | |
| 39 | 39 | /*****************************/ |
| 40 | 40 | /* preprocessor */ |
| @@ -127,7 +127,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 126 unmodified lines | ||
| 127 | 127 | uint64_t got = s1->got->sh_addr; |
| 128 | 128 | uint64_t off = (got - plt + 0x800) >> 12; |
| 129 | 129 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 130 | − tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | |
| 130 | + tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | |
| 131 | 131 | write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got) |
| 132 | 132 | write32le(p + 4, 0x41c30333); // sub t1, t1, t3 |
| 133 | 133 | write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2) |
| @@ -144,7 +144,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 10 unmodified lines | ||
| 144 | 144 | uint64_t addr = got + read64le(p); |
| 145 | 145 | uint64_t off = (addr - pc + 0x800) >> 12; |
| 146 | 146 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 147 | − tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | |
| 147 | + tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | |
| 148 | 148 | write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got) |
| 149 | 149 | write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3) |
| 150 | 150 | | (((addr - pc) & 0xfff) << 20)); |
| @@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 28 unmodified lines | ||
| 179 | 179 | case R_RISCV_BRANCH: |
| 180 | 180 | off64 = val - addr; |
| 181 | 181 | if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe) |
| 182 | − tcc_error("R_RISCV_BRANCH relocation failed" | |
| 182 | + tcc_error_noabort("R_RISCV_BRANCH relocation failed" | |
| 183 | 183 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 184 | 184 | off32 = off64 >> 1; |
| 185 | 185 | write32le(ptr, (read32le(ptr) & ~0xfe000f80) |
| @@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | ||
| 191 | 191 | case R_RISCV_JAL: |
| 192 | 192 | off64 = val - addr; |
| 193 | 193 | if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2)) |
| 194 | − tcc_error("R_RISCV_JAL relocation failed" | |
| 194 | + tcc_error_noabort("R_RISCV_JAL relocation failed" | |
| 195 | 195 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 196 | 196 | off32 = off64; |
| 197 | 197 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 15 unmodified lines | ||
| 213 | 213 | #endif |
| 214 | 214 | off64 = (int64_t)(val - addr + 0x800) >> 12; |
| 215 | 215 | if ((off64 + ((uint64_t)1 << 20)) >> 21) |
| 216 | − tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", | |
| 216 | + tcc_error_noabort("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", | |
| 217 | 217 | (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21), |
| 218 | 218 | symtab_section->link->data + sym->st_name); |
| 219 | 219 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -225,7 +225,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | ||
| 225 | 225 | val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset; |
| 226 | 226 | off64 = (int64_t)(val - addr + 0x800) >> 12; |
| 227 | 227 | if ((off64 + ((uint64_t)1 << 20)) >> 21) |
| 228 | − tcc_error("R_RISCV_GOT_HI20 relocation failed"); | |
| 228 | + tcc_error_noabort("R_RISCV_GOT_HI20 relocation failed"); | |
| 229 | 229 | last_hi.addr = addr; |
| 230 | 230 | last_hi.val = val; |
| 231 | 231 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 4 unmodified lines | ||
| 236 | 236 | printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr); |
| 237 | 237 | #endif |
| 238 | 238 | if (val != last_hi.addr) |
| 239 | − tcc_error("unsupported hi/lo pcrel reloc scheme"); | |
| 239 | + tcc_error_noabort("unsupported hi/lo pcrel reloc scheme"); | |
| 240 | 240 | val = last_hi.val; |
| 241 | 241 | addr = last_hi.addr; |
| 242 | 242 | write32le(ptr, (read32le(ptr) & 0xfffff) |
| @@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 1 unmodified line | ||
| 244 | 244 | return; |
| 245 | 245 | case R_RISCV_PCREL_LO12_S: |
| 246 | 246 | if (val != last_hi.addr) |
| 247 | − tcc_error("unsupported hi/lo pcrel reloc scheme"); | |
| 247 | + tcc_error_noabort("unsupported hi/lo pcrel reloc scheme"); | |
| 248 | 248 | val = last_hi.val; |
| 249 | 249 | addr = last_hi.addr; |
| 250 | 250 | off32 = val - addr; |
| @@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | ||
| 256 | 256 | case R_RISCV_RVC_BRANCH: |
| 257 | 257 | off64 = (val - addr); |
| 258 | 258 | if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe) |
| 259 | − tcc_error("R_RISCV_RVC_BRANCH relocation failed" | |
| 259 | + tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed" | |
| 260 | 260 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 261 | 261 | off32 = off64; |
| 262 | 262 | write16le(ptr, (read16le(ptr) & 0xe383) |
| @@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 6 unmodified lines | ||
| 269 | 269 | case R_RISCV_RVC_JUMP: |
| 270 | 270 | off64 = (val - addr); |
| 271 | 271 | if ((off64 + (1 << 11)) & ~(uint64_t)0xffe) |
| 272 | − tcc_error("R_RISCV_RVC_BRANCH relocation failed" | |
| 272 | + tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed" | |
| 273 | 273 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 274 | 274 | off32 = off64; |
| 275 | 275 | write16le(ptr, (read16le(ptr) & 0xe003) |
| @@ -286,6 +286,8 @@ redo: · 285 unmodified lines | ||
| 286 | 286 | tcc_set_options(s, CONFIG_TCC_SWITCHES); |
| 287 | 287 | #endif |
| 288 | 288 | opt = tcc_parse_args(s, &argc, &argv, 1); |
| 289 | + if (opt < 0) | |
| 290 | + return 1; | |
| 289 | 291 | |
| 290 | 292 | if (n == 0) { |
| 291 | 293 | if (opt == OPT_HELP) { |
| @@ -299,7 +301,7 @@ redo: · 7 unmodified lines | ||
| 299 | 301 | return 0; |
| 300 | 302 | } |
| 301 | 303 | if (opt == OPT_M32 || opt == OPT_M64) |
| 302 | − tcc_tool_cross(s, argv, opt); /* never returns */ | |
| 304 | + return tcc_tool_cross(s, argv, opt); | |
| 303 | 305 | if (s->verbose) |
| 304 | 306 | printf(version); |
| 305 | 307 | if (opt == OPT_AR) |
| @@ -318,22 +320,22 @@ redo: · 12 unmodified lines | ||
| 318 | 320 | return 0; |
| 319 | 321 | } |
| 320 | 322 | |
| 321 | − if (s->nb_files == 0) | |
| 322 | − tcc_error("no input files"); | |
| 323 | − | |
| 324 | − if (s->output_type == TCC_OUTPUT_PREPROCESS) { | |
| 323 | + if (s->nb_files == 0) { | |
| 324 | + tcc_error_noabort("no input files"); | |
| 325 | + } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { | |
| 325 | 326 | if (s->outfile && 0!=strcmp("-",s->outfile)) { |
| 326 | 327 | ppfp = fopen(s->outfile, "w"); |
| 327 | 328 | if (!ppfp) |
| 328 | − tcc_error("could not write '%s'", s->outfile); | |
| 329 | + tcc_error_noabort("could not write '%s'", s->outfile); | |
| 329 | 330 | } |
| 330 | 331 | } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { |
| 331 | 332 | if (s->nb_libraries) |
| 332 | − tcc_error("cannot specify libraries with -c"); | |
| 333 | − if (s->nb_files > 1 && s->outfile) | |
| 334 | − tcc_error("cannot specify output file with -c many files"); | |
| 333 | + tcc_error_noabort("cannot specify libraries with -c"); | |
| 334 | + else if (s->nb_files > 1 && s->outfile) | |
| 335 | + tcc_error_noabort("cannot specify output file with -c many files"); | |
| 335 | 336 | } |
| 336 | − | |
| 337 | + if (s->nb_errors) | |
| 338 | + return 1; | |
| 337 | 339 | if (s->do_bench) |
| 338 | 340 | start_time = getclock_ms(); |
| 339 | 341 | } |
| @@ -391,7 +393,7 @@ redo: · 51 unmodified lines | ||
| 391 | 393 | if (!s->just_deps && tcc_output_file(s, s->outfile)) |
| 392 | 394 | ret = 1; |
| 393 | 395 | else if (s->gen_deps) |
| 394 | − gen_makedeps(s, s->outfile, s->deps_outfile); | |
| 396 | + ret = gen_makedeps(s, s->outfile, s->deps_outfile); | |
| 395 | 397 | } |
| 396 | 398 | } |
| 397 | 399 | |
| @@ -1021,6 +1021,7 @@ struct TCCState { · 1020 unmodified lines | ||
| 1021 | 1021 | char *deps_outfile; /* option -MF */ |
| 1022 | 1022 | int argc; |
| 1023 | 1023 | char **argv; |
| 1024 | + CString linker_arg; /* collect -Wl options */ | |
| 1024 | 1025 | }; |
| 1025 | 1026 | |
| 1026 | 1027 | struct filespec { |
| @@ -1239,7 +1240,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); · 212 unmodified lines | ||
| 1239 | 1240 | #define realloc(p, s) use_tcc_realloc(p, s) |
| 1240 | 1241 | #undef strdup |
| 1241 | 1242 | #define strdup(s) use_tcc_strdup(s) |
| 1242 | −PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2); | |
| 1243 | +PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2); | |
| 1243 | 1244 | PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2); |
| 1244 | 1245 | PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2); |
| 1245 | 1246 | #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); · 541 unmodified lines | ||
| 1787 | 1788 | #ifdef TCC_TARGET_PE |
| 1788 | 1789 | ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv); |
| 1789 | 1790 | #endif |
| 1790 | −ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option); | |
| 1791 | −ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename); | |
| 1791 | +ST_FUNC int tcc_tool_cross(TCCState *s, char **argv, int option); | |
| 1792 | +ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename); | |
| 1792 | 1793 | #endif |
| 1793 | 1794 | |
| 1794 | 1795 | /* ------------ tccdbg.c ------------ */ |
| @@ -1915,7 +1916,9 @@ PUB_FUNC void tcc_exit_state(TCCState *s1); · 120 unmodified lines | ||
| 1915 | 1916 | # define TCC_STATE_VAR(sym) tcc_state->sym |
| 1916 | 1917 | # define TCC_SET_STATE(fn) fn |
| 1917 | 1918 | # undef USING_GLOBALS |
| 1919 | +# undef _tcc_error | |
| 1918 | 1920 | #else |
| 1919 | 1921 | # define TCC_STATE_VAR(sym) s1->sym |
| 1920 | 1922 | # define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn) |
| 1923 | +# define _tcc_error use_tcc_error_noabort | |
| 1921 | 1924 | #endif |
| @@ -21,6 +21,9 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include "tcc.h" |
| 23 | 23 | |
| 24 | +/* XXX: this file uses tcc_error() to the effect of exit(1) */ | |
| 25 | +#undef _tcc_error | |
| 26 | + | |
| 24 | 27 | #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */ |
| 25 | 28 | #define MAX_STR_TABLE 1000000 |
| 26 | 29 | AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */ |
| @@ -506,7 +506,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) · 505 unmodified lines | ||
| 506 | 506 | sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index]; |
| 507 | 507 | if (!sym_index || sym->st_shndx == SHN_UNDEF) { |
| 508 | 508 | if (err) |
| 509 | − tcc_error("%s not defined", name); | |
| 509 | + tcc_error_noabort("%s not defined", name); | |
| 510 | 510 | return (addr_t)-1; |
| 511 | 511 | } |
| 512 | 512 | return sym->st_value; |
| @@ -759,7 +759,7 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, · 246 unmodified lines | ||
| 759 | 759 | rel->r_addend = addend; |
| 760 | 760 | #endif |
| 761 | 761 | if (SHT_RELX != SHT_RELA && addend) |
| 762 | − tcc_error("non-zero addend on REL architecture"); | |
| 762 | + tcc_error_noabort("non-zero addend on REL architecture"); | |
| 763 | 763 | } |
| 764 | 764 | |
| 765 | 765 | 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) · 187 unmodified lines | ||
| 953 | 953 | PTR_SIZE * bloom_size + |
| 954 | 954 | nbuckets * 4 + |
| 955 | 955 | (nb_syms - (q - new_syms)) * 4) |
| 956 | − tcc_error ("gnu_hash size incorrect"); | |
| 956 | + tcc_error_noabort ("gnu_hash size incorrect"); | |
| 957 | 957 | |
| 958 | 958 | /* find buckets */ |
| 959 | 959 | for(i = 0; i < nbuckets; i++) |
| @@ -1364,8 +1364,10 @@ redo: · 404 unmodified lines | ||
| 1364 | 1364 | for_each_elem(s, 0, rel, ElfW_Rel) { |
| 1365 | 1365 | type = ELFW(R_TYPE)(rel->r_info); |
| 1366 | 1366 | gotplt_entry = gotplt_entry_type(type); |
| 1367 | − if (gotplt_entry == -1) | |
| 1368 | − tcc_error ("Unknown relocation type for got: %d", type); | |
| 1367 | + if (gotplt_entry == -1) { | |
| 1368 | + tcc_error_noabort ("Unknown relocation type for got: %d", type); | |
| 1369 | + continue; | |
| 1370 | + } | |
| 1369 | 1371 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 1370 | 1372 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1371 | 1373 | |
| @@ -1430,8 +1432,10 @@ redo: · 58 unmodified lines | ||
| 1430 | 1432 | } |
| 1431 | 1433 | #endif |
| 1432 | 1434 | reloc_type = code_reloc(type); |
| 1433 | − if (reloc_type == -1) | |
| 1434 | − tcc_error ("Unknown relocation type: %d", type); | |
| 1435 | + if (reloc_type == -1) { | |
| 1436 | + tcc_error_noabort ("Unknown relocation type: %d", type); | |
| 1437 | + continue; | |
| 1438 | + } | |
| 1435 | 1439 | |
| 1436 | 1440 | if (reloc_type != 0) { |
| 1437 | 1441 | jmp_slot: |
| @@ -1862,7 +1866,7 @@ static void fill_local_got_entries(TCCState *s1) · 424 unmodified lines | ||
| 1862 | 1866 | struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); |
| 1863 | 1867 | unsigned offset = attr->got_offset; |
| 1864 | 1868 | if (offset != rel->r_offset - s1->got->sh_addr) |
| 1865 | − tcc_error_noabort("huh"); | |
| 1869 | + tcc_error_noabort("fill_local_got_entries: huh?"); | |
| 1866 | 1870 | rel->r_info = ELFW(R_INFO)(0, R_RELATIVE); |
| 1867 | 1871 | #if SHT_RELX == SHT_RELA |
| 1868 | 1872 | rel->r_addend = sym->st_value; |
| @@ -2448,7 +2452,7 @@ static int tidy_section_headers(TCCState *s1, int *sec_order); · 579 unmodified lines | ||
| 2448 | 2452 | |
| 2449 | 2453 | /* Create an ELF file on disk. |
| 2450 | 2454 | This function handle ELF specific layout requirements */ |
| 2451 | −static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, | |
| 2455 | +static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, | |
| 2452 | 2456 | int file_offset, int *sec_order) |
| 2453 | 2457 | { |
| 2454 | 2458 | 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, · 52 unmodified lines | ||
| 2507 | 2511 | ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0); |
| 2508 | 2512 | if (ehdr.e_entry == (addr_t)-1) |
| 2509 | 2513 | ehdr.e_entry = text_section->sh_addr; |
| 2514 | + if (s1->nb_errors) | |
| 2515 | + return -1; | |
| 2510 | 2516 | } |
| 2511 | 2517 | |
| 2512 | 2518 | ehdr.e_machine = EM_TCC_TARGET; |
| @@ -2563,9 +2569,10 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 50 unmodified lines | ||
| 2563 | 2569 | } |
| 2564 | 2570 | fwrite(sh, 1, sizeof(ElfW(Shdr)), f); |
| 2565 | 2571 | } |
| 2572 | + return 0; | |
| 2566 | 2573 | } |
| 2567 | 2574 | |
| 2568 | −static void tcc_output_binary(TCCState *s1, FILE *f, | |
| 2575 | +static int tcc_output_binary(TCCState *s1, FILE *f, | |
| 2569 | 2576 | const int *sec_order) |
| 2570 | 2577 | { |
| 2571 | 2578 | Section *s; |
| @@ -2585,13 +2592,14 @@ static void tcc_output_binary(TCCState *s1, FILE *f, · 13 unmodified lines | ||
| 2585 | 2592 | offset += size; |
| 2586 | 2593 | } |
| 2587 | 2594 | } |
| 2595 | + return 0; | |
| 2588 | 2596 | } |
| 2589 | 2597 | |
| 2590 | 2598 | /* Write an elf, coff or "binary" file */ |
| 2591 | 2599 | static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, |
| 2592 | 2600 | ElfW(Phdr) *phdr, int file_offset, int *sec_order) |
| 2593 | 2601 | { |
| 2594 | − int fd, mode, file_type; | |
| 2602 | + int fd, mode, file_type, ret; | |
| 2595 | 2603 | FILE *f; |
| 2596 | 2604 | |
| 2597 | 2605 | file_type = s1->output_type; |
| @@ -2601,25 +2609,22 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, · 3 unmodified lines | ||
| 2601 | 2609 | mode = 0777; |
| 2602 | 2610 | unlink(filename); |
| 2603 | 2611 | fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); |
| 2604 | − if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) { | |
| 2605 | − tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno)); | |
| 2606 | − return -1; | |
| 2607 | − } | |
| 2612 | + if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) | |
| 2613 | + return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno)); | |
| 2608 | 2614 | if (s1->verbose) |
| 2609 | 2615 | printf("<- %s\n", filename); |
| 2610 | − | |
| 2611 | 2616 | #ifdef TCC_TARGET_COFF |
| 2612 | 2617 | if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) |
| 2613 | 2618 | tcc_output_coff(s1, f); |
| 2614 | 2619 | else |
| 2615 | 2620 | #endif |
| 2616 | 2621 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) |
| 2617 | − tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); | |
| 2622 | + ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); | |
| 2618 | 2623 | else |
| 2619 | − tcc_output_binary(s1, f, sec_order); | |
| 2624 | + ret = tcc_output_binary(s1, f, sec_order); | |
| 2620 | 2625 | fclose(f); |
| 2621 | 2626 | |
| 2622 | − return 0; | |
| 2627 | + return ret; | |
| 2623 | 2628 | } |
| 2624 | 2629 | |
| 2625 | 2630 | #ifndef ELF_OBJ_ONLY |
| @@ -3016,13 +3021,12 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 390 unmodified lines | ||
| 3016 | 3021 | |
| 3017 | 3022 | lseek(fd, file_offset, SEEK_SET); |
| 3018 | 3023 | if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL) |
| 3019 | − goto fail1; | |
| 3024 | + goto invalid; | |
| 3020 | 3025 | /* test CPU specific stuff */ |
| 3021 | 3026 | if (ehdr.e_ident[5] != ELFDATA2LSB || |
| 3022 | 3027 | ehdr.e_machine != EM_TCC_TARGET) { |
| 3023 | − fail1: | |
| 3024 | − tcc_error_noabort("invalid object file"); | |
| 3025 | − return -1; | |
| 3028 | +invalid: | |
| 3029 | + return tcc_error_noabort("invalid object file"); | |
| 3026 | 3030 | } |
| 3027 | 3031 | /* read sections */ |
| 3028 | 3032 | shdr = load_data(fd, file_offset + ehdr.e_shoff, |
| @@ -3040,14 +3044,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 11 unmodified lines | ||
| 3040 | 3044 | nb_syms = 0; |
| 3041 | 3045 | seencompressed = 0; |
| 3042 | 3046 | stab_index = stabstr_index = 0; |
| 3047 | + ret = -1; | |
| 3043 | 3048 | |
| 3044 | 3049 | for(i = 1; i < ehdr.e_shnum; i++) { |
| 3045 | 3050 | sh = &shdr[i]; |
| 3046 | 3051 | if (sh->sh_type == SHT_SYMTAB) { |
| 3047 | 3052 | if (symtab) { |
| 3048 | 3053 | tcc_error_noabort("object must contain only one symtab"); |
| 3049 | − fail: | |
| 3050 | − ret = -1; | |
| 3051 | 3054 | goto the_end; |
| 3052 | 3055 | } |
| 3053 | 3056 | nb_syms = sh->sh_size / sizeof(ElfW(Sym)); |
| @@ -3124,14 +3127,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 70 unmodified lines | ||
| 3124 | 3127 | s->sh_entsize = sh->sh_entsize; |
| 3125 | 3128 | sm_table[i].new_section = 1; |
| 3126 | 3129 | found: |
| 3127 | − if (sh->sh_type != s->sh_type) { | |
| 3130 | + if (sh->sh_type != s->sh_type | |
| 3128 | 3131 | #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD |
| 3129 | − if (strcmp (s->name, ".eh_frame")) | |
| 3132 | + && strcmp (s->name, ".eh_frame") | |
| 3130 | 3133 | #endif |
| 3131 | − { | |
| 3132 | − tcc_error_noabort("invalid section type"); | |
| 3133 | − goto fail; | |
| 3134 | − } | |
| 3134 | + ) { | |
| 3135 | + tcc_error_noabort("invalid section type"); | |
| 3136 | + goto the_end; | |
| 3135 | 3137 | } |
| 3136 | 3138 | /* align start of section */ |
| 3137 | 3139 | s->data_offset += -s->data_offset & (sh->sh_addralign - 1); |
| @@ -3255,7 +3257,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 117 unmodified lines | ||
| 3255 | 3257 | invalid_reloc: |
| 3256 | 3258 | tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", |
| 3257 | 3259 | i, strsec + sh->sh_name, (int)rel->r_offset); |
| 3258 | − goto fail; | |
| 3260 | + goto the_end; | |
| 3259 | 3261 | } |
| 3260 | 3262 | rel->r_info = ELFW(R_INFO)(sym_index, type); |
| 3261 | 3263 | /* offset the relocation offset */ |
| @@ -3391,10 +3393,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte) · 129 unmodified lines | ||
| 3391 | 3393 | len = read_ar_header(fd, file_offset, &hdr); |
| 3392 | 3394 | if (len == 0) |
| 3393 | 3395 | return 0; |
| 3394 | − if (len < 0) { | |
| 3395 | − tcc_error_noabort("invalid archive"); | |
| 3396 | − return -1; | |
| 3397 | − } | |
| 3396 | + if (len < 0) | |
| 3397 | + return tcc_error_noabort("invalid archive"); | |
| 3398 | 3398 | file_offset += len; |
| 3399 | 3399 | size = strtol(hdr.ar_size, NULL, 0); |
| 3400 | 3400 | /* align to even */ |
| @@ -3568,8 +3568,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 167 unmodified lines | ||
| 3568 | 3568 | /* test CPU specific stuff */ |
| 3569 | 3569 | if (ehdr.e_ident[5] != ELFDATA2LSB || |
| 3570 | 3570 | ehdr.e_machine != EM_TCC_TARGET) { |
| 3571 | − tcc_error_noabort("bad architecture"); | |
| 3572 | − return -1; | |
| 3571 | + return tcc_error_noabort("bad architecture"); | |
| 3573 | 3572 | } |
| 3574 | 3573 | |
| 3575 | 3574 | /* read sections */ |
| @@ -3655,7 +3654,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 79 unmodified lines | ||
| 3655 | 3654 | if (tcc_add_dllref(s1, name, -1)) |
| 3656 | 3655 | continue; |
| 3657 | 3656 | if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { |
| 3658 | − tcc_error_noabort("referenced dll '%s' not found", name); | |
| 3657 | + ret = tcc_error_noabort("referenced dll '%s' not found", name); | |
| 3659 | 3658 | goto the_end; |
| 3660 | 3659 | } |
| 3661 | 3660 | } |
| @@ -3830,24 +3829,21 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) · 168 unmodified lines | ||
| 3830 | 3829 | s1->new_undef_sym = 0; |
| 3831 | 3830 | t = ld_next(s1, filename, sizeof(filename)); |
| 3832 | 3831 | if (t != '(') { |
| 3833 | − tcc_error_noabort("( expected"); | |
| 3834 | − ret = -1; | |
| 3832 | + ret = tcc_error_noabort("( expected"); | |
| 3835 | 3833 | goto lib_parse_error; |
| 3836 | 3834 | } |
| 3837 | 3835 | t = ld_next(s1, filename, sizeof(filename)); |
| 3838 | 3836 | for(;;) { |
| 3839 | 3837 | libname[0] = '\0'; |
| 3840 | 3838 | if (t == LD_TOK_EOF) { |
| 3841 | − tcc_error_noabort("unexpected end of file"); | |
| 3842 | − ret = -1; | |
| 3839 | + ret = tcc_error_noabort("unexpected end of file"); | |
| 3843 | 3840 | goto lib_parse_error; |
| 3844 | 3841 | } else if (t == ')') { |
| 3845 | 3842 | break; |
| 3846 | 3843 | } else if (t == '-') { |
| 3847 | 3844 | t = ld_next(s1, filename, sizeof(filename)); |
| 3848 | 3845 | if ((t != LD_TOK_NAME) || (filename[0] != 'l')) { |
| 3849 | − tcc_error_noabort("library name expected"); | |
| 3850 | − ret = -1; | |
| 3846 | + ret = tcc_error_noabort("library name expected"); | |
| 3851 | 3847 | goto lib_parse_error; |
| 3852 | 3848 | } |
| 3853 | 3849 | pstrcpy(libname, sizeof libname, &filename[1]); |
| @@ -3857,8 +3853,7 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) · 3 unmodified lines | ||
| 3857 | 3853 | snprintf(filename, sizeof filename, "lib%s.so", libname); |
| 3858 | 3854 | } |
| 3859 | 3855 | } else if (t != LD_TOK_NAME) { |
| 3860 | − tcc_error_noabort("filename expected"); | |
| 3861 | − ret = -1; | |
| 3856 | + ret = tcc_error_noabort("filename expected"); | |
| 3862 | 3857 | goto lib_parse_error; |
| 3863 | 3858 | } |
| 3864 | 3859 | if (!strcmp(filename, "AS_NEEDED")) { |
| @@ -3922,15 +3917,12 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd) · 57 unmodified lines | ||
| 3922 | 3917 | !strcmp(cmd, "TARGET")) { |
| 3923 | 3918 | /* ignore some commands */ |
| 3924 | 3919 | t = ld_next(s1, cmd, sizeof(cmd)); |
| 3925 | − if (t != '(') { | |
| 3926 | − tcc_error_noabort("( expected"); | |
| 3927 | − return -1; | |
| 3928 | − } | |
| 3920 | + if (t != '(') | |
| 3921 | + return tcc_error_noabort("( expected"); | |
| 3929 | 3922 | for(;;) { |
| 3930 | 3923 | t = ld_next(s1, filename, sizeof(filename)); |
| 3931 | 3924 | if (t == LD_TOK_EOF) { |
| 3932 | − tcc_error_noabort("unexpected end of file"); | |
| 3933 | − return -1; | |
| 3925 | + return tcc_error_noabort("unexpected end of file"); | |
| 3934 | 3926 | } else if (t == ')') { |
| 3935 | 3927 | break; |
| 3936 | 3928 | } |
| @@ -2928,8 +2928,7 @@ redo: · 2927 unmodified lines | ||
| 2928 | 2928 | } |
| 2929 | 2929 | goto redo; |
| 2930 | 2930 | } else if (!combine_types(&combtype, vtop - 1, vtop, op)) { |
| 2931 | − tcc_error_noabort("invalid operand types for binary operation"); | |
| 2932 | − vpop(); | |
| 2931 | + tcc_error("invalid operand types for binary operation"); | |
| 2933 | 2932 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 2934 | 2933 | /* at least one operand is a pointer */ |
| 2935 | 2934 | /* relational op: must be both pointers */ |
| @@ -35,6 +35,9 @@ · 34 unmodified lines | ||
| 35 | 35 | #error Platform not supported |
| 36 | 36 | #endif |
| 37 | 37 | |
| 38 | +/* XXX: this file uses tcc_error() to the effect of exit(1) */ | |
| 39 | +#undef _tcc_error | |
| 40 | + | |
| 38 | 41 | #define DEBUG_MACHO 0 |
| 39 | 42 | #define dprintf if (DEBUG_MACHO) printf |
| 40 | 43 | |
| @@ -618,10 +618,8 @@ static int pe_write(struct pe_info *pe) · 617 unmodified lines | ||
| 618 | 618 | TCCState *s1 = pe->s1; |
| 619 | 619 | |
| 620 | 620 | pf.op = fopen(pe->filename, "wb"); |
| 621 | − if (NULL == pf.op) { | |
| 622 | − tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); | |
| 623 | − return -1; | |
| 624 | − } | |
| 621 | + if (NULL == pf.op) | |
| 622 | + return tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); | |
| 625 | 623 | |
| 626 | 624 | pe->sizeofheaders = pe_file_align(pe, |
| 627 | 625 | sizeof (struct pe_header) |
| @@ -1337,9 +1335,8 @@ static int pe_check_symbols(struct pe_info *pe) · 709 unmodified lines | ||
| 1337 | 1335 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) |
| 1338 | 1336 | /* STB_WEAK undefined symbols are accepted */ |
| 1339 | 1337 | continue; |
| 1340 | − tcc_error_noabort("undefined symbol '%s'%s", name, | |
| 1338 | + ret = tcc_error_noabort("undefined symbol '%s'%s", name, | |
| 1341 | 1339 | imp_sym < 0 ? ", missing __declspec(dllimport)?":""); |
| 1342 | − ret = -1; | |
| 1343 | 1340 | |
| 1344 | 1341 | } else if (pe->s1->rdynamic |
| 1345 | 1342 | && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| @@ -1990,7 +1987,6 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe) · 644 unmodified lines | ||
| 1990 | 1987 | |
| 1991 | 1988 | ST_FUNC int pe_output_file(TCCState *s1, const char *filename) |
| 1992 | 1989 | { |
| 1993 | − int ret; | |
| 1994 | 1990 | struct pe_info pe; |
| 1995 | 1991 | |
| 1996 | 1992 | memset(&pe, 0, sizeof pe); |
| @@ -2005,9 +2001,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 8 unmodified lines | ||
| 2005 | 2001 | pe_add_runtime(s1, &pe); |
| 2006 | 2002 | resolve_common_syms(s1); |
| 2007 | 2003 | pe_set_options(s1, &pe); |
| 2004 | + pe_check_symbols(&pe); | |
| 2008 | 2005 | |
| 2009 | − ret = pe_check_symbols(&pe); | |
| 2010 | − if (ret) | |
| 2006 | + if (s1->nb_errors) | |
| 2011 | 2007 | ; |
| 2012 | 2008 | else if (filename) { |
| 2013 | 2009 | pe_assign_addresses(&pe); |
| @@ -2016,10 +2012,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 2 unmodified lines | ||
| 2016 | 2012 | relocate_sections(s1); |
| 2017 | 2013 | pe.start_addr = (DWORD) |
| 2018 | 2014 | (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase); |
| 2019 | − if (s1->nb_errors) | |
| 2020 | − ret = -1; | |
| 2021 | − else | |
| 2022 | − ret = pe_write(&pe); | |
| 2015 | + if (0 == s1->nb_errors) | |
| 2016 | + pe_write(&pe); | |
| 2023 | 2017 | dynarray_reset(&pe.sec_info, &pe.sec_count); |
| 2024 | 2018 | } else { |
| 2025 | 2019 | #ifdef TCC_IS_NATIVE |
| @@ -2031,15 +2025,12 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 5 unmodified lines | ||
| 2031 | 2025 | #endif |
| 2032 | 2026 | #endif |
| 2033 | 2027 | } |
| 2034 | − | |
| 2035 | 2028 | pe_free_imports(&pe); |
| 2036 | − | |
| 2037 | 2029 | #if PE_PRINT_SECTIONS |
| 2038 | 2030 | if (s1->g_debug & 8) |
| 2039 | 2031 | pe_print_sections(s1, "tcc.log"); |
| 2040 | 2032 | #endif |
| 2041 | − return ret; | |
| 2033 | + return s1->nb_errors ? -1 : 0; | |
| 2042 | 2034 | } |
| 2043 | 2035 | |
| 2044 | 2036 | /* ------------------------------------------------------------- */ |
| 2045 | − | |
| @@ -63,7 +63,7 @@ static void rt_exit(int code); · 62 unmodified lines | ||
| 63 | 63 | # include <sys/mman.h> |
| 64 | 64 | #endif |
| 65 | 65 | |
| 66 | −static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length); | |
| 66 | +static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length); | |
| 67 | 67 | static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff); |
| 68 | 68 | |
| 69 | 69 | #ifdef _WIN64 |
| @@ -100,16 +100,17 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 30 unmodified lines | ||
| 100 | 100 | ptr = mmap(NULL, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); |
| 101 | 101 | /* mmap RX memory at a fixed distance */ |
| 102 | 102 | prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0); |
| 103 | + close(fd); | |
| 103 | 104 | if (ptr == MAP_FAILED || prx == MAP_FAILED) |
| 104 | − tcc_error("tccrun: could not map memory"); | |
| 105 | + return tcc_error_noabort("tccrun: could not map memory"); | |
| 105 | 106 | ptr_diff = (char*)prx - (char*)ptr; |
| 106 | − close(fd); | |
| 107 | 107 | //printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff); |
| 108 | 108 | } |
| 109 | 109 | #else |
| 110 | 110 | ptr = tcc_malloc(size); |
| 111 | 111 | #endif |
| 112 | − tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */ | |
| 112 | + if (tcc_relocate_ex(s1, ptr, ptr_diff)) | |
| 113 | + return -1; | |
| 113 | 114 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); |
| 114 | 115 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); |
| 115 | 116 | return 0; |
| @@ -237,6 +238,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 121 unmodified lines | ||
| 237 | 238 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) |
| 238 | 239 | return -1; |
| 239 | 240 | prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1); |
| 241 | + if ((addr_t)-1 == (addr_t)prog_main) | |
| 242 | + return -1; | |
| 240 | 243 | |
| 241 | 244 | #ifdef CONFIG_TCC_BACKTRACE |
| 242 | 245 | memset(rc, 0, sizeof *rc); |
| @@ -409,8 +412,10 @@ redo: · 166 unmodified lines | ||
| 409 | 412 | #if DEBUG_RUNMEN |
| 410 | 413 | printf("protect %d %p %04x\n", f, (void*)addr, n); |
| 411 | 414 | #endif |
| 412 | − if (n) | |
| 413 | − set_pages_executable(s1, f, (void*)addr, n); | |
| 415 | + if (n) { | |
| 416 | + if (set_pages_executable(s1, f, (void*)addr, n)) | |
| 417 | + return -1; | |
| 418 | + } | |
| 414 | 419 | } |
| 415 | 420 | } |
| 416 | 421 | |
| @@ -440,7 +445,7 @@ redo: · 23 unmodified lines | ||
| 440 | 445 | /* ------------------------------------------------------------- */ |
| 441 | 446 | /* allow to run code in memory */ |
| 442 | 447 | |
| 443 | −static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length) | |
| 448 | +static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length) | |
| 444 | 449 | { |
| 445 | 450 | #ifdef _WIN32 |
| 446 | 451 | static const unsigned char protect[] = { |
| @@ -450,7 +455,9 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon · 3 unmodified lines | ||
| 450 | 455 | PAGE_EXECUTE_READWRITE |
| 451 | 456 | }; |
| 452 | 457 | DWORD old; |
| 453 | − VirtualProtect(ptr, length, protect[mode], &old); | |
| 458 | + if (!VirtualProtect(ptr, length, protect[mode], &old)) | |
| 459 | + return -1; | |
| 460 | + return 0; | |
| 454 | 461 | #else |
| 455 | 462 | static const unsigned char protect[] = { |
| 456 | 463 | PROT_READ | PROT_EXEC, |
| @@ -463,8 +470,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon · 6 unmodified lines | ||
| 463 | 470 | end = (addr_t)ptr + length; |
| 464 | 471 | end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); |
| 465 | 472 | if (mprotect((void *)start, end - start, protect[mode])) |
| 466 | − tcc_error("mprotect failed: did you mean to configure --with-selinux?"); | |
| 467 | − | |
| 473 | + return tcc_error_noabort("mprotect failed: did you mean to configure --with-selinux?"); | |
| 468 | 474 | /* XXX: BSD sometimes dump core with bad system call */ |
| 469 | 475 | # if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64 |
| 470 | 476 | if (mode == 0 || mode == 3) { |
| @@ -472,7 +478,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon · 1 unmodified line | ||
| 472 | 478 | __clear_cache(ptr, (char *)ptr + length); |
| 473 | 479 | } |
| 474 | 480 | # endif |
| 475 | − | |
| 481 | + return 0; | |
| 476 | 482 | #endif |
| 477 | 483 | } |
| 478 | 484 | |
| @@ -490,9 +490,10 @@ the_end: · 489 unmodified lines | ||
| 490 | 490 | |
| 491 | 491 | #if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64 |
| 492 | 492 | |
| 493 | −ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int option) | |
| 493 | +ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option) | |
| 494 | 494 | { |
| 495 | − tcc_error("-m%d not implemented.", option); | |
| 495 | + tcc_error_noabort("-m%d not implemented.", option); | |
| 496 | + return 1; | |
| 496 | 497 | } |
| 497 | 498 | |
| 498 | 499 | #else |
| @@ -539,7 +540,7 @@ static int execvp_win32(const char *prog, char **argv) · 40 unmodified lines | ||
| 539 | 540 | #define execvp execvp_win32 |
| 540 | 541 | #endif /* _WIN32 */ |
| 541 | 542 | |
| 542 | −ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) | |
| 543 | +ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target) | |
| 543 | 544 | { |
| 544 | 545 | char program[4096]; |
| 545 | 546 | char *a0 = argv[0]; |
| @@ -558,7 +559,8 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) · 12 unmodified lines | ||
| 558 | 559 | |
| 559 | 560 | if (strcmp(a0, program)) |
| 560 | 561 | execvp(argv[0] = program, argv); |
| 561 | − tcc_error("could not run '%s'", program); | |
| 562 | + tcc_error_noabort("could not run '%s'", program); | |
| 563 | + return 1; | |
| 562 | 564 | } |
| 563 | 565 | |
| 564 | 566 | #endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */ |
| @@ -588,7 +590,7 @@ static char *escape_target_dep(const char *s) { · 23 unmodified lines | ||
| 588 | 590 | return res; |
| 589 | 591 | } |
| 590 | 592 | |
| 591 | −ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename) | |
| 593 | +ST_FUNC int gen_makedeps(TCCState *s1, const char *target, const char *filename) | |
| 592 | 594 | { |
| 593 | 595 | FILE *depout; |
| 594 | 596 | char buf[1024], *escaped_target; |
| @@ -601,16 +603,16 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename · 6 unmodified lines | ||
| 601 | 603 | filename = buf; |
| 602 | 604 | } |
| 603 | 605 | |
| 604 | − if (s1->verbose) | |
| 605 | − printf("<- %s\n", filename); | |
| 606 | − | |
| 607 | 606 | if(!strcmp(filename, "-")) |
| 608 | 607 | depout = fdopen(1, "w"); |
| 609 | 608 | else |
| 610 | 609 | /* XXX return err codes instead of error() ? */ |
| 611 | 610 | depout = fopen(filename, "w"); |
| 612 | 611 | if (!depout) |
| 613 | − tcc_error("could not open '%s'", filename); | |
| 612 | + return tcc_error_noabort("could not open '%s'", filename); | |
| 613 | + if (s1->verbose) | |
| 614 | + printf("<- %s\n", filename); | |
| 615 | + | |
| 614 | 616 | fprintf(depout, "%s:", target); |
| 615 | 617 | for (i = 0; i<s1->nb_target_deps; ++i) { |
| 616 | 618 | for (k = 0; k < i; ++k) |
| @@ -623,6 +625,7 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename · 6 unmodified lines | ||
| 623 | 625 | } |
| 624 | 626 | fprintf(depout, "\n"); |
| 625 | 627 | fclose(depout); |
| 628 | + return 0; | |
| 626 | 629 | } |
| 627 | 630 | |
| 628 | 631 | /* -------------------------------------------------------------- */ |
| @@ -251,7 +251,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 250 unmodified lines | ||
| 251 | 251 | /* ignore overflow with undefined weak symbols */ |
| 252 | 252 | if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) |
| 253 | 253 | #endif |
| 254 | − tcc_error("internal error: relocation failed"); | |
| 254 | + tcc_error_noabort("internal error: relocation failed"); | |
| 255 | 255 | } |
| 256 | 256 | add32le(ptr, diff); |
| 257 | 257 | } |
| @@ -336,7 +336,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 78 unmodified lines | ||
| 336 | 336 | add32le(ptr + 8, x); |
| 337 | 337 | } |
| 338 | 338 | else |
| 339 | − tcc_error("unexpected R_X86_64_TLSGD pattern"); | |
| 339 | + tcc_error_noabort("unexpected R_X86_64_TLSGD pattern"); | |
| 340 | 340 | } |
| 341 | 341 | break; |
| 342 | 342 | case R_X86_64_TLSLD: |
| @@ -356,7 +356,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 13 unmodified lines | ||
| 356 | 356 | rel[1].r_info = ELFW(R_INFO)(0, R_X86_64_NONE); |
| 357 | 357 | } |
| 358 | 358 | else |
| 359 | − tcc_error("unexpected R_X86_64_TLSLD pattern"); | |
| 359 | + tcc_error_noabort("unexpected R_X86_64_TLSLD pattern"); | |
| 360 | 360 | } |
| 361 | 361 | break; |
| 362 | 362 | case R_X86_64_DTPOFF32: |