Browse Source

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().
grischka 1 year ago
parent
commit
ace1225492
5 changed files with 40 additions and 40 deletions
  1. 24 21
      libtcc.c
  2. 2 5
      tcc.c
  3. 6 7
      tcc.h
  4. 7 4
      tccelf.c
  5. 1 3
      tccpe.c

+ 24 - 21
libtcc.c

@@ -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. */
-static int tcc_compile(TCCState *s1)
+static int tcc_compile(TCCState *s1, int filetype)
 {
     Sym *define_start;
-    int filetype, is_asm;
+    int is_asm;
 
     define_start = define_stack;
-    filetype = s1->filetype;
-    is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
+    is_asm = !!(filetype & (AFF_TYPE_ASM|AFF_TYPE_ASMPP));
     tccelf_begin_file(s1);
 
     if (setjmp(s1->error_jmp_buf) == 0) {
@@ -640,7 +639,7 @@ static int tcc_compile(TCCState *s1)
             tcc_preprocess(s1);
         } else if (is_asm) {
 #ifdef CONFIG_TCC_ASM
-            tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
+            tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
 #else
             tcc_error_noabort("asm not supported");
 #endif
@@ -667,7 +666,7 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
     len = strlen(str);
     tcc_open_bf(s, "<string>", len);
     memcpy(file->buffer, str, len);
-    ret = tcc_compile(s);
+    ret = tcc_compile(s, s->filetype);
     tcc_close();
     return ret;
 }
@@ -733,7 +732,6 @@ LIBTCCAPI TCCState *tcc_new(void)
     tcc_state = s;
     ++nb_states;
 
-    s->alacarte_link = 1;
     s->nocommon = 1;
     s->warn_implicit_function_declaration = 1;
     s->ms_extensions = 1;
@@ -1042,7 +1040,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
             break;
 #endif
         case AFF_BINTYPE_AR:
-            ret = tcc_load_archive(s1, fd);
+            ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
             break;
 #ifdef TCC_TARGET_COFF
         case AFF_BINTYPE_C67:
@@ -1061,7 +1059,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
             break;
         }
     } else {
-        ret = tcc_compile(s1);
+        ret = tcc_compile(s1, flags);
     }
     tcc_close();
     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)
 {
     int filetype = s->filetype;
-    int flags = AFF_PRINT_ERROR;
-    if (filetype == 0) {
+    if (0 == (filetype & AFF_TYPE_MASK)) {
         /* use a file extension to detect a filetype */
         const char *ext = tcc_fileextension(filename);
         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"))
                 filetype = AFF_TYPE_C;
             else
-                flags |= AFF_TYPE_BIN;
+                filetype |= AFF_TYPE_BIN;
         } else {
             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)
@@ -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 **pp = s->static_link ? libs + 1 : libs;
 #endif
+    int flags = s->filetype & AFF_WHOLE_ARCHIVE;
     while (*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;
         ++pp;
     }
@@ -1409,7 +1406,10 @@ static int tcc_set_linker(TCCState *s, const char *option)
                 goto err;
 #endif
         } 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) {
             return 0;
         } 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));
     f->type = filetype;
-    f->alacarte = s->alacarte_link;
     strcpy(f->name, filename);
     dynarray_add(&s->files, &s->nb_files, f);
 }
@@ -1742,7 +1741,7 @@ reparse:
             tcc_set_lib_path(s, optarg);
             break;
         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++;
             break;
         case TCC_OPTION_pthread:
@@ -1896,14 +1895,18 @@ reparse:
             exit(0);
             break;
         case TCC_OPTION_x:
+            x = 0;
             if (*optarg == 'c')
-                s->filetype = AFF_TYPE_C;
+                x = AFF_TYPE_C;
             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')
-                s->filetype = AFF_TYPE_NONE;
+                x = AFF_TYPE_NONE;
             else
                 tcc_warning("unsupported language '%s'", optarg);
+            s->filetype = x | (s->filetype & ~AFF_TYPE_MASK);
             break;
         case TCC_OPTION_O:
             last_o = atoi(optarg);

+ 2 - 5
tcc.c

