tcc_add_file(): preserve s->filetype

This is supposed to fix a bug where libtcc eventually was trying to
compile libtcc1.a as C source code.

Anyway, there is now only two functions that refer to s->filetype,
tcc_add_file() and tcc_add_library().
This commit is contained in:
grischka 2018-05-31 23:51:59 +02:00
parent 671dcace82
commit ace1225492
5 changed files with 40 additions and 40 deletions

View File

@ -621,14 +621,13 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
} }
/* compile the file opened in 'file'. Return non zero if errors. */ /* compile the file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1) static int tcc_compile(TCCState *s1, int filetype)
{ {
Sym *define_start; Sym *define_start;
int filetype, is_asm; int is_asm;
define_start = define_stack; define_start = define_stack;
filetype = s1->filetype; is_asm = !!(filetype & (AFF_TYPE_ASM|AFF_TYPE_ASMPP));
is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
tccelf_begin_file(s1); tccelf_begin_file(s1);
if (setjmp(s1->error_jmp_buf) == 0) { if (setjmp(s1->error_jmp_buf) == 0) {
@ -640,7 +639,7 @@ static int tcc_compile(TCCState *s1)
tcc_preprocess(s1); tcc_preprocess(s1);
} else if (is_asm) { } else if (is_asm) {
#ifdef CONFIG_TCC_ASM #ifdef CONFIG_TCC_ASM
tcc_assemble(s1, filetype == AFF_TYPE_ASMPP); tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
#else #else
tcc_error_noabort("asm not supported"); tcc_error_noabort("asm not supported");
#endif #endif
@ -667,7 +666,7 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
len = strlen(str); len = strlen(str);
tcc_open_bf(s, "<string>", len); tcc_open_bf(s, "<string>", len);
memcpy(file->buffer, str, len); memcpy(file->buffer, str, len);
ret = tcc_compile(s); ret = tcc_compile(s, s->filetype);
tcc_close(); tcc_close();
return ret; return ret;
} }
@ -733,7 +732,6 @@ LIBTCCAPI TCCState *tcc_new(void)
tcc_state = s; tcc_state = s;
++nb_states; ++nb_states;
s->alacarte_link = 1;
s->nocommon = 1; s->nocommon = 1;
s->warn_implicit_function_declaration = 1; s->warn_implicit_function_declaration = 1;
s->ms_extensions = 1; s->ms_extensions = 1;
@ -1042,7 +1040,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
break; break;
#endif #endif
case AFF_BINTYPE_AR: case AFF_BINTYPE_AR:
ret = tcc_load_archive(s1, fd); ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
break; break;
#ifdef TCC_TARGET_COFF #ifdef TCC_TARGET_COFF
case AFF_BINTYPE_C67: case AFF_BINTYPE_C67:
@ -1061,7 +1059,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
break; break;
} }
} else { } else {
ret = tcc_compile(s1); ret = tcc_compile(s1, flags);
} }
tcc_close(); tcc_close();
return ret; return ret;
@ -1070,8 +1068,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{ {
int filetype = s->filetype; int filetype = s->filetype;
int flags = AFF_PRINT_ERROR; if (0 == (filetype & AFF_TYPE_MASK)) {
if (filetype == 0) {
/* use a file extension to detect a filetype */ /* use a file extension to detect a filetype */
const char *ext = tcc_fileextension(filename); const char *ext = tcc_fileextension(filename);
if (ext[0]) { if (ext[0]) {
@ -1083,13 +1080,12 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
filetype = AFF_TYPE_C; filetype = AFF_TYPE_C;
else else
flags |= AFF_TYPE_BIN; filetype |= AFF_TYPE_BIN;
} else { } else {
filetype = AFF_TYPE_C; filetype = AFF_TYPE_C;
} }
s->filetype = filetype;
} }
return tcc_add_file_internal(s, filename, flags); return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR);
} }
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
@ -1141,9 +1137,10 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
const char **pp = s->static_link ? libs + 1 : libs; const char **pp = s->static_link ? libs + 1 : libs;
#endif #endif
int flags = s->filetype & AFF_WHOLE_ARCHIVE;
while (*pp) { while (*pp) {
if (0 == tcc_add_library_internal(s, *pp, if (0 == tcc_add_library_internal(s, *pp,
libraryname, 0, s->library_paths, s->nb_library_paths)) libraryname, flags, s->library_paths, s->nb_library_paths))
return 0; return 0;
++pp; ++pp;
} }
@ -1409,7 +1406,10 @@ static int tcc_set_linker(TCCState *s, const char *option)
goto err; goto err;
#endif #endif
} else if (ret = link_option(option, "?whole-archive", &p), ret) { } else if (ret = link_option(option, "?whole-archive", &p), ret) {
s->alacarte_link = ret < 0; if (ret > 0)
s->filetype |= AFF_WHOLE_ARCHIVE;
else
s->filetype &= ~AFF_WHOLE_ARCHIVE;
} else if (p) { } else if (p) {
return 0; return 0;
} else { } else {
@ -1595,7 +1595,6 @@ static void args_parser_add_file(TCCState *s, const char* filename, int filetype
{ {
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
f->type = filetype; f->type = filetype;
f->alacarte = s->alacarte_link;
strcpy(f->name, filename); strcpy(f->name, filename);
dynarray_add(&s->files, &s->nb_files, f); dynarray_add(&s->files, &s->nb_files, f);
} }
@ -1742,7 +1741,7 @@ reparse:
tcc_set_lib_path(s, optarg); tcc_set_lib_path(s, optarg);
break; break;
case TCC_OPTION_l: case TCC_OPTION_l:
args_parser_add_file(s, optarg, AFF_TYPE_LIB); args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));
s->nb_libraries++; s->nb_libraries++;
break; break;
case TCC_OPTION_pthread: case TCC_OPTION_pthread:
@ -1896,14 +1895,18 @@ reparse:
exit(0); exit(0);
break; break;
case TCC_OPTION_x: case TCC_OPTION_x:
x = 0;
if (*optarg == 'c') if (*optarg == 'c')
s->filetype = AFF_TYPE_C; x = AFF_TYPE_C;
else if (*optarg == 'a') else if (*optarg == 'a')
s->filetype = AFF_TYPE_ASMPP; x = AFF_TYPE_ASMPP;
else if (*optarg == 'b')
x = AFF_TYPE_BIN;
else if (*optarg == 'n') else if (*optarg == 'n')
s->filetype = AFF_TYPE_NONE; x = AFF_TYPE_NONE;
else else
tcc_warning("unsupported language '%s'", optarg); tcc_warning("unsupported language '%s'", optarg);
s->filetype = x | (s->filetype & ~AFF_TYPE_MASK);
break; break;
case TCC_OPTION_O: case TCC_OPTION_O:
last_o = atoi(optarg); last_o = atoi(optarg);

