History

tccelf.c: write section headers before sections

also avoid zero lenght PT_LOAD segments (which some musl loaders seem to dislike) Also: - tccasm.c: support .section with flags: .section .xyz,"wx" (fixes e4d874d88a2ef874a9c2fd7c47d3d3a35ae986e2) - tccgen,c: add __builtin_unreachable() - tccdefs.h: #define __has_attribute(x) 0 - tcc.c: tidy help for -std - tcctools.c/execvp_win32: quote strings more correctly - x86_64-gen.c:win32: set unwind begin-address to function-start - github action: add aarch64-osx (M1) & i386-win32 - configure: consider 32-bit build on MSYS64 native

grischka committed 2 years ago

Commit 45cff8f1 parent c21576f16 files · +170 −195Browse files

Unified · Split

16 files
  1. .github/workflows/build.yml +24 −6
  2. Makefile +4 −1
  3. configure +2 −1
  4. include/tccdefs.h +1 −0
  5. tcc.c +1 −2
  6. tccasm.c +12 −6
  7. tccelf.c +89 −95
  8. tccgen.c +8 −1
  9. tccpe.c +5 −4
  10. tcctok.h +1 −0
  11. tcctools.c +15 −23
  12. tests/exec_section_in_asm.c +0 −29
  13. tests/tcctest.c +1 −1
  14. tests/tests2/133_exec_section_in_c.c +0 −17
  15. tests/tests2/133_exec_section_in_c.expect +0 −1
  16. x86_64-gen.c +7 −8
.github/workflows/build.yml+24−6
@@ -10,7 +10,7 @@ jobs: · 9 unmodified lines
10 timeout-minutes: 210 timeout-minutes: 2
11 steps:11 steps:
12 - uses: actions/checkout@v412 - uses: actions/checkout@v4
13 - name: make & test tcc13 - name: make & test tcc (x86_64-linux)
14 run: ./configure && make && make test -k14 run: ./configure && make && make test -k
15 15
16 test-x86_64-osx:16 test-x86_64-osx:
@@ -18,21 +18,36 @@ jobs: · 1 unmodified line
18 timeout-minutes: 218 timeout-minutes: 2
19 steps:19 steps:
20 - uses: actions/checkout@v420 - uses: actions/checkout@v4
21 - name: make & test tcc21 - name: make & test tcc (x86_64-osx)
22 run: ./configure --config-codesign=no && make && make test -k22 run: ./configure && make && make test -k
23
24 test-aarch64-osx:
25 runs-on: macos-14
26 timeout-minutes: 2
27 steps:
28 - uses: actions/checkout@v4
29 - name: make & test tcc (aarch64-osx)
30 run: ./configure && make && make test -k
23 31
24 test-x86_64-win32:32 test-x86-win32:
25 runs-on: windows-201933 runs-on: windows-2019
26 timeout-minutes: 434 timeout-minutes: 6
27 steps:35 steps:
28 - uses: actions/checkout@v436 - uses: actions/checkout@v4
29 - name: make & test tcc37 - name: make & test tcc (x86_64-win32)
30 shell: cmd38 shell: cmd
31 run: |39 run: |
32 set MSYS2_PATH_TYPE=inherit40 set MSYS2_PATH_TYPE=inherit
33 set MSYSTEM=MINGW6441 set MSYSTEM=MINGW64
34 set CHERE_INVOKING=yes42 set CHERE_INVOKING=yes
35 C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"43 C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
44 - name: make & test tcc (i386-win32)
45 shell: cmd
46 run: |
47 set MSYS2_PATH_TYPE=inherit
48 set MSYSTEM=MINGW32
49 set CHERE_INVOKING=yes
50 C:\msys64\usr\bin\bash -l -c "./configure && make clean all && make test -k"
36 51
37 test-armv7-linux:52 test-armv7-linux:
38 runs-on: ubuntu-20.0453 runs-on: ubuntu-20.04
@@ -40,6 +55,7 @@ jobs: · 1 unmodified line
40 steps:55 steps:
41 - uses: actions/checkout@v456 - uses: actions/checkout@v4
42 - uses: uraimo/run-on-arch-action@v257 - uses: uraimo/run-on-arch-action@v2
58 name: make & test tcc (armv7-linux)
43 with:59 with:
44 arch: armv760 arch: armv7
45 distro: ubuntu20.0461 distro: ubuntu20.04
@@ -57,6 +73,7 @@ jobs: · 11 unmodified lines
57 steps:73 steps:
58 - uses: actions/checkout@v474 - uses: actions/checkout@v4
59 - uses: uraimo/run-on-arch-action@v275 - uses: uraimo/run-on-arch-action@v2
76 name: make & test tcc (aarch64-linux)
60 with:77 with:
61 arch: aarch6478 arch: aarch64
62 distro: ubuntu20.0479 distro: ubuntu20.04
@@ -74,6 +91,7 @@ jobs: · 11 unmodified lines
74 steps:91 steps:
75 - uses: actions/checkout@v492 - uses: actions/checkout@v4
76 - uses: uraimo/run-on-arch-action@v293 - uses: uraimo/run-on-arch-action@v2
94 name: make & test tcc (riscv64-linux)
77 with:95 with:
78 arch: riscv6496 arch: riscv64
79 distro: ubuntu20.0497 distro: ubuntu20.04
Makefile+4−1
@@ -69,7 +69,10 @@ else · 68 unmodified lines
69 ifdef CONFIG_OSX69 ifdef CONFIG_OSX
70 NATIVE_TARGET = $(ARCH)-osx70 NATIVE_TARGET = $(ARCH)-osx
71 ifneq ($(CC_NAME),tcc)71 ifneq ($(CC_NAME),tcc)
72 LDFLAGS += -flat_namespace -undefined warning72 LDFLAGS += -flat_namespace
73 ifneq (1,$(shell expr $(GCC_MAJOR) ">=" 15))
74 LDFLAGS += -undefined warning # depreciated in clang >= 15.0
75 endif
73 endif76 endif
74 export MACOSX_DEPLOYMENT_TARGET := 10.677 export MACOSX_DEPLOYMENT_TARGET := 10.6
75 endif78 endif
configure+2−1
@@ -227,10 +227,12 @@ fi · 226 unmodified lines
227 227
228# OS specific228# OS specific
229buildos=$(uname)229buildos=$(uname)
230cpu_sys=$(uname -m)
230 231
231case $buildos in232case $buildos in
232 Windows_NT|MINGW*|MSYS*|CYGWIN*)233 Windows_NT|MINGW*|MSYS*|CYGWIN*)
233 buildos="WIN32"234 buildos="WIN32"
235 test "$MSYSTEM" = "MINGW32" && cpu_sys=i386
234 ;;236 ;;
235 Linux)237 Linux)
236 if test "$(uname -o)" = "Android"; then238 if test "$(uname -o)" = "Android"; then
@@ -248,7 +250,6 @@ else · 11 unmodified lines
248 default targetos "$buildos"250 default targetos "$buildos"
249fi251fi
250 252
251cpu_sys=$(uname -m)
252default cpu "$cpu_sys"253default cpu "$cpu_sys"
253cpu_set="$cpu"254cpu_set="$cpu"
254 255
include/tccdefs.h+1−0
@@ -152,6 +152,7 @@ · 151 unmodified lines
152 #define __PRETTY_FUNCTION__ __FUNCTION__152 #define __PRETTY_FUNCTION__ __FUNCTION__
153 #define __has_builtin(x) 0153 #define __has_builtin(x) 0
154 #define __has_feature(x) 0154 #define __has_feature(x) 0
155 #define __has_atttribute(x) 0
155 /* C23 Keywords */156 /* C23 Keywords */
156 #define _Nonnull157 #define _Nonnull
157 #define _Nullable158 #define _Nullable
tcc.c+1−2
@@ -33,8 +33,6 @@ static const char help[] = · 32 unmodified lines
33 " -o outfile set output filename\n"33 " -o outfile set output filename\n"
34 " -run run compiled source\n"34 " -run run compiled source\n"
35 " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"35 " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
36 " -std=(c99|gnu99) Conform to the ISO 1999 C standard (default).\n"
37 " -std=(c11|gnu11) Conform to the ISO 2011 C standard.\n"
38 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"36 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
39 " -w disable all warnings\n"37 " -w disable all warnings\n"
40 " -v --version show version\n"38 " -v --version show version\n"
@@ -69,6 +67,7 @@ static const char help[] = · 28 unmodified lines
69 " -bt[N] link with backtrace (stack dump) support [show max N callers]\n"67 " -bt[N] link with backtrace (stack dump) support [show max N callers]\n"
70#endif68#endif
71 "Misc. options:\n"69 "Misc. options:\n"
70 " -std=version define __STDC_VERSION__ according to version (c11/gnu11)\n"
72 " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"71 " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
73 " -nostdinc do not use standard system include paths\n"72 " -nostdinc do not use standard system include paths\n"
74 " -nostdlib do not link with standard crt and libraries\n"73 " -nostdlib do not link with standard crt and libraries\n"
tccasm.c+12−6
@@ -857,6 +857,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 856 unmodified lines
857 {857 {
858 char sname[256];858 char sname[256];
859 int old_nb_section = s1->nb_sections;859 int old_nb_section = s1->nb_sections;
860 int flags = SHF_ALLOC;
860 861
861 tok1 = tok;862 tok1 = tok;
862 /* XXX: support more options */863 /* XXX: support more options */
@@ -870,10 +871,17 @@ static void asm_parse_directive(TCCState *s1, int global) · 7 unmodified lines
870 next();871 next();
871 }872 }
872 if (tok == ',') {873 if (tok == ',') {
874 const char *p;
873 /* skip section options */875 /* skip section options */
874 next();876 next();
875 if (tok != TOK_STR)877 if (tok != TOK_STR)
876 expect("string constant");878 expect("string constant");
879 for (p = tokc.str.data; *p; ++p) {
880 if (*p == 'w')
881 flags |= SHF_WRITE;
882 if (*p == 'x')
883 flags |= SHF_EXECINSTR;
884 }
877 next();885 next();
878 if (tok == ',') {886 if (tok == ',') {
879 next();887 next();
@@ -883,19 +891,17 @@ static void asm_parse_directive(TCCState *s1, int global) · 3 unmodified lines
883 }891 }
884 }892 }
885 last_text_section = cur_text_section;893 last_text_section = cur_text_section;
886 if (tok1 == TOK_ASMDIR_section) {894 if (tok1 == TOK_ASMDIR_section)
887 use_section(s1, sname);895 use_section(s1, sname);
888 /* The section directive supports flags, but they are unsupported.
889 For now, just assume any section contains code. */
890 cur_text_section->sh_flags |= SHF_EXECINSTR;
891 }
892 else896 else
893 push_section(s1, sname);897 push_section(s1, sname);
894 /* If we just allocated a new section reset its alignment to898 /* If we just allocated a new section reset its alignment to
895 1. new_section normally acts for GCC compatibility and899 1. new_section normally acts for GCC compatibility and
896 sets alignment to PTR_SIZE. The assembler behaves different. */900 sets alignment to PTR_SIZE. The assembler behaves different. */
897 if (old_nb_section != s1->nb_sections)901 if (old_nb_section != s1->nb_sections) {
898 cur_text_section->sh_addralign = 1;902 cur_text_section->sh_addralign = 1;
903 cur_text_section->sh_flags = flags;
904 }
899 }905 }
900 break;906 break;
901 case TOK_ASMDIR_previous:907 case TOK_ASMDIR_previous:
tccelf.c+89−95
@@ -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_PROGBITS1826 && (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 */
2138static int sort_sections(TCCState *s1, int *sec_order, Section *interp)2142static 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_NetBSD2220#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#else2225#else
2218 if ((k & 0xfff0) == 0x240) /* RELRO sections */2226 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2219 f |= 1<<4;2227 f |= 1<<4;
2220#endif2228#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
2509static 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 */
2514static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,2523static 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
2635static int tcc_output_binary(TCCState *s1, FILE *f,2635static 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 */
2659static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,2658static 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 else2678 else
2680#endif2679#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 else2682 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_ONLY2689#ifndef ELF_OBJ_ONLY
2691/* Sort section headers by assigned sh_addr, remove sections2690/* order sections according to sec_order, remove sections
2692 that we aren't going to output. */2691 that we aren't going to output. */
2693static int tidy_section_headers(TCCState *s1, int *sec_order)2692static 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_ARM2727#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 */
2798static int elf_output_file(TCCState *s1, const char *filename)2788static 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
tccgen.c+8−1
@@ -5716,6 +5716,12 @@ ST_FUNC void unary(void) · 5715 unmodified lines
5716 vtop--;5716 vtop--;
5717 vpushi(n);5717 vpushi(n);
5718 break;5718 break;
5719 case TOK_builtin_unreachable:
5720 parse_builtin_params(0, ""); /* just skip '()' */
5721 type.t = VT_VOID;
5722 vpush(&type);
5723 CODE_OFF();
5724 break;
5719 case TOK_builtin_frame_address:5725 case TOK_builtin_frame_address:
5720 case TOK_builtin_return_address:5726 case TOK_builtin_return_address:
5721 {5727 {
@@ -8306,7 +8312,6 @@ static void gen_function(Sym *sym) · 2584 unmodified lines
8306 cur_scope = root_scope = &f;8312 cur_scope = root_scope = &f;
8307 nocode_wanted = 0;8313 nocode_wanted = 0;
8308 8314
8309 cur_text_section->sh_flags |= SHF_EXECINSTR;
8310 ind = cur_text_section->data_offset;8315 ind = cur_text_section->data_offset;
8311 if (sym->a.aligned) {8316 if (sym->a.aligned) {
8312 size_t newoff = section_add(cur_text_section, 0,8317 size_t newoff = section_add(cur_text_section, 0,
@@ -8602,6 +8607,8 @@ static int decl(int l) · 289 unmodified lines
8602 cur_text_section = ad.section;8607 cur_text_section = ad.section;
8603 if (!cur_text_section)8608 if (!cur_text_section)
8604 cur_text_section = text_section;8609 cur_text_section = text_section;
8610 else if (cur_text_section->sh_num > bss_section->sh_num)
8611 cur_text_section->sh_flags = text_section->sh_flags;
8605 gen_function(sym);8612 gen_function(sym);
8606 }8613 }
8607 break;8614 break;
tccpe.c+5−4
@@ -525,7 +525,7 @@ static int pe_put_long_secname(char *secname, const char *name) · 524 unmodified lines
525 const char *d = dwarf_secs;525 const char *d = dwarf_secs;
526 do {526 do {
527 if (0 == strcmp(d, name)) {527 if (0 == strcmp(d, name)) {
528 sprintf(secname, "/%d", (int)(d - dwarf_secs + 4));528 snprintf(secname, 8, "/%d", (int)(d - dwarf_secs + 4));
529 return 1;529 return 1;
530 }530 }
531 d = strchr(d, 0) + 1;531 d = strchr(d, 0) + 1;
@@ -1871,10 +1871,11 @@ static unsigned pe_add_uwwind_info(TCCState *s1) · 1339 unmodified lines
1871 0x04, // UBYTE Size of prolog1871 0x04, // UBYTE Size of prolog
1872 0x02, // UBYTE Count of unwind codes1872 0x02, // UBYTE Count of unwind codes
1873 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)1873 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
1874 // USHORT * n Unwind codes array1874 // USHORT * n Unwind codes array (descending order)
1875 // 0x0b, 0x01, 0xff, 0xff, // stack size1875 // 0x0b, 0x01, 0xff, 0xff, // stack size
1876 0x04, 0x03, // set frame ptr (mov rsp -> rbp)1876 // UBYTE offset of end of instr in prolog + 1, UBYTE:4 operation, UBYTE:4 info
1877 0x01, 0x50 // push reg (rbp)1877 0x04, 0x03, // 3:0 UWOP_SET_FPREG (mov rsp -> rbp)
1878 0x01, 0x50, // 0:5 UWOP_PUSH_NONVOL (push rbp)
1878 };1879 };
1879 1880
1880 Section *s = text_section;1881 Section *s = text_section;
tcctok.h+1−0
@@ -171,6 +171,7 @@ · 170 unmodified lines
171 DEF(TOK_builtin_frame_address, "__builtin_frame_address")171 DEF(TOK_builtin_frame_address, "__builtin_frame_address")
172 DEF(TOK_builtin_return_address, "__builtin_return_address")172 DEF(TOK_builtin_return_address, "__builtin_return_address")
173 DEF(TOK_builtin_expect, "__builtin_expect")173 DEF(TOK_builtin_expect, "__builtin_expect")
174 DEF(TOK_builtin_unreachable, "__builtin_unreachable")
174 /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/175 /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
175#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64176#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
176 DEF(TOK_builtin_va_start, "__builtin_va_start")177 DEF(TOK_builtin_va_start, "__builtin_va_start")
tcctools.c+15−23
@@ -504,28 +504,21 @@ ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option) · 503 unmodified lines
504#ifdef _WIN32504#ifdef _WIN32
505#include <process.h>505#include <process.h>
506 506
507static char *str_replace(const char *str, const char *p, const char *r)507/* quote quotes in string and quote string if it contains spaces */
508static char *quote_win32(const char *s0)
508{509{
509 const char *s, *s0;510 const char *s;
510 char *d, *d0;511 char *p, *q;
511 int sl, pl, rl;512 int a = 0, b = 0, c;
512 513 for (s = s0; !!(c = *s); ++s)
513 sl = strlen(str);514 a += c == '"', b |= c == ' ';
514 pl = strlen(p);515 q = p = tcc_malloc(s - s0 + a + b + b + 1);
515 rl = strlen(r);516 *q = '"', q += b;
516 for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) {517 for (s = s0; !!(c = *s); *q++ = c, ++s)
517 for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) {518 if (c == '"')
518 if (d) {519 *q++ = '\\';
519 memcpy(d, s0, sl = s - s0), d += sl;520 *q = '"', q += b, *q = '\0';
520 memcpy(d, r, rl), d += rl;521 return p;
521 } else
522 sl += rl - pl;
523 }
524 if (d) {
525 strcpy(d, s0);
526 return d0;
527 }
528 }
529}522}
530 523
531static int execvp_win32(const char *prog, char **argv)524static int execvp_win32(const char *prog, char **argv)
@@ -533,8 +526,7 @@ static int execvp_win32(const char *prog, char **argv) · 1 unmodified line
533 int ret; char **p;526 int ret; char **p;
534 /* replace all " by \" */527 /* replace all " by \" */
535 for (p = argv; *p; ++p)528 for (p = argv; *p; ++p)
536 if (strchr(*p, '"'))529 *p = quote_win32(*p);
537 *p = str_replace(*p, "\"", "\\\"");
538 ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);530 ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
539 if (-1 == ret)531 if (-1 == ret)
540 return ret;532 return ret;
tests/exec_section_in_asm.c+0−29
@@ -1,29 +0,0 @@
1/* This test only works on x86-64. */
2/* Previously in TinyCC, ELF sections defined in assembly would always have the
3execute bit not set, so you would get segmentation faults when code in these
4sections was exectuted. This file is a minimal example of a file that will put
5the resulting code in a non-executable section (and invoke it) prior to the fix.
6*/
7#include <stdio.h>
8
9void *memset(void *dst, int c, int len);
10
11__asm__ (
12".section .text.nolibc_memset\n"
13".weak memset\n"
14"memset:\n"
15 "xchgl %eax, %esi\n\t"
16 "movq %rdx, %rcx\n\t"
17 "pushq %rdi\n\t"
18 "rep stosb\n\t"
19 "popq %rax\n\t"
20 "retq\n"
21);
22
23int main () {
24 char buf[10];
25 memset(&buf[0], 'A', 9);
26 buf[9] = 0;
27 puts(buf);
28 return 0;
29}
tests/tcctest.c+1−1
@@ -3989,7 +3989,7 @@ void builtin_test(void) · 3988 unmodified lines
3989 }3989 }
3990}3990}
3991 3991
3992#if defined _WIN323992#if defined _WIN32 || (defined __APPLE__ && GCC_MAJOR >= 15)
3993void weak_test(void) {}3993void weak_test(void) {}
3994#else3994#else
3995extern int __attribute__((weak)) weak_f1(void);3995extern int __attribute__((weak)) weak_f1(void);
tests/tests2/133_exec_section_in_c.c+0−17
@@ -1,17 +0,0 @@
1#include <stdio.h>
2
3/* Previously in TinyCC, ELF sections defined in attributes would always have
4the execute bit not set, so you would get segmentation faults when code in these
5sections was exectuted. This file is a minimal example of a file that will put
6the resulting code in a non-executable section (and invoke it) prior to the fix.
7*/
8__attribute__((section(".text.wumbo")))
9int wumbo (int arg) {
10 return arg * 2;
11}
12
13int main () {
14 wumbo(2);
15 puts("hi");
16 return 0;
17}
tests/tests2/133_exec_section_in_c.expect+0−1
@@ -1 +0,0 @@
1hi
x86_64-gen.c+7−8
@@ -489,7 +489,7 @@ void load(int r, SValue *sv) · 488 unmodified lines
489 }489 }
490#endif490#endif
491 } else if (is64_type(ft)) {491 } else if (is64_type(ft)) {
492 if (sv->c.i > UINT32_MAX) {492 if (sv->c.i >> 32) {
493 orex(1,r,0, 0xb8 + REG_VALUE(r)); /* movabs $xx, r */493 orex(1,r,0, 0xb8 + REG_VALUE(r)); /* movabs $xx, r */
494 gen_le64(sv->c.i);494 gen_le64(sv->c.i);
495 } else if (sv->c.i > 0) {495 } else if (sv->c.i > 0) {
@@ -1017,7 +1017,7 @@ void gfunc_prolog(Sym *func_sym) · 521 unmodified lines
1017/* generate function epilog */1017/* generate function epilog */
1018void gfunc_epilog(void)1018void gfunc_epilog(void)
1019{1019{
1020 int v, saved_ind;1020 int v, start;
1021 1021
1022 /* align local size to word & save local variables */1022 /* align local size to word & save local variables */
1023 func_scratch = (func_scratch + 15) & -16;1023 func_scratch = (func_scratch + 15) & -16;
@@ -1037,10 +1037,12 @@ void gfunc_epilog(void) · 13 unmodified lines
1037 g(func_ret_sub >> 8);1037 g(func_ret_sub >> 8);
1038 }1038 }
1039 1039
1040 saved_ind = ind;
1041 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
1042 v = -loc;1040 v = -loc;
1041 start = func_sub_sp_offset - FUNC_PROLOG_SIZE;
1042 cur_text_section->data_offset = ind;
1043 pe_add_unwind_data(start, ind, v);
1043 1044
1045 ind = start;
1044 if (v >= 4096) {1046 if (v >= 4096) {
1045 Sym *sym = external_helper_sym(TOK___chkstk);1047 Sym *sym = external_helper_sym(TOK___chkstk);
1046 oad(0xb8, v); /* mov stacksize, %eax */1048 oad(0xb8, v); /* mov stacksize, %eax */
@@ -1052,13 +1054,10 @@ void gfunc_epilog(void) · 5 unmodified lines
1052 o(0xec8148); /* sub rsp, stacksize */1054 o(0xec8148); /* sub rsp, stacksize */
1053 gen_le32(v);1055 gen_le32(v);
1054 }1056 }
1057 ind = cur_text_section->data_offset;
1055 1058
1056 /* add the "func_scratch" area after each alloca seen */1059 /* add the "func_scratch" area after each alloca seen */
1057 gsym_addr(func_alloca, -func_scratch);1060 gsym_addr(func_alloca, -func_scratch);
1058
1059 cur_text_section->data_offset = saved_ind;
1060 pe_add_unwind_data(ind, saved_ind, v);
1061 ind = cur_text_section->data_offset;
1062}1061}
1063 1062
1064#else1063#else

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t