History

libtcc: reimplement option -Wl,[-no]-whöle-archive

- taking advantage of previous commit "incremental -Wl parsing"

grischka committed 10 years ago

Commit 0d9f88e1 parent 2f117455 files · +114 −108Browse files

Unified · Split

5 files
  1. libtcc.c +69 −82
  2. tcc.c +4 −2
  3. tcc.h +14 −6
  4. tccelf.c +26 −17
  5. tccpe.c +1 −1
libtcc.c+69−82
@@ -1298,10 +1298,9 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 1297 unmodified lines
12981298
12991299 ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
13001300 {
1301− ElfW(Ehdr) ehdr;
1302− int fd, ret, size;
1303− int filetype = flags & 0x0F;
1301+ int ret, filetype;
13041302
1303+ filetype = flags & 0x0F;
13051304 if (filetype == 0) {
13061305 /* use a file extension to detect a filetype */
13071306 const char *ext = tcc_fileextension(filename);
@@ -1320,16 +1319,6 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 12 unmodified lines
13201319 }
13211320 }
13221321
1323− parse_flags = 0;
1324−#ifdef CONFIG_TCC_ASM
1325− /* if .S file, define __ASSEMBLER__ like gcc does */
1326− if (filetype == AFF_TYPE_ASM
1327− || filetype == AFF_TYPE_ASMPP) {
1328− tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
1329− parse_flags = PARSE_FLAG_ASM_FILE;
1330− }
1331−#endif
1332−
13331322 /* open the file */
13341323 ret = tcc_open(s1, filename);
13351324 if (ret < 0) {
@@ -1342,96 +1331,76 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 6 unmodified lines
13421331 dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
13431332 tcc_strdup(filename));
13441333
1345− if (flags & AFF_PREPROCESS) {
1346− ret = tcc_preprocess(s1);
1347− goto the_end;
1334+ parse_flags = 0;
1335+#ifdef CONFIG_TCC_ASM
1336+ /* if .S file, define __ASSEMBLER__ like gcc does */
1337+ if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
1338+ tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
1339+ parse_flags = PARSE_FLAG_ASM_FILE;
13481340 }
1341+#endif
13491342
1350− if (filetype == AFF_TYPE_C) {
1351− /* C file assumed */
1343+ if (flags & AFF_PREPROCESS) {
1344+ ret = tcc_preprocess(s1);
1345+ } else if (filetype == AFF_TYPE_C) {
13521346 ret = tcc_compile(s1);
1353− goto the_end;
1354− }
1355−
13561347 #ifdef CONFIG_TCC_ASM
1357− if (filetype == AFF_TYPE_ASMPP) {
1348+ } else if (filetype == AFF_TYPE_ASMPP) {
13581349 /* non preprocessed assembler */
13591350 ret = tcc_assemble(s1, 1);
1360− goto the_end;
1361− }
1362−
1363− if (filetype == AFF_TYPE_ASM) {
1351+ } else if (filetype == AFF_TYPE_ASM) {
13641352 /* preprocessed assembler */
13651353 ret = tcc_assemble(s1, 0);
1366− goto the_end;
1367− }
13681354 #endif
1355+ } else {
1356+ ElfW(Ehdr) ehdr;
1357+ int fd, obj_type;
13691358
1370− fd = file->fd;
1371− /* assume executable format: auto guess file type */
1372− size = read(fd, &ehdr, sizeof(ehdr));
1373− lseek(fd, 0, SEEK_SET);
1374− if (size <= 0) {
1375− tcc_error_noabort("could not read header");
1376− goto the_end;
1377− }
1378−
1379− if (size == sizeof(ehdr) &&
1380− ehdr.e_ident[0] == ELFMAG0 &&
1381− ehdr.e_ident[1] == ELFMAG1 &&
1382− ehdr.e_ident[2] == ELFMAG2 &&
1383− ehdr.e_ident[3] == ELFMAG3) {
1359+ fd = file->fd;
1360+ obj_type = tcc_object_type(fd, &ehdr);
1361+ lseek(fd, 0, SEEK_SET);
13841362
13851363 /* do not display line number if error */
13861364 file->line_num = 0;
1387− if (ehdr.e_type == ET_REL) {
1388− ret = tcc_load_object_file(s1, fd, 0);
1389− goto the_end;
13901365
1391− }
1366+ switch (obj_type) {
1367+ case AFF_BINTYPE_REL:
1368+ ret = tcc_load_object_file(s1, fd, 0);
1369+ break;
13921370 #ifndef TCC_TARGET_PE
1393− if (ehdr.e_type == ET_DYN) {
1371+ case AFF_BINTYPE_DYN:
13941372 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1373+ ret = 0;
13951374 #ifdef TCC_IS_NATIVE
1396− void *h;
1397− h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1398− if (h)
1375+ if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
1376+ ret = -1;
13991377 #endif
1400− ret = 0;
14011378 } else {
14021379 ret = tcc_load_dll(s1, fd, filename,
14031380 (flags & AFF_REFERENCED_DLL) != 0);
14041381 }
1405− goto the_end;
1406− }
1382+ break;
14071383 #endif
1408− tcc_error_noabort("unrecognized ELF file");
1409− goto the_end;
1410− }
1411−
1412− if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
1413− file->line_num = 0; /* do not display line number if error */
1414− ret = tcc_load_archive(s1, fd);
1415− goto the_end;
1416− }
1417−
1384+ case AFF_BINTYPE_AR:
1385+ ret = tcc_load_archive(s1, fd);
1386+ break;
14181387 #ifdef TCC_TARGET_COFF
1419− if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
1420− ret = tcc_load_coff(s1, fd);
1421− goto the_end;
1422− }
1388+ case AFF_BINTYPE_C67:
1389+ ret = tcc_load_coff(s1, fd);
1390+ break;
14231391 #endif
1424−
1392+ default:
14251393 #ifdef TCC_TARGET_PE
1426− ret = pe_load_file(s1, filename, fd);
1394+ ret = pe_load_file(s1, filename, fd);
14271395 #else
1428− /* as GNU ld, consider it is an ld script if not recognized */
1429− ret = tcc_load_ldscript(s1);
1396+ /* as GNU ld, consider it is an ld script if not recognized */
1397+ ret = tcc_load_ldscript(s1);
14301398 #endif
1431− if (ret < 0)
1432− tcc_error_noabort("unrecognized file type");
1433−
1434−the_end:
1399+ if (ret < 0)
1400+ tcc_error_noabort("unrecognized file type");
1401+ break;
1402+ }
1403+ }
14351404 tcc_close();
14361405 return ret;
14371406 }
@@ -1702,6 +1671,15 @@ static const FlagDef warning_defs[] = { · 264 unmodified lines
17021671 "implicit-function-declaration" },
17031672 };
17041673
1674+static int no_flag(const char **pp)
1675+{
1676+ const char *p = *pp;
1677+ if (*p != 'n' || *++p != 'o' || *++p != '-')
1678+ return 0;
1679+ *pp = p + 1;
1680+ return 1;
1681+}
1682+
17051683 ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
17061684 const char *name, int value)
17071685 {
@@ -1710,10 +1688,9 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, · 2 unmodified lines
17101688 const char *r;
17111689
17121690 r = name;
1713− if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
1714− r += 3;
1691+ if (no_flag(&r))
17151692 value = !value;
1716− }
1693+
17171694 for(i = 0, p = flags; i < nb_flags; i++, p++) {
17181695 if (!strcmp(r, p->name))
17191696 goto found;
@@ -1789,6 +1766,7 @@ static int strstart(const char *val, const char **str) · 69 unmodified lines
17891766 static int link_option(const char *str, const char *val, const char **ptr)
17901767 {
17911768 const char *p, *q;
1769+ int ret;
17921770
17931771 /* there should be 1 or 2 dashes */
17941772 if (*str++ != '-')
@@ -1800,6 +1778,13 @@ static int link_option(const char *str, const char *val, const char **ptr) · 5 unmodified lines
18001778 p = str;
18011779 q = val;
18021780
1781+ ret = 1;
1782+ if (q[0] == '?') {
1783+ ++q;
1784+ if (no_flag(&p))
1785+ ret = -1;
1786+ }
1787+
18031788 while (*q != '\0' && *q != '=') {
18041789 if (*p != *q)
18051790 return 0;
@@ -1816,7 +1801,7 @@ static int link_option(const char *str, const char *val, const char **ptr) · 10 unmodified lines
18161801 p++;
18171802 }
18181803 *ptr = p;
1819− return 1;
1804+ return ret;
18201805 }
18211806
18221807 static const char *skip_linker_arg(const char **str)
@@ -1842,6 +1827,7 @@ static int tcc_set_linker(TCCState *s, const char *option) · 19 unmodified lines
18421827 const char *p = NULL;
18431828 char *end = NULL;
18441829 int ignoring = 0;
1830+ int ret;
18451831
18461832 if (link_option(option, "Bsymbolic", &p)) {
18471833 s->symbolic = 1;
@@ -1915,6 +1901,8 @@ static int tcc_set_linker(TCCState *s, const char *option) · 67 unmodified lines
19151901 } else
19161902 goto err;
19171903 #endif
1904+ } else if (ret = link_option(option, "?whole-archive", &p), ret) {
1905+ s->alacarte_link = ret < 0;
19181906 } else if (p) {
19191907 return 0;
19201908 } else {
@@ -2152,7 +2140,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 231 unmodified lines
21522140 tcc_set_lib_path(s, optarg);
21532141 break;
21542142 case TCC_OPTION_l:
2155− args_parser_add_file(s, optarg, AFF_TYPE_LIB);
2143+ args_parser_add_file(s, optarg, AFF_TYPE_LIBWH - s->alacarte_link);
21562144 s->nb_libraries++;
21572145 break;
21582146 case TCC_OPTION_pthread:
@@ -2295,8 +2283,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 136 unmodified lines
22952283 printf ("%s\n", TCC_VERSION);
22962284 exit(0);
22972285 break;
2298− case TCC_OPTION_traditional:
2299− break;
23002286 case TCC_OPTION_x:
23012287 if (*optarg == 'c')
23022288 s->filetype = AFF_TYPE_C;
@@ -2312,6 +2298,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 9 unmodified lines
23122298 if (x > 0)
23132299 tcc_define_symbol(s, "__OPTIMIZE__", NULL);
23142300 break;
2301+ case TCC_OPTION_traditional:
23152302 case TCC_OPTION_pedantic:
23162303 case TCC_OPTION_pipe:
23172304 case TCC_OPTION_s:
tcc.c+4−2
@@ -314,7 +314,8 @@ int main(int argc, char **argv) · 313 unmodified lines
314314 /* compile or add each files or library */
315315 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
316316 struct filespec *f = s->files[i];
317− if (f->type == AFF_TYPE_LIB) {
317+ if (f->type >= AFF_TYPE_LIB) {
318+ s->alacarte_link = f->type == AFF_TYPE_LIB;
318319 if (tcc_add_library_err(s, f->name) < 0)
319320 ret = 1;
320321 } else {
@@ -323,10 +324,11 @@ int main(int argc, char **argv) · 2 unmodified lines
323324 s->filetype = f->type;
324325 if (tcc_add_file(s, f->name) < 0)
325326 ret = 1;
326− s->filetype = AFF_TYPE_NONE;
327327 if (!first_file)
328328 first_file = f->name;
329329 }
330+ s->filetype = AFF_TYPE_NONE;
331+ s->alacarte_link = 1;
330332 }
331333
332334 if (0 == ret) {
tcc.h+14−6
@@ -1143,12 +1143,19 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1142 unmodified lines
11431143 #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
11441144 #define AFF_PREPROCESS 0x40 /* preprocess file */
11451145 /* combined with: */
1146−#define AFF_TYPE_NONE 0
1147−#define AFF_TYPE_C 1
1148−#define AFF_TYPE_ASM 2
1149−#define AFF_TYPE_ASMPP 3
1150−#define AFF_TYPE_BIN 4
1151−#define AFF_TYPE_LIB 5
1146+#define AFF_TYPE_NONE 0
1147+#define AFF_TYPE_C 1
1148+#define AFF_TYPE_ASM 2
1149+#define AFF_TYPE_ASMPP 3
1150+#define AFF_TYPE_BIN 4
1151+#define AFF_TYPE_LIB 5
1152+#define AFF_TYPE_LIBWH 6
1153+/* values from tcc_object_type(...) */
1154+#define AFF_BINTYPE_REL 1
1155+#define AFF_BINTYPE_DYN 2
1156+#define AFF_BINTYPE_AR 3
1157+#define AFF_BINTYPE_C67 4
1158+
11521159
11531160 ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
11541161
@@ -1348,6 +1355,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s); · 193 unmodified lines
13481355 ST_FUNC void relocate_plt(TCCState *s1);
13491356
13501357 ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
1358+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
13511359 ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
13521360 ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
13531361 ST_FUNC void tcc_add_bcheck(TCCState *s1);
tccelf.c+26−17
@@ -2725,6 +2725,25 @@ typedef struct SectionMergeInfo { · 2724 unmodified lines
27252725 uint8_t link_once; /* true if link once section */
27262726 } SectionMergeInfo;
27272727
2728+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2729+{
2730+ int size = read(fd, h, sizeof *h);
2731+ if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2732+ if (h->e_type == ET_REL)
2733+ return AFF_BINTYPE_REL;
2734+ if (h->e_type == ET_DYN)
2735+ return AFF_BINTYPE_DYN;
2736+ } else if (size >= 8) {
2737+ if (0 == memcmp(h, ARMAG, 8))
2738+ return AFF_BINTYPE_AR;
2739+#ifdef TCC_TARGET_COFF
2740+ if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2741+ return AFF_BINTYPE_C67;
2742+#endif
2743+ }
2744+ return 0;
2745+}
2746+
27282747 /* load an object file and merge it with current files */
27292748 /* XXX: handle correctly stab (debug) info */
27302749 ST_FUNC int tcc_load_object_file(TCCState *s1,
@@ -2746,15 +2765,8 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 15 unmodified lines
27462765
27472766 stab_index = stabstr_index = 0;
27482767
2749− if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2750− goto fail1;
2751− if (ehdr.e_ident[0] != ELFMAG0 ||
2752− ehdr.e_ident[1] != ELFMAG1 ||
2753− ehdr.e_ident[2] != ELFMAG2 ||
2754− ehdr.e_ident[3] != ELFMAG3)
2755− goto fail1;
2756− /* test if object file */
2757− if (ehdr.e_type != ET_REL)
2768+ lseek(fd, file_offset, SEEK_SET);
2769+ if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
27582770 goto fail1;
27592771 /* test CPU specific stuff */
27602772 if (ehdr.e_ident[5] != ELFDATA2LSB ||
@@ -3052,7 +3064,6 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) · 291 unmodified lines
30523064 if(sym->st_shndx == SHN_UNDEF) {
30533065 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
30543066 ++bound;
3055− lseek(fd, off, SEEK_SET);
30563067 if(tcc_load_object_file(s1, fd, off) < 0) {
30573068 fail:
30583069 ret = -1;
@@ -3105,14 +3116,12 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd) · 46 unmodified lines
31053116 /* coff symbol table : we handle it */
31063117 if(s1->alacarte_link)
31073118 return tcc_load_alacarte(s1, fd, size);
3108− } else if (!strcmp(ar_name, "//") ||
3109− !strcmp(ar_name, "__.SYMDEF") ||
3110− !strcmp(ar_name, "__.SYMDEF/") ||
3111− !strcmp(ar_name, "ARFILENAMES/")) {
3112− /* skip symbol table or archive names */
31133119 } else {
3114− if (tcc_load_object_file(s1, fd, file_offset) < 0)
3115− return -1;
3120+ ElfW(Ehdr) ehdr;
3121+ if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3122+ if (tcc_load_object_file(s1, fd, file_offset) < 0)
3123+ return -1;
3124+ }
31163125 }
31173126 lseek(fd, file_offset + size, SEEK_SET);
31183127 }
tccpe.c+1−1
@@ -1664,7 +1664,7 @@ ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) · 1663 unmodified lines
16641664 ret = pe_load_def(s1, fd);
16651665 else if (pe_load_res(s1, fd) == 0)
16661666 ret = 0;
1667− else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
1667+ else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
16681668 ret = pe_load_dll(s1, tcc_basename(filename), fd);
16691669 return ret;
16701670 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t