7
tcc.c
View File

@ -62,7 +62,7 @@ static const char help[] =
" -bt N show N callers in stack traces\n" " -bt N show N callers in stack traces\n"
#endif #endif
"Misc. options:\n" "Misc. options:\n"
" -x[c|a|n] specify type of the next infile\n" " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
" -nostdinc do not use standard system include paths\n" " -nostdinc do not use standard system include paths\n"
" -nostdlib do not link with standard crt and libraries\n" " -nostdlib do not link with standard crt and libraries\n"
" -Bdir set tcc's private include/library dir\n" " -Bdir set tcc's private include/library dir\n"
@ -322,8 +322,7 @@ redo:
for (first_file = NULL, ret = 0;;) { for (first_file = NULL, ret = 0;;) {
struct filespec *f = s->files[s->nb_files - n]; struct filespec *f = s->files[s->nb_files - n];
s->filetype = f->type; s->filetype = f->type;
s->alacarte_link = f->alacarte; if (f->type & AFF_TYPE_LIB) {
if (f->type == AFF_TYPE_LIB) {
if (tcc_add_library_err(s, f->name) < 0) if (tcc_add_library_err(s, f->name) < 0)
ret = 1; ret = 1;
} else { } else {
@ -334,8 +333,6 @@ redo:
if (tcc_add_file(s, f->name) < 0) if (tcc_add_file(s, f->name) < 0)
ret = 1; ret = 1;
} }
s->filetype = 0;
s->alacarte_link = 1;
if (--n == 0 || ret if (--n == 0 || ret
|| (s->output_type == TCC_OUTPUT_OBJ && !s->option_r)) || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
break; break;

13
tcc.h
View File

@ -638,7 +638,6 @@ struct sym_attr {
}; };
struct TCCState { struct TCCState {
int verbose; /* if true, display some information during compilation */ int verbose; /* if true, display some information during compilation */
int nostdinc; /* if true, no standard headers are added */ int nostdinc; /* if true, no standard headers are added */
int nostdlib; /* if true, no standard libraries are added */ int nostdlib; /* if true, no standard libraries are added */
@ -646,7 +645,7 @@ struct TCCState {
int static_link; /* if true, static linking is performed */ int static_link; /* if true, static linking is performed */
int rdynamic; /* if true, all symbols are exported */ int rdynamic; /* if true, all symbols are exported */
int symbolic; /* if true, resolve symbols in the current module first */ int symbolic; /* if true, resolve symbols in the current module first */
int alacarte_link; /* if true, only link in referenced objects from archive */ int filetype; /* file type for compilation (NONE,C,ASM) */
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */ char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
char *soname; /* as specified on the command line (-soname) */ char *soname; /* as specified on the command line (-soname) */
@ -811,7 +810,6 @@ struct TCCState {
struct filespec **files; /* files seen on command line */ struct filespec **files; /* files seen on command line */
int nb_files; /* number thereof */ int nb_files; /* number thereof */
int nb_libraries; /* number of libs thereof */ int nb_libraries; /* number of libs thereof */
int filetype;
char *outfile; /* output filename */ char *outfile; /* output filename */
int option_r; /* option -r */ int option_r; /* option -r */
int do_bench; /* option -bench */ int do_bench; /* option -bench */
@ -824,7 +822,6 @@ struct TCCState {
struct filespec { struct filespec {
char type; char type;
char alacarte;
char name[1]; char name[1];
}; };
@ -1150,12 +1147,14 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
#define AFF_PRINT_ERROR 0x10 /* print error if file not found */ #define AFF_PRINT_ERROR 0x10 /* print error if file not found */
#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
#define AFF_TYPE_BIN 0x40 /* file to add is binary */ #define AFF_TYPE_BIN 0x40 /* file to add is binary */
#define AFF_WHOLE_ARCHIVE 0x80 /* load all objects from archive */
/* s->filetype: */ /* s->filetype: */
#define AFF_TYPE_NONE 0 #define AFF_TYPE_NONE 0
#define AFF_TYPE_C 1 #define AFF_TYPE_C 1
#define AFF_TYPE_ASM 2 #define AFF_TYPE_ASM 2
#define AFF_TYPE_ASMPP 3 #define AFF_TYPE_ASMPP 4
#define AFF_TYPE_LIB 4 #define AFF_TYPE_LIB 8
#define AFF_TYPE_MASK (15 | AFF_TYPE_BIN)
/* values from tcc_object_type(...) */ /* values from tcc_object_type(...) */
#define AFF_BINTYPE_REL 1 #define AFF_BINTYPE_REL 1
#define AFF_BINTYPE_DYN 2 #define AFF_BINTYPE_DYN 2
@ -1423,7 +1422,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s);
ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h); ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *s1, int fd); ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte);
ST_FUNC void tcc_add_bcheck(TCCState *s1); ST_FUNC void tcc_add_bcheck(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1); ST_FUNC void tcc_add_runtime(TCCState *s1);

View File

@ -1146,7 +1146,6 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
s->sh_num, sym_end); s->sh_num, sym_end);
} }
#endif
static int tcc_add_support(TCCState *s1, const char *filename) static int tcc_add_support(TCCState *s1, const char *filename)
{ {
@ -1154,6 +1153,7 @@ static int tcc_add_support(TCCState *s1, const char *filename)
snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename); snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
return tcc_add_file(s1, buf); return tcc_add_file(s1, buf);
} }
#endif
ST_FUNC void tcc_add_bcheck(TCCState *s1) ST_FUNC void tcc_add_bcheck(TCCState *s1)
{ {
@ -1189,8 +1189,10 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
/* add tcc runtime libraries */ /* add tcc runtime libraries */
ST_FUNC void tcc_add_runtime(TCCState *s1) ST_FUNC void tcc_add_runtime(TCCState *s1)
{ {
s1->filetype = 0;
tcc_add_bcheck(s1); tcc_add_bcheck(s1);
tcc_add_pragma_libs(s1); tcc_add_pragma_libs(s1);
#ifndef TCC_TARGET_PE
/* add libc */ /* add libc */
if (!s1->nostdlib) { if (!s1->nostdlib) {
tcc_add_library_err(s1, "c"); tcc_add_library_err(s1, "c");
@ -1207,6 +1209,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
if (s1->output_type != TCC_OUTPUT_MEMORY) if (s1->output_type != TCC_OUTPUT_MEMORY)
tcc_add_crt(s1, "crtn.o"); tcc_add_crt(s1, "crtn.o");
} }
#endif
} }
/* add various standard linker symbols (must be done after the /* add various standard linker symbols (must be done after the
@ -2628,7 +2631,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
} }
/* load a '.a' file */ /* load a '.a' file */
ST_FUNC int tcc_load_archive(TCCState *s1, int fd) ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
{ {
ArchiveHeader hdr; ArchiveHeader hdr;
char ar_size[11]; char ar_size[11];
@ -2662,10 +2665,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
size = (size + 1) & ~1; size = (size + 1) & ~1;
if (!strcmp(ar_name, "/")) { if (!strcmp(ar_name, "/")) {
/* coff symbol table : we handle it */ /* coff symbol table : we handle it */
if(s1->alacarte_link) if (alacarte)
return tcc_load_alacarte(s1, fd, size, 4); return tcc_load_alacarte(s1, fd, size, 4);
} else if (!strcmp(ar_name, "/SYM64/")) { } else if (!strcmp(ar_name, "/SYM64/")) {
if(s1->alacarte_link) if (alacarte)
return tcc_load_alacarte(s1, fd, size, 8); return tcc_load_alacarte(s1, fd, size, 8);
} else { } else {
ElfW(Ehdr) ehdr; ElfW(Ehdr) ehdr;

View File

@ -1866,8 +1866,6 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
SHN_UNDEF, start_symbol); SHN_UNDEF, start_symbol);
tcc_add_pragma_libs(s1);
if (0 == s1->nostdlib) { if (0 == s1->nostdlib) {
static const char *libs[] = { static const char *libs[] = {
TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
@ -1948,7 +1946,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
pe.filename = filename; pe.filename = filename;
pe.s1 = s1; pe.s1 = s1;
tcc_add_bcheck(s1); tcc_add_runtime(s1);
pe_add_runtime(s1, &pe); pe_add_runtime(s1, &pe);
resolve_common_syms(s1); resolve_common_syms(s1);
pe_set_options(s1, &pe); pe_set_options(s1, &pe);