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, ...)
This commit is contained in:
grischka 2023-04-15 09:54:23 +02:00
parent 19ef024aa9
commit 7916cf71cc
17 changed files with 190 additions and 181 deletions

View File

@ -214,7 +214,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
h = x & 2;
th_ko = (x & 3) && (!blx_avail || !is_call);
if (th_ko || x >= 0x2000000 || x < -0x2000000)
tcc_error("can't relocate value at %x,%d",addr, type);
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
x >>= 2;
x &= 0xffffff;
/* Only reached if blx is avail and it is a call */
@ -303,7 +303,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
- instruction must be a call (bl) or a jump to PLT */
if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
if (to_thumb || (val & 2) || (!is_call && !to_plt))
tcc_error("can't relocate value at %x,%d",addr, type);
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
/* Compute and store final offset */
s = (x >> 24) & 1;
@ -374,7 +374,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
x = (x * 2) / 2;
x += val - addr;
if((x^(x>>1))&0x40000000)
tcc_error("can't relocate value at %x,%d",addr, type);
tcc_error_noabort("can't relocate value at %x,%d",addr, type);
(*(int *)ptr) |= x & 0x7fffffff;
}
return;

View File

@ -126,7 +126,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
uint64_t got = s1->got->sh_addr + 16;
uint64_t off = (got >> 12) - (plt >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
write32le(p + 4, (0x90000010 | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
uint64_t addr = got + read64le(p);
uint64_t off = (addr >> 12) - (pc >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
write32le(p, (0x90000010 | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
@ -239,7 +239,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
case R_AARCH64_ADR_PREL_PG_HI21: {
uint64_t off = (val >> 12) - (addr >> 12);
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;
@ -272,7 +272,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
(char *) symtab_section->link->data + sym->st_name);
#endif
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
write32le(ptr, (0x14000000 |
(uint32_t)(type == R_AARCH64_CALL26) << 31 |
@ -283,7 +283,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
(((s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
tcc_error_noabort("R_AARCH64_ADR_GOT_PAGE relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;

View File

@ -67,7 +67,7 @@ int gotplt_entry_type (int reloc_type)
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
tcc_error("C67 got not implemented");
tcc_error_noabort("C67 got not implemented");
return 0;
}

View File

@ -227,7 +227,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
case R_386_16:
if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
output_file:
tcc_error("can only produce 16-bit binary files");
tcc_error_noabort("can only produce 16-bit binary files");
}
write16le(ptr, read16le(ptr) + val);
return;
@ -274,7 +274,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
add32le(ptr + 5, -x);
}
else
tcc_error("unexpected R_386_TLS_GD pattern");
tcc_error_noabort("unexpected R_386_TLS_GD pattern");
}
return;
case R_386_TLS_LDM:
@ -297,7 +297,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
}
else
tcc_error("unexpected R_386_TLS_LDM pattern");
tcc_error_noabort("unexpected R_386_TLS_LDM pattern");
}
return;
case R_386_TLS_LDO_32:

103
libtcc.c
View File

@ -250,6 +250,12 @@ ST_FUNC char *tcc_load_text(int fd)
#undef malloc
#undef realloc
void mem_error(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit (1);
}
#ifndef MEM_DEBUG
PUB_FUNC void tcc_free(void *ptr)
@ -262,7 +268,7 @@ PUB_FUNC void *tcc_malloc(unsigned long size)
void *ptr;
ptr = malloc(size);
if (!ptr && size)
_tcc_error("memory full (malloc)");
mem_error("memory full (malloc)");
return ptr;
}
@ -280,7 +286,7 @@ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
void *ptr1;
ptr1 = realloc(ptr, size);
if (!ptr1 && size)
_tcc_error("memory full (realloc)");
mem_error("memory full (realloc)");
return ptr1;
}
@ -345,7 +351,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
header = malloc(sizeof(mem_debug_header_t) + size);
if (!header)
_tcc_error("memory full (malloc)");
mem_error("memory full (malloc)");
header->magic1 = MEM_DEBUG_MAGIC1;
header->magic2 = MEM_DEBUG_MAGIC2;
@ -405,7 +411,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file
mem_debug_chain_update = (header == mem_debug_chain);
header = realloc(header, sizeof(mem_debug_header_t) + size);
if (!header)
_tcc_error("memory full (realloc)");
mem_error("memory full (realloc)");
header->size = size;
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
if (header->next)
@ -537,12 +543,6 @@ static void error1(int mode, const char *fmt, va_list ap)
TCCState *s1 = tcc_state;
CString cs;
cstr_new(&cs);
if (s1 == NULL)
/* can happen only if called from tcc_malloc(): 'out of memory' */
goto no_file;
tcc_exit_state(s1);
if (mode == ERROR_WARN) {
@ -563,6 +563,7 @@ static void error1(int mode, const char *fmt, va_list ap)
return;
}
cstr_new(&cs);
f = NULL;
if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */
/* use upper file if inline ":asm:" or token ":paste:" */
@ -578,8 +579,6 @@ static void error1(int mode, const char *fmt, va_list ap)
} else if (s1->current_filename) {
cstr_printf(&cs, "%s: ", s1->current_filename);
}
no_file:
if (0 == cs.size)
cstr_printf(&cs, "tcc: ");
cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");
@ -595,15 +594,10 @@ no_file:
s1->error_func(s1->error_opaque, (char*)cs.data);
}
cstr_free(&cs);
if (s1) {
if (mode != ERROR_WARN)
s1->nb_errors++;
if (mode != ERROR_ERROR)
return;
if (s1->error_set_jmp_enabled)
longjmp(s1->error_jmp_buf, 1);
}
exit(1);
if (mode != ERROR_WARN)
s1->nb_errors++;
if (mode == ERROR_ERROR && s1->error_set_jmp_enabled)
longjmp(s1->error_jmp_buf, 1);
}
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func)
@ -623,20 +617,24 @@ LIBTCCAPI void *tcc_get_error_opaque(TCCState *s)
}
/* error without aborting current compilation */
PUB_FUNC void _tcc_error_noabort(const char *fmt, ...)
PUB_FUNC int _tcc_error_noabort(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
error1(ERROR_NOABORT, fmt, ap);
va_end(ap);
return -1;
}
#undef _tcc_error
PUB_FUNC void _tcc_error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
for (;;) error1(ERROR_ERROR, fmt, ap);
error1(ERROR_ERROR, fmt, ap);
exit(1);
}
#define _tcc_error use_tcc_error_noabort
PUB_FUNC void _tcc_warning(const char *fmt, ...)
{
@ -646,6 +644,7 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...)
va_end(ap);
}
/********************************************************/
/* I/O layer */
@ -855,6 +854,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
dynarray_reset(&s1->argv, &s1->argc);
cstr_free(&s1->cmdline_defs);
cstr_free(&s1->cmdline_incl);
cstr_free(&s1->linker_arg);
#ifdef TCC_IS_NATIVE
/* free runtime memory */
tcc_run_free(s1);
@ -1218,7 +1218,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
{
if (-1 == tcc_add_library_internal(s1, "%s/%s",
filename, 0, s1->crt_paths, s1->nb_crt_paths))
tcc_error_noabort("file '%s' not found", filename);
return tcc_error_noabort("file '%s' not found", filename);
return 0;
}
#endif
@ -1505,7 +1505,7 @@ static int tcc_set_linker(TCCState *s, const char *option)
return 0;
} else {
err:
tcc_error("unsupported linker option '%s'", option);
return tcc_error_noabort("unsupported linker option '%s'", option);
}
if (ignoring)
tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);
@ -1775,7 +1775,7 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv)
}
/* read list file */
static void args_parser_listfile(TCCState *s,
static int args_parser_listfile(TCCState *s,
const char *filename, int optind, int *pargc, char ***pargv)
{
TCCState *s1 = s;
@ -1786,7 +1786,7 @@ static void args_parser_listfile(TCCState *s,
fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0)
tcc_error("listfile '%s' not found", filename);
return tcc_error_noabort("listfile '%s' not found", filename);
p = tcc_load_text(fd);
for (i = 0; i < *pargc; ++i)
@ -1798,6 +1798,7 @@ static void args_parser_listfile(TCCState *s,
tcc_free(p);
dynarray_reset(&s->argv, &s->argc);
*pargc = s->argc = argc, *pargv = s->argv = argv;
return 0;
}
#if defined TCC_TARGET_MACHO
@ -1815,7 +1816,7 @@ static uint32_t parse_version(TCCState *s1, const char *version)
c = strtoul(&last[1], &last, 10);
}
if (*last || a > 0xffff || b > 0xff || c > 0xff)
tcc_error("version a.b.c not correct: %s", version);
tcc_error_noabort("version a.b.c not correct: %s", version);
return (a << 16) | (b << 8) | c;
}
#endif
@ -1827,17 +1828,17 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
const char *optarg, *r;
const char *run = NULL;
int x;
CString linker_arg; /* collect -Wl options */
int tool = 0, arg_start = 0, noaction = optind;
char **argv = *pargv;
int argc = *pargc;
cstr_new(&linker_arg);
cstr_reset(&s->linker_arg);
while (optind < argc) {
r = argv[optind];
if (r[0] == '@' && r[1] != '\0') {
args_parser_listfile(s, r + 1, optind, &argc, &argv);
if (args_parser_listfile(s, r + 1, optind, &argc, &argv))
return -1;
continue;
}
optind++;
@ -1851,7 +1852,8 @@ reparse:
if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
args_parser_add_file(s, r, s->filetype);
if (run) {
tcc_set_options(s, run);
if (tcc_set_options(s, run))
return -1;
arg_start = optind - 1;
break;
}
@ -1863,7 +1865,7 @@ reparse:
const char *p1 = popt->name;
const char *r1 = r + 1;
if (p1 == NULL)
tcc_error("invalid option -- '%s'", r);
return tcc_error_noabort("invalid option -- '%s'", r);
if (!strstart(p1, &r1))
continue;
optarg = r1;
@ -1871,7 +1873,7 @@ reparse:
if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
if (optind >= argc)
arg_err:
tcc_error("argument to '%s' is missing", r);
return tcc_error_noabort("argument to '%s' is missing", r);
optarg = argv[optind++];
}
} else if (*r1 != '\0')
@ -1994,11 +1996,12 @@ reparse:
break;
case TCC_OPTION_run:
#ifndef TCC_IS_NATIVE
tcc_error("-run is not available in a cross compiler");
#endif
return tcc_error_noabort("-run is not available in a cross compiler");
#else
run = optarg;
x = TCC_OUTPUT_MEMORY;
goto set_output_type;
#endif
case TCC_OPTION_v:
do ++s->verbose; while (*optarg++ == 'v');
++noaction;
@ -2015,7 +2018,7 @@ reparse:
} else if (!strcmp(optarg, "hard"))
s->float_abi = ARM_HARD_FLOAT;
else
tcc_error("unsupported float abi '%s'", optarg);
return tcc_error_noabort("unsupported float abi '%s'", optarg);
break;
#endif
case TCC_OPTION_m:
@ -2039,11 +2042,14 @@ reparse:
s->rdynamic = 1;
break;
case TCC_OPTION_Wl:
if (linker_arg.size)
--linker_arg.size, cstr_ccat(&linker_arg, ',');
cstr_cat(&linker_arg, optarg, 0);
if (tcc_set_linker(s, linker_arg.data))
cstr_free(&linker_arg);
if (s->linker_arg.size)
((char*)s->linker_arg.data)[s->linker_arg.size - 1] = ',';
cstr_cat(&s->linker_arg, optarg, 0);
x = tcc_set_linker(s, s->linker_arg.data);
if (x)
cstr_reset(&s->linker_arg);
if (x < 0)
return -1;
break;
case TCC_OPTION_Wp:
r = optarg;
@ -2124,7 +2130,7 @@ reparse:
extra_action:
arg_start = optind - 1;
if (arg_start != noaction)
tcc_error("cannot parse %s here", r);
return tcc_error_noabort("cannot parse %s here", r);
tool = x;
break;
default:
@ -2133,8 +2139,8 @@ unsupported_option:
break;
}
}
if (linker_arg.size) {
r = linker_arg.data;
if (s->linker_arg.size) {
r = s->linker_arg.data;
goto arg_err;
}
*pargc = argc - arg_start;
@ -2150,13 +2156,14 @@ unsupported_option:
return OPT_HELP;
}
LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
{
char **argv = NULL;
int argc = 0;
int argc = 0, ret;
args_parser_make_argv(r, &argc, &argv);
tcc_parse_args(s, &argc, &argv, 0);
ret = tcc_parse_args(s, &argc, &argv, 0);
dynarray_reset(&argv, &argc);
return ret < 0 ? ret : 0;
}
PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)

