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
1298 1298
1299ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)1299ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
1300{1300{
1301 ElfW(Ehdr) ehdr;1301 int ret, filetype;
1302 int fd, ret, size;
1303 int filetype = flags & 0x0F;
1304 1302
1303 filetype = flags & 0x0F;
1305 if (filetype == 0) {1304 if (filetype == 0) {
1306 /* use a file extension to detect a filetype */1305 /* use a file extension to detect a filetype */
1307 const char *ext = tcc_fileextension(filename);1306 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
1320 }1319 }
1321 }1320 }
1322 1321
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
1333 /* open the file */1322 /* open the file */
1334 ret = tcc_open(s1, filename);1323 ret = tcc_open(s1, filename);
1335 if (ret < 0) {1324 if (ret < 0) {
@@ -1342,96 +1331,76 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 6 unmodified lines
1342 dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,1331 dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
1343 tcc_strdup(filename));1332 tcc_strdup(filename));
1344 1333
1345 if (flags & AFF_PREPROCESS) {1334 parse_flags = 0;
1346 ret = tcc_preprocess(s1);1335#ifdef CONFIG_TCC_ASM
1347 goto the_end;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;
1348 }1340 }
1341#endif
1349 1342
1350 if (filetype == AFF_TYPE_C) {1343 if (flags & AFF_PREPROCESS) {
1351 /* C file assumed */1344 ret = tcc_preprocess(s1);
1345 } else if (filetype == AFF_TYPE_C) {
1352 ret = tcc_compile(s1);1346 ret = tcc_compile(s1);
1353 goto the_end;
1354 }
1355
1356#ifdef CONFIG_TCC_ASM1347#ifdef CONFIG_TCC_ASM
1357 if (filetype == AFF_TYPE_ASMPP) {1348 } else if (filetype == AFF_TYPE_ASMPP) {
1358 /* non preprocessed assembler */1349 /* non preprocessed assembler */
1359 ret = tcc_assemble(s1, 1);1350 ret = tcc_assemble(s1, 1);
1360 goto the_end;1351 } else if (filetype == AFF_TYPE_ASM) {
1361 }
1362
1363 if (filetype == AFF_TYPE_ASM) {
1364 /* preprocessed assembler */1352 /* preprocessed assembler */
1365 ret = tcc_assemble(s1, 0);1353 ret = tcc_assemble(s1, 0);
1366 goto the_end;
1367 }
1368#endif1354#endif
1355 } else {
1356 ElfW(Ehdr) ehdr;
1357 int fd, obj_type;
1369 1358
1370 fd = file->fd;1359 fd = file->fd;
1371 /* assume executable format: auto guess file type */1360 obj_type = tcc_object_type(fd, &ehdr);
1372 size = read(fd, &ehdr, sizeof(ehdr));1361 lseek(fd, 0, SEEK_SET);
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) {
1384 1362
1385 /* do not display line number if error */1363 /* do not display line number if error */
1386 file->line_num = 0;1364 file->line_num = 0;
1387 if (ehdr.e_type == ET_REL) {
1388 ret = tcc_load_object_file(s1, fd, 0);
1389 goto the_end;
1390 1365
1391 }1366 switch (obj_type) {
1367 case AFF_BINTYPE_REL:
1368 ret = tcc_load_object_file(s1, fd, 0);
1369 break;
1392#ifndef TCC_TARGET_PE1370#ifndef TCC_TARGET_PE
1393 if (ehdr.e_type == ET_DYN) {1371 case AFF_BINTYPE_DYN:
1394 if (s1->output_type == TCC_OUTPUT_MEMORY) {1372 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1373 ret = 0;
1395#ifdef TCC_IS_NATIVE1374#ifdef TCC_IS_NATIVE
1396 void *h;1375 if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
1397 h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);1376 ret = -1;
1398 if (h)
1399#endif1377#endif
1400 ret = 0;
1401 } else {1378 } else {
1402 ret = tcc_load_dll(s1, fd, filename,1379 ret = tcc_load_dll(s1, fd, filename,
1403 (flags & AFF_REFERENCED_DLL) != 0);1380 (flags & AFF_REFERENCED_DLL) != 0);
1404 }1381 }
1405 goto the_end;1382 break;
1406 }
1407#endif1383#endif
1408 tcc_error_noabort("unrecognized ELF file");1384 case AFF_BINTYPE_AR:
1409 goto the_end;1385 ret = tcc_load_archive(s1, fd);
1410 }1386 break;
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
1418#ifdef TCC_TARGET_COFF1387#ifdef TCC_TARGET_COFF
1419 if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {1388 case AFF_BINTYPE_C67:
1420 ret = tcc_load_coff(s1, fd);1389 ret = tcc_load_coff(s1, fd);
1421 goto the_end;1390 break;
1422 }
1423#endif1391#endif
1424 1392 default:
1425#ifdef TCC_TARGET_PE1393#ifdef TCC_TARGET_PE
1426 ret = pe_load_file(s1, filename, fd);1394 ret = pe_load_file(s1, filename, fd);
1427#else1395#else
1428 /* as GNU ld, consider it is an ld script if not recognized */1396 /* as GNU ld, consider it is an ld script if not recognized */
1429 ret = tcc_load_ldscript(s1);1397 ret = tcc_load_ldscript(s1);
1430#endif1398#endif
1431 if (ret < 0)1399 if (ret < 0)
1432 tcc_error_noabort("unrecognized file type");1400 tcc_error_noabort("unrecognized file type");
1433 1401 break;
1434the_end:1402 }
1403 }
1435 tcc_close();1404 tcc_close();
1436 return ret;1405 return ret;
1437}1406}
@@ -1702,6 +1671,15 @@ static const FlagDef warning_defs[] = { · 264 unmodified lines
1702 "implicit-function-declaration" },1671 "implicit-function-declaration" },
1703};1672};
1704 1673
1674static 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
1705ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,1683ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
1706 const char *name, int value)1684 const char *name, int value)
1707{1685{
@@ -1710,10 +1688,9 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, · 2 unmodified lines
1710 const char *r;1688 const char *r;
1711 1689
1712 r = name;1690 r = name;
1713 if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {1691 if (no_flag(&r))
1714 r += 3;
1715 value = !value;1692 value = !value;
1716 }1693
1717 for(i = 0, p = flags; i < nb_flags; i++, p++) {1694 for(i = 0, p = flags; i < nb_flags; i++, p++) {
1718 if (!strcmp(r, p->name))1695 if (!strcmp(r, p->name))
1719 goto found;1696 goto found;
@@ -1789,6 +1766,7 @@ static int strstart(const char *val, const char **str) · 69 unmodified lines
1789static int link_option(const char *str, const char *val, const char **ptr)1766static int link_option(const char *str, const char *val, const char **ptr)
1790{1767{
1791 const char *p, *q;1768 const char *p, *q;
1769 int ret;
1792 1770
1793 /* there should be 1 or 2 dashes */1771 /* there should be 1 or 2 dashes */
1794 if (*str++ != '-')1772 if (*str++ != '-')
@@ -1800,6 +1778,13 @@ static int link_option(const char *str, const char *val, const char **ptr) · 5 unmodified lines
1800 p = str;1778 p = str;
1801 q = val;1779 q = val;
1802 1780
1781 ret = 1;
1782 if (q[0] == '?') {
1783 ++q;
1784 if (no_flag(&p))
1785 ret = -1;
1786 }
1787
1803 while (*q != '\0' && *q != '=') {1788 while (*q != '\0' && *q != '=') {
1804 if (*p != *q)1789 if (*p != *q)
1805 return 0;1790 return 0;
@@ -1816,7 +1801,7 @@ static int link_option(const char *str, const char *val, const char **ptr) · 10 unmodified lines
1816 p++;1801 p++;
1817 }1802 }
1818 *ptr = p;1803 *ptr = p;
1819 return 1;1804 return ret;
1820}1805}
1821 1806
1822static const char *skip_linker_arg(const char **str)1807static 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
1842 const char *p = NULL;1827 const char *p = NULL;
1843 char *end = NULL;1828 char *end = NULL;
1844 int ignoring = 0;1829 int ignoring = 0;
1830 int ret;
1845 1831
1846 if (link_option(option, "Bsymbolic", &p)) {1832 if (link_option(option, "Bsymbolic", &p)) {
1847 s->symbolic = 1;1833 s->symbolic = 1;
@@ -1915,6 +1901,8 @@ static int tcc_set_linker(TCCState *s, const char *option) · 67 unmodified lines
1915 } else1901 } else
1916 goto err;1902 goto err;
1917#endif1903#endif
1904 } else if (ret = link_option(option, "?whole-archive", &p), ret) {
1905 s->alacarte_link = ret < 0;
1918 } else if (p) {1906 } else if (p) {
1919 return 0;1907 return 0;
1920 } else {1908 } else {
@@ -2152,7 +2140,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 231 unmodified lines
2152 tcc_set_lib_path(s, optarg);2140 tcc_set_lib_path(s, optarg);
2153 break;2141 break;
2154 case TCC_OPTION_l:2142 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);
2156 s->nb_libraries++;2144 s->nb_libraries++;
2157 break;2145 break;
2158 case TCC_OPTION_pthread:2146 case TCC_OPTION_pthread:
@@ -2295,8 +2283,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 136 unmodified lines
2295 printf ("%s\n", TCC_VERSION);2283 printf ("%s\n", TCC_VERSION);
2296 exit(0);2284 exit(0);
2297 break;2285 break;
2298 case TCC_OPTION_traditional:
2299 break;
2300 case TCC_OPTION_x:2286 case TCC_OPTION_x:
2301 if (*optarg == 'c')2287 if (*optarg == 'c')
2302 s->filetype = AFF_TYPE_C;2288 s->filetype = AFF_TYPE_C;
@@ -2312,6 +2298,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 9 unmodified lines
2312 if (x > 0)2298 if (x > 0)
2313 tcc_define_symbol(s, "__OPTIMIZE__", NULL);2299 tcc_define_symbol(s, "__OPTIMIZE__", NULL);
2314 break;2300 break;
2301 case TCC_OPTION_traditional:
2315 case TCC_OPTION_pedantic:2302 case TCC_OPTION_pedantic:
2316 case TCC_OPTION_pipe:2303 case TCC_OPTION_pipe:
2317 case TCC_OPTION_s:2304 case TCC_OPTION_s:
tcc.c+4−2
@@ -314,7 +314,8 @@ int main(int argc, char **argv) · 313 unmodified lines
314 /* compile or add each files or library */314 /* compile or add each files or library */
315 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {315 for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
316 struct filespec *f = s->files[i];316 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;
318 if (tcc_add_library_err(s, f->name) < 0)319 if (tcc_add_library_err(s, f->name) < 0)
319 ret = 1;320 ret = 1;
320 } else {321 } else {
@@ -323,10 +324,11 @@ int main(int argc, char **argv) · 2 unmodified lines
323 s->filetype = f->type;324 s->filetype = f->type;
324 if (tcc_add_file(s, f->name) < 0)325 if (tcc_add_file(s, f->name) < 0)
325 ret = 1;326 ret = 1;
326 s->filetype = AFF_TYPE_NONE;
327 if (!first_file)327 if (!first_file)
328 first_file = f->name;328 first_file = f->name;
329 }329 }
330 s->filetype = AFF_TYPE_NONE;
331 s->alacarte_link = 1;
330 }332 }
331 333
332 if (0 == ret) {334 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
1143#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */1143#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
1144#define AFF_PREPROCESS 0x40 /* preprocess file */1144#define AFF_PREPROCESS 0x40 /* preprocess file */
1145/* combined with: */1145/* combined with: */
1146#define AFF_TYPE_NONE 01146#define AFF_TYPE_NONE 0
1147#define AFF_TYPE_C 11147#define AFF_TYPE_C 1
1148#define AFF_TYPE_ASM 21148#define AFF_TYPE_ASM 2
1149#define AFF_TYPE_ASMPP 31149#define AFF_TYPE_ASMPP 3
1150#define AFF_TYPE_BIN 41150#define AFF_TYPE_BIN 4
1151#define AFF_TYPE_LIB 51151#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
1152 1159
1153ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);1160ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
1154 1161
@@ -1348,6 +1355,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s); · 193 unmodified lines
1348ST_FUNC void relocate_plt(TCCState *s1);1355ST_FUNC void relocate_plt(TCCState *s1);
1349 1356
1350ST_FUNC void tcc_add_linker_symbols(TCCState *s1);1357ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
1358ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
1351ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);1359ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
1352ST_FUNC int tcc_load_archive(TCCState *s1, int fd);1360ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
1353ST_FUNC void tcc_add_bcheck(TCCState *s1);1361ST_FUNC void tcc_add_bcheck(TCCState *s1);
tccelf.c+26−17
@@ -2725,6 +2725,25 @@ typedef struct SectionMergeInfo { · 2724 unmodified lines
2725 uint8_t link_once; /* true if link once section */2725 uint8_t link_once; /* true if link once section */
2726} SectionMergeInfo;2726} SectionMergeInfo;
2727 2727
2728ST_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
2728/* load an object file and merge it with current files */2747/* load an object file and merge it with current files */
2729/* XXX: handle correctly stab (debug) info */2748/* XXX: handle correctly stab (debug) info */
2730ST_FUNC int tcc_load_object_file(TCCState *s1,2749ST_FUNC int tcc_load_object_file(TCCState *s1,
@@ -2746,15 +2765,8 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 15 unmodified lines
2746 2765
2747 stab_index = stabstr_index = 0;2766 stab_index = stabstr_index = 0;
2748 2767
2749 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))2768 lseek(fd, file_offset, SEEK_SET);
2750 goto fail1;2769 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
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)
2758 goto fail1;2770 goto fail1;
2759 /* test CPU specific stuff */2771 /* test CPU specific stuff */
2760 if (ehdr.e_ident[5] != ELFDATA2LSB ||2772 if (ehdr.e_ident[5] != ELFDATA2LSB ||
@@ -3052,7 +3064,6 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) · 291 unmodified lines
3052 if(sym->st_shndx == SHN_UNDEF) {3064 if(sym->st_shndx == SHN_UNDEF) {
3053 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);3065 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
3054 ++bound;3066 ++bound;
3055 lseek(fd, off, SEEK_SET);
3056 if(tcc_load_object_file(s1, fd, off) < 0) {3067 if(tcc_load_object_file(s1, fd, off) < 0) {
3057 fail:3068 fail:
3058 ret = -1;3069 ret = -1;
@@ -3105,14 +3116,12 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd) · 46 unmodified lines
3105 /* coff symbol table : we handle it */3116 /* coff symbol table : we handle it */
3106 if(s1->alacarte_link)3117 if(s1->alacarte_link)
3107 return tcc_load_alacarte(s1, fd, size);3118 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 */
3113 } else {3119 } else {
3114 if (tcc_load_object_file(s1, fd, file_offset) < 0)3120 ElfW(Ehdr) ehdr;
3115 return -1;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 }
3116 }3125 }
3117 lseek(fd, file_offset + size, SEEK_SET);3126 lseek(fd, file_offset + size, SEEK_SET);
3118 }3127 }
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
1664 ret = pe_load_def(s1, fd);1664 ret = pe_load_def(s1, fd);
1665 else if (pe_load_res(s1, fd) == 0)1665 else if (pe_load_res(s1, fd) == 0)
1666 ret = 0;1666 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))
1668 ret = pe_load_dll(s1, tcc_basename(filename), fd);1668 ret = pe_load_dll(s1, tcc_basename(filename), fd);
1669 return ret;1669 return ret;
1670}1670}

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