@@ -62,7 +62,7 @@ static const char help[] =
     "  -bt N       show N callers in stack traces\n"
 #endif
     "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"
     "  -nostdlib   do not link with standard crt and libraries\n"
     "  -Bdir       set tcc's private include/library dir\n"
@@ -322,8 +322,7 @@ redo:
     for (first_file = NULL, ret = 0;;) {
         struct filespec *f = s->files[s->nb_files - n];
         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)
                 ret = 1;
         } else {
@@ -334,8 +333,6 @@ redo:
             if (tcc_add_file(s, f->name) < 0)
                 ret = 1;
         }
-        s->filetype = 0;
-        s->alacarte_link = 1;
         if (--n == 0 || ret
             || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
             break;

+ 6 - 7
tcc.h

@@ -638,7 +638,6 @@ struct sym_attr {
 };
 
 struct TCCState {
-
     int verbose; /* if true, display some information during compilation */
     int nostdinc; /* if true, no standard headers 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 rdynamic; /* if true, all symbols are exported */
     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 *soname; /* as specified on the command line (-soname) */
@@ -811,7 +810,6 @@ struct TCCState {
     struct filespec **files; /* files seen on command line */
     int nb_files; /* number thereof */
     int nb_libraries; /* number of libs thereof */
-    int filetype;
     char *outfile; /* output filename */
     int option_r; /* option -r */
     int do_bench; /* option -bench */
@@ -824,7 +822,6 @@ struct TCCState {
 
 struct filespec {
     char type;
-    char alacarte;
     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_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
 #define AFF_TYPE_BIN        0x40 /* file to add is binary */
+#define AFF_WHOLE_ARCHIVE   0x80 /* load all objects from archive */
 /* s->filetype: */
 #define AFF_TYPE_NONE   0
 #define AFF_TYPE_C      1
 #define AFF_TYPE_ASM    2
-#define AFF_TYPE_ASMPP  3
-#define AFF_TYPE_LIB    4
+#define AFF_TYPE_ASMPP  4
+#define AFF_TYPE_LIB    8
+#define AFF_TYPE_MASK   (15 | AFF_TYPE_BIN)
 /* values from tcc_object_type(...) */
 #define AFF_BINTYPE_REL 1
 #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_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_runtime(TCCState *s1);
 

+ 7 - 4
tccelf.c

@@ -1146,7 +1146,6 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 s->sh_num, sym_end);
 }
-#endif
 
 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);
     return tcc_add_file(s1, buf);
 }
+#endif
 
 ST_FUNC void tcc_add_bcheck(TCCState *s1)
 {
@@ -1189,8 +1189,10 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
 /* add tcc runtime libraries */
 ST_FUNC void tcc_add_runtime(TCCState *s1)
 {
+    s1->filetype = 0;
     tcc_add_bcheck(s1);
     tcc_add_pragma_libs(s1);
+#ifndef TCC_TARGET_PE
     /* add libc */
     if (!s1->nostdlib) {
         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)
             tcc_add_crt(s1, "crtn.o");
     }
+#endif
 }
 
 /* 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 */
-ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
 {
     ArchiveHeader hdr;
     char ar_size[11];
@@ -2662,10 +2665,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
         size = (size + 1) & ~1;
         if (!strcmp(ar_name, "/")) {
             /* coff symbol table : we handle it */
-            if(s1->alacarte_link)
+            if (alacarte)
                 return tcc_load_alacarte(s1, fd, size, 4);
 	} else if (!strcmp(ar_name, "/SYM64/")) {
-            if(s1->alacarte_link)
+            if (alacarte)
                 return tcc_load_alacarte(s1, fd, size, 8);
         } else {
             ElfW(Ehdr) ehdr;

+ 1 - 3
tccpe.c

@@ -1866,8 +1866,6 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
         SHN_UNDEF, start_symbol);
 
-    tcc_add_pragma_libs(s1);
-
     if (0 == s1->nostdlib) {
         static const char *libs[] = {
             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.s1 = s1;
 
-    tcc_add_bcheck(s1);
+    tcc_add_runtime(s1);
     pe_add_runtime(s1, &pe);
     resolve_common_syms(s1);
     pe_set_options(s1, &pe);