History

tcc_error_noabort(): always use this unless compiling

This avoids 'exit(1)' with errors outside of compilation (nasty in particular with libtcc usage) As a sideeffect multiple errors can be seen for linker errors (such as undefined symbols, relocation errors, ...)

grischka committed 3 years ago

Commit 7916cf71 parent 19ef02417 files · +189 −180Browse files

Unified · Split

17 files
  1. arm-link.c +3 −3
  2. arm64-link.c +5 −5
  3. c67-link.c +1 −1
  4. i386-link.c +3 −3
  5. libtcc.c +55 −48
  6. libtcc.h +1 −1
  7. riscv64-link.c +10 −10
  8. tcc.c +13 −11
  9. tcc.h +6 −3
  10. tcccoff.c +3 −0
  11. tccelf.c +45 −53
  12. tccgen.c +1 −2
  13. tccmacho.c +3 −0
  14. tccpe.c +8 −17
  15. tccrun.c +17 −11
  16. tcctools.c +12 −9
  17. x86_64-link.c +3 −3
arm-link.c+3−3
@@ -214,7 +214,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 213 unmodified lines
214214 h = x & 2;
215215 th_ko = (x & 3) && (!blx_avail || !is_call);
216216 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);
218218 x >>= 2;
219219 x &= 0xffffff;
220220 /* 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
303303 - instruction must be a call (bl) or a jump to PLT */
304304 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
305305 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);
307307
308308 /* Compute and store final offset */
309309 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
374374 x = (x * 2) / 2;
375375 x += val - addr;
376376 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);
378378 (*(int *)ptr) |= x & 0x7fffffff;
379379 }
380380 return;
arm64-link.c+5−5
@@ -126,7 +126,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 125 unmodified lines
126126 uint64_t got = s1->got->sh_addr + 16;
127127 uint64_t off = (got >> 12) - (plt >> 12);
128128 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);
130130 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
131131 write32le(p + 4, (0x90000010 | // adrp x16,...
132132 (off & 0x1ffffc) << 3 | (off & 3) << 29));
@@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 12 unmodified lines
145145 uint64_t addr = got + read64le(p);
146146 uint64_t off = (addr >> 12) - (pc >> 12);
147147 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);
149149 write32le(p, (0x90000010 | // adrp x16,...
150150 (off & 0x1ffffc) << 3 | (off & 3) << 29));
151151 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
239239 case R_AARCH64_ADR_PREL_PG_HI21: {
240240 uint64_t off = (val >> 12) - (addr >> 12);
241241 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");
243243 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
244244 (off & 0x1ffffc) << 3 | (off & 3) << 29));
245245 return;
@@ -272,7 +272,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 26 unmodified lines
272272 (char *) symtab_section->link->data + sym->st_name);
273273 #endif
274274 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"
276276 " (val=%lx, addr=%lx)", (long)val, (long)addr);
277277 write32le(ptr, (0x14000000 |
278278 (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
283283 (((s1->got->sh_addr +
284284 get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
285285 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");
287287 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
288288 (off & 0x1ffffc) << 3 | (off & 3) << 29));
289289 return;
c67-link.c+1−1
@@ -67,7 +67,7 @@ int gotplt_entry_type (int reloc_type) · 66 unmodified lines
6767
6868 ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
6969 {
70− tcc_error("C67 got not implemented");
70+ tcc_error_noabort("C67 got not implemented");
7171 return 0;
7272 }
7373
i386-link.c+3−3
@@ -227,7 +227,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 226 unmodified lines
227227 case R_386_16:
228228 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
229229 output_file:
230− tcc_error("can only produce 16-bit binary files");
230+ tcc_error_noabort("can only produce 16-bit binary files");
231231 }
232232 write16le(ptr, read16le(ptr) + val);
233233 return;
@@ -274,7 +274,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 40 unmodified lines
274274 add32le(ptr + 5, -x);
275275 }
276276 else
277− tcc_error("unexpected R_386_TLS_GD pattern");
277+ tcc_error_noabort("unexpected R_386_TLS_GD pattern");
278278 }
279279 return;
280280 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
297297 rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
298298 }
299299 else
300− tcc_error("unexpected R_386_TLS_LDM pattern");
300+ tcc_error_noabort("unexpected R_386_TLS_LDM pattern");
301301 }
302302 return;
303303 case R_386_TLS_LDO_32:
libtcc.c+55−48
@@ -250,6 +250,12 @@ ST_FUNC char *tcc_load_text(int fd) · 249 unmodified lines
250250 #undef malloc
251251 #undef realloc
252252
253+void mem_error(const char *msg)
254+{
255+ fprintf(stderr, "%s\n", msg);
256+ exit (1);
257+}
258+
253259 #ifndef MEM_DEBUG
254260
255261 PUB_FUNC void tcc_free(void *ptr)
@@ -262,7 +268,7 @@ PUB_FUNC void *tcc_malloc(unsigned long size) · 6 unmodified lines
262268 void *ptr;
263269 ptr = malloc(size);
264270 if (!ptr && size)
265− _tcc_error("memory full (malloc)");
271+ mem_error("memory full (malloc)");
266272 return ptr;
267273 }
268274
@@ -280,7 +286,7 @@ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) · 11 unmodified lines
280286 void *ptr1;
281287 ptr1 = realloc(ptr, size);
282288 if (!ptr1 && size)
283− _tcc_error("memory full (realloc)");
289+ mem_error("memory full (realloc)");
284290 return ptr1;
285291 }
286292
@@ -345,7 +351,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 58 unmodified lines
345351
346352 header = malloc(sizeof(mem_debug_header_t) + size);
347353 if (!header)
348− _tcc_error("memory full (malloc)");
354+ mem_error("memory full (malloc)");
349355
350356 header->magic1 = MEM_DEBUG_MAGIC1;
351357 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
405411 mem_debug_chain_update = (header == mem_debug_chain);
406412 header = realloc(header, sizeof(mem_debug_header_t) + size);
407413 if (!header)
408− _tcc_error("memory full (realloc)");
414+ mem_error("memory full (realloc)");
409415 header->size = size;
410416 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
411417 if (header->next)
@@ -537,12 +543,6 @@ static void error1(int mode, const char *fmt, va_list ap) · 125 unmodified lines
537543 TCCState *s1 = tcc_state;
538544 CString cs;
539545
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−
546546 tcc_exit_state(s1);
547547
548548 if (mode == ERROR_WARN) {
@@ -563,6 +563,7 @@ static void error1(int mode, const char *fmt, va_list ap) · 14 unmodified lines
563563 return;
564564 }
565565
566+ cstr_new(&cs);
566567 f = NULL;
567568 if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */
568569 /* 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
578579 } else if (s1->current_filename) {
579580 cstr_printf(&cs, "%s: ", s1->current_filename);
580581 }
581−
582−no_file:
583582 if (0 == cs.size)
584583 cstr_printf(&cs, "tcc: ");
585584 cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");
@@ -595,15 +594,10 @@ no_file: · 9 unmodified lines
595594 s1->error_func(s1->error_opaque, (char*)cs.data);
596595 }
597596 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);
607601 }
608602
609603 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
623617 }
624618
625619 /* 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, ...)
627621 {
628622 va_list ap;
629623 va_start(ap, fmt);
630624 error1(ERROR_NOABORT, fmt, ap);
631625 va_end(ap);
626+ return -1;
632627 }
633628
629+#undef _tcc_error
634630 PUB_FUNC void _tcc_error(const char *fmt, ...)
635631 {
636632 va_list ap;
637633 va_start(ap, fmt);
638− for (;;) error1(ERROR_ERROR, fmt, ap);
634+ error1(ERROR_ERROR, fmt, ap);
635+ exit(1);
639636 }
637+#define _tcc_error use_tcc_error_noabort
640638
641639 PUB_FUNC void _tcc_warning(const char *fmt, ...)
642640 {
@@ -646,6 +644,7 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...) · 3 unmodified lines
646644 va_end(ap);
647645 }
648646
647+
649648 /********************************************************/
650649 /* I/O layer */
651650
@@ -855,6 +854,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 203 unmodified lines
855854 dynarray_reset(&s1->argv, &s1->argc);
856855 cstr_free(&s1->cmdline_defs);
857856 cstr_free(&s1->cmdline_incl);
857+ cstr_free(&s1->linker_arg);
858858 #ifdef TCC_IS_NATIVE
859859 /* free runtime memory */
860860 tcc_run_free(s1);
@@ -1218,7 +1218,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename) · 357 unmodified lines
12181218 {
12191219 if (-1 == tcc_add_library_internal(s1, "%s/%s",
12201220 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);
12221222 return 0;
12231223 }
12241224 #endif
@@ -1505,7 +1505,7 @@ static int tcc_set_linker(TCCState *s, const char *option) · 280 unmodified lines
15051505 return 0;
15061506 } else {
15071507 err:
1508− tcc_error("unsupported linker option '%s'", option);
1508+ return tcc_error_noabort("unsupported linker option '%s'", option);
15091509 }
15101510 if (ignoring)
15111511 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
17751775 }
17761776
17771777 /* read list file */
1778−static void args_parser_listfile(TCCState *s,
1778+static int args_parser_listfile(TCCState *s,
17791779 const char *filename, int optind, int *pargc, char ***pargv)
17801780 {
17811781 TCCState *s1 = s;
@@ -1786,7 +1786,7 @@ static void args_parser_listfile(TCCState *s, · 4 unmodified lines
17861786
17871787 fd = open(filename, O_RDONLY | O_BINARY);
17881788 if (fd < 0)
1789− tcc_error("listfile '%s' not found", filename);
1789+ return tcc_error_noabort("listfile '%s' not found", filename);
17901790
17911791 p = tcc_load_text(fd);
17921792 for (i = 0; i < *pargc; ++i)
@@ -1798,6 +1798,7 @@ static void args_parser_listfile(TCCState *s, · 5 unmodified lines
17981798 tcc_free(p);
17991799 dynarray_reset(&s->argv, &s->argc);
18001800 *pargc = s->argc = argc, *pargv = s->argv = argv;
1801+ return 0;
18011802 }
18021803
18031804 #if defined TCC_TARGET_MACHO
@@ -1815,7 +1816,7 @@ static uint32_t parse_version(TCCState *s1, const char *version) · 11 unmodified lines
18151816 c = strtoul(&last[1], &last, 10);
18161817 }
18171818 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);
18191820 return (a << 16) | (b << 8) | c;
18201821 }
18211822 #endif
@@ -1827,17 +1828,17 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) · 5 unmodified lines
18271828 const char *optarg, *r;
18281829 const char *run = NULL;
18291830 int x;
1830− CString linker_arg; /* collect -Wl options */
18311831 int tool = 0, arg_start = 0, noaction = optind;
18321832 char **argv = *pargv;
18331833 int argc = *pargc;
18341834
1835− cstr_new(&linker_arg);
1835+ cstr_reset(&s->linker_arg);
18361836
18371837 while (optind < argc) {
18381838 r = argv[optind];
18391839 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;
18411842 continue;
18421843 }
18431844 optind++;
@@ -1851,7 +1852,8 @@ reparse: · 7 unmodified lines
18511852 if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
18521853 args_parser_add_file(s, r, s->filetype);
18531854 if (run) {
1854− tcc_set_options(s, run);
1855+ if (tcc_set_options(s, run))
1856+ return -1;
18551857 arg_start = optind - 1;
18561858 break;
18571859 }
@@ -1863,7 +1865,7 @@ reparse: · 5 unmodified lines
18631865 const char *p1 = popt->name;
18641866 const char *r1 = r + 1;
18651867 if (p1 == NULL)
1866− tcc_error("invalid option -- '%s'", r);
1868+ return tcc_error_noabort("invalid option -- '%s'", r);
18671869 if (!strstart(p1, &r1))
18681870 continue;
18691871 optarg = r1;
@@ -1871,7 +1873,7 @@ reparse: · 1 unmodified line
18711873 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
18721874 if (optind >= argc)
18731875 arg_err:
1874− tcc_error("argument to '%s' is missing", r);
1876+ return tcc_error_noabort("argument to '%s' is missing", r);
18751877 optarg = argv[optind++];
18761878 }
18771879 } else if (*r1 != '\0')
@@ -1994,11 +1996,12 @@ reparse: · 116 unmodified lines
19941996 break;
19951997 case TCC_OPTION_run:
19961998 #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
19992001 run = optarg;
20002002 x = TCC_OUTPUT_MEMORY;
20012003 goto set_output_type;
2004+#endif
20022005 case TCC_OPTION_v:
20032006 do ++s->verbose; while (*optarg++ == 'v');
20042007 ++noaction;
@@ -2015,7 +2018,7 @@ reparse: · 10 unmodified lines
20152018 } else if (!strcmp(optarg, "hard"))
20162019 s->float_abi = ARM_HARD_FLOAT;
20172020 else
2018− tcc_error("unsupported float abi '%s'", optarg);
2021+ return tcc_error_noabort("unsupported float abi '%s'", optarg);
20192022 break;
20202023 #endif
20212024 case TCC_OPTION_m:
@@ -2039,11 +2042,14 @@ reparse: · 17 unmodified lines
20392042 s->rdynamic = 1;
20402043 break;
20412044 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;
20472053 break;
20482054 case TCC_OPTION_Wp:
20492055 r = optarg;
@@ -2124,7 +2130,7 @@ reparse: · 74 unmodified lines
21242130 extra_action:
21252131 arg_start = optind - 1;
21262132 if (arg_start != noaction)
2127− tcc_error("cannot parse %s here", r);
2133+ return tcc_error_noabort("cannot parse %s here", r);
21282134 tool = x;
21292135 break;
21302136 default:
@@ -2133,8 +2139,8 @@ unsupported_option: · 2 unmodified lines
21332139 break;
21342140 }
21352141 }
2136− if (linker_arg.size) {
2137− r = linker_arg.data;
2142+ if (s->linker_arg.size) {
2143+ r = s->linker_arg.data;
21382144 goto arg_err;
21392145 }
21402146 *pargc = argc - arg_start;
@@ -2150,13 +2156,14 @@ unsupported_option: · 9 unmodified lines
21502156 return OPT_HELP;
21512157 }
21522158
2153−LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
2159+LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
21542160 {
21552161 char **argv = NULL;
2156− int argc = 0;
2162+ int argc = 0, ret;
21572163 args_parser_make_argv(r, &argc, &argv);
2158− tcc_parse_args(s, &argc, &argv, 0);
2164+ ret = tcc_parse_args(s, &argc, &argv, 0);
21592165 dynarray_reset(&argv, &argc);
2166+ return ret < 0 ? ret : 0;
21602167 }
21612168
21622169 PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
libtcc.h+1−1
@@ -34,7 +34,7 @@ LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s); · 33 unmodified lines
3434 LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);
3535
3636 /* 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);
3838
3939 /*****************************/
4040 /* preprocessor */
riscv64-link.c+10−10
@@ -127,7 +127,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 126 unmodified lines
127127 uint64_t got = s1->got->sh_addr;
128128 uint64_t off = (got - plt + 0x800) >> 12;
129129 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);
131131 write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)
132132 write32le(p + 4, 0x41c30333); // sub t1, t1, t3
133133 write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)
@@ -144,7 +144,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 10 unmodified lines
144144 uint64_t addr = got + read64le(p);
145145 uint64_t off = (addr - pc + 0x800) >> 12;
146146 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);
148148 write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)
149149 write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)
150150 | (((addr - pc) & 0xfff) << 20));
@@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 28 unmodified lines
179179 case R_RISCV_BRANCH:
180180 off64 = val - addr;
181181 if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)
182− tcc_error("R_RISCV_BRANCH relocation failed"
182+ tcc_error_noabort("R_RISCV_BRANCH relocation failed"
183183 " (val=%lx, addr=%lx)", (long)val, (long)addr);
184184 off32 = off64 >> 1;
185185 write32le(ptr, (read32le(ptr) & ~0xfe000f80)
@@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
191191 case R_RISCV_JAL:
192192 off64 = val - addr;
193193 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"
195195 " (val=%lx, addr=%lx)", (long)val, (long)addr);
196196 off32 = off64;
197197 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 15 unmodified lines
213213 #endif
214214 off64 = (int64_t)(val - addr + 0x800) >> 12;
215215 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",
217217 (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),
218218 symtab_section->link->data + sym->st_name);
219219 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -225,7 +225,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
225225 val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset;
226226 off64 = (int64_t)(val - addr + 0x800) >> 12;
227227 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");
229229 last_hi.addr = addr;
230230 last_hi.val = val;
231231 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 4 unmodified lines
236236 printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);
237237 #endif
238238 if (val != last_hi.addr)
239− tcc_error("unsupported hi/lo pcrel reloc scheme");
239+ tcc_error_noabort("unsupported hi/lo pcrel reloc scheme");
240240 val = last_hi.val;
241241 addr = last_hi.addr;
242242 write32le(ptr, (read32le(ptr) & 0xfffff)
@@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 1 unmodified line
244244 return;
245245 case R_RISCV_PCREL_LO12_S:
246246 if (val != last_hi.addr)
247− tcc_error("unsupported hi/lo pcrel reloc scheme");
247+ tcc_error_noabort("unsupported hi/lo pcrel reloc scheme");
248248 val = last_hi.val;
249249 addr = last_hi.addr;
250250 off32 = val - addr;
@@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
256256 case R_RISCV_RVC_BRANCH:
257257 off64 = (val - addr);
258258 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"
260260 " (val=%lx, addr=%lx)", (long)val, (long)addr);
261261 off32 = off64;
262262 write16le(ptr, (read16le(ptr) & 0xe383)
@@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 6 unmodified lines
269269 case R_RISCV_RVC_JUMP:
270270 off64 = (val - addr);
271271 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"
273273 " (val=%lx, addr=%lx)", (long)val, (long)addr);
274274 off32 = off64;
275275 write16le(ptr, (read16le(ptr) & 0xe003)
tcc.c+13−11
@@ -286,6 +286,8 @@ redo: · 285 unmodified lines
286286 tcc_set_options(s, CONFIG_TCC_SWITCHES);
287287 #endif
288288 opt = tcc_parse_args(s, &argc, &argv, 1);
289+ if (opt < 0)
290+ return 1;
289291
290292 if (n == 0) {
291293 if (opt == OPT_HELP) {
@@ -299,7 +301,7 @@ redo: · 7 unmodified lines
299301 return 0;
300302 }
301303 if (opt == OPT_M32 || opt == OPT_M64)
302− tcc_tool_cross(s, argv, opt); /* never returns */
304+ return tcc_tool_cross(s, argv, opt);
303305 if (s->verbose)
304306 printf(version);
305307 if (opt == OPT_AR)
@@ -318,22 +320,22 @@ redo: · 12 unmodified lines
318320 return 0;
319321 }
320322
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) {
325326 if (s->outfile && 0!=strcmp("-",s->outfile)) {
326327 ppfp = fopen(s->outfile, "w");
327328 if (!ppfp)
328− tcc_error("could not write '%s'", s->outfile);
329+ tcc_error_noabort("could not write '%s'", s->outfile);
329330 }
330331 } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
331332 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");
335336 }
336−
337+ if (s->nb_errors)
338+ return 1;
337339 if (s->do_bench)
338340 start_time = getclock_ms();
339341 }
@@ -391,7 +393,7 @@ redo: · 51 unmodified lines
391393 if (!s->just_deps && tcc_output_file(s, s->outfile))
392394 ret = 1;
393395 else if (s->gen_deps)
394− gen_makedeps(s, s->outfile, s->deps_outfile);
396+ ret = gen_makedeps(s, s->outfile, s->deps_outfile);
395397 }
396398 }
397399
tcc.h+6−3
@@ -1021,6 +1021,7 @@ struct TCCState { · 1020 unmodified lines
10211021 char *deps_outfile; /* option -MF */
10221022 int argc;
10231023 char **argv;
1024+ CString linker_arg; /* collect -Wl options */
10241025 };
10251026
10261027 struct filespec {
@@ -1239,7 +1240,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); · 212 unmodified lines
12391240 #define realloc(p, s) use_tcc_realloc(p, s)
12401241 #undef strdup
12411242 #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);
12431244 PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);
12441245 PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);
12451246 #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
17871788 #ifdef TCC_TARGET_PE
17881789 ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
17891790 #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);
17921793 #endif
17931794
17941795 /* ------------ tccdbg.c ------------ */
@@ -1915,7 +1916,9 @@ PUB_FUNC void tcc_exit_state(TCCState *s1); · 120 unmodified lines
19151916 # define TCC_STATE_VAR(sym) tcc_state->sym
19161917 # define TCC_SET_STATE(fn) fn
19171918 # undef USING_GLOBALS
1919+# undef _tcc_error
19181920 #else
19191921 # define TCC_STATE_VAR(sym) s1->sym
19201922 # define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)
1923+# define _tcc_error use_tcc_error_noabort
19211924 #endif
tcccoff.c+3−0
@@ -21,6 +21,9 @@ · 20 unmodified lines
2121
2222 #include "tcc.h"
2323
24+/* XXX: this file uses tcc_error() to the effect of exit(1) */
25+#undef _tcc_error
26+
2427 #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
2528 #define MAX_STR_TABLE 1000000
2629 AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
tccelf.c+45−53
@@ -506,7 +506,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) · 505 unmodified lines
506506 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
507507 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
508508 if (err)
509− tcc_error("%s not defined", name);
509+ tcc_error_noabort("%s not defined", name);
510510 return (addr_t)-1;
511511 }
512512 return sym->st_value;
@@ -759,7 +759,7 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, · 246 unmodified lines
759759 rel->r_addend = addend;
760760 #endif
761761 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");
763763 }
764764
765765 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
953953 PTR_SIZE * bloom_size +
954954 nbuckets * 4 +
955955 (nb_syms - (q - new_syms)) * 4)
956− tcc_error ("gnu_hash size incorrect");
956+ tcc_error_noabort ("gnu_hash size incorrect");
957957
958958 /* find buckets */
959959 for(i = 0; i < nbuckets; i++)
@@ -1364,8 +1364,10 @@ redo: · 404 unmodified lines
13641364 for_each_elem(s, 0, rel, ElfW_Rel) {
13651365 type = ELFW(R_TYPE)(rel->r_info);
13661366 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+ }
13691371 sym_index = ELFW(R_SYM)(rel->r_info);
13701372 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
13711373
@@ -1430,8 +1432,10 @@ redo: · 58 unmodified lines
14301432 }
14311433 #endif
14321434 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+ }
14351439
14361440 if (reloc_type != 0) {
14371441 jmp_slot:
@@ -1862,7 +1866,7 @@ static void fill_local_got_entries(TCCState *s1) · 424 unmodified lines
18621866 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
18631867 unsigned offset = attr->got_offset;
18641868 if (offset != rel->r_offset - s1->got->sh_addr)
1865− tcc_error_noabort("huh");
1869+ tcc_error_noabort("fill_local_got_entries: huh?");
18661870 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
18671871 #if SHT_RELX == SHT_RELA
18681872 rel->r_addend = sym->st_value;
@@ -2448,7 +2452,7 @@ static int tidy_section_headers(TCCState *s1, int *sec_order); · 579 unmodified lines
24482452
24492453 /* Create an ELF file on disk.
24502454 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,
24522456 int file_offset, int *sec_order)
24532457 {
24542458 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
25072511 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
25082512 if (ehdr.e_entry == (addr_t)-1)
25092513 ehdr.e_entry = text_section->sh_addr;
2514+ if (s1->nb_errors)
2515+ return -1;
25102516 }
25112517
25122518 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
25632569 }
25642570 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
25652571 }
2572+ return 0;
25662573 }
25672574
2568−static void tcc_output_binary(TCCState *s1, FILE *f,
2575+static int tcc_output_binary(TCCState *s1, FILE *f,
25692576 const int *sec_order)
25702577 {
25712578 Section *s;
@@ -2585,13 +2592,14 @@ static void tcc_output_binary(TCCState *s1, FILE *f, · 13 unmodified lines
25852592 offset += size;
25862593 }
25872594 }
2595+ return 0;
25882596 }
25892597
25902598 /* Write an elf, coff or "binary" file */
25912599 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
25922600 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
25932601 {
2594− int fd, mode, file_type;
2602+ int fd, mode, file_type, ret;
25952603 FILE *f;
25962604
25972605 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
26012609 mode = 0777;
26022610 unlink(filename);
26032611 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));
26082614 if (s1->verbose)
26092615 printf("<- %s\n", filename);
2610−
26112616 #ifdef TCC_TARGET_COFF
26122617 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
26132618 tcc_output_coff(s1, f);
26142619 else
26152620 #endif
26162621 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);
26182623 else
2619− tcc_output_binary(s1, f, sec_order);
2624+ ret = tcc_output_binary(s1, f, sec_order);
26202625 fclose(f);
26212626
2622− return 0;
2627+ return ret;
26232628 }
26242629
26252630 #ifndef ELF_OBJ_ONLY
@@ -3016,13 +3021,12 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 390 unmodified lines
30163021
30173022 lseek(fd, file_offset, SEEK_SET);
30183023 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3019− goto fail1;
3024+ goto invalid;
30203025 /* test CPU specific stuff */
30213026 if (ehdr.e_ident[5] != ELFDATA2LSB ||
30223027 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");
30263030 }
30273031 /* read sections */
30283032 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
30403044 nb_syms = 0;
30413045 seencompressed = 0;
30423046 stab_index = stabstr_index = 0;
3047+ ret = -1;
30433048
30443049 for(i = 1; i < ehdr.e_shnum; i++) {
30453050 sh = &shdr[i];
30463051 if (sh->sh_type == SHT_SYMTAB) {
30473052 if (symtab) {
30483053 tcc_error_noabort("object must contain only one symtab");
3049− fail:
3050− ret = -1;
30513054 goto the_end;
30523055 }
30533056 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
@@ -3124,14 +3127,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 70 unmodified lines
31243127 s->sh_entsize = sh->sh_entsize;
31253128 sm_table[i].new_section = 1;
31263129 found:
3127− if (sh->sh_type != s->sh_type) {
3130+ if (sh->sh_type != s->sh_type
31283131 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3129− if (strcmp (s->name, ".eh_frame"))
3132+ && strcmp (s->name, ".eh_frame")
31303133 #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;
31353137 }
31363138 /* align start of section */
31373139 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
32553257 invalid_reloc:
32563258 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
32573259 i, strsec + sh->sh_name, (int)rel->r_offset);
3258− goto fail;
3260+ goto the_end;
32593261 }
32603262 rel->r_info = ELFW(R_INFO)(sym_index, type);
32613263 /* offset the relocation offset */
@@ -3391,10 +3393,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte) · 129 unmodified lines
33913393 len = read_ar_header(fd, file_offset, &hdr);
33923394 if (len == 0)
33933395 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");
33983398 file_offset += len;
33993399 size = strtol(hdr.ar_size, NULL, 0);
34003400 /* 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
35683568 /* test CPU specific stuff */
35693569 if (ehdr.e_ident[5] != ELFDATA2LSB ||
35703570 ehdr.e_machine != EM_TCC_TARGET) {
3571− tcc_error_noabort("bad architecture");
3572− return -1;
3571+ return tcc_error_noabort("bad architecture");
35733572 }
35743573
35753574 /* read sections */
@@ -3655,7 +3654,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 79 unmodified lines
36553654 if (tcc_add_dllref(s1, name, -1))
36563655 continue;
36573656 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);
36593658 goto the_end;
36603659 }
36613660 }
@@ -3830,24 +3829,21 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) · 168 unmodified lines
38303829 s1->new_undef_sym = 0;
38313830 t = ld_next(s1, filename, sizeof(filename));
38323831 if (t != '(') {
3833− tcc_error_noabort("( expected");
3834− ret = -1;
3832+ ret = tcc_error_noabort("( expected");
38353833 goto lib_parse_error;
38363834 }
38373835 t = ld_next(s1, filename, sizeof(filename));
38383836 for(;;) {
38393837 libname[0] = '\0';
38403838 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");
38433840 goto lib_parse_error;
38443841 } else if (t == ')') {
38453842 break;
38463843 } else if (t == '-') {
38473844 t = ld_next(s1, filename, sizeof(filename));
38483845 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");
38513847 goto lib_parse_error;
38523848 }
38533849 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
38573853 snprintf(filename, sizeof filename, "lib%s.so", libname);
38583854 }
38593855 } else if (t != LD_TOK_NAME) {
3860− tcc_error_noabort("filename expected");
3861− ret = -1;
3856+ ret = tcc_error_noabort("filename expected");
38623857 goto lib_parse_error;
38633858 }
38643859 if (!strcmp(filename, "AS_NEEDED")) {
@@ -3922,15 +3917,12 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd) · 57 unmodified lines
39223917 !strcmp(cmd, "TARGET")) {
39233918 /* ignore some commands */
39243919 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");
39293922 for(;;) {
39303923 t = ld_next(s1, filename, sizeof(filename));
39313924 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");
39343926 } else if (t == ')') {
39353927 break;
39363928 }
tccgen.c+1−2
@@ -2928,8 +2928,7 @@ redo: · 2927 unmodified lines
29282928 }
29292929 goto redo;
29302930 } 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");
29332932 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
29342933 /* at least one operand is a pointer */
29352934 /* relational op: must be both pointers */
tccmacho.c+3−0
@@ -35,6 +35,9 @@ · 34 unmodified lines
3535 #error Platform not supported
3636 #endif
3737
38+/* XXX: this file uses tcc_error() to the effect of exit(1) */
39+#undef _tcc_error
40+
3841 #define DEBUG_MACHO 0
3942 #define dprintf if (DEBUG_MACHO) printf
4043
tccpe.c+8−17
@@ -618,10 +618,8 @@ static int pe_write(struct pe_info *pe) · 617 unmodified lines
618618 TCCState *s1 = pe->s1;
619619
620620 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));
625623
626624 pe->sizeofheaders = pe_file_align(pe,
627625 sizeof (struct pe_header)
@@ -1337,9 +1335,8 @@ static int pe_check_symbols(struct pe_info *pe) · 709 unmodified lines
13371335 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
13381336 /* STB_WEAK undefined symbols are accepted */
13391337 continue;
1340− tcc_error_noabort("undefined symbol '%s'%s", name,
1338+ ret = tcc_error_noabort("undefined symbol '%s'%s", name,
13411339 imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
1342− ret = -1;
13431340
13441341 } else if (pe->s1->rdynamic
13451342 && 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
19901987
19911988 ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
19921989 {
1993− int ret;
19941990 struct pe_info pe;
19951991
19961992 memset(&pe, 0, sizeof pe);
@@ -2005,9 +2001,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 8 unmodified lines
20052001 pe_add_runtime(s1, &pe);
20062002 resolve_common_syms(s1);
20072003 pe_set_options(s1, &pe);
2004+ pe_check_symbols(&pe);
20082005
2009− ret = pe_check_symbols(&pe);
2010− if (ret)
2006+ if (s1->nb_errors)
20112007 ;
20122008 else if (filename) {
20132009 pe_assign_addresses(&pe);
@@ -2016,10 +2012,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 2 unmodified lines
20162012 relocate_sections(s1);
20172013 pe.start_addr = (DWORD)
20182014 (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);
20232017 dynarray_reset(&pe.sec_info, &pe.sec_count);
20242018 } else {
20252019 #ifdef TCC_IS_NATIVE
@@ -2031,15 +2025,12 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 5 unmodified lines
20312025 #endif
20322026 #endif
20332027 }
2034−
20352028 pe_free_imports(&pe);
2036−
20372029 #if PE_PRINT_SECTIONS
20382030 if (s1->g_debug & 8)
20392031 pe_print_sections(s1, "tcc.log");
20402032 #endif
2041− return ret;
2033+ return s1->nb_errors ? -1 : 0;
20422034 }
20432035
20442036 /* ------------------------------------------------------------- */
2045−
tccrun.c+17−11
@@ -63,7 +63,7 @@ static void rt_exit(int code); · 62 unmodified lines
6363 # include <sys/mman.h>
6464 #endif
6565
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);
6767 static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
6868
6969 #ifdef _WIN64
@@ -100,16 +100,17 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 30 unmodified lines
100100 ptr = mmap(NULL, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
101101 /* mmap RX memory at a fixed distance */
102102 prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0);
103+ close(fd);
103104 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");
105106 ptr_diff = (char*)prx - (char*)ptr;
106− close(fd);
107107 //printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff);
108108 }
109109 #else
110110 ptr = tcc_malloc(size);
111111 #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;
113114 dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
114115 dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
115116 return 0;
@@ -237,6 +238,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 121 unmodified lines
237238 if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
238239 return -1;
239240 prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1);
241+ if ((addr_t)-1 == (addr_t)prog_main)
242+ return -1;
240243
241244 #ifdef CONFIG_TCC_BACKTRACE
242245 memset(rc, 0, sizeof *rc);
@@ -409,8 +412,10 @@ redo: · 166 unmodified lines
409412 #if DEBUG_RUNMEN
410413 printf("protect %d %p %04x\n", f, (void*)addr, n);
411414 #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+ }
414419 }
415420 }
416421
@@ -440,7 +445,7 @@ redo: · 23 unmodified lines
440445 /* ------------------------------------------------------------- */
441446 /* allow to run code in memory */
442447
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)
444449 {
445450 #ifdef _WIN32
446451 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
450455 PAGE_EXECUTE_READWRITE
451456 };
452457 DWORD old;
453− VirtualProtect(ptr, length, protect[mode], &old);
458+ if (!VirtualProtect(ptr, length, protect[mode], &old))
459+ return -1;
460+ return 0;
454461 #else
455462 static const unsigned char protect[] = {
456463 PROT_READ | PROT_EXEC,
@@ -463,8 +470,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon · 6 unmodified lines
463470 end = (addr_t)ptr + length;
464471 end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
465472 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?");
468474 /* XXX: BSD sometimes dump core with bad system call */
469475 # if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64
470476 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
472478 __clear_cache(ptr, (char *)ptr + length);
473479 }
474480 # endif
475−
481+ return 0;
476482 #endif
477483 }
478484
tcctools.c+12−9
@@ -490,9 +490,10 @@ the_end: · 489 unmodified lines
490490
491491 #if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
492492
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)
494494 {
495− tcc_error("-m%d not implemented.", option);
495+ tcc_error_noabort("-m%d not implemented.", option);
496+ return 1;
496497 }
497498
498499 #else
@@ -539,7 +540,7 @@ static int execvp_win32(const char *prog, char **argv) · 40 unmodified lines
539540 #define execvp execvp_win32
540541 #endif /* _WIN32 */
541542
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)
543544 {
544545 char program[4096];
545546 char *a0 = argv[0];
@@ -558,7 +559,8 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) · 12 unmodified lines
558559
559560 if (strcmp(a0, program))
560561 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;
562564 }
563565
564566 #endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
@@ -588,7 +590,7 @@ static char *escape_target_dep(const char *s) { · 23 unmodified lines
588590 return res;
589591 }
590592
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)
592594 {
593595 FILE *depout;
594596 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
601603 filename = buf;
602604 }
603605
604− if (s1->verbose)
605− printf("<- %s\n", filename);
606−
607606 if(!strcmp(filename, "-"))
608607 depout = fdopen(1, "w");
609608 else
610609 /* XXX return err codes instead of error() ? */
611610 depout = fopen(filename, "w");
612611 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+
614616 fprintf(depout, "%s:", target);
615617 for (i = 0; i<s1->nb_target_deps; ++i) {
616618 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
623625 }
624626 fprintf(depout, "\n");
625627 fclose(depout);
628+ return 0;
626629 }
627630
628631 /* -------------------------------------------------------------- */
x86_64-link.c+3−3
@@ -251,7 +251,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 250 unmodified lines
251251 /* ignore overflow with undefined weak symbols */
252252 if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF)
253253 #endif
254− tcc_error("internal error: relocation failed");
254+ tcc_error_noabort("internal error: relocation failed");
255255 }
256256 add32le(ptr, diff);
257257 }
@@ -336,7 +336,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 78 unmodified lines
336336 add32le(ptr + 8, x);
337337 }
338338 else
339− tcc_error("unexpected R_X86_64_TLSGD pattern");
339+ tcc_error_noabort("unexpected R_X86_64_TLSGD pattern");
340340 }
341341 break;
342342 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
356356 rel[1].r_info = ELFW(R_INFO)(0, R_X86_64_NONE);
357357 }
358358 else
359− tcc_error("unexpected R_X86_64_TLSLD pattern");
359+ tcc_error_noabort("unexpected R_X86_64_TLSLD pattern");
360360 }
361361 break;
362362 case R_X86_64_DTPOFF32:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t