History

review some recent changes

tccrun.c: - simplify usage of VirtualAlloc on win32/64 from 6728a64f1b539386bde6458212b349851ff20cd1 tccpe.c: - revert changes to pe_create_pdb() (doesn't work and/or too much complication) from 37b72477962173806d6164ef1af96bc5c39898de - reduce #ifdef amount tccgen.c: - fix fix for cast to void from fad812360ba836b4ca6f52236d867476ff671633 tccelf.c: - put create_riscv_attribute_section() into right place from c77339ab415e537798d3231613f8d0a0bb285e9d tcc.h/libtcc.c: - simplify link-option parser for pe dll_characteristics from 1a54e47dda4722e849a83b2fb5108a6ee7bb8725 i386-gen.c: - fix tls from 8502540b4aad94a8c349b0a3b7309363617a2ff9 workflow/build.yml: - add i386-linux - disable riscv64-linux-native (seems not supported currently)

grischka committed 5 months ago

Commit 7f7845c1 parent a33825813 files · +178 −310Browse files

Unified · Split

13 files
  1. .github/workflows/build.yml +24 −18
  2. i386-gen.c +2 −2
  3. lib/Makefile +1 −1
  4. lib/armflush.c +6 −0
  5. lib/lib-riscv.c +0 −20
  6. libtcc.c +29 −44
  7. tcc-doc.texi +1 −3
  8. tcc.h +0 −10
  9. tccelf.c +4 −3
  10. tccgen.c +2 −0
  11. tccpe.c +82 −174
  12. tccrun.c +18 −24
  13. tests/tests2/Makefile +9 −11
.github/workflows/build.yml+24−18
@@ -34,16 +34,13 @@ jobs: · 33 unmodified lines
3434 timeout-minutes: 6
3535 steps:
3636 - uses: actions/checkout@v4
37− - name: build tcc (x86_64-win32)
37+ - name: build & test (x86_64-win32)
3838 shell: cmd
3939 run: |
4040 cd win32
4141 for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64
4242 call build-tcc.bat -c cl -t x86_64
43− - name: test (x86_64-win32)
44− shell: cmd
45− run: |
46− cd tests
43+ cd ..\tests
4744 call test-win32.bat all -k
4845
4946 test-i386-win32:
@@ -51,16 +48,13 @@ jobs: · 1 unmodified line
5148 timeout-minutes: 6
5249 steps:
5350 - uses: actions/checkout@v4
54− - name: build tcc (i386-win32)
51+ - name: build & test (i386-win32)
5552 shell: cmd
5653 run: |
5754 cd win32
5855 for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" x86
5956 call build-tcc.bat -c cl -t i386
60− - name: test (i386-win32)
61− shell: cmd
62− run: |
63− cd tests
57+ cd ..\tests
6458 call test-win32.bat -p c:\mingw32\bin all -k
6559
6660 test-arm64-win32:
@@ -72,9 +66,8 @@ jobs: · 5 unmodified lines
7266 shell: cmd
7367 run: |
7468 cd win32
75− for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
69+ for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" arm64
7670 call build-tcc.bat -c cl -t arm64
77− set "PATH=C:\Program Files\LLVM\bin;%CD%;%PATH%"
7871 cd ..\tests
7972 call test-win32.bat -c clang all -k
8073
@@ -132,12 +125,25 @@ jobs: · 51 unmodified lines
132125 echo "::endgroup::" # flatten 'run container'
133126 ./configure && make && make test -k
134127
135− test-riscv64-linux-native:
136− runs-on: ubuntu-24.04-riscv
137− timeout-minutes: 8
128+# test-riscv64-linux-native:
129+# runs-on: ubuntu-24.04-riscv
130+# timeout-minutes: 8
131+# steps:
132+# - uses: actions/checkout@v4
133+# - name: make & test tcc (riscv64-linux native)
134+# run: |
135+# uname -m # riscv64
136+# ./configure && make && make test -k
137+
138+ test-i386-linux:
139+ runs-on: ubuntu-latest
140+ timeout-minutes: 3
138141 steps:
139142 - uses: actions/checkout@v4
140− - name: make & test tcc (riscv64-linux native)
143+ - name: install i386-gcc
141144 run: |
142− uname -m # riscv64
143− ./configure && make && make test -k
145+ sudo dpkg --add-architecture i386
146+ sudo apt-get update -q -y
147+ sudo apt-get install -q -y gcc-multilib libc6-dev:i386
148+ - name: make & test tcc (i386-linux)
149+ run: ./configure --cpu=i386 --cc="gcc -m32" && make && make test -k
i386-gen.c+2−2
@@ -439,7 +439,7 @@ ST_FUNC void store(int r, SValue *v) · 438 unmodified lines
439439 } else
440440 #endif
441441
442− if ((fr & VT_SYM) && v->sym->type.t & VT_TLS) {
442+ if ((v->r & VT_SYM) && v->sym->type.t & VT_TLS) {
443443 o(0x65); /* gs segment prefix */
444444 o(opc);
445445 o(0x04 | (REG_VALUE(r) << 3)); /* modrm: [sib] | srcreg */
@@ -467,7 +467,7 @@ static void gadd_sp(int val) · 21 unmodified lines
467467 }
468468 }
469469
470−#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE || defined CONFIG_TCC_PIC
470+#if defined TCC_TARGET_PE || defined CONFIG_TCC_PIC
471471 static void gen_static_call(int v)
472472 {
473473 Sym *sym;
lib/Makefile+1−1
@@ -73,7 +73,7 @@ OBJ-arm-vfp = $(OBJ-arm) · 72 unmodified lines
7373 OBJ-arm-eabi = $(OBJ-arm)
7474 OBJ-arm-eabihf = $(OBJ-arm)
7575 OBJ-arm-wince = $(ARM_O) $(WIN_O)
76−OBJ-riscv64 = $(RISCV64_O) lib-riscv.o $(LIN_O)
76+OBJ-riscv64 = $(RISCV64_O) armflush.o $(LIN_O)
7777
7878 OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
7979 OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
lib/armflush.c+6−0
@@ -61,4 +61,10 @@ void __clear_cache(void *beg, void *end) · 60 unmodified lines
6161 }
6262
6363 /* ------------------------------------------------------------- */
64+#elif defined __riscv
65+void __clear_cache(void *beg, void *end)
66+{
67+ __riscv64_clear_cache(beg, end);
68+}
69+
6470 #endif
lib/lib-riscv.c+0−20
@@ -1,20 +0,0 @@
1−/*
2− * TCC runtime library for riscv64.
3− *
4− * Copyright (c) 2026
5− *
6− * Copying and distribution of this file, with or without modification,
7− * are permitted in any medium without royalty provided the copyright
8− * notice and this notice are preserved. This file is offered as-is,
9− * without any warranty.
10− */
11−
12−/* ------------------------------------------------------------- */
13−/* __clear_cache is used in tccrun.c. It is a built-in
14− intrinsic with gcc. However tcc in order to compile
15− itself needs this function */
16−
17−void __clear_cache(void *beg, void *end)
18−{
19− __riscv64_clear_cache(beg, end);
20−}
libtcc.c+29−44
@@ -899,6 +899,9 @@ LIBTCCAPI TCCState *tcc_new(void) · 898 unmodified lines
899899 #ifdef TCC_ARM_HARDFLOAT
900900 s->float_abi = ARM_HARD_FLOAT;
901901 #endif
902+#if defined TCC_TARGET_ARM64 && defined TCC_TARGET_PE
903+ s->pe_dll_characteristics = 0x8160;
904+#endif
902905 #ifdef CONFIG_NEW_DTAGS
903906 s->enable_new_dtags = 1;
904907 #endif
@@ -1365,7 +1368,7 @@ struct lopt { · 460 unmodified lines
13651368 static int link_option(struct lopt *o, const char *q)
13661369 {
13671370 const char *p;
1368− int c;
1371+ int c, r;
13691372 redo:
13701373 /* there should be 1 or 2 dashes */
13711374 p = o->opt;
@@ -1373,6 +1376,16 @@ redo: · 1 unmodified line
13731376 return 0;
13741377 if (*p == '-')
13751378 p++;
1379+ r = 1;
1380+ if (q[0] == '?') { /* check for no-/disable- prefix */
1381+ ++q;
1382+ if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
1383+ p += 3, r = -1;
1384+#ifdef TCC_TARGET_PE
1385+ else if (0 == memcmp(p, "disable-", 8))
1386+ p += 8, r = -1;
1387+#endif
1388+ }
13761389 while ((c = *q) == *p) {
13771390 if (c == '\0')
13781391 goto succ; /* -Wl,-opt */
@@ -1401,24 +1414,13 @@ redo: · 22 unmodified lines
14011414 succ:
14021415 o->arg = p;
14031416 //printf("set %s '%s'\n", o->opt, o->arg);
1404− return 1;
1417+ return r;
14051418 }
14061419
14071420 static void args_parser_add_file(TCCState *s, const char* filename, int filetype);
14081421
1409−#ifdef TCC_TARGET_PE
1410−static void tcc_pe_set_dll_characteristics(TCCState *s, unsigned flags)
1411−{
1412− s->pe_dll_characteristics |= flags;
1413− s->pe_dll_characteristics_clear &= ~flags;
1414−}
1415−
1416−static void tcc_pe_clear_dll_characteristics(TCCState *s, unsigned flags)
1417−{
1418− s->pe_dll_characteristics &= ~flags;
1419− s->pe_dll_characteristics_clear |= flags;
1420−}
1421−#endif
1422+#define SET_OR_CLEAR(v,f) (v = r > 0 ? v | f : v & ~f)
1423+#define SET_OR_CLEAR_2(v,f1,f2) (v = r > 0 ? v | f1 : v & ~f2)
14221424
14231425 /* set linker options */
14241426 static int tcc_set_linker(TCCState *s, const char *optarg)
@@ -1431,6 +1433,7 @@ static int tcc_set_linker(TCCState *s, const char *optarg) · 6 unmodified lines
14311433 char *end = NULL;
14321434 int ignoring = 0;
14331435 struct lopt o = {0};
1436+ int r;
14341437 o.s = s;
14351438 o.opt = s->link_argv[s->link_optind];
14361439
@@ -1481,39 +1484,21 @@ static int tcc_set_linker(TCCState *s, const char *optarg) · 44 unmodified lines
14811484 s->section_align = strtoul(o.arg, &end, 16);
14821485 } else if (link_option(&o, "soname=|install_name=")) {
14831486 tcc_set_str(&s->soname, o.arg);
1484− } else if (link_option(&o, "whole-archive")) {
1485− s->filetype |= AFF_WHOLE_ARCHIVE;
1486− } else if (link_option(&o, "no-whole-archive")) {
1487− s->filetype &= ~AFF_WHOLE_ARCHIVE;
1487+ } else if (!!(r = link_option(&o, "?whole-archive"))) {
1488+ SET_OR_CLEAR(s->filetype, AFF_WHOLE_ARCHIVE);
14881489 } else if (link_option(&o, "znodelete")) {
14891490 s->znodelete = 1;
14901491 #ifdef TCC_TARGET_PE
14911492 } else if (link_option(&o, "large-address-aware")) {
1492− s->pe_characteristics |= PE_IMAGE_FILE_LARGE_ADDRESS_AWARE;
1493− } else if (link_option(&o, "dynamicbase")) {
1494− tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
1495− } else if (link_option(&o, "disable-dynamicbase|no-dynamicbase")) {
1496− tcc_pe_clear_dll_characteristics(s,
1497− PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
1498− PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
1499− } else if (link_option(&o, "nxcompat")) {
1500− tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
1501− } else if (link_option(&o, "disable-nxcompat|no-nxcompat")) {
1502− tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
1503− } else if (link_option(&o, "high-entropy-va")) {
1504−# if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
1505− tcc_pe_set_dll_characteristics(s,
1506− PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
1507− PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
1508−# else
1509− goto err;
1510−# endif
1511− } else if (link_option(&o, "disable-high-entropy-va|no-high-entropy-va")) {
1512− tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
1513− } else if (link_option(&o, "tsaware")) {
1514− tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
1515− } else if (link_option(&o, "disable-tsaware|no-tsaware")) {
1516− tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
1493+ s->pe_characteristics |= 0x20;
1494+ } else if (!!(r = link_option(&o, "?dynamicbase"))) {
1495+ SET_OR_CLEAR_2(s1->pe_dll_characteristics, 0x40, 0x60);
1496+ } else if (!!(r = link_option(&o, "?high-entropy-va"))) {
1497+ SET_OR_CLEAR_2(s1->pe_dll_characteristics, 0x60, 0x20);
1498+ } else if (!!(r = link_option(&o, "?nxcompat"))) {
1499+ SET_OR_CLEAR(s1->pe_dll_characteristics, 0x100);
1500+ } else if (!!(r = link_option(&o, "?tsaware"))) {
1501+ SET_OR_CLEAR(s1->pe_dll_characteristics, 0x8000);
15171502 } else if (link_option(&o, "file-alignment=")) {
15181503 s->pe_file_align = strtoul(o.arg, &end, 16);
15191504 } else if (link_option(&o, "stack=")) {
tcc-doc.texi+1−3
@@ -386,9 +386,7 @@ Set type for PE (Windows) executables. · 385 unmodified lines
386386 @item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
387387 Modify executable layout.
388388
389−@item -Wl,-[dynamicbase | nxcompat | high-entropy-va | tsaware]
390−@item -Wl,-[no-dynamicbase | no-nxcompat | no-high-entropy-va | no-tsaware]
391−@item -Wl,-[disable-dynamicbase | disable-nxcompat | disable-high-entropy-va | disable-tsaware]
389+@item -Wl,-(no-|disable-)[dynamicbase | nxcompat | high-entropy-va | tsaware]
392390 Set or clear PE (Windows) executable header hardening flags. The
393391 @option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE
394392 targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also
tcc.h+0−10
@@ -727,15 +727,6 @@ struct sym_attr { · 726 unmodified lines
727727 #endif
728728 };
729729
730−#ifdef TCC_TARGET_PE
731−#define PE_IMAGE_FILE_RELOCS_STRIPPED 0x0001
732−#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
733−#define PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
734−#define PE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
735−#define PE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
736−#define PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
737−#endif
738−
739730 struct TCCState {
740731 unsigned char verbose; /* if true, display some information during compilation */
741732 unsigned char nostdinc; /* if true, no standard headers are added */
@@ -949,7 +940,6 @@ struct TCCState { · 207 unmodified lines
949940 int pe_subsystem;
950941 unsigned pe_characteristics;
951942 unsigned pe_dll_characteristics;
952− unsigned pe_dll_characteristics_clear;
953943 unsigned pe_file_align;
954944 unsigned pe_stack_size;
955945 addr_t pe_imagebase;
tccelf.c+4−3
@@ -2992,6 +2992,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 2991 unmodified lines
29922992 create_arm_attribute_section (s1);
29932993 #endif
29942994
2995+#ifdef TCC_TARGET_RISCV64
2996+ create_riscv_attribute_section(s1);
2997+#endif
2998+
29952999 #if TARGETOS_OpenBSD
29963000 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
29973001 #endif
@@ -3172,9 +3176,6 @@ static int elf_output_obj(TCCState *s1, const char *filename) · 174 unmodified lines
31723176 {
31733177 Section *s;
31743178 int i, ret, file_offset;
3175−#ifdef TCC_TARGET_RISCV64
3176− create_riscv_attribute_section(s1);
3177−#endif
31783179 /* Allocate strings for section names */
31793180 alloc_sec_names(s1, 1);
31803181 file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
tccgen.c+2−0
@@ -3280,6 +3280,8 @@ again: · 3279 unmodified lines
32803280 dbt_bt = dbt & VT_BTYPE;
32813281 sbt_bt = sbt & VT_BTYPE;
32823282 if (dbt_bt == VT_VOID) {
3283+ /* do not confuse backends with VT_VOID in registers */
3284+ vpop(), vpushi(0);
32833285 goto done;
32843286 }
32853287 if (sbt_bt == VT_VOID) {
tccpe.c+82−174
@@ -27,54 +27,78 @@ · 26 unmodified lines
2727 #define stricmp strcasecmp
2828 #define strnicmp strncasecmp
2929 #include <sys/stat.h> /* chmod() */
30−#else
31−#include <process.h>
3230 #endif
3331
34−#ifdef TCC_TARGET_X86_64
35−# define ADDR3264 ULONGLONG
36−# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
32+#if defined TCC_TARGET_X86_64
3733 # define REL_TYPE_DIRECT R_X86_64_64
3834 # define R_XXX_THUNKFIX R_X86_64_PC32
3935 # define R_XXX_RELATIVE R_X86_64_RELATIVE
4036 # define R_XXX_FUNCCALL R_X86_64_PLT32
41−# define IMAGE_FILE_MACHINE 0x8664
4237 # define RSRC_RELTYPE 3
38+# define IMAGE_FILE_MACHINE 0x8664
39+# define CHARACTERISTICS_EXE 0x022F
40+# define CHARACTERISTICS_DLL 0x222E
41+# define IMAGE_BASE_EXE 0x00400000
42+# define IMAGE_BASE_DLL 0x10000000
43+# define DLLCHARACTERISTICS 0
44+# define OS_VER 0x0400
4345
4446 #elif defined TCC_TARGET_ARM
45−# define ADDR3264 DWORD
46−# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
4747 # define REL_TYPE_DIRECT R_ARM_ABS32
4848 # define R_XXX_THUNKFIX R_ARM_ABS32
4949 # define R_XXX_RELATIVE R_ARM_RELATIVE
5050 # define R_XXX_FUNCCALL R_ARM_PC24
5151 # define R_XXX_FUNCCALL2 R_ARM_ABS32
52−# define IMAGE_FILE_MACHINE 0x01C0
5352 # define RSRC_RELTYPE 7 /* ??? (not tested) */
53+# define IMAGE_FILE_MACHINE 0x01C0
54+# define CHARACTERISTICS_EXE 0x010F
55+# define CHARACTERISTICS_DLL 0x230F
56+# define IMAGE_BASE_EXE 0x00100000
57+# define IMAGE_BASE_DLL 0x10000000
58+# define DLLCHARACTERISTICS 0
59+# define OS_VER 0x0400
5460
5561 #elif defined TCC_TARGET_ARM64
56−# define ADDR3264 ULONGLONG
57−# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
5862 # define REL_TYPE_DIRECT R_AARCH64_ABS64
5963 # define R_XXX_THUNKFIX R_AARCH64_ABS64
6064 # define R_XXX_RELATIVE R_AARCH64_RELATIVE
6165 # define R_XXX_FUNCCALL R_AARCH64_CALL26
62−# define IMAGE_FILE_MACHINE 0xAA64
6366 # define RSRC_RELTYPE 3
67+# define IMAGE_FILE_MACHINE 0xAA64
68+# define CHARACTERISTICS_EXE 0x0022
69+# define CHARACTERISTICS_DLL 0x2022
70+# define IMAGE_BASE_EXE 0x140000000ULL
71+# define IMAGE_BASE_DLL 0x180000000ULL
72+# define OS_VER 0x0602
73+# define DLLCHARACTERISTICS 0x8160
6474
6575 #elif defined TCC_TARGET_I386
66−# define ADDR3264 DWORD
67−# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
6876 # define REL_TYPE_DIRECT R_386_32
6977 # define R_XXX_THUNKFIX R_386_32
7078 # define R_XXX_RELATIVE R_386_RELATIVE
7179 # define R_XXX_FUNCCALL R_386_PC32
72−# define IMAGE_FILE_MACHINE 0x014C
7380 # define RSRC_RELTYPE 7 /* DIR32NB */
81+# define IMAGE_FILE_MACHINE 0x014C
82+# define CHARACTERISTICS_EXE 0x030F
83+# define CHARACTERISTICS_DLL 0x230E
84+# define IMAGE_BASE_EXE 0x00400000
85+# define IMAGE_BASE_DLL 0x10000000
86+# define OS_VER 0x0400
87+# define DLLCHARACTERISTICS 0
88+#endif
7489
90+#if PTR_SIZE == 8
91+# define ADDR3264 ULONGLONG
92+# define PE_MAGIC 0x020B
93+# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
94+#else
95+# define ADDR3264 DWORD
96+# define PE_MAGIC 0x010B
97+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
7598 #endif
7699
77100 #ifndef IMAGE_NT_SIGNATURE
101+/* cross compiler: windows.h was not included */
78102 /* ----------------------------------------------------------- */
79103 /* definitions below are from winnt.h */
80104
@@ -107,7 +131,6 @@ typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */ · 26 unmodified lines
107131 } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
108132
109133 #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
110−#define SIZE_OF_NT_SIGNATURE 4
111134
112135 typedef struct _IMAGE_FILE_HEADER {
113136 WORD Machine;
@@ -138,7 +161,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER { · 24 unmodified lines
138161 DWORD SizeOfUninitializedData;
139162 DWORD AddressOfEntryPoint;
140163 DWORD BaseOfCode;
141−#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
164+#if PTR_SIZE == 4
142165 DWORD BaseOfData;
143166 #endif
144167 /* NT additional fields. */
@@ -237,19 +260,6 @@ typedef struct _IMAGE_BASE_RELOCATION { · 92 unmodified lines
237260
238261 #define IMAGE_SIZEOF_BASE_RELOCATION 8
239262
240−#ifndef IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
241−#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
242−#endif
243−#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
244−#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE PE_DLLCHARACTERISTICS_DYNAMIC_BASE
245−#endif
246−#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
247−#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT PE_DLLCHARACTERISTICS_NX_COMPAT
248−#endif
249−#ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
250−#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
251−#endif
252−
253263 #define IMAGE_REL_BASED_ABSOLUTE 0
254264 #define IMAGE_REL_BASED_HIGH 1
255265 #define IMAGE_REL_BASED_LOW 2
@@ -269,34 +279,19 @@ typedef struct _IMAGE_BASE_RELOCATION { · 13 unmodified lines
269279 #define IMAGE_SCN_MEM_READ 0x40000000
270280 #define IMAGE_SCN_MEM_WRITE 0x80000000
271281
282+#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
283+#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
284+#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
285+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
286+
287+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
288+
272289 #pragma pack(pop)
273290
274291 /* ----------------------------------------------------------- */
275292 #endif /* ndef IMAGE_NT_SIGNATURE */
276293 /* ----------------------------------------------------------- */
277294
278−static WORD pe_get_dll_characteristics(TCCState *s1)
279−{
280− unsigned v = 0;
281−
282−#ifdef TCC_TARGET_ARM64
283− v = PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
284− PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
285− PE_DLLCHARACTERISTICS_NX_COMPAT |
286− PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
287−#endif
288− v |= s1->pe_dll_characteristics;
289− v &= ~s1->pe_dll_characteristics_clear;
290− return v;
291−}
292−
293−#ifndef IMAGE_FILE_MACHINE_ARM64
294−#define IMAGE_FILE_MACHINE_ARM64 0xAA64
295−#endif
296−#ifndef IMAGE_REL_BASED_DIR64
297−# define IMAGE_REL_BASED_DIR64 10
298−#endif
299−
300295 #pragma pack(push, 1)
301296 struct pe_header
302297 {
@@ -304,7 +299,7 @@ struct pe_header · 1 unmodified line
304299 BYTE dosstub[0x40];
305300 DWORD nt_sig;
306301 IMAGE_FILE_HEADER filehdr;
307−#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
302+#if PTR_SIZE == 8
308303 IMAGE_OPTIONAL_HEADER64 opthdr;
309304 #else
310305 #ifdef _WIN64
@@ -580,55 +575,17 @@ static void pe_add_coffsym(struct pe_info *pe) · 269 unmodified lines
580575
581576 /* Run cv2pdb, available at https://github.com/rainers/cv2pdb. It reads
582577 and strips the dwarf info and creates a <exename>.pdb file instead */
583−#ifndef _WIN32
584−static void pe_shell_quote(CString *cmd, const char *arg)
585−{
586− cstr_cat(cmd, "'", 1);
587− while (*arg) {
588− if (*arg == '\'')
589− cstr_cat(cmd, "'\\''", 4);
590− else
591− cstr_cat(cmd, arg, 1);
592− ++arg;
593− }
594− cstr_cat(cmd, "'", 1);
595−}
596−#endif
597−
598−static intptr_t pe_run_cv2pdb(const char *exename)
599−{
600−#ifdef _WIN32
601− const char *argv[] = { "cv2pdb.exe", exename, NULL };
602− return _spawnvp(_P_WAIT, "cv2pdb.exe", argv);
603−#else
604− CString cmd;
605− intptr_t ret;
606−
607− cstr_new(&cmd);
608− cstr_cat(&cmd, "cv2pdb.exe ", -1);
609− pe_shell_quote(&cmd, exename);
610− cstr_ccat(&cmd, 0);
611− ret = system(cmd.data);
612− cstr_free(&cmd);
613− return ret;
614−#endif
615−}
616−
617578 static void pe_create_pdb(TCCState *s1, const char *exename)
618579 {
619− size_t len = strlen(exename);
620− char *pdbfile = tcc_malloc(len + sizeof(".pdb"));
621− intptr_t r;
622−
623− strcpy(pdbfile, exename);
624− strcpy(tcc_fileextension(pdbfile), ".pdb");
625− r = pe_run_cv2pdb(exename);
580+ char buf[300]; int r;
581+ snprintf(buf, sizeof buf, "cv2pdb.exe \"%s\"", exename);
582+ r = system(buf);
583+ strcpy(tcc_fileextension(strcpy(buf, exename)), ".pdb");
626584 if (r) {
627− tcc_error_noabort("could not create '%s'\n(need working cv2pdb from https://github.com/rainers/cv2pdb)", pdbfile);
585+ tcc_error_noabort("could not create '%s'\n(need working cv2pdb from https://github.com/rainers/cv2pdb)", buf);
628586 } else if (s1->verbose) {
629− printf("<- %s\n", pdbfile);
587+ printf("<- %s\n", buf);
630588 }
631− tcc_free(pdbfile);
632589 }
633590
634591 /*----------------------------------------------------------------------------*/
@@ -674,31 +631,12 @@ static int pe_write(struct pe_info *pe) · 39 unmodified lines
674631 0x00000000, /*DWORD TimeDateStamp; */
675632 0x00000000, /*DWORD PointerToSymbolTable; */
676633 0x00000000, /*DWORD NumberOfSymbols; */
677−#if defined(TCC_TARGET_X86_64)
678− 0x00F0, /*WORD SizeOfOptionalHeader; */
679− 0x022F /*WORD Characteristics; */
680−#define CHARACTERISTICS_DLL 0x222E
681−#elif defined(TCC_TARGET_I386)
682− 0x00E0, /*WORD SizeOfOptionalHeader; */
683− 0x030F /*WORD Characteristics; */
684−#define CHARACTERISTICS_DLL 0x230E
685−#elif defined(TCC_TARGET_ARM)
686− 0x00E0, /*WORD SizeOfOptionalHeader; */
687− 0x010F, /*WORD Characteristics; */
688−#define CHARACTERISTICS_DLL 0x230F
689−#elif defined(TCC_TARGET_ARM64)
690− 0x00F0, /*WORD SizeOfOptionalHeader; */
691− 0x0022 /*WORD Characteristics; */
692−#define CHARACTERISTICS_DLL 0x2022
693−#endif
694−},{
634+ 0x00E0 + (PTR_SIZE-4)*4, /*WORD SizeOfOptionalHeader; */
635+ CHARACTERISTICS_EXE, /*WORD Characteristics; */
636+ },{
695637 /* IMAGE_OPTIONAL_HEADER opthdr */
696638 /* Standard fields. */
697−#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
698− 0x020B, /*WORD Magic; */
699−#else
700− 0x010B, /*WORD Magic; */
701−#endif
639+ PE_MAGIC, /*WORD Magic; */
702640 0x06, /*BYTE MajorLinkerVersion; */
703641 0x00, /*BYTE MinorLinkerVersion; */
704642 0x00000000, /*DWORD SizeOfCode; */
@@ -706,45 +644,29 @@ static int pe_write(struct pe_info *pe) · 1 unmodified line
706644 0x00000000, /*DWORD SizeOfUninitializedData; */
707645 0x00000000, /*DWORD AddressOfEntryPoint; */
708646 0x00000000, /*DWORD BaseOfCode; */
709−#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
647+#if PTR_SIZE == 4
710648 0x00000000, /*DWORD BaseOfData; */
711649 #endif
712650 /* NT additional fields. */
713−#if defined(TCC_TARGET_ARM)
714− 0x00100000, /*DWORD ImageBase; */
715−#elif defined(TCC_TARGET_ARM64)
716− 0x140000000ULL, /*ULONGLONG ImageBase; */
717−#else
718− 0x00400000, /*DWORD ImageBase; */
719−#endif
651+ 0x00000000, /*ADDR3264 ImageBase; */
720652 0x00001000, /*DWORD SectionAlignment; */
721653 0x00000200, /*DWORD FileAlignment; */
722−#if defined(TCC_TARGET_ARM64)
723− 0x0006, /*WORD MajorOperatingSystemVersion; */
724− 0x0002, /*WORD MinorOperatingSystemVersion; */
725−#else
726− 0x0004, /*WORD MajorOperatingSystemVersion; */
727− 0x0000, /*WORD MinorOperatingSystemVersion; */
728−#endif
654+ OS_VER >> 8, /*WORD MajorOperatingSystemVersion; */
655+ OS_VER & 255, /*WORD MinorOperatingSystemVersion; */
729656 0x0000, /*WORD MajorImageVersion; */
730657 0x0000, /*WORD MinorImageVersion; */
731−#if defined(TCC_TARGET_ARM64)
732− 0x0006, /*WORD MajorSubsystemVersion; */
733− 0x0002, /*WORD MinorSubsystemVersion; */
734−#else
735− 0x0004, /*WORD MajorSubsystemVersion; */
736− 0x0000, /*WORD MinorSubsystemVersion; */
737−#endif
658+ OS_VER >> 8, /*WORD MajorSubsystemVersion; */
659+ OS_VER & 255, /*WORD MinorSubsystemVersion; */
738660 0x00000000, /*DWORD Win32VersionValue; */
739661 0x00000000, /*DWORD SizeOfImage; */
740662 0x00000200, /*DWORD SizeOfHeaders; */
741663 0x00000000, /*DWORD CheckSum; */
742664 0x0002, /*WORD Subsystem; */
743− 0x0000, /*WORD DllCharacteristics; */
744− 0x00100000, /*DWORD SizeOfStackReserve; */
745− 0x00001000, /*DWORD SizeOfStackCommit; */
746− 0x00100000, /*DWORD SizeOfHeapReserve; */
747− 0x00001000, /*DWORD SizeOfHeapCommit; */
665+ DLLCHARACTERISTICS, /*WORD DllCharacteristics; */
666+ 0x00100000, /*ADDR3264 SizeOfStackReserve; */
667+ 0x00001000, /*ADDR3264 SizeOfStackCommit; */
668+ 0x00100000, /*ADDR3264 SizeOfHeapReserve; */
669+ 0x00001000, /*ADDR3264 SizeOfHeapCommit; */
748670 0x00000000, /*DWORD LoaderFlags; */
749671 0x00000010, /*DWORD NumberOfRvaAndSizes; */
750672
@@ -799,7 +721,7 @@ static int pe_write(struct pe_info *pe) · 48 unmodified lines
799721 break;
800722
801723 case sec_data:
802−#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
724+#if PTR_SIZE == 4
803725 if (!pe_header.opthdr.BaseOfData)
804726 pe_header.opthdr.BaseOfData = addr;
805727 #endif
@@ -861,14 +783,14 @@ static int pe_write(struct pe_info *pe) · 55 unmodified lines
861783 pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
862784 pe_header.opthdr.ImageBase = pe->imagebase;
863785 pe_header.opthdr.Subsystem = pe->subsystem;
864− pe_header.opthdr.DllCharacteristics = pe_get_dll_characteristics(s1);
786+ pe_header.opthdr.DllCharacteristics = s1->pe_dll_characteristics;
865787 if (s1->pe_stack_size)
866788 pe_header.opthdr.SizeOfStackReserve = s1->pe_stack_size;
867789 if (PE_DLL == pe->type)
868790 pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
869791 pe_header.filehdr.Characteristics |= s1->pe_characteristics;
870792 if (pe->reloc)
871− pe_header.filehdr.Characteristics &= ~PE_IMAGE_FILE_RELOCS_STRIPPED;
793+ pe_header.filehdr.Characteristics &= ~IMAGE_FILE_RELOCS_STRIPPED;
872794
873795 if (pe->coffsym) {
874796 pe_add_coffsym(pe);
@@ -1291,8 +1213,8 @@ static int pe_assign_addresses (struct pe_info *pe) · 416 unmodified lines
12911213 Section *s;
12921214 TCCState *s1 = pe->s1;
12931215
1294− if (PE_DLL == pe->type ||
1295− (pe_get_dll_characteristics(s1) & PE_DLLCHARACTERISTICS_DYNAMIC_BASE))
1216+ if (PE_DLL == pe->type
1217+ || (s1->pe_dll_characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
12961218 pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
12971219 //pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
12981220
@@ -1483,14 +1405,10 @@ static int pe_check_symbols(struct pe_info *pe) · 184 unmodified lines
14831405 offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
14841406 #elif defined(TCC_TARGET_ARM64)
14851407 p = section_ptr_add(text_section, 24);
1486− /* ldr x16, [pc, #16] */
1487− write32le(p + 0, 0x58000090);
1488− /* ldr x16, [x16] */
1489− write32le(p + 4, 0xf9400210);
1490− /* br x16 */
1491− write32le(p + 8, 0xd61f0200);
1492− /* nop for 8-byte literal alignment */
1493− write32le(p + 12, 0xd503201f);
1408+ write32le(p + 0, 0x58000090); /* ldr x16, [pc, #16] */
1409+ write32le(p + 4, 0xf9400210); /* ldr x16, [x16] */
1410+ write32le(p + 8, 0xd61f0200); /* br x16 */
1411+ write32le(p + 12, 0xd503201f); /* nop for alignment */
14941412 put_elf_reloc(symtab_section, text_section,
14951413 offset + 16, R_XXX_THUNKFIX, is->iat_index);
14961414 #else
@@ -1716,7 +1634,7 @@ static int get_dllexports(int fd, char **pp) · 219 unmodified lines
17161634 if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
17171635 goto the_end;
17181636 opt_hdroffset = pef_hdroffset + sizeof ih;
1719− if (ih.Machine == 0x014C) {
1637+ if (ih.Machine == 0x014C || ih.Machine == 0x01C0) {
17201638 IMAGE_OPTIONAL_HEADER32 oh;
17211639 sec_hdroffset = opt_hdroffset + sizeof oh;
17221640 if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
@@ -1724,7 +1642,7 @@ static int get_dllexports(int fd, char **pp) · 1 unmodified line
17241642 if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
17251643 goto the_end_0;
17261644 addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
1727− } else if (ih.Machine == 0x8664 || ih.Machine == IMAGE_FILE_MACHINE_ARM64) {
1645+ } else if (ih.Machine == 0x8664 || ih.Machine == 0xAA64) {
17281646 IMAGE_OPTIONAL_HEADER64 oh;
17291647 sec_hdroffset = opt_hdroffset + sizeof oh;
17301648 if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
@@ -2209,19 +2127,9 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe) · 478 unmodified lines
22092127 {
22102128 if (PE_DLL == pe->type) {
22112129 /* XXX: check if is correct for arm-pe target */
2212−#if defined(TCC_TARGET_ARM64)
2213− pe->imagebase = 0x180000000ULL;
2214−#else
2215− pe->imagebase = 0x10000000;
2216−#endif
2130+ pe->imagebase = IMAGE_BASE_DLL;
22172131 } else {
2218−#if defined(TCC_TARGET_ARM)
2219− pe->imagebase = 0x00010000;
2220−#elif defined(TCC_TARGET_ARM64)
2221− pe->imagebase = 0x140000000ULL;
2222−#else
2223− pe->imagebase = 0x00400000;
2224−#endif
2132+ pe->imagebase = IMAGE_BASE_EXE;
22252133 }
22262134
22272135 #if defined(TCC_TARGET_ARM)
tccrun.c+18−24
@@ -108,6 +108,11 @@ static void win64_del_function_table(void *); · 107 unmodified lines
108108 //#define CONFIG_SELINUX 1
109109 #endif
110110
111+/* use VirtualAlloc() instead of tcc_malloc() */
112+#if defined _WIN32 && !defined CONFIG_RUNMEM_VIRTUALALLOC
113+# define CONFIG_RUNMEM_VIRTUALALLOC 1
114+#endif
115+
111116 static int rt_mem(TCCState *s1, int size)
112117 {
113118 void *ptr;
@@ -129,16 +134,14 @@ static int rt_mem(TCCState *s1, int size) · 15 unmodified lines
129134 ptr_diff = (char*)prw - (char*)ptr; /* = size; */
130135 //printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
131136 size *= 2;
132−#else
133−# ifdef _WIN32
134− /* Generated code is page-protected below; avoid changing CRT heap pages. */
137+#elif CONFIG_RUNMEM_VIRTUALALLOC
138+ /* always page-aligned */
135139 ptr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
136−# else
137− ptr = tcc_malloc(size += PAGESIZE); /* one extra page to align malloc memory */
138−# endif
139−#endif
140140 if (!ptr)
141141 return tcc_error_noabort("tccrun: could not allocate memory");
142+#else
143+ ptr = tcc_malloc(size += PAGESIZE); /* one extra page to align malloc memory */
144+#endif
142145 s1->run_ptr = ptr;
143146 s1->run_size = size;
144147 return ptr_diff;
@@ -191,24 +194,18 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 46 unmodified lines
191194 if (NULL == ptr)
192195 return;
193196 st_unlink(s1);
197+#ifdef _WIN64
198+ win64_del_function_table(s1->run_function_table);
199+#endif
194200 size = s1->run_size;
195201 #ifdef CONFIG_SELINUX
196202 munmap(ptr, size);
203+#elif CONFIG_RUNMEM_VIRTUALALLOC
204+ VirtualFree(ptr, size, MEM_RELEASE);
197205 #else
198−# ifdef _WIN32
199− (void)size;
200−# ifdef _WIN64
201− win64_del_function_table(s1->run_function_table);
202−# endif
203− VirtualFree(ptr, 0, MEM_RELEASE);
204−# else
205206 /* unprotect memory to make it usable for malloc again */
206207 protect_pages((void*)PAGEALIGN(ptr), size - PAGESIZE, 2 /*rw*/);
207−# ifdef _WIN64
208− win64_del_function_table(s1->run_function_table);
209−# endif
210208 tcc_free(ptr);
211−# endif
212209 #endif
213210 }
214211
@@ -312,7 +309,7 @@ static void cleanup_sections(TCCState *s1) · 97 unmodified lines
312309 }
313310
314311 /* ------------------------------------------------------------- */
315−/* 0 = .text rwx other rw (memory >= 2 pages a 4096 bytes) */
312+/* 0 = .text rwx other rwx (memory >= 2 pages a 4096 bytes) */
316313 /* 1 = .text rx other rw (memory >= 3 pages) */
317314 /* 2 = .text rx .rdata ro .data/.bss rw (memory >= 4 pages) */
318315
@@ -506,14 +503,11 @@ static void *win64_add_function_table(TCCState *s1) · 187 unmodified lines
506503 void *p = NULL;
507504 if (s1->uw_pdata) {
508505 p = (void*)s1->uw_pdata->sh_addr;
509− if (!RtlAddFunctionTable(
506+ RtlAddFunctionTable(
510507 (RUNTIME_FUNCTION*)p,
511508 s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
512509 s1->pe_imagebase
513− )) {
514− tcc_error_noabort("RtlAddFunctionTable failed");
515− p = NULL;
516− }
510+ );
517511 s1->uw_pdata = NULL;
518512 }
519513 return p;
tests/tests2/Makefile+9−11
@@ -19,9 +19,6 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) · 18 unmodified lines
1919 SKIP += 85_asm-outside-function.test # x86 asm
2020 SKIP += 127_asm_goto.test # hardcodes x86 asm
2121 endif
22−ifeq (,$(filter x86_64 riscv64 arm64 i386,$(ARCH)))
23− SKIP += 144_tls.test # TLS only implemented on these architectures so far
24−endif
2522 ifeq ($(CONFIG_backtrace),no)
2623 SKIP += 113_btdll.test
2724 CONFIG_bcheck = no
@@ -57,22 +54,23 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) · 29 unmodified lines
5754 SKIP += 114_bound_signal.test # libc problem signal/fork
5855 SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
5956 endif
60−ifdef CONFIG_OSX
57+ifeq ($(CONFIG_OSX),yes)
6158 SKIP += 144_tls.test # TLS runtime not supported on Mach-O
6259 endif
63−ifeq (,$(filter arm64 aarch64,$(ARCH)))
60+ifeq (,$(filter i386 x86_64 riscv64 arm64,$(ARCH)))
61+ SKIP += 144_tls.test # TLS only implemented on these architectures so far
62+endif
63+ifneq (-$(ARCH)-,-arm64-)
6464 SKIP += 138_arm64_encoding.test
6565 SKIP += 139_arm64_errors.test
6666 SKIP += 140_arm64_extasm.test
6767 endif
68−ifneq ($(CONFIG_WIN32),yes)
69− SKIP += 145_winarm64_interlocked.test
70−else ifeq (,$(filter arm64 aarch64,$(ARCH)))
71− SKIP += 145_winarm64_interlocked.test
72−endif
73−ifeq (,$(filter riscv64,$(ARCH)))
68+ifneq (-$(ARCH)-,-riscv64-)
7469 SKIP += 141_riscv_asm.test # riscv64 asm
7570 endif
71+ifneq (-$(ARCH)-$(CONFIG_WIN32)-,-arm64-yes-)
72+ SKIP += 145_winarm64_interlocked.test
73+endif
7674
7775 # Some tests might need arguments
7876 ARGS =

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