| @@ -1298,10 +1298,9 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 1297 unmodified lines |
| 1298 | | 1298 | |
| 1299 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) | 1299 | ST_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_ASM | 1347 | #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 | #endif | 1354 | #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_PE | 1370 | #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_NATIVE | 1374 | #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 | #endif | 1377 | #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 | #endif | 1383 | #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_COFF | 1387 | #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 | #endif | 1391 | #endif |
| 1424 | | 1392 | default: |
| 1425 | #ifdef TCC_TARGET_PE | 1393 | #ifdef TCC_TARGET_PE |
| 1426 | ret = pe_load_file(s1, filename, fd); | 1394 | ret = pe_load_file(s1, filename, fd); |
| 1427 | #else | 1395 | #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 | #endif | 1398 | #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; |
| 1434 | the_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 | |
| | 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 | ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, | 1683 | ST_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 |
| 1789 | static int link_option(const char *str, const char *val, const char **ptr) | 1766 | static 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 | |
| 1822 | static const char *skip_linker_arg(const char **str) | 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 | 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 | } else | 1901 | } else |
| 1916 | goto err; | 1902 | goto err; |
| 1917 | #endif | 1903 | #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: |