| @@ -1071,11 +1071,6 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 1070 unmodified lines |
| 1071 | 1071 | break; |
| 1072 | 1072 | } |
| 1073 | 1073 | } |
| 1074 | | − if (count) { |
| 1075 | | − /* allocate the section */ |
| 1076 | | − sr->sh_flags |= SHF_ALLOC; |
| 1077 | | − sr->sh_size = count * sizeof(ElfW_Rel); |
| 1078 | | − } |
| 1079 | 1074 | #endif |
| 1080 | 1075 | return count; |
| 1081 | 1076 | } |
| @@ -1566,29 +1561,8 @@ ST_FUNC void resolve_common_syms(TCCState *s1) · 484 unmodified lines |
| 1566 | 1561 | tcc_add_linker_symbols(s1); |
| 1567 | 1562 | } |
| 1568 | 1563 | |
| 1569 | | −static void tcc_output_binary(TCCState *s1, FILE *f, |
| 1570 | | − const int *sec_order) |
| 1571 | | −{ |
| 1572 | | − Section *s; |
| 1573 | | − int i, offset, size; |
| 1574 | | − |
| 1575 | | − offset = 0; |
| 1576 | | − for(i=1;i<s1->nb_sections;i++) { |
| 1577 | | − s = s1->sections[sec_order[i]]; |
| 1578 | | − if (s->sh_type != SHT_NOBITS && |
| 1579 | | − (s->sh_flags & SHF_ALLOC)) { |
| 1580 | | − while (offset < s->sh_offset) { |
| 1581 | | − fputc(0, f); |
| 1582 | | − offset++; |
| 1583 | | − } |
| 1584 | | − size = s->sh_size; |
| 1585 | | − fwrite(s->data, 1, size, f); |
| 1586 | | − offset += size; |
| 1587 | | − } |
| 1588 | | − } |
| 1589 | | −} |
| 1590 | | − |
| 1591 | 1564 | #ifndef ELF_OBJ_ONLY |
| 1565 | + |
| 1592 | 1566 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) |
| 1593 | 1567 | { |
| 1594 | 1568 | int sym_index = ELFW(R_SYM) (rel->r_info); |
| @@ -1791,43 +1765,40 @@ static void export_global_syms(TCCState *s1) · 196 unmodified lines |
| 1791 | 1765 | } |
| 1792 | 1766 | } |
| 1793 | 1767 | } |
| 1794 | | −#endif |
| 1795 | 1768 | |
| 1796 | | −/* Allocate strings for section names and decide if an unallocated section |
| 1797 | | − should be output. |
| 1798 | | − NOTE: the strsec section comes last, so its size is also correct ! */ |
| 1799 | | −static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) |
| 1769 | +/* decide if an unallocated section should be output. */ |
| 1770 | +static int set_sec_sizes(TCCState *s1) |
| 1800 | 1771 | { |
| 1801 | 1772 | int i; |
| 1802 | 1773 | Section *s; |
| 1803 | 1774 | int textrel = 0; |
| 1775 | + int file_type = s1->output_type; |
| 1804 | 1776 | |
| 1805 | 1777 | /* Allocate strings for section names */ |
| 1806 | 1778 | for(i = 1; i < s1->nb_sections; i++) { |
| 1807 | 1779 | s = s1->sections[i]; |
| 1808 | | − /* when generating a DLL, we include relocations but we may |
| 1809 | | − patch them */ |
| 1810 | | −#ifndef ELF_OBJ_ONLY |
| 1811 | | − if (file_type == TCC_OUTPUT_DLL && |
| 1812 | | − s->sh_type == SHT_RELX && |
| 1813 | | − !(s->sh_flags & SHF_ALLOC) && |
| 1814 | | − (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) && |
| 1815 | | − prepare_dynamic_rel(s1, s)) { |
| 1816 | | − if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE)) |
| 1817 | | − textrel = 1; |
| 1818 | | − } else |
| 1819 | | −#endif |
| 1820 | | − if ((s1->do_debug && s->sh_type != SHT_RELX) || |
| 1821 | | − file_type == TCC_OUTPUT_OBJ || |
| 1822 | | − (s->sh_flags & SHF_ALLOC) || |
| 1823 | | − i == (s1->nb_sections - 1) |
| 1780 | + if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) { |
| 1781 | + /* when generating a DLL, we include relocations but |
| 1782 | + we may patch them */ |
| 1783 | + if (file_type == TCC_OUTPUT_DLL |
| 1784 | + && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) { |
| 1785 | + int count = prepare_dynamic_rel(s1, s); |
| 1786 | + if (count) { |
| 1787 | + /* allocate the section */ |
| 1788 | + s->sh_flags |= SHF_ALLOC; |
| 1789 | + s->sh_size = count * sizeof(ElfW_Rel); |
| 1790 | + if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE)) |
| 1791 | + textrel = 1; |
| 1792 | + } |
| 1793 | + } |
| 1794 | + } else if ((s->sh_flags & SHF_ALLOC) |
| 1824 | 1795 | #ifdef TCC_TARGET_ARM |
| 1825 | | − || s->sh_type == SHT_ARM_ATTRIBUTES |
| 1796 | + || s->sh_type == SHT_ARM_ATTRIBUTES |
| 1826 | 1797 | #endif |
| 1827 | | − ) { |
| 1828 | | − /* we output all sections if debug or object file */ |
| 1798 | + || s1->do_debug) { |
| 1829 | 1799 | s->sh_size = s->data_offset; |
| 1830 | 1800 | } |
| 1801 | + |
| 1831 | 1802 | #ifdef TCC_TARGET_ARM |
| 1832 | 1803 | /* XXX: Suppress stack unwinding section. */ |
| 1833 | 1804 | if (s->sh_type == SHT_ARM_EXIDX) { |
| @@ -1835,13 +1806,12 @@ static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) · 1 unmodified line |
| 1835 | 1806 | s->sh_size = 0; |
| 1836 | 1807 | } |
| 1837 | 1808 | #endif |
| 1838 | | − if (s->sh_size || (s->sh_flags & SHF_ALLOC)) |
| 1839 | | − s->sh_name = put_elf_str(strsec, s->name); |
| 1809 | + |
| 1840 | 1810 | } |
| 1841 | | − strsec->sh_size = strsec->data_offset; |
| 1842 | 1811 | return textrel; |
| 1843 | 1812 | } |
| 1844 | 1813 | |
| 1814 | + |
| 1845 | 1815 | /* Info to be copied in dynamic section */ |
| 1846 | 1816 | struct dyn_inf { |
| 1847 | 1817 | Section *dynamic; |
| @@ -1858,23 +1828,29 @@ struct ro_inf { · 10 unmodified lines |
| 1858 | 1828 | addr_t sh_size; |
| 1859 | 1829 | }; |
| 1860 | 1830 | |
| 1831 | +static void alloc_sec_names( |
| 1832 | + TCCState *s1, int is_obj |
| 1833 | + ); |
| 1834 | + |
| 1835 | +static int layout_any_sections( |
| 1836 | + TCCState *s1, int file_offset, int *sec_order, int is_obj |
| 1837 | + ); |
| 1838 | + |
| 1861 | 1839 | /* Assign sections to segments and decide how are sections laid out when loaded |
| 1862 | 1840 | in memory. This function also fills corresponding program headers. */ |
| 1863 | 1841 | static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, |
| 1864 | 1842 | int phnum, int phfill, |
| 1865 | | − Section *interp, Section* strsec, |
| 1843 | + Section *interp, |
| 1866 | 1844 | struct ro_inf *roinf, int *sec_order) |
| 1867 | 1845 | { |
| 1868 | | − int i, sh_order_index, file_offset; |
| 1846 | + int i, file_offset; |
| 1869 | 1847 | Section *s; |
| 1870 | 1848 | |
| 1871 | | − sh_order_index = 1; |
| 1872 | 1849 | file_offset = 0; |
| 1873 | 1850 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) |
| 1874 | 1851 | file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); |
| 1875 | 1852 | |
| 1876 | | −#ifndef ELF_OBJ_ONLY |
| 1877 | | − if (phnum > 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */ |
| 1853 | + { |
| 1878 | 1854 | unsigned long s_align; |
| 1879 | 1855 | long long tmp; |
| 1880 | 1856 | addr_t addr; |
| @@ -1979,7 +1955,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 98 unmodified lines |
| 1979 | 1955 | if (k != 5) |
| 1980 | 1956 | continue; |
| 1981 | 1957 | } |
| 1982 | | − sec_order[sh_order_index++] = i; |
| 1958 | + *sec_order++ = i; |
| 1983 | 1959 | |
| 1984 | 1960 | /* section matches: we align it and add its size */ |
| 1985 | 1961 | tmp = addr; |
| @@ -2039,26 +2015,11 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 53 unmodified lines |
| 2039 | 2015 | } |
| 2040 | 2016 | } |
| 2041 | 2017 | } |
| 2042 | | −#endif /* ELF_OBJ_ONLY */ |
| 2043 | 2018 | |
| 2044 | 2019 | /* all other sections come after */ |
| 2045 | | − for(i = 1; i < s1->nb_sections; i++) { |
| 2046 | | − s = s1->sections[i]; |
| 2047 | | − if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) |
| 2048 | | − continue; |
| 2049 | | − sec_order[sh_order_index++] = i; |
| 2050 | | − |
| 2051 | | − file_offset = (file_offset + s->sh_addralign - 1) & |
| 2052 | | − ~(s->sh_addralign - 1); |
| 2053 | | − s->sh_offset = file_offset; |
| 2054 | | − if (s->sh_type != SHT_NOBITS) |
| 2055 | | − file_offset += s->sh_size; |
| 2056 | | − } |
| 2057 | | − |
| 2058 | | − return file_offset; |
| 2020 | + return layout_any_sections(s1, file_offset, sec_order, 0); |
| 2059 | 2021 | } |
| 2060 | 2022 | |
| 2061 | | −#ifndef ELF_OBJ_ONLY |
| 2062 | 2023 | /* put dynamic tag */ |
| 2063 | 2024 | static void put_dt(Section *dynamic, int dt, addr_t val) |
| 2064 | 2025 | { |
| @@ -2269,7 +2230,8 @@ static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf) · 204 unmodified lines |
| 2269 | 2230 | } |
| 2270 | 2231 | } |
| 2271 | 2232 | } |
| 2272 | | −#endif |
| 2233 | + |
| 2234 | +#endif /* ndef ELF_OBJ_ONLY */ |
| 2273 | 2235 | |
| 2274 | 2236 | /* Create an ELF file on disk. |
| 2275 | 2237 | This function handle ELF specific layout requirements */ |
| @@ -2390,6 +2352,28 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 114 unmodified lines |
| 2390 | 2352 | } |
| 2391 | 2353 | } |
| 2392 | 2354 | |
| 2355 | +static void tcc_output_binary(TCCState *s1, FILE *f, |
| 2356 | + const int *sec_order) |
| 2357 | +{ |
| 2358 | + Section *s; |
| 2359 | + int i, offset, size; |
| 2360 | + |
| 2361 | + offset = 0; |
| 2362 | + for(i=1;i<s1->nb_sections;i++) { |
| 2363 | + s = s1->sections[sec_order[i]]; |
| 2364 | + if (s->sh_type != SHT_NOBITS && |
| 2365 | + (s->sh_flags & SHF_ALLOC)) { |
| 2366 | + while (offset < s->sh_offset) { |
| 2367 | + fputc(0, f); |
| 2368 | + offset++; |
| 2369 | + } |
| 2370 | + size = s->sh_size; |
| 2371 | + fwrite(s->data, 1, size, f); |
| 2372 | + offset += size; |
| 2373 | + } |
| 2374 | + } |
| 2375 | +} |
| 2376 | + |
| 2393 | 2377 | /* Write an elf, coff or "binary" file */ |
| 2394 | 2378 | static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, |
| 2395 | 2379 | ElfW(Phdr) *phdr, int file_offset, int *sec_order) |
| @@ -2472,7 +2456,6 @@ static void tidy_section_headers(TCCState *s1, int *sec_order) · 76 unmodified lines |
| 2472 | 2456 | s1->nb_sections = nnew; |
| 2473 | 2457 | tcc_free(backmap); |
| 2474 | 2458 | } |
| 2475 | | −#endif |
| 2476 | 2459 | |
| 2477 | 2460 | #ifdef TCC_TARGET_ARM |
| 2478 | 2461 | static void create_arm_attribute_section(TCCState *s1) |
| @@ -2539,33 +2522,30 @@ static int elf_output_file(TCCState *s1, const char *filename) · 60 unmodified lines |
| 2539 | 2522 | struct dyn_inf dyninf = {0}; |
| 2540 | 2523 | struct ro_inf roinf; |
| 2541 | 2524 | ElfW(Phdr) *phdr; |
| 2542 | | − Section *strsec, *interp, *dynamic, *dynstr, *note = NULL; |
| 2543 | | −//#ifndef ELF_OBJ_ONLY |
| 2525 | + Section *interp, *dynamic, *dynstr, *note; |
| 2544 | 2526 | struct ro_inf *roinf_use = NULL; |
| 2545 | | −//#endif |
| 2527 | + int textrel; |
| 2546 | 2528 | |
| 2547 | 2529 | file_type = s1->output_type; |
| 2530 | + s1->nb_errors = 0; |
| 2531 | + ret = -1; |
| 2532 | + phdr = NULL; |
| 2533 | + sec_order = NULL; |
| 2534 | + interp = dynamic = dynstr = note = NULL; |
| 2548 | 2535 | |
| 2549 | 2536 | #ifdef TCC_TARGET_ARM |
| 2550 | 2537 | create_arm_attribute_section (s1); |
| 2551 | 2538 | #endif |
| 2539 | + |
| 2552 | 2540 | #if TARGETOS_OpenBSD |
| 2553 | | − if (file_type != TCC_OUTPUT_OBJ) |
| 2554 | | − note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD"); |
| 2541 | + note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD"); |
| 2555 | 2542 | #endif |
| 2543 | + |
| 2556 | 2544 | #if TARGETOS_NetBSD |
| 2557 | | − if (file_type != TCC_OUTPUT_OBJ) |
| 2558 | | − note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD"); |
| 2545 | + note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD"); |
| 2559 | 2546 | #endif |
| 2560 | 2547 | |
| 2561 | | − s1->nb_errors = 0; |
| 2562 | | − ret = -1; |
| 2563 | | − phdr = NULL; |
| 2564 | | − sec_order = NULL; |
| 2565 | | − interp = dynamic = dynstr = NULL; /* avoid warning */ |
| 2566 | | − |
| 2567 | | −#ifndef ELF_OBJ_ONLY |
| 2568 | | − if (file_type != TCC_OUTPUT_OBJ) { |
| 2548 | + { |
| 2569 | 2549 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ |
| 2570 | 2550 | tcc_add_runtime(s1); |
| 2571 | 2551 | resolve_common_syms(s1); |
| @@ -2612,17 +2592,11 @@ static int elf_output_file(TCCState *s1, const char *filename) · 40 unmodified lines |
| 2612 | 2592 | build_got_entries(s1); |
| 2613 | 2593 | version_add (s1); |
| 2614 | 2594 | } |
| 2615 | | −#endif |
| 2616 | 2595 | |
| 2617 | | − /* we add a section for symbols */ |
| 2618 | | − strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); |
| 2619 | | − put_elf_str(strsec, ""); |
| 2620 | | − |
| 2621 | | − /* Allocate strings for section names */ |
| 2622 | | − ret = alloc_sec_names(s1, file_type, strsec); |
| 2596 | + textrel = set_sec_sizes(s1); |
| 2597 | + alloc_sec_names(s1, 0); |
| 2623 | 2598 | |
| 2624 | | −#ifndef ELF_OBJ_ONLY |
| 2625 | | − if (dynamic) { |
| 2599 | + if (!s1->static_link) { |
| 2626 | 2600 | int i; |
| 2627 | 2601 | /* add a list of needed dlls */ |
| 2628 | 2602 | for(i = 0; i < s1->nb_loaded_dlls; i++) { |
| @@ -2640,7 +2614,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 11 unmodified lines |
| 2640 | 2614 | put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); |
| 2641 | 2615 | /* XXX: currently, since we do not handle PIC code, we |
| 2642 | 2616 | must relocate the readonly segments */ |
| 2643 | | − if (ret) |
| 2617 | + if (textrel) |
| 2644 | 2618 | put_dt(dynamic, DT_TEXTREL, 0); |
| 2645 | 2619 | } |
| 2646 | 2620 | |
| @@ -2655,16 +2629,13 @@ static int elf_output_file(TCCState *s1, const char *filename) · 8 unmodified lines |
| 2655 | 2629 | dynamic->sh_size = dynamic->data_offset; |
| 2656 | 2630 | dynstr->sh_size = dynstr->data_offset; |
| 2657 | 2631 | } |
| 2658 | | −#endif |
| 2659 | 2632 | |
| 2660 | 2633 | for (i = 1; i < s1->nb_sections && |
| 2661 | 2634 | !(s1->sections[i]->sh_flags & SHF_TLS); i++); |
| 2662 | 2635 | phfill = 2 + (i < s1->nb_sections); |
| 2663 | 2636 | |
| 2664 | 2637 | /* compute number of program headers */ |
| 2665 | | − if (file_type == TCC_OUTPUT_OBJ) |
| 2666 | | − phnum = phfill = 0; |
| 2667 | | − else if (file_type == TCC_OUTPUT_DLL) |
| 2638 | + if (file_type == TCC_OUTPUT_DLL) |
| 2668 | 2639 | phnum = 3; |
| 2669 | 2640 | else if (s1->static_link) |
| 2670 | 2641 | phnum = 3; |
| @@ -2673,31 +2644,25 @@ static int elf_output_file(TCCState *s1, const char *filename) · 2 unmodified lines |
| 2673 | 2644 | } |
| 2674 | 2645 | |
| 2675 | 2646 | phnum += note != NULL; |
| 2676 | | − |
| 2677 | | −#if !TARGETOS_FreeBSD && !TARGETOS_NetBSD && !defined(__APPLE__) && !defined(_WIN32) |
| 2647 | +#if !TARGETOS_FreeBSD && !TARGETOS_NetBSD |
| 2678 | 2648 | /* GNU_RELRO */ |
| 2679 | | − if (file_type != TCC_OUTPUT_OBJ) |
| 2680 | | − phnum++, roinf_use = &roinf; |
| 2649 | + phnum++, roinf_use = &roinf; |
| 2681 | 2650 | #endif |
| 2682 | 2651 | |
| 2683 | 2652 | /* allocate program segment headers */ |
| 2684 | 2653 | phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); |
| 2685 | | − |
| 2686 | 2654 | /* compute number of sections */ |
| 2687 | 2655 | shnum = s1->nb_sections; |
| 2688 | | − |
| 2689 | 2656 | /* this array is used to reorder sections in the output file */ |
| 2690 | 2657 | sec_order = tcc_malloc(sizeof(int) * shnum); |
| 2691 | 2658 | sec_order[0] = 0; |
| 2692 | 2659 | |
| 2693 | 2660 | /* compute section to program header mapping */ |
| 2694 | | − file_offset = layout_sections(s1, phdr, phnum, phfill, interp, strsec, |
| 2695 | | − &roinf, sec_order); |
| 2661 | + file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1); |
| 2696 | 2662 | |
| 2697 | | −#ifndef ELF_OBJ_ONLY |
| 2698 | 2663 | /* Fill remaining program header and finalize relocation related to dynamic |
| 2699 | 2664 | linking. */ |
| 2700 | | − if (file_type != TCC_OUTPUT_OBJ) { |
| 2665 | + { |
| 2701 | 2666 | fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use); |
| 2702 | 2667 | if (dynamic) { |
| 2703 | 2668 | ElfW(Sym) *sym; |
| @@ -2735,32 +2700,85 @@ static int elf_output_file(TCCState *s1, const char *filename) · 31 unmodified lines |
| 2735 | 2700 | else if (s1->got) |
| 2736 | 2701 | fill_local_got_entries(s1); |
| 2737 | 2702 | } |
| 2738 | | −#endif |
| 2739 | | − |
| 2740 | 2703 | /* Create the ELF file with name 'filename' */ |
| 2741 | 2704 | ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); |
| 2742 | 2705 | s1->nb_sections = shnum; |
| 2743 | | − goto the_end; |
| 2706 | + |
| 2744 | 2707 | the_end: |
| 2745 | 2708 | tcc_free(sec_order); |
| 2746 | 2709 | tcc_free(phdr); |
| 2747 | 2710 | return ret; |
| 2748 | 2711 | } |
| 2712 | +#endif /* ndef ELF_OBJ_ONLY */ |
| 2713 | + |
| 2714 | +/* Allocate strings for section names */ |
| 2715 | +static void alloc_sec_names(TCCState *s1, int is_obj) |
| 2716 | +{ |
| 2717 | + int i; |
| 2718 | + Section *s, *strsec; |
| 2719 | + |
| 2720 | + strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); |
| 2721 | + put_elf_str(strsec, ""); |
| 2722 | + for(i = 1; i < s1->nb_sections; i++) { |
| 2723 | + s = s1->sections[i]; |
| 2724 | + if (is_obj) |
| 2725 | + s->sh_size = s->data_offset; |
| 2726 | + if (s->sh_size || (s->sh_flags & SHF_ALLOC)) |
| 2727 | + s->sh_name = put_elf_str(strsec, s->name); |
| 2728 | + } |
| 2729 | + strsec->sh_size = strsec->data_offset; |
| 2730 | +} |
| 2731 | + |
| 2732 | +static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj) |
| 2733 | +{ |
| 2734 | + int i; |
| 2735 | + Section *s; |
| 2736 | + for(i = 1; i < s1->nb_sections; i++) { |
| 2737 | + s = s1->sections[i]; |
| 2738 | + if (!is_obj && (s->sh_flags & SHF_ALLOC)) |
| 2739 | + continue; |
| 2740 | + *sec_order++ = i; |
| 2741 | + file_offset = (file_offset + s->sh_addralign - 1) & |
| 2742 | + ~(s->sh_addralign - 1); |
| 2743 | + s->sh_offset = file_offset; |
| 2744 | + if (s->sh_type != SHT_NOBITS) |
| 2745 | + file_offset += s->sh_size; |
| 2746 | + } |
| 2747 | + return file_offset; |
| 2748 | +} |
| 2749 | + |
| 2750 | +/* Output an elf .o file */ |
| 2751 | +static int elf_output_obj(TCCState *s1, const char *filename) |
| 2752 | +{ |
| 2753 | + int ret, file_offset; |
| 2754 | + int *sec_order; |
| 2755 | + s1->nb_errors = 0; |
| 2756 | + |
| 2757 | + /* Allocate strings for section names */ |
| 2758 | + alloc_sec_names(s1, 1); |
| 2759 | + |
| 2760 | + /* this array is used to reorder sections in the output file */ |
| 2761 | + sec_order = tcc_malloc(sizeof(int) * s1->nb_sections); |
| 2762 | + sec_order[0] = 0; |
| 2763 | + file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1); |
| 2764 | + |
| 2765 | + /* Create the ELF file with name 'filename' */ |
| 2766 | + ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order); |
| 2767 | + tcc_free(sec_order); |
| 2768 | + return ret; |
| 2769 | +} |
| 2749 | 2770 | |
| 2750 | 2771 | LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename) |
| 2751 | 2772 | { |
| 2752 | | − int ret; |
| 2773 | + if (s->output_type == TCC_OUTPUT_OBJ) |
| 2774 | + return elf_output_obj(s, filename); |
| 2753 | 2775 | #ifdef TCC_TARGET_PE |
| 2754 | | − if (s->output_type != TCC_OUTPUT_OBJ) { |
| 2755 | | − ret = pe_output_file(s, filename); |
| 2756 | | − } else |
| 2776 | + return pe_output_file(s, filename); |
| 2757 | 2777 | #elif TCC_TARGET_MACHO |
| 2758 | | − if (s->output_type != TCC_OUTPUT_OBJ) { |
| 2759 | | − ret = macho_output_file(s, filename); |
| 2760 | | − } else |
| 2778 | + return macho_output_file(s, filename); |
| 2779 | +#else |
| 2780 | + return elf_output_file(s, filename); |
| 2761 | 2781 | #endif |
| 2762 | | − ret = elf_output_file(s, filename); |
| 2763 | | − return ret; |
| 2764 | 2782 | } |
| 2765 | 2783 | |
| 2766 | 2784 | ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) { |