| @@ -1488,7 +1488,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 1487 unmodified lines |
| 1488 | 1488 | s = have_section(s1, section_name); |
| 1489 | 1489 | if (!s || !(s->sh_flags & SHF_ALLOC)) { |
| 1490 | 1490 | end_offset = 0; |
| 1491 | | − s = data_section; |
| 1491 | + s = text_section; |
| 1492 | 1492 | } else { |
| 1493 | 1493 | end_offset = s->data_offset; |
| 1494 | 1494 | } |
| @@ -1823,11 +1823,14 @@ static void tcc_add_linker_symbols(TCCState *s1) · 328 unmodified lines |
| 1823 | 1823 | for(i = 1; i < s1->nb_sections; i++) { |
| 1824 | 1824 | s = s1->sections[i]; |
| 1825 | 1825 | if ((s->sh_flags & SHF_ALLOC) |
| 1826 | | − && (s->sh_type == SHT_PROGBITS |
| 1826 | + && (s->sh_type == SHT_PROGBITS || s->sh_type == SHT_NOBITS |
| 1827 | 1827 | || s->sh_type == SHT_STRTAB)) { |
| 1828 | | − const char *p; |
| 1829 | 1828 | /* check if section name can be expressed in C */ |
| 1830 | | − p = s->name; |
| 1829 | + const char *p0, *p; |
| 1830 | + p0 = s->name; |
| 1831 | + if (*p0 == '.') |
| 1832 | + ++p0; |
| 1833 | + p = p0; |
| 1831 | 1834 | for(;;) { |
| 1832 | 1835 | int c = *p; |
| 1833 | 1836 | if (!c) |
| @@ -1836,9 +1839,9 @@ static void tcc_add_linker_symbols(TCCState *s1) · 2 unmodified lines |
| 1836 | 1839 | goto next_sec; |
| 1837 | 1840 | p++; |
| 1838 | 1841 | } |
| 1839 | | − snprintf(buf, sizeof(buf), "__start_%s", s->name); |
| 1842 | + snprintf(buf, sizeof(buf), "__start_%s", p0); |
| 1840 | 1843 | set_global_sym(s1, buf, s, 0); |
| 1841 | | − snprintf(buf, sizeof(buf), "__stop_%s", s->name); |
| 1844 | + snprintf(buf, sizeof(buf), "__stop_%s", p0); |
| 1842 | 1845 | set_global_sym(s1, buf, s, -1); |
| 1843 | 1846 | } |
| 1844 | 1847 | next_sec: ; |
| @@ -2123,6 +2126,7 @@ struct dyn_inf { · 278 unmodified lines |
| 2123 | 2126 | |
| 2124 | 2127 | ElfW(Phdr) *phdr; |
| 2125 | 2128 | int phnum; |
| 2129 | + int shnum; |
| 2126 | 2130 | Section *interp; |
| 2127 | 2131 | Section *note; |
| 2128 | 2132 | Section *gnu_hash; |
| @@ -2135,7 +2139,7 @@ struct dyn_inf { · 6 unmodified lines |
| 2135 | 2139 | program headers are filled since they contain info about the layout. |
| 2136 | 2140 | We do the following ordering: interp, symbol tables, relocations, progbits, |
| 2137 | 2141 | nobits */ |
| 2138 | | −static int sort_sections(TCCState *s1, int *sec_order, Section *interp) |
| 2142 | +static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) |
| 2139 | 2143 | { |
| 2140 | 2144 | Section *s; |
| 2141 | 2145 | int i, j, k, f, f0, n; |
| @@ -2144,16 +2148,16 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 2 unmodified lines |
| 2144 | 2148 | |
| 2145 | 2149 | for (i = 1; i < nb_sections; i++) { |
| 2146 | 2150 | s = s1->sections[i]; |
| 2147 | | − if (s->sh_flags & SHF_ALLOC) { |
| 2151 | + if (0 == s->sh_name) { |
| 2152 | + j = 0x900; /* no sh_name: won't go to file */ |
| 2153 | + } else if (s->sh_flags & SHF_ALLOC) { |
| 2148 | 2154 | j = 0x100; |
| 2149 | 2155 | if (s->sh_flags & SHF_WRITE) |
| 2150 | 2156 | j = 0x200; |
| 2151 | 2157 | if (s->sh_flags & SHF_TLS) |
| 2152 | 2158 | j += 0x200; |
| 2153 | | − } else if (s->sh_name) { |
| 2154 | | − j = 0x700; |
| 2155 | 2159 | } else { |
| 2156 | | − j = 0x900; /* no sh_name: won't go to file */ |
| 2160 | + j = 0x700; |
| 2157 | 2161 | } |
| 2158 | 2162 | if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) { |
| 2159 | 2163 | k = 0x10; |
| @@ -2191,7 +2195,7 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 31 unmodified lines |
| 2191 | 2195 | k = 0x70; |
| 2192 | 2196 | if (s->sh_type == SHT_NOBITS) |
| 2193 | 2197 | k = 0x80; |
| 2194 | | − if (s == interp) |
| 2198 | + if (s == d->interp) |
| 2195 | 2199 | k = 0x00; |
| 2196 | 2200 | } |
| 2197 | 2201 | k += j; |
| @@ -2201,6 +2205,7 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 3 unmodified lines |
| 2201 | 2205 | sec_cls[n] = k, sec_order[n] = i; |
| 2202 | 2206 | } |
| 2203 | 2207 | sec_order[0] = 0; |
| 2208 | + d->shnum = 1; |
| 2204 | 2209 | |
| 2205 | 2210 | /* count PT_LOAD headers needed */ |
| 2206 | 2211 | n = f0 = 0; |
| @@ -2208,21 +2213,25 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 1 unmodified line |
| 2208 | 2213 | s = s1->sections[sec_order[i]]; |
| 2209 | 2214 | k = sec_cls[i]; |
| 2210 | 2215 | f = 0; |
| 2216 | + if (k < 0x900) |
| 2217 | + ++d->shnum; |
| 2211 | 2218 | if (k < 0x700) { |
| 2212 | 2219 | f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS); |
| 2213 | 2220 | #if TARGETOS_NetBSD |
| 2214 | 2221 | /* NetBSD only supports 2 PT_LOAD sections. |
| 2215 | 2222 | See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */ |
| 2216 | | − if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR; |
| 2223 | + if ((f & SHF_WRITE) == 0) |
| 2224 | + f |= SHF_EXECINSTR; |
| 2217 | 2225 | #else |
| 2218 | 2226 | if ((k & 0xfff0) == 0x240) /* RELRO sections */ |
| 2219 | 2227 | f |= 1<<4; |
| 2220 | 2228 | #endif |
| 2221 | | − if (f != f0) /* start new header when flags changed or relro */ |
| 2229 | + /* start new header when flags changed or relro, but avoid zero memsz */ |
| 2230 | + if (f != f0 && s->sh_size) |
| 2222 | 2231 | f0 = f, ++n, f |= 1<<8; |
| 2223 | 2232 | } |
| 2224 | 2233 | sec_cls[i] = f; |
| 2225 | | − //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name); |
| 2234 | + //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, s->sh_size, s->name); |
| 2226 | 2235 | } |
| 2227 | 2236 | return n; |
| 2228 | 2237 | } |
| @@ -2253,7 +2262,7 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 24 unmodified lines |
| 2253 | 2262 | int file_offset; |
| 2254 | 2263 | |
| 2255 | 2264 | /* compute number of program headers */ |
| 2256 | | − phnum = sort_sections(s1, sec_order, d->interp); |
| 2265 | + phnum = sort_sections(s1, sec_order, d); |
| 2257 | 2266 | phfill = 0; /* set to 1 to have dll's with a PT_PHDR */ |
| 2258 | 2267 | if (d->interp) |
| 2259 | 2268 | phfill = 2; |
| @@ -2268,8 +2277,10 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 8 unmodified lines |
| 2268 | 2277 | d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); |
| 2269 | 2278 | |
| 2270 | 2279 | file_offset = 0; |
| 2271 | | − if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) |
| 2272 | | − file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); |
| 2280 | + if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { |
| 2281 | + file_offset = (sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)) + 3) & -4; |
| 2282 | + file_offset += d->shnum * sizeof (ElfW(Shdr)); |
| 2283 | + } |
| 2273 | 2284 | |
| 2274 | 2285 | s_align = ELF_PAGE_SIZE; |
| 2275 | 2286 | if (s1->section_align) |
| @@ -2392,7 +2403,7 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 116 unmodified lines |
| 2392 | 2403 | ph->p_align = 4; |
| 2393 | 2404 | fill_phdr(ph, PT_PHDR, NULL); |
| 2394 | 2405 | } |
| 2395 | | − return file_offset; |
| 2406 | + return 0; |
| 2396 | 2407 | } |
| 2397 | 2408 | |
| 2398 | 2409 | /* put dynamic tag */ |
| @@ -2505,14 +2516,11 @@ static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf) · 106 unmodified lines |
| 2505 | 2516 | } |
| 2506 | 2517 | } |
| 2507 | 2518 | } |
| 2508 | | − |
| 2509 | | −static int tidy_section_headers(TCCState *s1, int *sec_order); |
| 2510 | 2519 | #endif /* ndef ELF_OBJ_ONLY */ |
| 2511 | 2520 | |
| 2512 | 2521 | /* Create an ELF file on disk. |
| 2513 | 2522 | This function handle ELF specific layout requirements */ |
| 2514 | | −static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, |
| 2515 | | − int file_offset, int *sec_order) |
| 2523 | +static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr) |
| 2516 | 2524 | { |
| 2517 | 2525 | int i, shnum, offset, size, file_type; |
| 2518 | 2526 | Section *s; |
| @@ -2523,19 +2531,12 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 4 unmodified lines |
| 2523 | 2531 | shnum = s1->nb_sections; |
| 2524 | 2532 | |
| 2525 | 2533 | memset(&ehdr, 0, sizeof(ehdr)); |
| 2526 | | − |
| 2527 | 2534 | if (phnum > 0) { |
| 2528 | 2535 | ehdr.e_phentsize = sizeof(ElfW(Phdr)); |
| 2529 | 2536 | ehdr.e_phnum = phnum; |
| 2530 | 2537 | ehdr.e_phoff = sizeof(ElfW(Ehdr)); |
| 2531 | | −#ifndef ELF_OBJ_ONLY |
| 2532 | | − shnum = tidy_section_headers(s1, sec_order); |
| 2533 | | −#endif |
| 2534 | 2538 | } |
| 2535 | 2539 | |
| 2536 | | − /* align to 4 */ |
| 2537 | | − file_offset = (file_offset + 3) & -4; |
| 2538 | | − |
| 2539 | 2540 | /* fill header */ |
| 2540 | 2541 | ehdr.e_ident[0] = ELFMAG0; |
| 2541 | 2542 | ehdr.e_ident[1] = ELFMAG1; |
| @@ -2577,32 +2578,15 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 35 unmodified lines |
| 2577 | 2578 | |
| 2578 | 2579 | ehdr.e_machine = EM_TCC_TARGET; |
| 2579 | 2580 | ehdr.e_version = EV_CURRENT; |
| 2580 | | − ehdr.e_shoff = file_offset; |
| 2581 | + ehdr.e_shoff = (sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)) + 3) & -4; |
| 2581 | 2582 | ehdr.e_ehsize = sizeof(ElfW(Ehdr)); |
| 2582 | 2583 | ehdr.e_shentsize = sizeof(ElfW(Shdr)); |
| 2583 | 2584 | ehdr.e_shnum = shnum; |
| 2584 | 2585 | ehdr.e_shstrndx = shnum - 1; |
| 2585 | 2586 | |
| 2586 | | − fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); |
| 2587 | + offset = fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); |
| 2587 | 2588 | if (phdr) |
| 2588 | | − fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); |
| 2589 | | − offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); |
| 2590 | | − |
| 2591 | | − sort_syms(s1, symtab_section); |
| 2592 | | − |
| 2593 | | − for(i = 1; i < shnum; i++) { |
| 2594 | | − s = s1->sections[sec_order ? sec_order[i] : i]; |
| 2595 | | − if (s->sh_type != SHT_NOBITS) { |
| 2596 | | − while (offset < s->sh_offset) { |
| 2597 | | − fputc(0, f); |
| 2598 | | − offset++; |
| 2599 | | − } |
| 2600 | | − size = s->sh_size; |
| 2601 | | − if (size) |
| 2602 | | − fwrite(s->data, 1, size, f); |
| 2603 | | − offset += size; |
| 2604 | | − } |
| 2605 | | − } |
| 2589 | + offset += fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); |
| 2606 | 2590 | |
| 2607 | 2591 | /* output section headers */ |
| 2608 | 2592 | while (offset < ehdr.e_shoff) { |
| @@ -2613,8 +2597,8 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 4 unmodified lines |
| 2613 | 2597 | for(i = 0; i < shnum; i++) { |
| 2614 | 2598 | sh = &shdr; |
| 2615 | 2599 | memset(sh, 0, sizeof(ElfW(Shdr))); |
| 2616 | | − s = s1->sections[i]; |
| 2617 | | − if (s) { |
| 2600 | + if (i) { |
| 2601 | + s = s1->sections[i]; |
| 2618 | 2602 | sh->sh_name = s->sh_name; |
| 2619 | 2603 | sh->sh_type = s->sh_type; |
| 2620 | 2604 | sh->sh_flags = s->sh_flags; |
| @@ -2627,20 +2611,35 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 6 unmodified lines |
| 2627 | 2611 | sh->sh_offset = s->sh_offset; |
| 2628 | 2612 | sh->sh_size = s->sh_size; |
| 2629 | 2613 | } |
| 2630 | | − fwrite(sh, 1, sizeof(ElfW(Shdr)), f); |
| 2614 | + offset += fwrite(sh, 1, sizeof(ElfW(Shdr)), f); |
| 2615 | + } |
| 2616 | + |
| 2617 | + sort_syms(s1, s1->symtab); |
| 2618 | + |
| 2619 | + /* output sections */ |
| 2620 | + for(i = 1; i < s1->nb_sections; i++) { |
| 2621 | + s = s1->sections[i]; |
| 2622 | + if (s->sh_type != SHT_NOBITS) { |
| 2623 | + while (offset < s->sh_offset) { |
| 2624 | + fputc(0, f); |
| 2625 | + offset++; |
| 2626 | + } |
| 2627 | + size = s->sh_size; |
| 2628 | + if (size) |
| 2629 | + offset += fwrite(s->data, 1, size, f); |
| 2630 | + } |
| 2631 | 2631 | } |
| 2632 | 2632 | return 0; |
| 2633 | 2633 | } |
| 2634 | 2634 | |
| 2635 | | −static int tcc_output_binary(TCCState *s1, FILE *f, |
| 2636 | | − const int *sec_order) |
| 2635 | +static int tcc_output_binary(TCCState *s1, FILE *f) |
| 2637 | 2636 | { |
| 2638 | 2637 | Section *s; |
| 2639 | 2638 | int i, offset, size; |
| 2640 | 2639 | |
| 2641 | 2640 | offset = 0; |
| 2642 | 2641 | for(i=1;i<s1->nb_sections;i++) { |
| 2643 | | − s = s1->sections[sec_order[i]]; |
| 2642 | + s = s1->sections[i]; |
| 2644 | 2643 | if (s->sh_type != SHT_NOBITS && |
| 2645 | 2644 | (s->sh_flags & SHF_ALLOC)) { |
| 2646 | 2645 | while (offset < s->sh_offset) { |
| @@ -2657,7 +2656,7 @@ static int tcc_output_binary(TCCState *s1, FILE *f, · 10 unmodified lines |
| 2657 | 2656 | |
| 2658 | 2657 | /* Write an elf, coff or "binary" file */ |
| 2659 | 2658 | static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, |
| 2660 | | − ElfW(Phdr) *phdr, int file_offset, int *sec_order) |
| 2659 | + ElfW(Phdr) *phdr) |
| 2661 | 2660 | { |
| 2662 | 2661 | int fd, mode, file_type, ret; |
| 2663 | 2662 | FILE *f; |
| @@ -2679,59 +2678,50 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, · 15 unmodified lines |
| 2679 | 2678 | else |
| 2680 | 2679 | #endif |
| 2681 | 2680 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) |
| 2682 | | − ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); |
| 2681 | + ret = tcc_output_elf(s1, f, phnum, phdr); |
| 2683 | 2682 | else |
| 2684 | | − ret = tcc_output_binary(s1, f, sec_order); |
| 2683 | + ret = tcc_output_binary(s1, f); |
| 2685 | 2684 | fclose(f); |
| 2686 | 2685 | |
| 2687 | 2686 | return ret; |
| 2688 | 2687 | } |
| 2689 | 2688 | |
| 2690 | 2689 | #ifndef ELF_OBJ_ONLY |
| 2691 | | −/* Sort section headers by assigned sh_addr, remove sections |
| 2690 | +/* order sections according to sec_order, remove sections |
| 2692 | 2691 | that we aren't going to output. */ |
| 2693 | | −static int tidy_section_headers(TCCState *s1, int *sec_order) |
| 2692 | +static void reorder_sections(TCCState *s1, int *sec_order) |
| 2694 | 2693 | { |
| 2695 | | − int i, nnew, l, *backmap; |
| 2694 | + int i, nnew, k, *backmap; |
| 2696 | 2695 | Section **snew, *s; |
| 2697 | 2696 | ElfW(Sym) *sym; |
| 2698 | 2697 | |
| 2699 | | − snew = tcc_malloc(s1->nb_sections * sizeof(snew[0])); |
| 2700 | 2698 | backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0])); |
| 2701 | | − for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) { |
| 2702 | | − s = s1->sections[sec_order[i]]; |
| 2699 | + for (i = 0, nnew = 0, snew = NULL; i < s1->nb_sections; i++) { |
| 2700 | + k = sec_order[i]; |
| 2701 | + s = s1->sections[k]; |
| 2703 | 2702 | if (!i || s->sh_name) { |
| 2704 | | − backmap[sec_order[i]] = nnew; |
| 2705 | | − snew[nnew] = s; |
| 2706 | | − ++nnew; |
| 2703 | + backmap[k] = nnew; |
| 2704 | + dynarray_add(&snew, &nnew, s); |
| 2707 | 2705 | } else { |
| 2708 | | − backmap[sec_order[i]] = 0; |
| 2709 | | − snew[--l] = s; |
| 2706 | + backmap[k] = 0; |
| 2707 | + /* just remember to free them later */ |
| 2708 | + dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, s); |
| 2710 | 2709 | } |
| 2711 | 2710 | } |
| 2712 | | − for (i = 0; i < nnew; i++) { |
| 2711 | + for (i = 1; i < nnew; i++) { |
| 2713 | 2712 | s = snew[i]; |
| 2714 | | − if (s) { |
| 2715 | | − s->sh_num = i; |
| 2716 | | − if (s->sh_type == SHT_RELX) |
| 2717 | | − s->sh_info = backmap[s->sh_info]; |
| 2718 | | − } |
| 2713 | + s->sh_num = i; |
| 2714 | + if (s->sh_type == SHT_RELX) |
| 2715 | + s->sh_info = backmap[s->sh_info]; |
| 2716 | + else if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) |
| 2717 | + for_each_elem(s, 1, sym, ElfW(Sym)) |
| 2718 | + if (sym->st_shndx < s1->nb_sections) |
| 2719 | + sym->st_shndx = backmap[sym->st_shndx]; |
| 2719 | 2720 | } |
| 2720 | | − |
| 2721 | | − for_each_elem(symtab_section, 1, sym, ElfW(Sym)) |
| 2722 | | − if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) |
| 2723 | | − sym->st_shndx = backmap[sym->st_shndx]; |
| 2724 | | − if ( !s1->static_link ) { |
| 2725 | | − for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) |
| 2726 | | − if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) |
| 2727 | | − sym->st_shndx = backmap[sym->st_shndx]; |
| 2728 | | − } |
| 2729 | | − for (i = 0; i < s1->nb_sections; i++) |
| 2730 | | − sec_order[i] = i; |
| 2731 | 2721 | tcc_free(s1->sections); |
| 2732 | 2722 | s1->sections = snew; |
| 2723 | + s1->nb_sections = nnew; |
| 2733 | 2724 | tcc_free(backmap); |
| 2734 | | − return nnew; |
| 2735 | 2725 | } |
| 2736 | 2726 | |
| 2737 | 2727 | #ifdef TCC_TARGET_ARM |
| @@ -2797,7 +2787,7 @@ static void alloc_sec_names(TCCState *s1, int is_obj); · 59 unmodified lines |
| 2797 | 2787 | /* XXX: suppress unneeded sections */ |
| 2798 | 2788 | static int elf_output_file(TCCState *s1, const char *filename) |
| 2799 | 2789 | { |
| 2800 | | − int i, ret, file_type, file_offset, *sec_order; |
| 2790 | + int i, ret, file_type, *sec_order; |
| 2801 | 2791 | struct dyn_inf dyninf = {0}; |
| 2802 | 2792 | Section *interp, *dynstr, *dynamic; |
| 2803 | 2793 | int textrel, got_sym, dt_flags_1; |
| @@ -2876,7 +2866,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 72 unmodified lines |
| 2876 | 2866 | version_add (s1); |
| 2877 | 2867 | |
| 2878 | 2868 | textrel = set_sec_sizes(s1); |
| 2879 | | − alloc_sec_names(s1, 0); |
| 2880 | 2869 | |
| 2881 | 2870 | if (!s1->static_link) { |
| 2882 | 2871 | /* add a list of needed dlls */ |
| @@ -2915,10 +2904,12 @@ static int elf_output_file(TCCState *s1, const char *filename) · 32 unmodified lines |
| 2915 | 2904 | dynstr->sh_size = dynstr->data_offset; |
| 2916 | 2905 | } |
| 2917 | 2906 | |
| 2907 | + /* create and fill .shstrtab section */ |
| 2908 | + alloc_sec_names(s1, 0); |
| 2918 | 2909 | /* this array is used to reorder sections in the output file */ |
| 2919 | 2910 | sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections); |
| 2920 | 2911 | /* compute section to program header mapping */ |
| 2921 | | − file_offset = layout_sections(s1, sec_order, &dyninf); |
| 2912 | + layout_sections(s1, sec_order, &dyninf); |
| 2922 | 2913 | |
| 2923 | 2914 | if (dynamic) { |
| 2924 | 2915 | /* put in GOT the dynamic section address and relocate PLT */ |
| @@ -2950,8 +2941,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 25 unmodified lines |
| 2950 | 2941 | if (dyninf.gnu_hash) |
| 2951 | 2942 | update_gnu_hash(s1, dyninf.gnu_hash); |
| 2952 | 2943 | |
| 2944 | + reorder_sections(s1, sec_order); |
| 2945 | + |
| 2953 | 2946 | /* Create the ELF file with name 'filename' */ |
| 2954 | | − ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order); |
| 2947 | + ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr); |
| 2955 | 2948 | the_end: |
| 2956 | 2949 | tcc_free(sec_order); |
| 2957 | 2950 | tcc_free(dyninf.phdr); |
| @@ -2971,7 +2964,7 @@ static void alloc_sec_names(TCCState *s1, int is_obj) · 13 unmodified lines |
| 2971 | 2964 | s = s1->sections[i]; |
| 2972 | 2965 | if (is_obj) |
| 2973 | 2966 | s->sh_size = s->data_offset; |
| 2974 | | − if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC)) |
| 2967 | + if (s->sh_size || s == strsec || (s->sh_flags & SHF_ALLOC) || is_obj) |
| 2975 | 2968 | s->sh_name = put_elf_str(strsec, s->name); |
| 2976 | 2969 | } |
| 2977 | 2970 | strsec->sh_size = strsec->data_offset; |
| @@ -2985,7 +2978,8 @@ static int elf_output_obj(TCCState *s1, const char *filename) · 7 unmodified lines |
| 2985 | 2978 | s1->nb_errors = 0; |
| 2986 | 2979 | /* Allocate strings for section names */ |
| 2987 | 2980 | alloc_sec_names(s1, 1); |
| 2988 | | − file_offset = sizeof (ElfW(Ehdr)); |
| 2981 | + file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4; |
| 2982 | + file_offset += s1->nb_sections * sizeof(ElfW(Shdr)); |
| 2989 | 2983 | for(i = 1; i < s1->nb_sections; i++) { |
| 2990 | 2984 | s = s1->sections[i]; |
| 2991 | 2985 | file_offset = (file_offset + 15) & -16; |
| @@ -2994,7 +2988,7 @@ static int elf_output_obj(TCCState *s1, const char *filename) · 2 unmodified lines |
| 2994 | 2988 | file_offset += s->sh_size; |
| 2995 | 2989 | } |
| 2996 | 2990 | /* Create the ELF file with name 'filename' */ |
| 2997 | | − ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL); |
| 2991 | + ret = tcc_write_elf_file(s1, filename, 0, NULL); |
| 2998 | 2992 | return ret; |
| 2999 | 2993 | } |
| 3000 | 2994 | |