mirror of
https://github.com/TinyCC/tinycc.git
synced 2026-02-04 04:41:37 +00:00
linker options & tcc_load_ldscript() reworked
cleanup libtcc.c:tcc_set_linker() cleanup tccelf.c:tcc_load_ldscript() Also - tccrun.c, tccelf.c:relocate_syms(): with tcc -run -nostdlib, do resolve but only from explicitly on the command-line given libraries. - tccgen.c: optimize UMOD x % c -> x & (c-1) for c = 2^n - tcc-doc.texi: cleanup - tcc.h, tccpp.c, libtcc.c: add 'size' arg to pstrncpy() Also reorder functions in libtcc.c a bit. 9 files changed, 556 insertions(+), 617 deletions(-)
This commit is contained in:
22
tcc-doc.texi
22
tcc-doc.texi
@@ -185,16 +185,6 @@ Show included files. As sole argument, print search dirs. -vvv shows tries too
|
||||
@item -bench
|
||||
Display compilation statistics.
|
||||
|
||||
@item -pthread
|
||||
Preprocess with @option{-D_REENTRANT}, link with @option{-lpthread}.
|
||||
|
||||
@item -On
|
||||
Pretend to optimise: set @option{-D__OPTIMIZE__} to the numeric value of n.
|
||||
Note that TCC performs no additional optimisation.
|
||||
|
||||
@item -dt
|
||||
With @option{-run}/@option{-E}: auto-define 'test_...' macros
|
||||
|
||||
@end table
|
||||
|
||||
Preprocessor options:
|
||||
@@ -441,6 +431,12 @@ gnu11; @code{199901} otherwise.
|
||||
@item -x[c|a|b|n]
|
||||
Specify content of next input file: respectively C, assembly, binary, or none.
|
||||
|
||||
@item -O[n]
|
||||
Same as @option{-D__OPTIMIZE__} except for -O0.
|
||||
|
||||
@item -pthread
|
||||
Preprocess with @option{-D_REENTRANT}, link with @option{-lpthread}.
|
||||
|
||||
@item -M
|
||||
Just output makefile fragment with dependencies
|
||||
|
||||
@@ -456,6 +452,9 @@ Like -MD except mention only user header files, not system header files.
|
||||
@item -MF depfile
|
||||
Use @file{depfile} as output for -MD.
|
||||
|
||||
@item -MP
|
||||
Mention all dependencies as targets too.
|
||||
|
||||
@item -print-search-dirs
|
||||
Print the configured installation directory and a list of library
|
||||
and include directories tcc will search.
|
||||
@@ -463,6 +462,9 @@ and include directories tcc will search.
|
||||
@item -dumpversion
|
||||
Print version.
|
||||
|
||||
@item -dt
|
||||
With @option{-run}/@option{-E}: auto-define 'test_...' macros
|
||||
|
||||
@end table
|
||||
|
||||
Target specific options:
|
||||
|
||||
10
tcc.c
10
tcc.c
@@ -158,7 +158,7 @@ static const char help2[] =
|
||||
#endif
|
||||
" -Bsymbolic set DT_SYMBOLIC elf tag\n"
|
||||
" -oformat=[elf32/64-* binary] set executable output format\n"
|
||||
" -init= -fini= -Map= -as-needed -O (ignored)\n"
|
||||
" -init= -fini= -Map= -as-needed -O -z= (ignored)\n"
|
||||
"Predefined macros:\n"
|
||||
" tcc -E -dM - < /dev/null\n"
|
||||
#endif
|
||||
@@ -221,7 +221,7 @@ static void print_search_dirs(TCCState *s)
|
||||
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
|
||||
print_dirs("libraries", s->library_paths, s->nb_library_paths);
|
||||
printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
|
||||
#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
|
||||
#ifdef TCC_TARGET_UNIX
|
||||
print_dirs("crt", s->crt_paths, s->nb_crt_paths);
|
||||
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
|
||||
#endif
|
||||
@@ -253,7 +253,9 @@ static char *default_outputfile(TCCState *s, const char *first_file)
|
||||
|
||||
if (first_file && strcmp(first_file, "-"))
|
||||
name = tcc_basename(first_file);
|
||||
snprintf(buf, sizeof(buf), "%s", name);
|
||||
if (strlen(name) + 4 >= sizeof buf)
|
||||
name = "a";
|
||||
strcpy(buf, name);
|
||||
ext = tcc_fileextension(buf);
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (s->output_type == TCC_OUTPUT_DLL)
|
||||
@@ -293,7 +295,7 @@ int main(int argc0, char **argv0)
|
||||
redo:
|
||||
argc = argc0, argv = argv0;
|
||||
s = s1 = tcc_new();
|
||||
opt = tcc_parse_args(s, &argc, &argv, 1);
|
||||
opt = tcc_parse_args(s, &argc, &argv);
|
||||
if (opt < 0)
|
||||
return 1;
|
||||
|
||||
|
||||
23
tcc.h
23
tcc.h
@@ -217,6 +217,8 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
|
||||
#if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO
|
||||
# define ELF_OBJ_ONLY /* create elf .o but native executables */
|
||||
#else
|
||||
# define TCC_TARGET_UNIX 1
|
||||
#endif
|
||||
|
||||
/* No ten-byte long doubles on window and macos except in
|
||||
@@ -919,8 +921,6 @@ struct TCCState {
|
||||
/* debug state */
|
||||
struct _tccdbg *dState;
|
||||
|
||||
/* Is there a new undefined sym since last new_undef_sym() */
|
||||
int new_undef_sym;
|
||||
/* extra attributes (eg. GOT/PLT value) for symtab symbols */
|
||||
struct sym_attr *sym_attrs;
|
||||
int nb_sym_attrs;
|
||||
@@ -988,7 +988,7 @@ struct TCCState {
|
||||
unsigned int total_output[4];
|
||||
|
||||
/* used by tcc_load_ldscript */
|
||||
int fd, cc;
|
||||
unsigned char *ld_p; /* text pointer */
|
||||
|
||||
/* for warnings/errors for object files */
|
||||
const char *current_filename;
|
||||
@@ -1001,7 +1001,9 @@ struct TCCState {
|
||||
char *deps_outfile; /* option -MF */
|
||||
int argc;
|
||||
char **argv;
|
||||
CString linker_arg; /* collect -Wl options */
|
||||
/* -Wl options */
|
||||
char **link_argv;
|
||||
int link_argc, link_optind;
|
||||
};
|
||||
|
||||
struct filespec {
|
||||
@@ -1195,7 +1197,7 @@ ST_DATA int g_debug;
|
||||
/* public functions currently used by the tcc main function */
|
||||
ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
|
||||
ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s);
|
||||
ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
|
||||
ST_FUNC char *pstrncpy(char *out, size_t buf_size, const char *s, size_t num);
|
||||
PUB_FUNC char *tcc_basename(const char *name);
|
||||
PUB_FUNC char *tcc_fileextension (const char *name);
|
||||
|
||||
@@ -1265,7 +1267,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
#define AFF_TYPE_ASM 2
|
||||
#define AFF_TYPE_ASMPP 4
|
||||
#define AFF_TYPE_LIB 8
|
||||
#define AFF_TYPE_MASK (15 | AFF_TYPE_BIN)
|
||||
#define AFF_TYPE_MASK (7 | AFF_TYPE_BIN)
|
||||
/* values from tcc_object_type(...) */
|
||||
#define AFF_BINTYPE_REL 1
|
||||
#define AFF_BINTYPE_DYN 2
|
||||
@@ -1274,6 +1276,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
|
||||
/* return value of tcc_add_file_internal(): 0, -1, or FILE_NOT_FOUND */
|
||||
#define FILE_NOT_FOUND -2
|
||||
#define FILE_NOT_RECOGNIZED -3 /* unrecognized file type */
|
||||
|
||||
#ifndef ELF_OBJ_ONLY
|
||||
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
|
||||
@@ -1289,7 +1292,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1);
|
||||
ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
|
||||
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
|
||||
PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
|
||||
PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
|
||||
PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv);
|
||||
#ifdef _WIN32
|
||||
ST_FUNC char *normalize_slashes(char *path);
|
||||
#endif
|
||||
@@ -1571,7 +1574,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1);
|
||||
|
||||
/* ------------ xxx-link.c ------------ */
|
||||
|
||||
#if !defined ELF_OBJ_ONLY || defined TCC_TARGET_MACHO
|
||||
#ifndef TCC_TARGET_PE
|
||||
ST_FUNC int code_reloc (int reloc_type);
|
||||
ST_FUNC int gotplt_entry_type (int reloc_type);
|
||||
/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
|
||||
@@ -1583,13 +1586,11 @@ enum gotplt_entry {
|
||||
ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
|
||||
};
|
||||
#define NEED_RELOC_TYPE
|
||||
|
||||
#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE
|
||||
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
|
||||
ST_FUNC void relocate_plt(TCCState *s1);
|
||||
ST_FUNC void build_got_entries(TCCState *s1, int got_sym); /* in tccelf.c */
|
||||
#define NEED_BUILD_GOT
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1809,7 +1810,7 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev);
|
||||
ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev);
|
||||
#ifdef TCC_IS_NATIVE
|
||||
ST_FUNC void tcc_add_macos_sdkpath(TCCState* s);
|
||||
ST_FUNC const char* macho_tbd_soname(const char* filename);
|
||||
ST_FUNC char* macho_tbd_soname(int fd);
|
||||
#endif
|
||||
#endif
|
||||
/* ------------ tccrun.c ----------------- */
|
||||
|
||||
210
tccelf.c
210
tccelf.c
@@ -526,6 +526,24 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
|
||||
return addr == -1 ? NULL : (void*)(uintptr_t)addr;
|
||||
}
|
||||
|
||||
LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
|
||||
{
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* On x86_64 'val' might not be reachable with a 32bit offset.
|
||||
So it is handled here as if it were in a DLL. */
|
||||
pe_putimport(s1, 0, name, (uintptr_t)val);
|
||||
#else
|
||||
char buf[256];
|
||||
if (s1->leading_underscore) {
|
||||
buf[0] = '_';
|
||||
pstrcpy(buf + 1, sizeof(buf) - 1, name);
|
||||
name = buf;
|
||||
}
|
||||
set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list elf symbol names and values */
|
||||
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
|
||||
void (*symbol_cb)(void *ctx, const char *name, const void *val))
|
||||
@@ -733,7 +751,6 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||
do_patch:
|
||||
esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
|
||||
esym->st_shndx = shndx;
|
||||
s1->new_undef_sym = 1;
|
||||
esym->st_value = value;
|
||||
esym->st_size = size;
|
||||
}
|
||||
@@ -1058,15 +1075,16 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
|
||||
if (do_resolve) {
|
||||
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
|
||||
/* dlsym() needs the undecorated name. */
|
||||
void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
|
||||
#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
|
||||
const char *name_ud = &name[s1->leading_underscore];
|
||||
void *addr = NULL;
|
||||
if (!s1->nostdlib)
|
||||
addr = dlsym(RTLD_DEFAULT, name_ud);
|
||||
if (addr == NULL) {
|
||||
int i;
|
||||
for (i = 0; i < s1->nb_loaded_dlls; i++)
|
||||
if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
|
||||
if ((addr = dlsym(s1->loaded_dlls[i]->handle, name_ud)))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (addr) {
|
||||
sym->st_value = (addr_t) addr;
|
||||
#ifdef DEBUG_RELOC
|
||||
@@ -1691,7 +1709,7 @@ static void tcc_tcov_add_file(TCCState *s1, const char *filename)
|
||||
set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
|
||||
}
|
||||
|
||||
#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
|
||||
#ifdef TCC_TARGET_UNIX
|
||||
/* add libc crt1/crti objects */
|
||||
ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
|
||||
{
|
||||
@@ -1750,7 +1768,7 @@ ST_FUNC void tccelf_add_crtend(TCCState *s1)
|
||||
tcc_add_crt(s1, "crtn.o");
|
||||
#endif
|
||||
}
|
||||
#endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
|
||||
#endif /* TCC_TARGET_UNIX */
|
||||
|
||||
#ifndef TCC_TARGET_PE
|
||||
/* add tcc runtime libraries */
|
||||
@@ -3789,19 +3807,15 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
||||
|
||||
#define LD_TOK_NAME 256
|
||||
#define LD_TOK_EOF (-1)
|
||||
|
||||
static int ld_inp(TCCState *s1)
|
||||
{
|
||||
char b;
|
||||
if (s1->cc != -1) {
|
||||
int c = s1->cc;
|
||||
s1->cc = -1;
|
||||
return c;
|
||||
}
|
||||
if (1 == read(s1->fd, &b, 1))
|
||||
return b;
|
||||
return CH_EOF;
|
||||
int c = *s1->ld_p;
|
||||
if (c == 0)
|
||||
return CH_EOF;
|
||||
++s1->ld_p;
|
||||
return c;
|
||||
}
|
||||
#define ld_unget(s1, ch) if (ch != CH_EOF) --s1->ld_p
|
||||
|
||||
/* return next ld script token */
|
||||
static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
@@ -3811,6 +3825,7 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
|
||||
redo:
|
||||
ch = ld_inp(s1);
|
||||
q = name, *q++ = ch;
|
||||
switch(ch) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
@@ -3829,8 +3844,6 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
}
|
||||
goto redo;
|
||||
} else {
|
||||
q = name;
|
||||
*q++ = '/';
|
||||
goto parse_name;
|
||||
}
|
||||
break;
|
||||
@@ -3889,13 +3902,14 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
case 'X':
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case '-':
|
||||
case '_':
|
||||
case '.':
|
||||
case '$':
|
||||
case '~':
|
||||
q = name;
|
||||
parse_name:
|
||||
for(;;) {
|
||||
ch = ld_inp(s1);
|
||||
parse_name:
|
||||
if (!((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
@@ -3904,10 +3918,8 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
if ((q - name) < name_size - 1) {
|
||||
*q++ = ch;
|
||||
}
|
||||
ch = ld_inp(s1);
|
||||
}
|
||||
s1->cc = ch;
|
||||
*q = '\0';
|
||||
ld_unget(s1, ch);
|
||||
c = LD_TOK_NAME;
|
||||
break;
|
||||
case CH_EOF:
|
||||
@@ -3917,93 +3929,71 @@ static int ld_next(TCCState *s1, char *name, int name_size)
|
||||
c = ch;
|
||||
break;
|
||||
}
|
||||
*q = '\0';
|
||||
return c;
|
||||
}
|
||||
|
||||
static int ld_add_file(TCCState *s1, const char filename[])
|
||||
{
|
||||
if (filename[0] == '/') {
|
||||
if (CONFIG_SYSROOT[0] == '\0'
|
||||
&& tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
|
||||
return 0;
|
||||
filename = tcc_basename(filename);
|
||||
if (filename[0] == '-' && filename[1] == 'l')
|
||||
return tcc_add_library(s1, filename + 2);
|
||||
if (CONFIG_SYSROOT[0] != '\0') {
|
||||
/* lookup via library paths */
|
||||
int ret = tcc_add_dll(s1, tcc_basename(filename), 0);
|
||||
if (ret != FILE_NOT_FOUND)
|
||||
return ret;
|
||||
}
|
||||
return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
|
||||
return tcc_add_file_internal(s1, filename, AFF_PRINT_ERROR);
|
||||
}
|
||||
|
||||
static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
|
||||
/* did static libraries add new undefined symbols? */
|
||||
static int new_undef_sym(TCCState *s1, int sym_offset)
|
||||
{
|
||||
char filename[1024], libname[1016];
|
||||
int t, group, nblibs = 0, ret = 0;
|
||||
char **libs = NULL;
|
||||
|
||||
group = !strcmp(cmd, "GROUP");
|
||||
if (!as_needed)
|
||||
s1->new_undef_sym = 0;
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t != '(') {
|
||||
ret = tcc_error_noabort("( expected");
|
||||
goto lib_parse_error;
|
||||
while (sym_offset < s1->symtab->data_offset) {
|
||||
ElfW(Sym) *esym = (void*)(s1->symtab->data + sym_offset);
|
||||
if (esym->st_shndx == SHN_UNDEF)
|
||||
return 1;
|
||||
sym_offset += sizeof (ElfW(Sym));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ld_add_file_list(TCCState *s1, const char *cmd)
|
||||
{
|
||||
char filename[1024];
|
||||
int t, c, sym_offset, ret = 0;
|
||||
unsigned char *pos = s1->ld_p;
|
||||
|
||||
repeat:
|
||||
s1->ld_p = pos;
|
||||
sym_offset = s1->symtab->data_offset;
|
||||
c = cmd[0];
|
||||
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t != '(')
|
||||
return tcc_error_noabort("expected '(' after %s", cmd);
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
for(;;) {
|
||||
libname[0] = '\0';
|
||||
if (t == LD_TOK_EOF) {
|
||||
ret = tcc_error_noabort("unexpected end of file");
|
||||
goto lib_parse_error;
|
||||
return tcc_error_noabort("unexpected end of file");
|
||||
} else if (t == ')') {
|
||||
break;
|
||||
} else if (t == '-') {
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
|
||||
ret = tcc_error_noabort("library name expected");
|
||||
goto lib_parse_error;
|
||||
}
|
||||
pstrcpy(libname, sizeof libname, &filename[1]);
|
||||
if (s1->static_link) {
|
||||
snprintf(filename, sizeof filename, "lib%s.a", libname);
|
||||
} else {
|
||||
snprintf(filename, sizeof filename, "lib%s.so", libname);
|
||||
}
|
||||
} else if (t != LD_TOK_NAME) {
|
||||
ret = tcc_error_noabort("filename expected");
|
||||
goto lib_parse_error;
|
||||
}
|
||||
if (!strcmp(filename, "AS_NEEDED")) {
|
||||
ret = ld_add_file_list(s1, cmd, 1);
|
||||
if (ret)
|
||||
goto lib_parse_error;
|
||||
} else {
|
||||
/* TODO: Implement AS_NEEDED support. */
|
||||
/* DT_NEEDED is not used any more so ignore as_needed */
|
||||
if (1 || !as_needed) {
|
||||
ret = ld_add_file(s1, filename);
|
||||
if (ret)
|
||||
goto lib_parse_error;
|
||||
if (group) {
|
||||
/* Add the filename *and* the libname to avoid future conversions */
|
||||
dynarray_add(&libs, &nblibs, tcc_strdup(filename));
|
||||
if (libname[0] != '\0')
|
||||
dynarray_add(&libs, &nblibs, tcc_strdup(libname));
|
||||
}
|
||||
}
|
||||
return tcc_error_noabort("unexpected token '%c'", t);
|
||||
} else if (!strcmp(filename, "AS_NEEDED")) {
|
||||
ret = ld_add_file_list(s1, filename);
|
||||
} else if (c == 'I' || c == 'G' || c == 'A') {
|
||||
ret = ld_add_file(s1, filename);
|
||||
}
|
||||
if (ret)
|
||||
return -1;
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t == ',') {
|
||||
if (t == ',')
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
}
|
||||
}
|
||||
if (group && !as_needed) {
|
||||
while (s1->new_undef_sym) {
|
||||
int i;
|
||||
s1->new_undef_sym = 0;
|
||||
for (i = 0; i < nblibs; i ++)
|
||||
ld_add_file(s1, libs[i]);
|
||||
}
|
||||
}
|
||||
lib_parse_error:
|
||||
dynarray_reset(&libs, &nblibs);
|
||||
return ret;
|
||||
if (c == 'G' && new_undef_sym(s1, sym_offset))
|
||||
goto repeat;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* interpret a subset of GNU ldscripts to handle the dummy libc.so
|
||||
@@ -4011,40 +4001,30 @@ lib_parse_error:
|
||||
ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
|
||||
{
|
||||
char cmd[64];
|
||||
char filename[1024];
|
||||
int t, ret;
|
||||
int t, ret = FILE_NOT_RECOGNIZED;
|
||||
unsigned char *text_ptr, *saved_ptr;
|
||||
|
||||
s1->fd = fd;
|
||||
s1->cc = -1;
|
||||
saved_ptr = s1->ld_p;
|
||||
s1->ld_p = text_ptr = (void*)tcc_load_text(fd);
|
||||
for(;;) {
|
||||
t = ld_next(s1, cmd, sizeof(cmd));
|
||||
if (t == LD_TOK_EOF)
|
||||
return 0;
|
||||
else if (t != LD_TOK_NAME)
|
||||
return -1;
|
||||
break;
|
||||
if (!strcmp(cmd, "INPUT") ||
|
||||
!strcmp(cmd, "GROUP")) {
|
||||
ret = ld_add_file_list(s1, cmd, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = ld_add_file_list(s1, cmd);
|
||||
} else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
|
||||
!strcmp(cmd, "TARGET")) {
|
||||
/* ignore some commands */
|
||||
t = ld_next(s1, cmd, sizeof(cmd));
|
||||
if (t != '(')
|
||||
return tcc_error_noabort("( expected");
|
||||
for(;;) {
|
||||
t = ld_next(s1, filename, sizeof(filename));
|
||||
if (t == LD_TOK_EOF) {
|
||||
return tcc_error_noabort("unexpected end of file");
|
||||
} else if (t == ')') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
ret = ld_add_file_list(s1, cmd);
|
||||
} else if (0 == ret) {
|
||||
ret = tcc_error_noabort("unexpected '%s'", cmd);
|
||||
}
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
tcc_free(text_ptr);
|
||||
s1->ld_p = saved_ptr;
|
||||
return ret;
|
||||
}
|
||||
#endif /* !ELF_OBJ_ONLY */
|
||||
|
||||
7
tccgen.c
7
tccgen.c
@@ -2401,10 +2401,15 @@ static void gen_opic(int op)
|
||||
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
|
||||
/* filter out NOP operations like x*1, x-0, x&-1... */
|
||||
vtop--;
|
||||
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
|
||||
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV || op == TOK_UMOD)) {
|
||||
/* try to use shifts instead of muls or divs */
|
||||
if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
|
||||
int n = -1;
|
||||
if (op == TOK_UMOD) {
|
||||
vtop->c.i = l2 - 1;
|
||||
op = '&';
|
||||
goto general_case;
|
||||
}
|
||||
while (l2) {
|
||||
l2 >>= 1;
|
||||
n++;
|
||||
|
||||
12
tccmacho.c
12
tccmacho.c
@@ -2195,9 +2195,6 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
|
||||
tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (s1->verbose)
|
||||
printf("<- %s\n", filename);
|
||||
|
||||
tcc_add_runtime(s1);
|
||||
tcc_macho_add_destructor(s1);
|
||||
resolve_common_syms(s1);
|
||||
@@ -2222,6 +2219,8 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
|
||||
bind_rebase_import(s1, &mo);
|
||||
#endif
|
||||
convert_symbols(s1, &mo);
|
||||
if (s1->verbose)
|
||||
printf("<- %s\n", filename);
|
||||
macho_write(s1, &mo, fp);
|
||||
}
|
||||
|
||||
@@ -2291,12 +2290,9 @@ ST_FUNC void tcc_add_macos_sdkpath(TCCState* s)
|
||||
cstr_free(&path);
|
||||
}
|
||||
|
||||
ST_FUNC const char* macho_tbd_soname(const char* filename) {
|
||||
ST_FUNC char* macho_tbd_soname(int fd) {
|
||||
char *soname, *data, *pos;
|
||||
const char *ret = filename;
|
||||
|
||||
int fd = open(filename,O_RDONLY);
|
||||
if (fd<0) return ret;
|
||||
char *ret = 0;
|
||||
pos = data = tcc_load_text(fd);
|
||||
if (!tbd_parse_movepast("install-name: ")) goto the_end;
|
||||
tbd_parse_skipws;
|
||||
|
||||
4
tccpp.c
4
tccpp.c
@@ -1354,7 +1354,7 @@ static int parse_include(TCCState *s1, int do_next, int test)
|
||||
cstr_reset(&tokcstr);
|
||||
file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &tokcstr);
|
||||
i = tokcstr.size;
|
||||
pstrncpy(name, tokcstr.data, i >= sizeof name ? sizeof name - 1 : i);
|
||||
pstrncpy(name, sizeof name, tokcstr.data, i);
|
||||
next_nomacro();
|
||||
} else {
|
||||
/* computed #include : concatenate tokens until result is one of
|
||||
@@ -1395,7 +1395,7 @@ static int parse_include(TCCState *s1, int do_next, int test)
|
||||
if (c != '\"')
|
||||
continue;
|
||||
p = file->true_filename;
|
||||
pstrncpy(buf, p, tcc_basename(p) - p);
|
||||
pstrncpy(buf, sizeof buf, p, tcc_basename(p) - p);
|
||||
} else {
|
||||
int j = i - 2, k = j - s1->nb_include_paths;
|
||||
if (k < 0)
|
||||
|
||||
4
tccrun.c
4
tccrun.c
@@ -221,7 +221,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
|
||||
tcc_add_symbol(s1, "__rt_exit", rt_exit);
|
||||
if (s1->nostdlib) {
|
||||
s1->run_main = top_sym = "_start";
|
||||
s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";
|
||||
} else {
|
||||
tcc_add_support(s1, "runmain.o");
|
||||
s1->run_main = "_runmain";
|
||||
@@ -421,7 +421,7 @@ redo:
|
||||
}
|
||||
|
||||
/* relocate symbols */
|
||||
relocate_syms(s1, s1->symtab, !(s1->nostdlib));
|
||||
relocate_syms(s1, s1->symtab, 1);
|
||||
/* relocate sections */
|
||||
#ifdef TCC_TARGET_PE
|
||||
s1->pe_imagebase = mem;
|
||||
|
||||
Reference in New Issue
Block a user