View File

@ -34,7 +34,7 @@ LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s);
LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);
/* set options as from command line (multiple supported) */
LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
/*****************************/
/* preprocessor */

View File

@ -127,7 +127,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
uint64_t got = s1->got->sh_addr;
uint64_t off = (got - plt + 0x800) >> 12;
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)
write32le(p + 4, 0x41c30333); // sub t1, t1, t3
write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)
@ -144,7 +144,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
uint64_t addr = got + read64le(p);
uint64_t off = (addr - pc + 0x800) >> 12;
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)
write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)
| (((addr - pc) & 0xfff) << 20));
@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
case R_RISCV_BRANCH:
off64 = val - addr;
if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)
tcc_error("R_RISCV_BRANCH relocation failed"
tcc_error_noabort("R_RISCV_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64 >> 1;
write32le(ptr, (read32le(ptr) & ~0xfe000f80)
@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
case R_RISCV_JAL:
off64 = val - addr;
if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2))
tcc_error("R_RISCV_JAL relocation failed"
tcc_error_noabort("R_RISCV_JAL relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write32le(ptr, (read32le(ptr) & 0xfff)
@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
#endif
off64 = (int64_t)(val - addr + 0x800) >> 12;
if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",
tcc_error_noabort("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",
(long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),
symtab_section->link->data + sym->st_name);
write32le(ptr, (read32le(ptr) & 0xfff)
@ -225,7 +225,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset;
off64 = (int64_t)(val - addr + 0x800) >> 12;
if ((off64 + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_RISCV_GOT_HI20 relocation failed");
tcc_error_noabort("R_RISCV_GOT_HI20 relocation failed");
last_hi.addr = addr;
last_hi.val = val;
write32le(ptr, (read32le(ptr) & 0xfff)
@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);
#endif
if (val != last_hi.addr)
tcc_error("unsupported hi/lo pcrel reloc scheme");
tcc_error_noabort("unsupported hi/lo pcrel reloc scheme");
val = last_hi.val;
addr = last_hi.addr;
write32le(ptr, (read32le(ptr) & 0xfffff)
@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
return;
case R_RISCV_PCREL_LO12_S:
if (val != last_hi.addr)
tcc_error("unsupported hi/lo pcrel reloc scheme");
tcc_error_noabort("unsupported hi/lo pcrel reloc scheme");
val = last_hi.val;
addr = last_hi.addr;
off32 = val - addr;
@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
case R_RISCV_RVC_BRANCH:
off64 = (val - addr);
if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe)
tcc_error("R_RISCV_RVC_BRANCH relocation failed"
tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write16le(ptr, (read16le(ptr) & 0xe383)
@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
case R_RISCV_RVC_JUMP:
off64 = (val - addr);
if ((off64 + (1 << 11)) & ~(uint64_t)0xffe)
tcc_error("R_RISCV_RVC_BRANCH relocation failed"
tcc_error_noabort("R_RISCV_RVC_BRANCH relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
off32 = off64;
write16le(ptr, (read16le(ptr) & 0xe003)

24
tcc.c
View File

@ -286,6 +286,8 @@ redo:
tcc_set_options(s, CONFIG_TCC_SWITCHES);
#endif
opt = tcc_parse_args(s, &argc, &argv, 1);
if (opt < 0)
return 1;
if (n == 0) {
if (opt == OPT_HELP) {
@ -299,7 +301,7 @@ redo:
return 0;
}
if (opt == OPT_M32 || opt == OPT_M64)
tcc_tool_cross(s, argv, opt); /* never returns */
return tcc_tool_cross(s, argv, opt);
if (s->verbose)
printf(version);
if (opt == OPT_AR)
@ -318,22 +320,22 @@ redo:
return 0;
}
if (s->nb_files == 0)
tcc_error("no input files");
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
if (s->nb_files == 0) {
tcc_error_noabort("no input files");
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
if (s->outfile && 0!=strcmp("-",s->outfile)) {
ppfp = fopen(s->outfile, "w");
if (!ppfp)
tcc_error("could not write '%s'", s->outfile);
tcc_error_noabort("could not write '%s'", s->outfile);
}
} else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
if (s->nb_libraries)
tcc_error("cannot specify libraries with -c");
if (s->nb_files > 1 && s->outfile)
tcc_error("cannot specify output file with -c many files");
tcc_error_noabort("cannot specify libraries with -c");
else if (s->nb_files > 1 && s->outfile)
tcc_error_noabort("cannot specify output file with -c many files");
}
if (s->nb_errors)
return 1;
if (s->do_bench)
start_time = getclock_ms();
}
@ -391,7 +393,7 @@ redo:
if (!s->just_deps && tcc_output_file(s, s->outfile))
ret = 1;
else if (s->gen_deps)
gen_makedeps(s, s->outfile, s->deps_outfile);
ret = gen_makedeps(s, s->outfile, s->deps_outfile);
}
}

9
tcc.h
View File

@ -1021,6 +1021,7 @@ struct TCCState {
char *deps_outfile; /* option -MF */
int argc;
char **argv;
CString linker_arg; /* collect -Wl options */
};
struct filespec {
@ -1239,7 +1240,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
#define realloc(p, s) use_tcc_realloc(p, s)
#undef strdup
#define strdup(s) use_tcc_strdup(s)
PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);
PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);
#define tcc_internal_error(msg) tcc_error("internal compiler error\n"\
@ -1787,8 +1788,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
#ifdef TCC_TARGET_PE
ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
#endif
ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
ST_FUNC int tcc_tool_cross(TCCState *s, char **argv, int option);
ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename);
#endif
/* ------------ tccdbg.c ------------ */
@ -1915,7 +1916,9 @@ PUB_FUNC void tcc_exit_state(TCCState *s1);
# define TCC_STATE_VAR(sym) tcc_state->sym
# define TCC_SET_STATE(fn) fn
# undef USING_GLOBALS
# undef _tcc_error
#else
# define TCC_STATE_VAR(sym) s1->sym
# define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)
# define _tcc_error use_tcc_error_noabort
#endif

View File

@ -21,6 +21,9 @@
#include "tcc.h"
/* XXX: this file uses tcc_error() to the effect of exit(1) */
#undef _tcc_error
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
#define MAX_STR_TABLE 1000000
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */

View File

@ -506,7 +506,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
if (!sym_index || sym->st_shndx == SHN_UNDEF) {
if (err)
tcc_error("%s not defined", name);
tcc_error_noabort("%s not defined", name);
return (addr_t)-1;
}
return sym->st_value;
@ -759,7 +759,7 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
rel->r_addend = addend;
#endif
if (SHT_RELX != SHT_RELA && addend)
tcc_error("non-zero addend on REL architecture");
tcc_error_noabort("non-zero addend on REL architecture");
}
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
@ -953,7 +953,7 @@ static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
PTR_SIZE * bloom_size +
nbuckets * 4 +
(nb_syms - (q - new_syms)) * 4)
tcc_error ("gnu_hash size incorrect");
tcc_error_noabort ("gnu_hash size incorrect");
/* find buckets */
for(i = 0; i < nbuckets; i++)
@ -1364,8 +1364,10 @@ redo:
for_each_elem(s, 0, rel, ElfW_Rel) {
type = ELFW(R_TYPE)(rel->r_info);
gotplt_entry = gotplt_entry_type(type);
if (gotplt_entry == -1)
tcc_error ("Unknown relocation type for got: %d", type);
if (gotplt_entry == -1) {
tcc_error_noabort ("Unknown relocation type for got: %d", type);
continue;
}
sym_index = ELFW(R_SYM)(rel->r_info);
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
@ -1430,8 +1432,10 @@ redo:
}
#endif
reloc_type = code_reloc(type);
if (reloc_type == -1)
tcc_error ("Unknown relocation type: %d", type);
if (reloc_type == -1) {
tcc_error_noabort ("Unknown relocation type: %d", type);
continue;
}
if (reloc_type != 0) {
jmp_slot:
@ -1862,7 +1866,7 @@ static void fill_local_got_entries(TCCState *s1)
struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
unsigned offset = attr->got_offset;
if (offset != rel->r_offset - s1->got->sh_addr)
tcc_error_noabort("huh");
tcc_error_noabort("fill_local_got_entries: huh?");
rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
#if SHT_RELX == SHT_RELA
rel->r_addend = sym->st_value;
@ -2448,7 +2452,7 @@ static int tidy_section_headers(TCCState *s1, int *sec_order);
/* Create an ELF file on disk.
This function handle ELF specific layout requirements */
static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
int file_offset, int *sec_order)
{
int i, shnum, offset, size, file_type;
@ -2507,6 +2511,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
if (ehdr.e_entry == (addr_t)-1)
ehdr.e_entry = text_section->sh_addr;
if (s1->nb_errors)
return -1;
}
ehdr.e_machine = EM_TCC_TARGET;
@ -2563,9 +2569,10 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
}
fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
}
return 0;
}
static void tcc_output_binary(TCCState *s1, FILE *f,
static int tcc_output_binary(TCCState *s1, FILE *f,
const int *sec_order)
{
Section *s;
@ -2585,13 +2592,14 @@ static void tcc_output_binary(TCCState *s1, FILE *f,
offset += size;
}
}
return 0;
}
/* Write an elf, coff or "binary" file */
static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
ElfW(Phdr) *phdr, int file_offset, int *sec_order)
{
int fd, mode, file_type;
int fd, mode, file_type, ret;
FILE *f;
file_type = s1->output_type;
@ -2601,25 +2609,22 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
mode = 0777;
unlink(filename);
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
return -1;
}
if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
if (s1->verbose)
printf("<- %s\n", filename);
#ifdef TCC_TARGET_COFF
if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
tcc_output_coff(s1, f);
else
#endif
if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
else
tcc_output_binary(s1, f, sec_order);
ret = tcc_output_binary(s1, f, sec_order);
fclose(f);
return 0;
return ret;
}
#ifndef ELF_OBJ_ONLY
@ -3016,13 +3021,12 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
lseek(fd, file_offset, SEEK_SET);
if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
goto fail1;
goto invalid;
/* test CPU specific stuff */
if (ehdr.e_ident[5] != ELFDATA2LSB ||
ehdr.e_machine != EM_TCC_TARGET) {
fail1:
tcc_error_noabort("invalid object file");
return -1;
invalid:
return tcc_error_noabort("invalid object file");
}
/* read sections */
shdr = load_data(fd, file_offset + ehdr.e_shoff,
@ -3040,14 +3044,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
nb_syms = 0;
seencompressed = 0;
stab_index = stabstr_index = 0;
ret = -1;
for(i = 1; i < ehdr.e_shnum; i++) {
sh = &shdr[i];
if (sh->sh_type == SHT_SYMTAB) {
if (symtab) {
tcc_error_noabort("object must contain only one symtab");
fail:
ret = -1;
goto the_end;
}
nb_syms = sh->sh_size / sizeof(ElfW(Sym));
@ -3124,14 +3127,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
s->sh_entsize = sh->sh_entsize;
sm_table[i].new_section = 1;
found:
if (sh->sh_type != s->sh_type) {
if (sh->sh_type != s->sh_type
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
if (strcmp (s->name, ".eh_frame"))
&& strcmp (s->name, ".eh_frame")
#endif
{
tcc_error_noabort("invalid section type");
goto fail;
}
) {
tcc_error_noabort("invalid section type");
goto the_end;
}
/* align start of section */
s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
@ -3255,7 +3257,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
invalid_reloc:
tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
i, strsec + sh->sh_name, (int)rel->r_offset);
goto fail;
goto the_end;
}
rel->r_info = ELFW(R_INFO)(sym_index, type);
/* offset the relocation offset */
@ -3391,10 +3393,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
len = read_ar_header(fd, file_offset, &hdr);
if (len == 0)
return 0;
if (len < 0) {
tcc_error_noabort("invalid archive");
return -1;
}
if (len < 0)
return tcc_error_noabort("invalid archive");
file_offset += len;
size = strtol(hdr.ar_size, NULL, 0);
/* align to even */
@ -3568,8 +3568,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
/* test CPU specific stuff */
if (ehdr.e_ident[5] != ELFDATA2LSB ||
ehdr.e_machine != EM_TCC_TARGET) {
tcc_error_noabort("bad architecture");
return -1;
return tcc_error_noabort("bad architecture");
}
/* read sections */
@ -3655,7 +3654,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
if (tcc_add_dllref(s1, name, -1))
continue;
if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
tcc_error_noabort("referenced dll '%s' not found", name);
ret = tcc_error_noabort("referenced dll '%s' not found", name);
goto the_end;
}
}
@ -3830,24 +3829,21 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
s1->new_undef_sym = 0;
t = ld_next(s1, filename, sizeof(filename));
if (t != '(') {
tcc_error_noabort("( expected");
ret = -1;
ret = tcc_error_noabort("( expected");
goto lib_parse_error;
}
t = ld_next(s1, filename, sizeof(filename));
for(;;) {
libname[0] = '\0';
if (t == LD_TOK_EOF) {
tcc_error_noabort("unexpected end of file");
ret = -1;
ret = tcc_error_noabort("unexpected end of file");
goto lib_parse_error;
} else if (t == ')') {
break;
} else if (t == '-') {
t = ld_next(s1, filename, sizeof(filename));
if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
tcc_error_noabort("library name expected");
ret = -1;
ret = tcc_error_noabort("library name expected");
goto lib_parse_error;
}
pstrcpy(libname, sizeof libname, &filename[1]);
@ -3857,8 +3853,7 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
snprintf(filename, sizeof filename, "lib%s.so", libname);
}
} else if (t != LD_TOK_NAME) {
tcc_error_noabort("filename expected");
ret = -1;
ret = tcc_error_noabort("filename expected");
goto lib_parse_error;
}
if (!strcmp(filename, "AS_NEEDED")) {
@ -3922,15 +3917,12 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
!strcmp(cmd, "TARGET")) {
/* ignore some commands */
t = ld_next(s1, cmd, sizeof(cmd));
if (t != '(') {
tcc_error_noabort("( expected");
return -1;
}
if (t != '(')
return tcc_error_noabort("( expected");
for(;;) {
t = ld_next(s1, filename, sizeof(filename));
if (t == LD_TOK_EOF) {
tcc_error_noabort("unexpected end of file");
return -1;
return tcc_error_noabort("unexpected end of file");
} else if (t == ')') {
break;
}

View File

@ -2928,8 +2928,7 @@ redo:
}
goto redo;
} else if (!combine_types(&combtype, vtop - 1, vtop, op)) {
tcc_error_noabort("invalid operand types for binary operation");
vpop();
tcc_error("invalid operand types for binary operation");
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
/* at least one operand is a pointer */
/* relational op: must be both pointers */

View File

@ -35,6 +35,9 @@
#error Platform not supported
#endif
/* XXX: this file uses tcc_error() to the effect of exit(1) */
#undef _tcc_error
#define DEBUG_MACHO 0
#define dprintf if (DEBUG_MACHO) printf

25
tccpe.c
View File

@ -618,10 +618,8 @@ static int pe_write(struct pe_info *pe)
TCCState *s1 = pe->s1;
pf.op = fopen(pe->filename, "wb");
if (NULL == pf.op) {
tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
return -1;
}
if (NULL == pf.op)
return tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
pe->sizeofheaders = pe_file_align(pe,
sizeof (struct pe_header)
@ -1337,9 +1335,8 @@ static int pe_check_symbols(struct pe_info *pe)
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
/* STB_WEAK undefined symbols are accepted */
continue;
tcc_error_noabort("undefined symbol '%s'%s", name,
ret = tcc_error_noabort("undefined symbol '%s'%s", name,
imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
ret = -1;
} else if (pe->s1->rdynamic
&& ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
@ -1990,7 +1987,6 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe)
ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
{
int ret;
struct pe_info pe;
memset(&pe, 0, sizeof pe);
@ -2005,9 +2001,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
pe_add_runtime(s1, &pe);
resolve_common_syms(s1);
pe_set_options(s1, &pe);
pe_check_symbols(&pe);
ret = pe_check_symbols(&pe);
if (ret)
if (s1->nb_errors)
;
else if (filename) {
pe_assign_addresses(&pe);
@ -2016,10 +2012,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
relocate_sections(s1);
pe.start_addr = (DWORD)
(get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);
if (s1->nb_errors)
ret = -1;
else
ret = pe_write(&pe);
if (0 == s1->nb_errors)
pe_write(&pe);
dynarray_reset(&pe.sec_info, &pe.sec_count);
} else {
#ifdef TCC_IS_NATIVE
@ -2031,15 +2025,12 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
#endif
#endif
}
pe_free_imports(&pe);
#if PE_PRINT_SECTIONS
if (s1->g_debug & 8)
pe_print_sections(s1, "tcc.log");
#endif
return ret;
return s1->nb_errors ? -1 : 0;
}
/* ------------------------------------------------------------- */

View File

@ -63,7 +63,7 @@ static void rt_exit(int code);
# include <sys/mman.h>
#endif
static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length);
static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length);
static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
#ifdef _WIN64
@ -100,16 +100,17 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
ptr = mmap(NULL, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
/* mmap RX memory at a fixed distance */
prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0);
if (ptr == MAP_FAILED || prx == MAP_FAILED)
tcc_error("tccrun: could not map memory");
ptr_diff = (char*)prx - (char*)ptr;
close(fd);
if (ptr == MAP_FAILED || prx == MAP_FAILED)
return tcc_error_noabort("tccrun: could not map memory");
ptr_diff = (char*)prx - (char*)ptr;
//printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff);
}
#else
ptr = tcc_malloc(size);
#endif
tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
if (tcc_relocate_ex(s1, ptr, ptr_diff))
return -1;
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
return 0;
@ -237,6 +238,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
return -1;
prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1);
if ((addr_t)-1 == (addr_t)prog_main)
return -1;
#ifdef CONFIG_TCC_BACKTRACE
memset(rc, 0, sizeof *rc);
@ -409,8 +412,10 @@ redo:
#if DEBUG_RUNMEN
printf("protect %d %p %04x\n", f, (void*)addr, n);
#endif
if (n)
set_pages_executable(s1, f, (void*)addr, n);
if (n) {
if (set_pages_executable(s1, f, (void*)addr, n))
return -1;
}
}
}
@ -440,7 +445,7 @@ redo:
/* ------------------------------------------------------------- */
/* allow to run code in memory */
static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length)
static int set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length)
{
#ifdef _WIN32
static const unsigned char protect[] = {
@ -450,7 +455,9 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon
PAGE_EXECUTE_READWRITE
};
DWORD old;
VirtualProtect(ptr, length, protect[mode], &old);
if (!VirtualProtect(ptr, length, protect[mode], &old))
return -1;
return 0;
#else
static const unsigned char protect[] = {
PROT_READ | PROT_EXEC,
@ -463,8 +470,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon
end = (addr_t)ptr + length;
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
if (mprotect((void *)start, end - start, protect[mode]))
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
return tcc_error_noabort("mprotect failed: did you mean to configure --with-selinux?");
/* XXX: BSD sometimes dump core with bad system call */
# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64
if (mode == 0 || mode == 3) {
@ -472,7 +478,7 @@ static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned lon
__clear_cache(ptr, (char *)ptr + length);
}
# endif
return 0;
#endif
}

View File

@ -490,9 +490,10 @@ the_end:
#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int option)
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option)
{
tcc_error("-m%d not implemented.", option);
tcc_error_noabort("-m%d not implemented.", option);
return 1;
}
#else
@ -539,7 +540,7 @@ static int execvp_win32(const char *prog, char **argv)
#define execvp execvp_win32
#endif /* _WIN32 */
ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target)
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target)
{
char program[4096];
char *a0 = argv[0];
@ -558,7 +559,8 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target)
if (strcmp(a0, program))
execvp(argv[0] = program, argv);
tcc_error("could not run '%s'", program);
tcc_error_noabort("could not run '%s'", program);
return 1;
}
#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
@ -588,7 +590,7 @@ static char *escape_target_dep(const char *s) {
return res;
}
ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename)
ST_FUNC int gen_makedeps(TCCState *s1, const char *target, const char *filename)
{
FILE *depout;
char buf[1024], *escaped_target;
@ -601,16 +603,16 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename
filename = buf;
}
if (s1->verbose)
printf("<- %s\n", filename);
if(!strcmp(filename, "-"))
depout = fdopen(1, "w");
else
/* XXX return err codes instead of error() ? */
depout = fopen(filename, "w");
if (!depout)
tcc_error("could not open '%s'", filename);
return tcc_error_noabort("could not open '%s'", filename);
if (s1->verbose)
printf("<- %s\n", filename);
fprintf(depout, "%s:", target);
for (i = 0; i<s1->nb_target_deps; ++i) {
for (k = 0; k < i; ++k)
@ -623,6 +625,7 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename
}
fprintf(depout, "\n");
fclose(depout);
return 0;
}
/* -------------------------------------------------------------- */

View File

@ -251,7 +251,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
/* ignore overflow with undefined weak symbols */
if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF)
#endif
tcc_error("internal error: relocation failed");
tcc_error_noabort("internal error: relocation failed");
}
add32le(ptr, diff);
}
@ -336,7 +336,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
add32le(ptr + 8, x);
}
else
tcc_error("unexpected R_X86_64_TLSGD pattern");
tcc_error_noabort("unexpected R_X86_64_TLSGD pattern");
}
break;
case R_X86_64_TLSLD:
@ -356,7 +356,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
rel[1].r_info = ELFW(R_INFO)(0, R_X86_64_NONE);
}
else
tcc_error("unexpected R_X86_64_TLSLD pattern");
tcc_error_noabort("unexpected R_X86_64_TLSLD pattern");
}
break;
case R_X86_64_DTPOFF32: