| @@ -1298,10 +1298,9 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 1297 unmodified lines |
| 1298 | 1298 | |
| 1299 | 1299 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) |
| 1300 | 1300 | { |
| 1301 | | − ElfW(Ehdr) ehdr; |
| 1302 | | − int fd, ret, size; |
| 1303 | | − int filetype = flags & 0x0F; |
| 1301 | + int ret, filetype; |
| 1304 | 1302 | |
| 1303 | + filetype = flags & 0x0F; |
| 1305 | 1304 | if (filetype == 0) { |
| 1306 | 1305 | /* use a file extension to detect a filetype */ |
| 1307 | 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 | 1322 | /* open the file */ |
| 1334 | 1323 | ret = tcc_open(s1, filename); |
| 1335 | 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 | 1331 | dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, |
| 1343 | 1332 | tcc_strdup(filename)); |
| 1344 | 1333 | |
| 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; |
| 1348 | 1340 | } |
| 1341 | +#endif |
| 1349 | 1342 | |
| 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) { |
| 1352 | 1346 | ret = tcc_compile(s1); |
| 1353 | | − goto the_end; |
| 1354 | | − } |
| 1355 | | − |
| 1356 | 1347 | #ifdef CONFIG_TCC_ASM |
| 1357 | | − if (filetype == AFF_TYPE_ASMPP) { |
| 1348 | + } else if (filetype == AFF_TYPE_ASMPP) { |
| 1358 | 1349 | /* non preprocessed assembler */ |
| 1359 | 1350 | ret = tcc_assemble(s1, 1); |
| 1360 | | − goto the_end; |
| 1361 | | − } |
| 1362 | | − |
| 1363 | | − if (filetype == AFF_TYPE_ASM) { |
| 1351 | + } else if (filetype == AFF_TYPE_ASM) { |
| 1364 | 1352 | /* preprocessed assembler */ |
| 1365 | 1353 | ret = tcc_assemble(s1, 0); |
| 1366 | | − goto the_end; |
| 1367 | | − } |
| 1368 | 1354 | #endif |
| 1355 | + } else { |
| 1356 | + ElfW(Ehdr) ehdr; |
| 1357 | + int fd, obj_type; |
| 1369 | 1358 | |
| 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); |
| 1384 | 1362 | |
| 1385 | 1363 | /* do not display line number if error */ |
| 1386 | 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 | 1370 | #ifndef TCC_TARGET_PE |
| 1393 | | − if (ehdr.e_type == ET_DYN) { |
| 1371 | + case AFF_BINTYPE_DYN: |
| 1394 | 1372 | if (s1->output_type == TCC_OUTPUT_MEMORY) { |
| 1373 | + ret = 0; |
| 1395 | 1374 | #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; |
| 1399 | 1377 | #endif |
| 1400 | | − ret = 0; |
| 1401 | 1378 | } else { |
| 1402 | 1379 | ret = tcc_load_dll(s1, fd, filename, |
| 1403 | 1380 | (flags & AFF_REFERENCED_DLL) != 0); |
| 1404 | 1381 | } |
| 1405 | | − goto the_end; |
| 1406 | | − } |
| 1382 | + break; |
| 1407 | 1383 | #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; |
| 1418 | 1387 | #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; |
| 1423 | 1391 | #endif |
| 1424 | | − |
| 1392 | + default: |
| 1425 | 1393 | #ifdef TCC_TARGET_PE |
| 1426 | | − ret = pe_load_file(s1, filename, fd); |
| 1394 | + ret = pe_load_file(s1, filename, fd); |
| 1427 | 1395 | #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); |
| 1430 | 1398 | #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 | + } |
| 1435 | 1404 | tcc_close(); |
| 1436 | 1405 | return ret; |
| 1437 | 1406 | } |
| @@ -1702,6 +1671,15 @@ static const FlagDef warning_defs[] = { · 264 unmodified lines |
| 1702 | 1671 | "implicit-function-declaration" }, |
| 1703 | 1672 | }; |
| 1704 | 1673 | |
| 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 | + |
| 1705 | 1683 | ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, |
| 1706 | 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 | 1688 | const char *r; |
| 1711 | 1689 | |
| 1712 | 1690 | r = name; |
| 1713 | | − if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') { |
| 1714 | | − r += 3; |
| 1691 | + if (no_flag(&r)) |
| 1715 | 1692 | value = !value; |
| 1716 | | − } |
| 1693 | + |
| 1717 | 1694 | for(i = 0, p = flags; i < nb_flags; i++, p++) { |
| 1718 | 1695 | if (!strcmp(r, p->name)) |
| 1719 | 1696 | goto found; |
| @@ -1789,6 +1766,7 @@ static int strstart(const char *val, const char **str) · 69 unmodified lines |
| 1789 | 1766 | static int link_option(const char *str, const char *val, const char **ptr) |
| 1790 | 1767 | { |
| 1791 | 1768 | const char *p, *q; |
| 1769 | + int ret; |
| 1792 | 1770 | |
| 1793 | 1771 | /* there should be 1 or 2 dashes */ |
| 1794 | 1772 | if (*str++ != '-') |
| @@ -1800,6 +1778,13 @@ static int link_option(const char *str, const char *val, const char **ptr) · 5 unmodified lines |
| 1800 | 1778 | p = str; |
| 1801 | 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 | 1788 | while (*q != '\0' && *q != '=') { |
| 1804 | 1789 | if (*p != *q) |
| 1805 | 1790 | return 0; |
| @@ -1816,7 +1801,7 @@ static int link_option(const char *str, const char *val, const char **ptr) · 10 unmodified lines |
| 1816 | 1801 | p++; |
| 1817 | 1802 | } |
| 1818 | 1803 | *ptr = p; |
| 1819 | | − return 1; |
| 1804 | + return ret; |
| 1820 | 1805 | } |
| 1821 | 1806 | |
| 1822 | 1807 | 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 |
| 1842 | 1827 | const char *p = NULL; |
| 1843 | 1828 | char *end = NULL; |
| 1844 | 1829 | int ignoring = 0; |
| 1830 | + int ret; |
| 1845 | 1831 | |
| 1846 | 1832 | if (link_option(option, "Bsymbolic", &p)) { |
| 1847 | 1833 | s->symbolic = 1; |
| @@ -1915,6 +1901,8 @@ static int tcc_set_linker(TCCState *s, const char *option) · 67 unmodified lines |
| 1915 | 1901 | } else |
| 1916 | 1902 | goto err; |
| 1917 | 1903 | #endif |
| 1904 | + } else if (ret = link_option(option, "?whole-archive", &p), ret) { |
| 1905 | + s->alacarte_link = ret < 0; |
| 1918 | 1906 | } else if (p) { |
| 1919 | 1907 | return 0; |
| 1920 | 1908 | } else { |
| @@ -2152,7 +2140,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 231 unmodified lines |
| 2152 | 2140 | tcc_set_lib_path(s, optarg); |
| 2153 | 2141 | break; |
| 2154 | 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 | 2144 | s->nb_libraries++; |
| 2157 | 2145 | break; |
| 2158 | 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 | 2283 | printf ("%s\n", TCC_VERSION); |
| 2296 | 2284 | exit(0); |
| 2297 | 2285 | break; |
| 2298 | | − case TCC_OPTION_traditional: |
| 2299 | | − break; |
| 2300 | 2286 | case TCC_OPTION_x: |
| 2301 | 2287 | if (*optarg == 'c') |
| 2302 | 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 | 2298 | if (x > 0) |
| 2313 | 2299 | tcc_define_symbol(s, "__OPTIMIZE__", NULL); |
| 2314 | 2300 | break; |
| 2301 | + case TCC_OPTION_traditional: |
| 2315 | 2302 | case TCC_OPTION_pedantic: |
| 2316 | 2303 | case TCC_OPTION_pipe: |
| 2317 | 2304 | case TCC_OPTION_s: |