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