| @@ -1488,7 +1488,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 1487 unmodified lines |
| 1488 | s = have_section(s1, section_name); | 1488 | s = have_section(s1, section_name); |
| 1489 | if (!s || !(s->sh_flags & SHF_ALLOC)) { | 1489 | if (!s || !(s->sh_flags & SHF_ALLOC)) { |
| 1490 | end_offset = 0; | 1490 | end_offset = 0; |
| 1491 | s = data_section; | 1491 | s = text_section; |
| 1492 | } else { | 1492 | } else { |
| 1493 | end_offset = s->data_offset; | 1493 | end_offset = s->data_offset; |
| 1494 | } | 1494 | } |
| @@ -1823,11 +1823,14 @@ static void tcc_add_linker_symbols(TCCState *s1) · 328 unmodified lines |
| 1823 | for(i = 1; i < s1->nb_sections; i++) { | 1823 | for(i = 1; i < s1->nb_sections; i++) { |
| 1824 | s = s1->sections[i]; | 1824 | s = s1->sections[i]; |
| 1825 | if ((s->sh_flags & SHF_ALLOC) | 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 | || s->sh_type == SHT_STRTAB)) { | 1827 | || s->sh_type == SHT_STRTAB)) { |
| 1828 | const char *p; | | |
| 1829 | /* check if section name can be expressed in C */ | 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 | for(;;) { | 1834 | for(;;) { |
| 1832 | int c = *p; | 1835 | int c = *p; |
| 1833 | if (!c) | 1836 | if (!c) |
| @@ -1836,9 +1839,9 @@ static void tcc_add_linker_symbols(TCCState *s1) · 2 unmodified lines |
| 1836 | goto next_sec; | 1839 | goto next_sec; |
| 1837 | p++; | 1840 | p++; |
| 1838 | } | 1841 | } |
| 1839 | snprintf(buf, sizeof(buf), "__start_%s", s->name); | 1842 | snprintf(buf, sizeof(buf), "__start_%s", p0); |
| 1840 | set_global_sym(s1, buf, s, 0); | 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 | set_global_sym(s1, buf, s, -1); | 1845 | set_global_sym(s1, buf, s, -1); |
| 1843 | } | 1846 | } |
| 1844 | next_sec: ; | 1847 | next_sec: ; |
| @@ -2123,6 +2126,7 @@ struct dyn_inf { · 278 unmodified lines |
| 2123 | | 2126 | |
| 2124 | ElfW(Phdr) *phdr; | 2127 | ElfW(Phdr) *phdr; |
| 2125 | int phnum; | 2128 | int phnum; |
| | 2129 | int shnum; |
| 2126 | Section *interp; | 2130 | Section *interp; |
| 2127 | Section *note; | 2131 | Section *note; |
| 2128 | Section *gnu_hash; | 2132 | Section *gnu_hash; |
| @@ -2135,7 +2139,7 @@ struct dyn_inf { · 6 unmodified lines |
| 2135 | program headers are filled since they contain info about the layout. | 2139 | program headers are filled since they contain info about the layout. |
| 2136 | We do the following ordering: interp, symbol tables, relocations, progbits, | 2140 | We do the following ordering: interp, symbol tables, relocations, progbits, |
| 2137 | nobits */ | 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 | Section *s; | 2144 | Section *s; |
| 2141 | int i, j, k, f, f0, n; | 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 | for (i = 1; i < nb_sections; i++) { | 2149 | for (i = 1; i < nb_sections; i++) { |
| 2146 | s = s1->sections[i]; | 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 | j = 0x100; | 2154 | j = 0x100; |
| 2149 | if (s->sh_flags & SHF_WRITE) | 2155 | if (s->sh_flags & SHF_WRITE) |
| 2150 | j = 0x200; | 2156 | j = 0x200; |
| 2151 | if (s->sh_flags & SHF_TLS) | 2157 | if (s->sh_flags & SHF_TLS) |
| 2152 | j += 0x200; | 2158 | j += 0x200; |
| 2153 | } else if (s->sh_name) { | | |
| 2154 | j = 0x700; | | |
| 2155 | } else { | 2159 | } else { |
| 2156 | j = 0x900; /* no sh_name: won't go to file */ | 2160 | j = 0x700; |
| 2157 | } | 2161 | } |
| 2158 | if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) { | 2162 | if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) { |
| 2159 | k = 0x10; | 2163 | k = 0x10; |
| @@ -2191,7 +2195,7 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 31 unmodified lines |
| 2191 | k = 0x70; | 2195 | k = 0x70; |
| 2192 | if (s->sh_type == SHT_NOBITS) | 2196 | if (s->sh_type == SHT_NOBITS) |
| 2193 | k = 0x80; | 2197 | k = 0x80; |
| 2194 | if (s == interp) | 2198 | if (s == d->interp) |
| 2195 | k = 0x00; | 2199 | k = 0x00; |
| 2196 | } | 2200 | } |
| 2197 | k += j; | 2201 | k += j; |
| @@ -2201,6 +2205,7 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 3 unmodified lines |
| 2201 | sec_cls[n] = k, sec_order[n] = i; | 2205 | sec_cls[n] = k, sec_order[n] = i; |
| 2202 | } | 2206 | } |
| 2203 | sec_order[0] = 0; | 2207 | sec_order[0] = 0; |
| | 2208 | d->shnum = 1; |
| 2204 | | 2209 | |
| 2205 | /* count PT_LOAD headers needed */ | 2210 | /* count PT_LOAD headers needed */ |
| 2206 | n = f0 = 0; | 2211 | n = f0 = 0; |
| @@ -2208,21 +2213,25 @@ static int sort_sections(TCCState *s1, int *sec_order, Section *interp) · 1 unmodified line |
| 2208 | s = s1->sections[sec_order[i]]; | 2213 | s = s1->sections[sec_order[i]]; |
| 2209 | k = sec_cls[i]; | 2214 | k = sec_cls[i]; |
| 2210 | f = 0; | 2215 | f = 0; |
| | 2216 | if (k < 0x900) |
| | 2217 | ++d->shnum; |
| 2211 | if (k < 0x700) { | 2218 | if (k < 0x700) { |
| 2212 | f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS); | 2219 | f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS); |
| 2213 | #if TARGETOS_NetBSD | 2220 | #if TARGETOS_NetBSD |
| 2214 | /* NetBSD only supports 2 PT_LOAD sections. | 2221 | /* NetBSD only supports 2 PT_LOAD sections. |
| 2215 | See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */ | 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 | #else | 2225 | #else |
| 2218 | if ((k & 0xfff0) == 0x240) /* RELRO sections */ | 2226 | if ((k & 0xfff0) == 0x240) /* RELRO sections */ |
| 2219 | f |= 1<<4; | 2227 | f |= 1<<4; |
| 2220 | #endif | 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 | f0 = f, ++n, f |= 1<<8; | 2231 | f0 = f, ++n, f |= 1<<8; |
| 2223 | } | 2232 | } |
| 2224 | sec_cls[i] = f; | 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 | return n; | 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 | int file_offset; | 2262 | int file_offset; |
| 2254 | | 2263 | |
| 2255 | /* compute number of program headers */ | 2264 | /* compute number of program headers */ |
| 2256 | phnum = sort_sections(s1, sec_order, d->interp); | 2265 | phnum = sort_sections(s1, sec_order, d); |
| 2257 | phfill = 0; /* set to 1 to have dll's with a PT_PHDR */ | 2266 | phfill = 0; /* set to 1 to have dll's with a PT_PHDR */ |
| 2258 | if (d->interp) | 2267 | if (d->interp) |
| 2259 | phfill = 2; | 2268 | phfill = 2; |
| @@ -2268,8 +2277,10 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 8 unmodified lines |
| 2268 | d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); | 2277 | d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); |
| 2269 | | 2278 | |
| 2270 | file_offset = 0; | 2279 | file_offset = 0; |
| 2271 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) | 2280 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { |
| 2272 | file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); | 2281 | file_offset = (sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)) + 3) & -4; |
| | 2282 | file_offset += d->shnum * sizeof (ElfW(Shdr)); |
| | 2283 | } |
| 2273 | | 2284 | |
| 2274 | s_align = ELF_PAGE_SIZE; | 2285 | s_align = ELF_PAGE_SIZE; |
| 2275 | if (s1->section_align) | 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 | ph->p_align = 4; | 2403 | ph->p_align = 4; |
| 2393 | fill_phdr(ph, PT_PHDR, NULL); | 2404 | fill_phdr(ph, PT_PHDR, NULL); |
| 2394 | } | 2405 | } |
| 2395 | return file_offset; | 2406 | return 0; |
| 2396 | } | 2407 | } |
| 2397 | | 2408 | |
| 2398 | /* put dynamic tag */ | 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 | #endif /* ndef ELF_OBJ_ONLY */ | 2519 | #endif /* ndef ELF_OBJ_ONLY */ |
| 2511 | | 2520 | |
| 2512 | /* Create an ELF file on disk. | 2521 | /* Create an ELF file on disk. |
| 2513 | This function handle ELF specific layout requirements */ | 2522 | This function handle ELF specific layout requirements */ |
| 2514 | static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, | 2523 | static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr) |
| 2515 | int file_offset, int *sec_order) | | |
| 2516 | { | 2524 | { |
| 2517 | int i, shnum, offset, size, file_type; | 2525 | int i, shnum, offset, size, file_type; |
| 2518 | Section *s; | 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 | shnum = s1->nb_sections; | 2531 | shnum = s1->nb_sections; |
| 2524 | | 2532 | |
| 2525 | memset(&ehdr, 0, sizeof(ehdr)); | 2533 | memset(&ehdr, 0, sizeof(ehdr)); |
| 2526 | | | |
| 2527 | if (phnum > 0) { | 2534 | if (phnum > 0) { |
| 2528 | ehdr.e_phentsize = sizeof(ElfW(Phdr)); | 2535 | ehdr.e_phentsize = sizeof(ElfW(Phdr)); |
| 2529 | ehdr.e_phnum = phnum; | 2536 | ehdr.e_phnum = phnum; |
| 2530 | ehdr.e_phoff = sizeof(ElfW(Ehdr)); | 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 | /* fill header */ | 2540 | /* fill header */ |
| 2540 | ehdr.e_ident[0] = ELFMAG0; | 2541 | ehdr.e_ident[0] = ELFMAG0; |
| 2541 | ehdr.e_ident[1] = ELFMAG1; | 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 | ehdr.e_machine = EM_TCC_TARGET; | 2579 | ehdr.e_machine = EM_TCC_TARGET; |
| 2579 | ehdr.e_version = EV_CURRENT; | 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 | ehdr.e_ehsize = sizeof(ElfW(Ehdr)); | 2582 | ehdr.e_ehsize = sizeof(ElfW(Ehdr)); |
| 2582 | ehdr.e_shentsize = sizeof(ElfW(Shdr)); | 2583 | ehdr.e_shentsize = sizeof(ElfW(Shdr)); |
| 2583 | ehdr.e_shnum = shnum; | 2584 | ehdr.e_shnum = shnum; |
| 2584 | ehdr.e_shstrndx = shnum - 1; | 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 | if (phdr) | 2588 | if (phdr) |
| 2588 | fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); | 2589 | offset += 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 | } | | |
| 2606 | | 2590 | |
| 2607 | /* output section headers */ | 2591 | /* output section headers */ |
| 2608 | while (offset < ehdr.e_shoff) { | 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 | for(i = 0; i < shnum; i++) { | 2597 | for(i = 0; i < shnum; i++) { |
| 2614 | sh = &shdr; | 2598 | sh = &shdr; |
| 2615 | memset(sh, 0, sizeof(ElfW(Shdr))); | 2599 | memset(sh, 0, sizeof(ElfW(Shdr))); |
| 2616 | s = s1->sections[i]; | 2600 | if (i) { |
| 2617 | if (s) { | 2601 | s = s1->sections[i]; |
| 2618 | sh->sh_name = s->sh_name; | 2602 | sh->sh_name = s->sh_name; |
| 2619 | sh->sh_type = s->sh_type; | 2603 | sh->sh_type = s->sh_type; |
| 2620 | sh->sh_flags = s->sh_flags; | 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 | sh->sh_offset = s->sh_offset; | 2611 | sh->sh_offset = s->sh_offset; |
| 2628 | sh->sh_size = s->sh_size; | 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 | return 0; | 2632 | return 0; |
| 2633 | } | 2633 | } |
| 2634 | | 2634 | |
| 2635 | static int tcc_output_binary(TCCState *s1, FILE *f, | 2635 | static int tcc_output_binary(TCCState *s1, FILE *f) |
| 2636 | const int *sec_order) | | |
| 2637 | { | 2636 | { |
| 2638 | Section *s; | 2637 | Section *s; |
| 2639 | int i, offset, size; | 2638 | int i, offset, size; |
| 2640 | | 2639 | |
| 2641 | offset = 0; | 2640 | offset = 0; |
| 2642 | for(i=1;i<s1->nb_sections;i++) { | 2641 | for(i=1;i<s1->nb_sections;i++) { |
| 2643 | s = s1->sections[sec_order[i]]; | 2642 | s = s1->sections[i]; |
| 2644 | if (s->sh_type != SHT_NOBITS && | 2643 | if (s->sh_type != SHT_NOBITS && |
| 2645 | (s->sh_flags & SHF_ALLOC)) { | 2644 | (s->sh_flags & SHF_ALLOC)) { |
| 2646 | while (offset < s->sh_offset) { | 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 | /* Write an elf, coff or "binary" file */ | 2657 | /* Write an elf, coff or "binary" file */ |
| 2659 | static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, | 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 | int fd, mode, file_type, ret; | 2661 | int fd, mode, file_type, ret; |
| 2663 | FILE *f; | 2662 | FILE *f; |
| @@ -2679,59 +2678,50 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, · 15 unmodified lines |
| 2679 | else | 2678 | else |
| 2680 | #endif | 2679 | #endif |
| 2681 | if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) | 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 | else | 2682 | else |
| 2684 | ret = tcc_output_binary(s1, f, sec_order); | 2683 | ret = tcc_output_binary(s1, f); |
| 2685 | fclose(f); | 2684 | fclose(f); |
| 2686 | | 2685 | |
| 2687 | return ret; | 2686 | return ret; |
| 2688 | } | 2687 | } |
| 2689 | | 2688 | |
| 2690 | #ifndef ELF_OBJ_ONLY | 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 | that we aren't going to output. */ | 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 | Section **snew, *s; | 2695 | Section **snew, *s; |
| 2697 | ElfW(Sym) *sym; | 2696 | ElfW(Sym) *sym; |
| 2698 | | 2697 | |
| 2699 | snew = tcc_malloc(s1->nb_sections * sizeof(snew[0])); | | |
| 2700 | backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0])); | 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++) { | 2699 | for (i = 0, nnew = 0, snew = NULL; i < s1->nb_sections; i++) { |
| 2702 | s = s1->sections[sec_order[i]]; | 2700 | k = sec_order[i]; |
| | 2701 | s = s1->sections[k]; |
| 2703 | if (!i || s->sh_name) { | 2702 | if (!i || s->sh_name) { |
| 2704 | backmap[sec_order[i]] = nnew; | 2703 | backmap[k] = nnew; |
| 2705 | snew[nnew] = s; | 2704 | dynarray_add(&snew, &nnew, s); |
| 2706 | ++nnew; | | |
| 2707 | } else { | 2705 | } else { |
| 2708 | backmap[sec_order[i]] = 0; | 2706 | backmap[k] = 0; |
| 2709 | snew[--l] = s; | 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 | s = snew[i]; | 2712 | s = snew[i]; |
| 2714 | if (s) { | 2713 | s->sh_num = i; |
| 2715 | s->sh_num = i; | 2714 | if (s->sh_type == SHT_RELX) |
| 2716 | if (s->sh_type == SHT_RELX) | 2715 | s->sh_info = backmap[s->sh_info]; |
| 2717 | s->sh_info = backmap[s->sh_info]; | 2716 | else if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) |
| 2718 | } | 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 | tcc_free(s1->sections); | 2721 | tcc_free(s1->sections); |
| 2732 | s1->sections = snew; | 2722 | s1->sections = snew; |
| | 2723 | s1->nb_sections = nnew; |
| 2733 | tcc_free(backmap); | 2724 | tcc_free(backmap); |
| 2734 | return nnew; | | |
| 2735 | } | 2725 | } |
| 2736 | | 2726 | |
| 2737 | #ifdef TCC_TARGET_ARM | 2727 | #ifdef TCC_TARGET_ARM |
| @@ -2797,7 +2787,7 @@ static void alloc_sec_names(TCCState *s1, int is_obj); · 59 unmodified lines |
| 2797 | /* XXX: suppress unneeded sections */ | 2787 | /* XXX: suppress unneeded sections */ |
| 2798 | static int elf_output_file(TCCState *s1, const char *filename) | 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 | struct dyn_inf dyninf = {0}; | 2791 | struct dyn_inf dyninf = {0}; |
| 2802 | Section *interp, *dynstr, *dynamic; | 2792 | Section *interp, *dynstr, *dynamic; |
| 2803 | int textrel, got_sym, dt_flags_1; | 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 | version_add (s1); | 2866 | version_add (s1); |
| 2877 | | 2867 | |
| 2878 | textrel = set_sec_sizes(s1); | 2868 | textrel = set_sec_sizes(s1); |
| 2879 | alloc_sec_names(s1, 0); | | |
| 2880 | | 2869 | |
| 2881 | if (!s1->static_link) { | 2870 | if (!s1->static_link) { |
| 2882 | /* add a list of needed dlls */ | 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 | dynstr->sh_size = dynstr->data_offset; | 2904 | dynstr->sh_size = dynstr->data_offset; |
| 2916 | } | 2905 | } |
| 2917 | | 2906 | |
| | 2907 | /* create and fill .shstrtab section */ |
| | 2908 | alloc_sec_names(s1, 0); |
| 2918 | /* this array is used to reorder sections in the output file */ | 2909 | /* this array is used to reorder sections in the output file */ |
| 2919 | sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections); | 2910 | sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections); |
| 2920 | /* compute section to program header mapping */ | 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 | if (dynamic) { | 2914 | if (dynamic) { |
| 2924 | /* put in GOT the dynamic section address and relocate PLT */ | 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 | if (dyninf.gnu_hash) | 2941 | if (dyninf.gnu_hash) |
| 2951 | update_gnu_hash(s1, dyninf.gnu_hash); | 2942 | update_gnu_hash(s1, dyninf.gnu_hash); |
| 2952 | | 2943 | |
| | 2944 | reorder_sections(s1, sec_order); |
| | 2945 | |
| 2953 | /* Create the ELF file with name 'filename' */ | 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 | the_end: | 2948 | the_end: |
| 2956 | tcc_free(sec_order); | 2949 | tcc_free(sec_order); |
| 2957 | tcc_free(dyninf.phdr); | 2950 | tcc_free(dyninf.phdr); |
| @@ -2971,7 +2964,7 @@ static void alloc_sec_names(TCCState *s1, int is_obj) · 13 unmodified lines |
| 2971 | s = s1->sections[i]; | 2964 | s = s1->sections[i]; |
| 2972 | if (is_obj) | 2965 | if (is_obj) |
| 2973 | s->sh_size = s->data_offset; | 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 | s->sh_name = put_elf_str(strsec, s->name); | 2968 | s->sh_name = put_elf_str(strsec, s->name); |
| 2976 | } | 2969 | } |
| 2977 | strsec->sh_size = strsec->data_offset; | 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 | s1->nb_errors = 0; | 2978 | s1->nb_errors = 0; |
| 2986 | /* Allocate strings for section names */ | 2979 | /* Allocate strings for section names */ |
| 2987 | alloc_sec_names(s1, 1); | 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 | for(i = 1; i < s1->nb_sections; i++) { | 2983 | for(i = 1; i < s1->nb_sections; i++) { |
| 2990 | s = s1->sections[i]; | 2984 | s = s1->sections[i]; |
| 2991 | file_offset = (file_offset + 15) & -16; | 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 | file_offset += s->sh_size; | 2988 | file_offset += s->sh_size; |
| 2995 | } | 2989 | } |
| 2996 | /* Create the ELF file with name 'filename' */ | 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 | return ret; | 2992 | return ret; |
| 2999 | } | 2993 | } |
| 3000 | | 2994 | |