mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-24 03:40:09 +08:00
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:
parent
19ef024aa9
commit
7916cf71cc
@ -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;
|
||||
|
10
arm64-link.c
10
arm64-link.c
@ -126,7 +126,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
uint64_t got = s1->got->sh_addr + 16;
|
||||
uint64_t off = (got >> 12) - (plt >> 12);
|
||||
if ((off + ((uint32_t)1 << 20)) >> 21)
|
||||
tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
|
||||
tcc_error_noabort("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
|
||||
write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
|
||||
write32le(p + 4, (0x90000010 | // adrp x16,...
|
||||
(off & 0x1ffffc) << 3 | (off & 3) << 29));
|
||||
@ -145,7 +145,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
|
||||
uint64_t addr = got + read64le(p);
|
||||
uint64_t off = (addr >> 12) - (pc >> 12);
|
||||
if ((off + ((uint32_t)1 << 20)) >> 21)
|
||||
tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
|
||||
tcc_error_noabort("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
|
||||
write32le(p, (0x90000010 | // adrp x16,...
|
||||
(off & 0x1ffffc) << 3 | (off & 3) << 29));
|
||||
write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
|
||||
@ -239,7 +239,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
|
||||
case R_AARCH64_ADR_PREL_PG_HI21: {
|
||||
uint64_t off = (val >> 12) - (addr >> 12);
|
||||
if ((off + ((uint64_t)1 << 20)) >> 21)
|
||||
tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
|
||||
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
|
||||
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
|
||||
(off & 0x1ffffc) << 3 | (off & 3) << 29));
|
||||
return;
|
||||
@ -272,7 +272,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
|
||||
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
|
||||
tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
write32le(ptr, (0x14000000 |
|
||||
(uint32_t)(type == R_AARCH64_CALL26) << 31 |
|
||||
@ -283,7 +283,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
|
||||
(((s1->got->sh_addr +
|
||||
get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
|
||||
if ((off + ((uint64_t)1 << 20)) >> 21)
|
||||
tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
|
||||
tcc_error_noabort("R_AARCH64_ADR_GOT_PAGE relocation failed");
|
||||
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
|
||||
(off & 0x1ffffc) << 3 | (off & 3) << 29));
|
||||
return;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
103
libtcc.c
@ -250,6 +250,12 @@ ST_FUNC char *tcc_load_text(int fd)
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
|
||||
void mem_error(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
#ifndef MEM_DEBUG
|
||||
|
||||
PUB_FUNC void tcc_free(void *ptr)
|
||||
@ -262,7 +268,7 @@ PUB_FUNC void *tcc_malloc(unsigned long size)
|
||||
void *ptr;
|
||||
ptr = malloc(size);
|
||||
if (!ptr && size)
|
||||
_tcc_error("memory full (malloc)");
|
||||
mem_error("memory full (malloc)");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -280,7 +286,7 @@ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
||||
void *ptr1;
|
||||
ptr1 = realloc(ptr, size);
|
||||
if (!ptr1 && size)
|
||||
_tcc_error("memory full (realloc)");
|
||||
mem_error("memory full (realloc)");
|
||||
return ptr1;
|
||||
}
|
||||
|
||||
@ -345,7 +351,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
|
||||
|
||||
header = malloc(sizeof(mem_debug_header_t) + size);
|
||||
if (!header)
|
||||
_tcc_error("memory full (malloc)");
|
||||
mem_error("memory full (malloc)");
|
||||
|
||||
header->magic1 = MEM_DEBUG_MAGIC1;
|
||||
header->magic2 = MEM_DEBUG_MAGIC2;
|
||||
@ -405,7 +411,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file
|
||||
mem_debug_chain_update = (header == mem_debug_chain);
|
||||
header = realloc(header, sizeof(mem_debug_header_t) + size);
|
||||
if (!header)
|
||||
_tcc_error("memory full (realloc)");
|
||||
mem_error("memory full (realloc)");
|
||||
header->size = size;
|
||||
write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
|
||||
if (header->next)
|
||||
@ -537,12 +543,6 @@ static void error1(int mode, const char *fmt, va_list ap)
|
||||
TCCState *s1 = tcc_state;
|
||||
CString cs;
|
||||
|
||||
cstr_new(&cs);
|
||||
|
||||
if (s1 == NULL)
|
||||
/* can happen only if called from tcc_malloc(): 'out of memory' */
|
||||
goto no_file;
|
||||
|
||||
tcc_exit_state(s1);
|
||||
|
||||
if (mode == ERROR_WARN) {
|
||||
@ -563,6 +563,7 @@ static void error1(int mode, const char *fmt, va_list ap)
|
||||
return;
|
||||
}
|
||||
|
||||
cstr_new(&cs);
|
||||
f = NULL;
|
||||
if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */
|
||||
/* use upper file if inline ":asm:" or token ":paste:" */
|
||||
@ -578,8 +579,6 @@ static void error1(int mode, const char *fmt, va_list ap)
|
||||
} else if (s1->current_filename) {
|
||||
cstr_printf(&cs, "%s: ", s1->current_filename);
|
||||
}
|
||||
|
||||
no_file:
|
||||
if (0 == cs.size)
|
||||
cstr_printf(&cs, "tcc: ");
|
||||
cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");
|
||||
@ -595,15 +594,10 @@ no_file:
|
||||
s1->error_func(s1->error_opaque, (char*)cs.data);
|
||||
}
|
||||
cstr_free(&cs);
|
||||
if (s1) {
|
||||
if (mode != ERROR_WARN)
|
||||
s1->nb_errors++;
|
||||
if (mode != ERROR_ERROR)
|
||||
return;
|
||||
if (s1->error_set_jmp_enabled)
|
||||
longjmp(s1->error_jmp_buf, 1);
|
||||
}
|
||||
exit(1);
|
||||
if (mode != ERROR_WARN)
|
||||
s1->nb_errors++;
|
||||
if (mode == ERROR_ERROR && s1->error_set_jmp_enabled)
|
||||
longjmp(s1->error_jmp_buf, 1);
|
||||
}
|
||||
|
||||
LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func)
|
||||
@ -623,20 +617,24 @@ LIBTCCAPI void *tcc_get_error_opaque(TCCState *s)
|
||||
}
|
||||
|
||||
/* error without aborting current compilation */
|
||||
PUB_FUNC void _tcc_error_noabort(const char *fmt, ...)
|
||||
PUB_FUNC int _tcc_error_noabort(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
error1(ERROR_NOABORT, fmt, ap);
|
||||
va_end(ap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#undef _tcc_error
|
||||
PUB_FUNC void _tcc_error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
for (;;) error1(ERROR_ERROR, fmt, ap);
|
||||
error1(ERROR_ERROR, fmt, ap);
|
||||
exit(1);
|
||||
}
|
||||
#define _tcc_error use_tcc_error_noabort
|
||||
|
||||
PUB_FUNC void _tcc_warning(const char *fmt, ...)
|
||||
{
|
||||
@ -646,6 +644,7 @@ PUB_FUNC void _tcc_warning(const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************/
|
||||
/* I/O layer */
|
||||
|
||||
@ -855,6 +854,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
|
||||
dynarray_reset(&s1->argv, &s1->argc);
|
||||
cstr_free(&s1->cmdline_defs);
|
||||
cstr_free(&s1->cmdline_incl);
|
||||
cstr_free(&s1->linker_arg);
|
||||
#ifdef TCC_IS_NATIVE
|
||||
/* free runtime memory */
|
||||
tcc_run_free(s1);
|
||||
@ -1218,7 +1218,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
|
||||
{
|
||||
if (-1 == tcc_add_library_internal(s1, "%s/%s",
|
||||
filename, 0, s1->crt_paths, s1->nb_crt_paths))
|
||||
tcc_error_noabort("file '%s' not found", filename);
|
||||
return tcc_error_noabort("file '%s' not found", filename);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -1505,7 +1505,7 @@ static int tcc_set_linker(TCCState *s, const char *option)
|
||||
return 0;
|
||||
} else {
|
||||
err:
|
||||
tcc_error("unsupported linker option '%s'", option);
|
||||
return tcc_error_noabort("unsupported linker option '%s'", option);
|
||||
}
|
||||
if (ignoring)
|
||||
tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);
|
||||
@ -1775,7 +1775,7 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv)
|
||||
}
|
||||
|
||||
/* read list file */
|
||||
static void args_parser_listfile(TCCState *s,
|
||||
static int args_parser_listfile(TCCState *s,
|
||||
const char *filename, int optind, int *pargc, char ***pargv)
|
||||
{
|
||||
TCCState *s1 = s;
|
||||
@ -1786,7 +1786,7 @@ static void args_parser_listfile(TCCState *s,
|
||||
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
tcc_error("listfile '%s' not found", filename);
|
||||
return tcc_error_noabort("listfile '%s' not found", filename);
|
||||
|
||||
p = tcc_load_text(fd);
|
||||
for (i = 0; i < *pargc; ++i)
|
||||
@ -1798,6 +1798,7 @@ static void args_parser_listfile(TCCState *s,
|
||||
tcc_free(p);
|
||||
dynarray_reset(&s->argv, &s->argc);
|
||||
*pargc = s->argc = argc, *pargv = s->argv = argv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined TCC_TARGET_MACHO
|
||||
@ -1815,7 +1816,7 @@ static uint32_t parse_version(TCCState *s1, const char *version)
|
||||
c = strtoul(&last[1], &last, 10);
|
||||
}
|
||||
if (*last || a > 0xffff || b > 0xff || c > 0xff)
|
||||
tcc_error("version a.b.c not correct: %s", version);
|
||||
tcc_error_noabort("version a.b.c not correct: %s", version);
|
||||
return (a << 16) | (b << 8) | c;
|
||||
}
|
||||
#endif
|
||||
@ -1827,17 +1828,17 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
||||
const char *optarg, *r;
|
||||
const char *run = NULL;
|
||||
int x;
|
||||
CString linker_arg; /* collect -Wl options */
|
||||
int tool = 0, arg_start = 0, noaction = optind;
|
||||
char **argv = *pargv;
|
||||
int argc = *pargc;
|
||||
|
||||
cstr_new(&linker_arg);
|
||||
cstr_reset(&s->linker_arg);
|
||||
|
||||
while (optind < argc) {
|
||||
r = argv[optind];
|
||||
if (r[0] == '@' && r[1] != '\0') {
|
||||
args_parser_listfile(s, r + 1, optind, &argc, &argv);
|
||||
if (args_parser_listfile(s, r + 1, optind, &argc, &argv))
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
optind++;
|
||||
@ -1851,7 +1852,8 @@ reparse:
|
||||
if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
|
||||
args_parser_add_file(s, r, s->filetype);
|
||||
if (run) {
|
||||
tcc_set_options(s, run);
|
||||
if (tcc_set_options(s, run))
|
||||
return -1;
|
||||
arg_start = optind - 1;
|
||||
break;
|
||||
}
|
||||
@ -1863,7 +1865,7 @@ reparse:
|
||||
const char *p1 = popt->name;
|
||||
const char *r1 = r + 1;
|
||||
if (p1 == NULL)
|
||||
tcc_error("invalid option -- '%s'", r);
|
||||
return tcc_error_noabort("invalid option -- '%s'", r);
|
||||
if (!strstart(p1, &r1))
|
||||
continue;
|
||||
optarg = r1;
|
||||
@ -1871,7 +1873,7 @@ reparse:
|
||||
if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
|
||||
if (optind >= argc)
|
||||
arg_err:
|
||||
tcc_error("argument to '%s' is missing", r);
|
||||
return tcc_error_noabort("argument to '%s' is missing", r);
|
||||
optarg = argv[optind++];
|
||||
}
|
||||
} else if (*r1 != '\0')
|
||||
@ -1994,11 +1996,12 @@ reparse:
|
||||
break;
|
||||
case TCC_OPTION_run:
|
||||
#ifndef TCC_IS_NATIVE
|
||||
tcc_error("-run is not available in a cross compiler");
|
||||
#endif
|
||||
return tcc_error_noabort("-run is not available in a cross compiler");
|
||||
#else
|
||||
run = optarg;
|
||||
x = TCC_OUTPUT_MEMORY;
|
||||
goto set_output_type;
|
||||
#endif
|
||||
case TCC_OPTION_v:
|
||||
do ++s->verbose; while (*optarg++ == 'v');
|
||||
++noaction;
|
||||
@ -2015,7 +2018,7 @@ reparse:
|
||||
} else if (!strcmp(optarg, "hard"))
|
||||
s->float_abi = ARM_HARD_FLOAT;
|
||||
else
|
||||
tcc_error("unsupported float abi '%s'", optarg);
|
||||
return tcc_error_noabort("unsupported float abi '%s'", optarg);
|
||||
break;
|
||||
#endif
|
||||
case TCC_OPTION_m:
|
||||
@ -2039,11 +2042,14 @@ reparse:
|
||||
s->rdynamic = 1;
|
||||
break;
|
||||
case TCC_OPTION_Wl:
|
||||
if (linker_arg.size)
|
||||
--linker_arg.size, cstr_ccat(&linker_arg, ',');
|
||||
cstr_cat(&linker_arg, optarg, 0);
|
||||
if (tcc_set_linker(s, linker_arg.data))
|
||||
cstr_free(&linker_arg);
|
||||
if (s->linker_arg.size)
|
||||
((char*)s->linker_arg.data)[s->linker_arg.size - 1] = ',';
|
||||
cstr_cat(&s->linker_arg, optarg, 0);
|
||||
x = tcc_set_linker(s, s->linker_arg.data);
|
||||
if (x)
|
||||
cstr_reset(&s->linker_arg);
|
||||
if (x < 0)
|
||||
return -1;
|
||||
break;
|
||||
case TCC_OPTION_Wp:
|
||||
r = optarg;
|
||||
@ -2124,7 +2130,7 @@ reparse:
|
||||
extra_action:
|
||||
arg_start = optind - 1;
|
||||
if (arg_start != noaction)
|
||||
tcc_error("cannot parse %s here", r);
|
||||
return tcc_error_noabort("cannot parse %s here", r);
|
||||
tool = x;
|
||||
break;
|
||||
default:
|
||||
@ -2133,8 +2139,8 @@ unsupported_option:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (linker_arg.size) {
|
||||
r = linker_arg.data;
|
||||
if (s->linker_arg.size) {
|
||||
r = s->linker_arg.data;
|
||||
goto arg_err;
|
||||
}
|
||||
*pargc = argc - arg_start;
|
||||
@ -2150,13 +2156,14 @@ unsupported_option:
|
||||
return OPT_HELP;
|
||||
}
|
||||
|
||||
LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
|
||||
LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
|
||||
{
|
||||
char **argv = NULL;
|
||||
int argc = 0;
|
||||
int argc = 0, ret;
|
||||
args_parser_make_argv(r, &argc, &argv);
|
||||
tcc_parse_args(s, &argc, &argv, 0);
|
||||
ret = tcc_parse_args(s, &argc, &argv, 0);
|
||||
dynarray_reset(&argv, &argc);
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
|
||||
|
2
libtcc.h
2
libtcc.h
@ -34,7 +34,7 @@ LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s);
|
||||
LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);
|
||||
|
||||
/* set options as from command line (multiple supported) */
|
||||
LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
|
||||
LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
|
||||
|
||||
/*****************************/
|
||||
/* preprocessor */
|
||||
|
@ -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
24
tcc.c
@ -286,6 +286,8 @@ redo:
|
||||
tcc_set_options(s, CONFIG_TCC_SWITCHES);
|
||||
#endif
|
||||
opt = tcc_parse_args(s, &argc, &argv, 1);
|
||||
if (opt < 0)
|
||||
return 1;
|
||||
|
||||
if (n == 0) {
|
||||
if (opt == OPT_HELP) {
|
||||
@ -299,7 +301,7 @@ redo:
|
||||
return 0;
|
||||
}
|
||||
if (opt == OPT_M32 || opt == OPT_M64)
|
||||
tcc_tool_cross(s, argv, opt); /* never returns */
|
||||
return tcc_tool_cross(s, argv, opt);
|
||||
if (s->verbose)
|
||||
printf(version);
|
||||
if (opt == OPT_AR)
|
||||
@ -318,22 +320,22 @@ redo:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s->nb_files == 0)
|
||||
tcc_error("no input files");
|
||||
|
||||
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
if (s->nb_files == 0) {
|
||||
tcc_error_noabort("no input files");
|
||||
} else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
if (s->outfile && 0!=strcmp("-",s->outfile)) {
|
||||
ppfp = fopen(s->outfile, "w");
|
||||
if (!ppfp)
|
||||
tcc_error("could not write '%s'", s->outfile);
|
||||
tcc_error_noabort("could not write '%s'", s->outfile);
|
||||
}
|
||||
} else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
|
||||
if (s->nb_libraries)
|
||||
tcc_error("cannot specify libraries with -c");
|
||||
if (s->nb_files > 1 && s->outfile)
|
||||
tcc_error("cannot specify output file with -c many files");
|
||||
tcc_error_noabort("cannot specify libraries with -c");
|
||||
else if (s->nb_files > 1 && s->outfile)
|
||||
tcc_error_noabort("cannot specify output file with -c many files");
|
||||
}
|
||||
|
||||
if (s->nb_errors)
|
||||
return 1;
|
||||
if (s->do_bench)
|
||||
start_time = getclock_ms();
|
||||
}
|
||||
@ -391,7 +393,7 @@ redo:
|
||||
if (!s->just_deps && tcc_output_file(s, s->outfile))
|
||||
ret = 1;
|
||||
else if (s->gen_deps)
|
||||
gen_makedeps(s, s->outfile, s->deps_outfile);
|
||||
ret = gen_makedeps(s, s->outfile, s->deps_outfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
9
tcc.h
9
tcc.h
@ -1021,6 +1021,7 @@ struct TCCState {
|
||||
char *deps_outfile; /* option -MF */
|
||||
int argc;
|
||||
char **argv;
|
||||
CString linker_arg; /* collect -Wl options */
|
||||
};
|
||||
|
||||
struct filespec {
|
||||
@ -1239,7 +1240,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
|
||||
#define realloc(p, s) use_tcc_realloc(p, s)
|
||||
#undef strdup
|
||||
#define strdup(s) use_tcc_strdup(s)
|
||||
PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
|
||||
PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
|
||||
PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);
|
||||
PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);
|
||||
#define tcc_internal_error(msg) tcc_error("internal compiler error\n"\
|
||||
@ -1787,8 +1788,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
|
||||
#ifdef TCC_TARGET_PE
|
||||
ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
|
||||
#endif
|
||||
ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
|
||||
ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
|
||||
ST_FUNC int tcc_tool_cross(TCCState *s, char **argv, int option);
|
||||
ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename);
|
||||
#endif
|
||||
|
||||
/* ------------ tccdbg.c ------------ */
|
||||
@ -1915,7 +1916,9 @@ PUB_FUNC void tcc_exit_state(TCCState *s1);
|
||||
# define TCC_STATE_VAR(sym) tcc_state->sym
|
||||
# define TCC_SET_STATE(fn) fn
|
||||
# undef USING_GLOBALS
|
||||
# undef _tcc_error
|
||||
#else
|
||||
# define TCC_STATE_VAR(sym) s1->sym
|
||||
# define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)
|
||||
# define _tcc_error use_tcc_error_noabort
|
||||
#endif
|
||||
|
@ -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 */
|
||||
|
98
tccelf.c
98
tccelf.c
@ -506,7 +506,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
|
||||
sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
|
||||
if (!sym_index || sym->st_shndx == SHN_UNDEF) {
|
||||
if (err)
|
||||
tcc_error("%s not defined", name);
|
||||
tcc_error_noabort("%s not defined", name);
|
||||
return (addr_t)-1;
|
||||
}
|
||||
return sym->st_value;
|
||||
@ -759,7 +759,7 @@ ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
|
||||
rel->r_addend = addend;
|
||||
#endif
|
||||
if (SHT_RELX != SHT_RELA && addend)
|
||||
tcc_error("non-zero addend on REL architecture");
|
||||
tcc_error_noabort("non-zero addend on REL architecture");
|
||||
}
|
||||
|
||||
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
|
||||
@ -953,7 +953,7 @@ static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
|
||||
PTR_SIZE * bloom_size +
|
||||
nbuckets * 4 +
|
||||
(nb_syms - (q - new_syms)) * 4)
|
||||
tcc_error ("gnu_hash size incorrect");
|
||||
tcc_error_noabort ("gnu_hash size incorrect");
|
||||
|
||||
/* find buckets */
|
||||
for(i = 0; i < nbuckets; i++)
|
||||
@ -1364,8 +1364,10 @@ redo:
|
||||
for_each_elem(s, 0, rel, ElfW_Rel) {
|
||||
type = ELFW(R_TYPE)(rel->r_info);
|
||||
gotplt_entry = gotplt_entry_type(type);
|
||||
if (gotplt_entry == -1)
|
||||
tcc_error ("Unknown relocation type for got: %d", type);
|
||||
if (gotplt_entry == -1) {
|
||||
tcc_error_noabort ("Unknown relocation type for got: %d", type);
|
||||
continue;
|
||||
}
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
|
||||
@ -1430,8 +1432,10 @@ redo:
|
||||
}
|
||||
#endif
|
||||
reloc_type = code_reloc(type);
|
||||
if (reloc_type == -1)
|
||||
tcc_error ("Unknown relocation type: %d", type);
|
||||
if (reloc_type == -1) {
|
||||
tcc_error_noabort ("Unknown relocation type: %d", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reloc_type != 0) {
|
||||
jmp_slot:
|
||||
@ -1862,7 +1866,7 @@ static void fill_local_got_entries(TCCState *s1)
|
||||
struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
|
||||
unsigned offset = attr->got_offset;
|
||||
if (offset != rel->r_offset - s1->got->sh_addr)
|
||||
tcc_error_noabort("huh");
|
||||
tcc_error_noabort("fill_local_got_entries: huh?");
|
||||
rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
|
||||
#if SHT_RELX == SHT_RELA
|
||||
rel->r_addend = sym->st_value;
|
||||
@ -2448,7 +2452,7 @@ static int tidy_section_headers(TCCState *s1, int *sec_order);
|
||||
|
||||
/* Create an ELF file on disk.
|
||||
This function handle ELF specific layout requirements */
|
||||
static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||
static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||
int file_offset, int *sec_order)
|
||||
{
|
||||
int i, shnum, offset, size, file_type;
|
||||
@ -2507,6 +2511,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||
ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
|
||||
if (ehdr.e_entry == (addr_t)-1)
|
||||
ehdr.e_entry = text_section->sh_addr;
|
||||
if (s1->nb_errors)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ehdr.e_machine = EM_TCC_TARGET;
|
||||
@ -2563,9 +2569,10 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
||||
}
|
||||
fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tcc_output_binary(TCCState *s1, FILE *f,
|
||||
static int tcc_output_binary(TCCState *s1, FILE *f,
|
||||
const int *sec_order)
|
||||
{
|
||||
Section *s;
|
||||
@ -2585,13 +2592,14 @@ static void tcc_output_binary(TCCState *s1, FILE *f,
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write an elf, coff or "binary" file */
|
||||
static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
|
||||
ElfW(Phdr) *phdr, int file_offset, int *sec_order)
|
||||
{
|
||||
int fd, mode, file_type;
|
||||
int fd, mode, file_type, ret;
|
||||
FILE *f;
|
||||
|
||||
file_type = s1->output_type;
|
||||
@ -2601,25 +2609,22 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
|
||||
mode = 0777;
|
||||
unlink(filename);
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
|
||||
if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
|
||||
tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
|
||||
return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
|
||||
if (s1->verbose)
|
||||
printf("<- %s\n", filename);
|
||||
|
||||
#ifdef TCC_TARGET_COFF
|
||||
if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
|
||||
tcc_output_coff(s1, f);
|
||||
else
|
||||
#endif
|
||||
if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
|
||||
tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
|
||||
ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
|
||||
else
|
||||
tcc_output_binary(s1, f, sec_order);
|
||||
ret = tcc_output_binary(s1, f, sec_order);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef ELF_OBJ_ONLY
|
||||
@ -3016,13 +3021,12 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
||||
|
||||
lseek(fd, file_offset, SEEK_SET);
|
||||
if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
|
||||
goto fail1;
|
||||
goto invalid;
|
||||
/* test CPU specific stuff */
|
||||
if (ehdr.e_ident[5] != ELFDATA2LSB ||
|
||||
ehdr.e_machine != EM_TCC_TARGET) {
|
||||
fail1:
|
||||
tcc_error_noabort("invalid object file");
|
||||
return -1;
|
||||
invalid:
|
||||
return tcc_error_noabort("invalid object file");
|
||||
}
|
||||
/* read sections */
|
||||
shdr = load_data(fd, file_offset + ehdr.e_shoff,
|
||||
@ -3040,14 +3044,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
||||
nb_syms = 0;
|
||||
seencompressed = 0;
|
||||
stab_index = stabstr_index = 0;
|
||||
ret = -1;
|
||||
|
||||
for(i = 1; i < ehdr.e_shnum; i++) {
|
||||
sh = &shdr[i];
|
||||
if (sh->sh_type == SHT_SYMTAB) {
|
||||
if (symtab) {
|
||||
tcc_error_noabort("object must contain only one symtab");
|
||||
fail:
|
||||
ret = -1;
|
||||
goto the_end;
|
||||
}
|
||||
nb_syms = sh->sh_size / sizeof(ElfW(Sym));
|
||||
@ -3124,14 +3127,13 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
||||
s->sh_entsize = sh->sh_entsize;
|
||||
sm_table[i].new_section = 1;
|
||||
found:
|
||||
if (sh->sh_type != s->sh_type) {
|
||||
if (sh->sh_type != s->sh_type
|
||||
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
|
||||
if (strcmp (s->name, ".eh_frame"))
|
||||
&& strcmp (s->name, ".eh_frame")
|
||||
#endif
|
||||
{
|
||||
tcc_error_noabort("invalid section type");
|
||||
goto fail;
|
||||
}
|
||||
) {
|
||||
tcc_error_noabort("invalid section type");
|
||||
goto the_end;
|
||||
}
|
||||
/* align start of section */
|
||||
s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
|
||||
@ -3255,7 +3257,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
||||
invalid_reloc:
|
||||
tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
|
||||
i, strsec + sh->sh_name, (int)rel->r_offset);
|
||||
goto fail;
|
||||
goto the_end;
|
||||
}
|
||||
rel->r_info = ELFW(R_INFO)(sym_index, type);
|
||||
/* offset the relocation offset */
|
||||
@ -3391,10 +3393,8 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
|
||||
len = read_ar_header(fd, file_offset, &hdr);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (len < 0) {
|
||||
tcc_error_noabort("invalid archive");
|
||||
return -1;
|
||||
}
|
||||
if (len < 0)
|
||||
return tcc_error_noabort("invalid archive");
|
||||
file_offset += len;
|
||||
size = strtol(hdr.ar_size, NULL, 0);
|
||||
/* align to even */
|
||||
@ -3568,8 +3568,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
||||
/* test CPU specific stuff */
|
||||
if (ehdr.e_ident[5] != ELFDATA2LSB ||
|
||||
ehdr.e_machine != EM_TCC_TARGET) {
|
||||
tcc_error_noabort("bad architecture");
|
||||
return -1;
|
||||
return tcc_error_noabort("bad architecture");
|
||||
}
|
||||
|
||||
/* read sections */
|
||||
@ -3655,7 +3654,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
||||
if (tcc_add_dllref(s1, name, -1))
|
||||
continue;
|
||||
if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
|
||||
tcc_error_noabort("referenced dll '%s' not found", name);
|
||||
ret = tcc_error_noabort("referenced dll '%s' not found", name);
|
||||
goto the_end;
|
||||
}
|
||||
}
|
||||
@ -3830,24 +3829,21 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
|
||||
s1->new_undef_sym = 0;
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t != '(') {
|
||||
tcc_error_noabort("( expected");
|
||||
ret = -1;
|
||||
ret = tcc_error_noabort("( expected");
|
||||
goto lib_parse_error;
|
||||
}
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
for(;;) {
|
||||
libname[0] = '\0';
|
||||
if (t == LD_TOK_EOF) {
|
||||
tcc_error_noabort("unexpected end of file");
|
||||
ret = -1;
|
||||
ret = tcc_error_noabort("unexpected end of file");
|
||||
goto lib_parse_error;
|
||||
} else if (t == ')') {
|
||||
break;
|
||||
} else if (t == '-') {
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
|
||||
tcc_error_noabort("library name expected");
|
||||
ret = -1;
|
||||
ret = tcc_error_noabort("library name expected");
|
||||
goto lib_parse_error;
|
||||
}
|
||||
pstrcpy(libname, sizeof libname, &filename[1]);
|
||||
@ -3857,8 +3853,7 @@ static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
|
||||
snprintf(filename, sizeof filename, "lib%s.so", libname);
|
||||
}
|
||||
} else if (t != LD_TOK_NAME) {
|
||||
tcc_error_noabort("filename expected");
|
||||
ret = -1;
|
||||
ret = tcc_error_noabort("filename expected");
|
||||
goto lib_parse_error;
|
||||
}
|
||||
if (!strcmp(filename, "AS_NEEDED")) {
|
||||
@ -3922,15 +3917,12 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
|
||||
!strcmp(cmd, "TARGET")) {
|
||||
/* ignore some commands */
|
||||
t = ld_next(s1, cmd, sizeof(cmd));
|
||||
if (t != '(') {
|
||||
tcc_error_noabort("( expected");
|
||||
return -1;
|
||||
}
|
||||
if (t != '(')
|
||||
return tcc_error_noabort("( expected");
|
||||
for(;;) {
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t == LD_TOK_EOF) {
|
||||
tcc_error_noabort("unexpected end of file");
|
||||
return -1;
|
||||
return tcc_error_noabort("unexpected end of file");
|
||||
} else if (t == ')') {
|
||||
break;
|
||||
}
|
||||
|
3
tccgen.c
3
tccgen.c
@ -2928,8 +2928,7 @@ redo:
|
||||
}
|
||||
goto redo;
|
||||
} else if (!combine_types(&combtype, vtop - 1, vtop, op)) {
|
||||
tcc_error_noabort("invalid operand types for binary operation");
|
||||
vpop();
|
||||
tcc_error("invalid operand types for binary operation");
|
||||
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
||||
/* at least one operand is a pointer */
|
||||
/* relational op: must be both pointers */
|
||||
|
@ -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
25
tccpe.c
@ -618,10 +618,8 @@ static int pe_write(struct pe_info *pe)
|
||||
TCCState *s1 = pe->s1;
|
||||
|
||||
pf.op = fopen(pe->filename, "wb");
|
||||
if (NULL == pf.op) {
|
||||
tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (NULL == pf.op)
|
||||
return tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
|
||||
|
||||
pe->sizeofheaders = pe_file_align(pe,
|
||||
sizeof (struct pe_header)
|
||||
@ -1337,9 +1335,8 @@ static int pe_check_symbols(struct pe_info *pe)
|
||||
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||
/* STB_WEAK undefined symbols are accepted */
|
||||
continue;
|
||||
tcc_error_noabort("undefined symbol '%s'%s", name,
|
||||
ret = tcc_error_noabort("undefined symbol '%s'%s", name,
|
||||
imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
|
||||
ret = -1;
|
||||
|
||||
} else if (pe->s1->rdynamic
|
||||
&& ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
||||
@ -1990,7 +1987,6 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe)
|
||||
|
||||
ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
{
|
||||
int ret;
|
||||
struct pe_info pe;
|
||||
|
||||
memset(&pe, 0, sizeof pe);
|
||||
@ -2005,9 +2001,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
pe_add_runtime(s1, &pe);
|
||||
resolve_common_syms(s1);
|
||||
pe_set_options(s1, &pe);
|
||||
pe_check_symbols(&pe);
|
||||
|
||||
ret = pe_check_symbols(&pe);
|
||||
if (ret)
|
||||
if (s1->nb_errors)
|
||||
;
|
||||
else if (filename) {
|
||||
pe_assign_addresses(&pe);
|
||||
@ -2016,10 +2012,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
relocate_sections(s1);
|
||||
pe.start_addr = (DWORD)
|
||||
(get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);
|
||||
if (s1->nb_errors)
|
||||
ret = -1;
|
||||
else
|
||||
ret = pe_write(&pe);
|
||||
if (0 == s1->nb_errors)
|
||||
pe_write(&pe);
|
||||
dynarray_reset(&pe.sec_info, &pe.sec_count);
|
||||
} else {
|
||||
#ifdef TCC_IS_NATIVE
|
||||
@ -2031,15 +2025,12 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
pe_free_imports(&pe);
|
||||
|
||||
#if PE_PRINT_SECTIONS
|
||||
if (s1->g_debug & 8)
|
||||
pe_print_sections(s1, "tcc.log");
|
||||
#endif
|
||||
return ret;
|
||||
return s1->nb_errors ? -1 : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
|
30
tccrun.c
30
tccrun.c
@ -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
|
||||
}
|
||||
|
||||
|
21
tcctools.c
21
tcctools.c
@ -490,9 +490,10 @@ the_end:
|
||||
|
||||
#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
|
||||
|
||||
ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int option)
|
||||
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option)
|
||||
{
|
||||
tcc_error("-m%d not implemented.", option);
|
||||
tcc_error_noabort("-m%d not implemented.", option);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -539,7 +540,7 @@ static int execvp_win32(const char *prog, char **argv)
|
||||
#define execvp execvp_win32
|
||||
#endif /* _WIN32 */
|
||||
|
||||
ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target)
|
||||
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target)
|
||||
{
|
||||
char program[4096];
|
||||
char *a0 = argv[0];
|
||||
@ -558,7 +559,8 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target)
|
||||
|
||||
if (strcmp(a0, program))
|
||||
execvp(argv[0] = program, argv);
|
||||
tcc_error("could not run '%s'", program);
|
||||
tcc_error_noabort("could not run '%s'", program);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
|
||||
@ -588,7 +590,7 @@ static char *escape_target_dep(const char *s) {
|
||||
return res;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename)
|
||||
ST_FUNC int gen_makedeps(TCCState *s1, const char *target, const char *filename)
|
||||
{
|
||||
FILE *depout;
|
||||
char buf[1024], *escaped_target;
|
||||
@ -601,16 +603,16 @@ ST_FUNC void gen_makedeps(TCCState *s1, const char *target, const char *filename
|
||||
filename = buf;
|
||||
}
|
||||
|
||||
if (s1->verbose)
|
||||
printf("<- %s\n", filename);
|
||||
|
||||
if(!strcmp(filename, "-"))
|
||||
depout = fdopen(1, "w");
|
||||
else
|
||||
/* XXX return err codes instead of error() ? */
|
||||
depout = fopen(filename, "w");
|
||||
if (!depout)
|
||||
tcc_error("could not open '%s'", filename);
|
||||
return tcc_error_noabort("could not open '%s'", filename);
|
||||
if (s1->verbose)
|
||||
printf("<- %s\n", filename);
|
||||
|
||||
fprintf(depout, "%s:", target);
|
||||
for (i = 0; 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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user