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)
Unified · Split
| @@ -34,16 +34,13 @@ jobs: · 33 unmodified lines | ||
| 34 | 34 | timeout-minutes: 6 |
| 35 | 35 | steps: |
| 36 | 36 | - uses: actions/checkout@v4 |
| 37 | − - name: build tcc (x86_64-win32) | |
| 37 | + - name: build & test (x86_64-win32) | |
| 38 | 38 | shell: cmd |
| 39 | 39 | run: | |
| 40 | 40 | cd win32 |
| 41 | 41 | for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64 |
| 42 | 42 | 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 | |
| 47 | 44 | call test-win32.bat all -k |
| 48 | 45 | |
| 49 | 46 | test-i386-win32: |
| @@ -51,16 +48,13 @@ jobs: · 1 unmodified line | ||
| 51 | 48 | timeout-minutes: 6 |
| 52 | 49 | steps: |
| 53 | 50 | - uses: actions/checkout@v4 |
| 54 | − - name: build tcc (i386-win32) | |
| 51 | + - name: build & test (i386-win32) | |
| 55 | 52 | shell: cmd |
| 56 | 53 | run: | |
| 57 | 54 | cd win32 |
| 58 | 55 | for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" x86 |
| 59 | 56 | call build-tcc.bat -c cl -t i386 |
| 60 | − - name: test (i386-win32) | |
| 61 | − shell: cmd | |
| 62 | − run: | | |
| 63 | − cd tests | |
| 57 | + cd ..\tests | |
| 64 | 58 | call test-win32.bat -p c:\mingw32\bin all -k |
| 65 | 59 | |
| 66 | 60 | test-arm64-win32: |
| @@ -72,9 +66,8 @@ jobs: · 5 unmodified lines | ||
| 72 | 66 | shell: cmd |
| 73 | 67 | run: | |
| 74 | 68 | 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 | |
| 76 | 70 | call build-tcc.bat -c cl -t arm64 |
| 77 | − set "PATH=C:\Program Files\LLVM\bin;%CD%;%PATH%" | |
| 78 | 71 | cd ..\tests |
| 79 | 72 | call test-win32.bat -c clang all -k |
| 80 | 73 | |
| @@ -132,12 +125,25 @@ jobs: · 51 unmodified lines | ||
| 132 | 125 | echo "::endgroup::" # flatten 'run container' |
| 133 | 126 | ./configure && make && make test -k |
| 134 | 127 | |
| 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 | |
| 138 | 141 | steps: |
| 139 | 142 | - uses: actions/checkout@v4 |
| 140 | − - name: make & test tcc (riscv64-linux native) | |
| 143 | + - name: install i386-gcc | |
| 141 | 144 | 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 | |
| @@ -439,7 +439,7 @@ ST_FUNC void store(int r, SValue *v) · 438 unmodified lines | ||
| 439 | 439 | } else |
| 440 | 440 | #endif |
| 441 | 441 | |
| 442 | − if ((fr & VT_SYM) && v->sym->type.t & VT_TLS) { | |
| 442 | + if ((v->r & VT_SYM) && v->sym->type.t & VT_TLS) { | |
| 443 | 443 | o(0x65); /* gs segment prefix */ |
| 444 | 444 | o(opc); |
| 445 | 445 | o(0x04 | (REG_VALUE(r) << 3)); /* modrm: [sib] | srcreg */ |
| @@ -467,7 +467,7 @@ static void gadd_sp(int val) · 21 unmodified lines | ||
| 467 | 467 | } |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | −#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE || defined CONFIG_TCC_PIC | |
| 470 | +#if defined TCC_TARGET_PE || defined CONFIG_TCC_PIC | |
| 471 | 471 | static void gen_static_call(int v) |
| 472 | 472 | { |
| 473 | 473 | Sym *sym; |
| @@ -73,7 +73,7 @@ OBJ-arm-vfp = $(OBJ-arm) · 72 unmodified lines | ||
| 73 | 73 | OBJ-arm-eabi = $(OBJ-arm) |
| 74 | 74 | OBJ-arm-eabihf = $(OBJ-arm) |
| 75 | 75 | 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) | |
| 77 | 77 | |
| 78 | 78 | OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T)) |
| 79 | 79 | OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) |
| @@ -61,4 +61,10 @@ void __clear_cache(void *beg, void *end) · 60 unmodified lines | ||
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | /* ------------------------------------------------------------- */ |
| 64 | +#elif defined __riscv | |
| 65 | +void __clear_cache(void *beg, void *end) | |
| 66 | +{ | |
| 67 | + __riscv64_clear_cache(beg, end); | |
| 68 | +} | |
| 69 | + | |
| 64 | 70 | #endif |
| @@ -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 | −} | |
| @@ -899,6 +899,9 @@ LIBTCCAPI TCCState *tcc_new(void) · 898 unmodified lines | ||
| 899 | 899 | #ifdef TCC_ARM_HARDFLOAT |
| 900 | 900 | s->float_abi = ARM_HARD_FLOAT; |
| 901 | 901 | #endif |
| 902 | +#if defined TCC_TARGET_ARM64 && defined TCC_TARGET_PE | |
| 903 | + s->pe_dll_characteristics = 0x8160; | |
| 904 | +#endif | |
| 902 | 905 | #ifdef CONFIG_NEW_DTAGS |
| 903 | 906 | s->enable_new_dtags = 1; |
| 904 | 907 | #endif |
| @@ -1365,7 +1368,7 @@ struct lopt { · 460 unmodified lines | ||
| 1365 | 1368 | static int link_option(struct lopt *o, const char *q) |
| 1366 | 1369 | { |
| 1367 | 1370 | const char *p; |
| 1368 | − int c; | |
| 1371 | + int c, r; | |
| 1369 | 1372 | redo: |
| 1370 | 1373 | /* there should be 1 or 2 dashes */ |
| 1371 | 1374 | p = o->opt; |
| @@ -1373,6 +1376,16 @@ redo: · 1 unmodified line | ||
| 1373 | 1376 | return 0; |
| 1374 | 1377 | if (*p == '-') |
| 1375 | 1378 | 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 | + } | |
| 1376 | 1389 | while ((c = *q) == *p) { |
| 1377 | 1390 | if (c == '\0') |
| 1378 | 1391 | goto succ; /* -Wl,-opt */ |
| @@ -1401,24 +1414,13 @@ redo: · 22 unmodified lines | ||
| 1401 | 1414 | succ: |
| 1402 | 1415 | o->arg = p; |
| 1403 | 1416 | //printf("set %s '%s'\n", o->opt, o->arg); |
| 1404 | − return 1; | |
| 1417 | + return r; | |
| 1405 | 1418 | } |
| 1406 | 1419 | |
| 1407 | 1420 | static void args_parser_add_file(TCCState *s, const char* filename, int filetype); |
| 1408 | 1421 | |
| 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) | |
| 1422 | 1424 | |
| 1423 | 1425 | /* set linker options */ |
| 1424 | 1426 | 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 | ||
| 1431 | 1433 | char *end = NULL; |
| 1432 | 1434 | int ignoring = 0; |
| 1433 | 1435 | struct lopt o = {0}; |
| 1436 | + int r; | |
| 1434 | 1437 | o.s = s; |
| 1435 | 1438 | o.opt = s->link_argv[s->link_optind]; |
| 1436 | 1439 | |
| @@ -1481,39 +1484,21 @@ static int tcc_set_linker(TCCState *s, const char *optarg) · 44 unmodified lines | ||
| 1481 | 1484 | s->section_align = strtoul(o.arg, &end, 16); |
| 1482 | 1485 | } else if (link_option(&o, "soname=|install_name=")) { |
| 1483 | 1486 | 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); | |
| 1488 | 1489 | } else if (link_option(&o, "znodelete")) { |
| 1489 | 1490 | s->znodelete = 1; |
| 1490 | 1491 | #ifdef TCC_TARGET_PE |
| 1491 | 1492 | } 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); | |
| 1517 | 1502 | } else if (link_option(&o, "file-alignment=")) { |
| 1518 | 1503 | s->pe_file_align = strtoul(o.arg, &end, 16); |
| 1519 | 1504 | } else if (link_option(&o, "stack=")) { |
| @@ -386,9 +386,7 @@ Set type for PE (Windows) executables. · 385 unmodified lines | ||
| 386 | 386 | @item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#] |
| 387 | 387 | Modify executable layout. |
| 388 | 388 | |
| 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] | |
| 392 | 390 | Set or clear PE (Windows) executable header hardening flags. The |
| 393 | 391 | @option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE |
| 394 | 392 | targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also |
| @@ -727,15 +727,6 @@ struct sym_attr { · 726 unmodified lines | ||
| 727 | 727 | #endif |
| 728 | 728 | }; |
| 729 | 729 | |
| 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 | − | |
| 739 | 730 | struct TCCState { |
| 740 | 731 | unsigned char verbose; /* if true, display some information during compilation */ |
| 741 | 732 | unsigned char nostdinc; /* if true, no standard headers are added */ |
| @@ -949,7 +940,6 @@ struct TCCState { · 207 unmodified lines | ||
| 949 | 940 | int pe_subsystem; |
| 950 | 941 | unsigned pe_characteristics; |
| 951 | 942 | unsigned pe_dll_characteristics; |
| 952 | − unsigned pe_dll_characteristics_clear; | |
| 953 | 943 | unsigned pe_file_align; |
| 954 | 944 | unsigned pe_stack_size; |
| 955 | 945 | addr_t pe_imagebase; |
| @@ -2992,6 +2992,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 2991 unmodified lines | ||
| 2992 | 2992 | create_arm_attribute_section (s1); |
| 2993 | 2993 | #endif |
| 2994 | 2994 | |
| 2995 | +#ifdef TCC_TARGET_RISCV64 | |
| 2996 | + create_riscv_attribute_section(s1); | |
| 2997 | +#endif | |
| 2998 | + | |
| 2995 | 2999 | #if TARGETOS_OpenBSD |
| 2996 | 3000 | dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD"); |
| 2997 | 3001 | #endif |
| @@ -3172,9 +3176,6 @@ static int elf_output_obj(TCCState *s1, const char *filename) · 174 unmodified lines | ||
| 3172 | 3176 | { |
| 3173 | 3177 | Section *s; |
| 3174 | 3178 | int i, ret, file_offset; |
| 3175 | −#ifdef TCC_TARGET_RISCV64 | |
| 3176 | − create_riscv_attribute_section(s1); | |
| 3177 | −#endif | |
| 3178 | 3179 | /* Allocate strings for section names */ |
| 3179 | 3180 | alloc_sec_names(s1, 1); |
| 3180 | 3181 | file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4; |
| @@ -3280,6 +3280,8 @@ again: · 3279 unmodified lines | ||
| 3280 | 3280 | dbt_bt = dbt & VT_BTYPE; |
| 3281 | 3281 | sbt_bt = sbt & VT_BTYPE; |
| 3282 | 3282 | if (dbt_bt == VT_VOID) { |
| 3283 | + /* do not confuse backends with VT_VOID in registers */ | |
| 3284 | + vpop(), vpushi(0); | |
| 3283 | 3285 | goto done; |
| 3284 | 3286 | } |
| 3285 | 3287 | if (sbt_bt == VT_VOID) { |
| @@ -27,54 +27,78 @@ · 26 unmodified lines | ||
| 27 | 27 | #define stricmp strcasecmp |
| 28 | 28 | #define strnicmp strncasecmp |
| 29 | 29 | #include <sys/stat.h> /* chmod() */ |
| 30 | −#else | |
| 31 | −#include <process.h> | |
| 32 | 30 | #endif |
| 33 | 31 | |
| 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 | |
| 37 | 33 | # define REL_TYPE_DIRECT R_X86_64_64 |
| 38 | 34 | # define R_XXX_THUNKFIX R_X86_64_PC32 |
| 39 | 35 | # define R_XXX_RELATIVE R_X86_64_RELATIVE |
| 40 | 36 | # define R_XXX_FUNCCALL R_X86_64_PLT32 |
| 41 | −# define IMAGE_FILE_MACHINE 0x8664 | |
| 42 | 37 | # 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 | |
| 43 | 45 | |
| 44 | 46 | #elif defined TCC_TARGET_ARM |
| 45 | −# define ADDR3264 DWORD | |
| 46 | −# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW | |
| 47 | 47 | # define REL_TYPE_DIRECT R_ARM_ABS32 |
| 48 | 48 | # define R_XXX_THUNKFIX R_ARM_ABS32 |
| 49 | 49 | # define R_XXX_RELATIVE R_ARM_RELATIVE |
| 50 | 50 | # define R_XXX_FUNCCALL R_ARM_PC24 |
| 51 | 51 | # define R_XXX_FUNCCALL2 R_ARM_ABS32 |
| 52 | −# define IMAGE_FILE_MACHINE 0x01C0 | |
| 53 | 52 | # 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 | |
| 54 | 60 | |
| 55 | 61 | #elif defined TCC_TARGET_ARM64 |
| 56 | −# define ADDR3264 ULONGLONG | |
| 57 | −# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64 | |
| 58 | 62 | # define REL_TYPE_DIRECT R_AARCH64_ABS64 |
| 59 | 63 | # define R_XXX_THUNKFIX R_AARCH64_ABS64 |
| 60 | 64 | # define R_XXX_RELATIVE R_AARCH64_RELATIVE |
| 61 | 65 | # define R_XXX_FUNCCALL R_AARCH64_CALL26 |
| 62 | −# define IMAGE_FILE_MACHINE 0xAA64 | |
| 63 | 66 | # 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 | |
| 64 | 74 | |
| 65 | 75 | #elif defined TCC_TARGET_I386 |
| 66 | −# define ADDR3264 DWORD | |
| 67 | −# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW | |
| 68 | 76 | # define REL_TYPE_DIRECT R_386_32 |
| 69 | 77 | # define R_XXX_THUNKFIX R_386_32 |
| 70 | 78 | # define R_XXX_RELATIVE R_386_RELATIVE |
| 71 | 79 | # define R_XXX_FUNCCALL R_386_PC32 |
| 72 | −# define IMAGE_FILE_MACHINE 0x014C | |
| 73 | 80 | # 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 | |
| 74 | 89 | |
| 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 | |
| 75 | 98 | #endif |
| 76 | 99 | |
| 77 | 100 | #ifndef IMAGE_NT_SIGNATURE |
| 101 | +/* cross compiler: windows.h was not included */ | |
| 78 | 102 | /* ----------------------------------------------------------- */ |
| 79 | 103 | /* definitions below are from winnt.h */ |
| 80 | 104 | |
| @@ -107,7 +131,6 @@ typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */ · 26 unmodified lines | ||
| 107 | 131 | } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; |
| 108 | 132 | |
| 109 | 133 | #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ |
| 110 | −#define SIZE_OF_NT_SIGNATURE 4 | |
| 111 | 134 | |
| 112 | 135 | typedef struct _IMAGE_FILE_HEADER { |
| 113 | 136 | WORD Machine; |
| @@ -138,7 +161,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER { · 24 unmodified lines | ||
| 138 | 161 | DWORD SizeOfUninitializedData; |
| 139 | 162 | DWORD AddressOfEntryPoint; |
| 140 | 163 | DWORD BaseOfCode; |
| 141 | −#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64) | |
| 164 | +#if PTR_SIZE == 4 | |
| 142 | 165 | DWORD BaseOfData; |
| 143 | 166 | #endif |
| 144 | 167 | /* NT additional fields. */ |
| @@ -237,19 +260,6 @@ typedef struct _IMAGE_BASE_RELOCATION { · 92 unmodified lines | ||
| 237 | 260 | |
| 238 | 261 | #define IMAGE_SIZEOF_BASE_RELOCATION 8 |
| 239 | 262 | |
| 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 | − | |
| 253 | 263 | #define IMAGE_REL_BASED_ABSOLUTE 0 |
| 254 | 264 | #define IMAGE_REL_BASED_HIGH 1 |
| 255 | 265 | #define IMAGE_REL_BASED_LOW 2 |
| @@ -269,34 +279,19 @@ typedef struct _IMAGE_BASE_RELOCATION { · 13 unmodified lines | ||
| 269 | 279 | #define IMAGE_SCN_MEM_READ 0x40000000 |
| 270 | 280 | #define IMAGE_SCN_MEM_WRITE 0x80000000 |
| 271 | 281 | |
| 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 | + | |
| 272 | 289 | #pragma pack(pop) |
| 273 | 290 | |
| 274 | 291 | /* ----------------------------------------------------------- */ |
| 275 | 292 | #endif /* ndef IMAGE_NT_SIGNATURE */ |
| 276 | 293 | /* ----------------------------------------------------------- */ |
| 277 | 294 | |
| 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 | − | |
| 300 | 295 | #pragma pack(push, 1) |
| 301 | 296 | struct pe_header |
| 302 | 297 | { |
| @@ -304,7 +299,7 @@ struct pe_header · 1 unmodified line | ||
| 304 | 299 | BYTE dosstub[0x40]; |
| 305 | 300 | DWORD nt_sig; |
| 306 | 301 | IMAGE_FILE_HEADER filehdr; |
| 307 | −#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64) | |
| 302 | +#if PTR_SIZE == 8 | |
| 308 | 303 | IMAGE_OPTIONAL_HEADER64 opthdr; |
| 309 | 304 | #else |
| 310 | 305 | #ifdef _WIN64 |
| @@ -580,55 +575,17 @@ static void pe_add_coffsym(struct pe_info *pe) · 269 unmodified lines | ||
| 580 | 575 | |
| 581 | 576 | /* Run cv2pdb, available at https://github.com/rainers/cv2pdb. It reads |
| 582 | 577 | 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 | − | |
| 617 | 578 | static void pe_create_pdb(TCCState *s1, const char *exename) |
| 618 | 579 | { |
| 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"); | |
| 626 | 584 | 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); | |
| 628 | 586 | } else if (s1->verbose) { |
| 629 | − printf("<- %s\n", pdbfile); | |
| 587 | + printf("<- %s\n", buf); | |
| 630 | 588 | } |
| 631 | − tcc_free(pdbfile); | |
| 632 | 589 | } |
| 633 | 590 | |
| 634 | 591 | /*----------------------------------------------------------------------------*/ |
| @@ -674,31 +631,12 @@ static int pe_write(struct pe_info *pe) · 39 unmodified lines | ||
| 674 | 631 | 0x00000000, /*DWORD TimeDateStamp; */ |
| 675 | 632 | 0x00000000, /*DWORD PointerToSymbolTable; */ |
| 676 | 633 | 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 | + },{ | |
| 695 | 637 | /* IMAGE_OPTIONAL_HEADER opthdr */ |
| 696 | 638 | /* 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; */ | |
| 702 | 640 | 0x06, /*BYTE MajorLinkerVersion; */ |
| 703 | 641 | 0x00, /*BYTE MinorLinkerVersion; */ |
| 704 | 642 | 0x00000000, /*DWORD SizeOfCode; */ |
| @@ -706,45 +644,29 @@ static int pe_write(struct pe_info *pe) · 1 unmodified line | ||
| 706 | 644 | 0x00000000, /*DWORD SizeOfUninitializedData; */ |
| 707 | 645 | 0x00000000, /*DWORD AddressOfEntryPoint; */ |
| 708 | 646 | 0x00000000, /*DWORD BaseOfCode; */ |
| 709 | −#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64) | |
| 647 | +#if PTR_SIZE == 4 | |
| 710 | 648 | 0x00000000, /*DWORD BaseOfData; */ |
| 711 | 649 | #endif |
| 712 | 650 | /* 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; */ | |
| 720 | 652 | 0x00001000, /*DWORD SectionAlignment; */ |
| 721 | 653 | 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; */ | |
| 729 | 656 | 0x0000, /*WORD MajorImageVersion; */ |
| 730 | 657 | 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; */ | |
| 738 | 660 | 0x00000000, /*DWORD Win32VersionValue; */ |
| 739 | 661 | 0x00000000, /*DWORD SizeOfImage; */ |
| 740 | 662 | 0x00000200, /*DWORD SizeOfHeaders; */ |
| 741 | 663 | 0x00000000, /*DWORD CheckSum; */ |
| 742 | 664 | 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; */ | |
| 748 | 670 | 0x00000000, /*DWORD LoaderFlags; */ |
| 749 | 671 | 0x00000010, /*DWORD NumberOfRvaAndSizes; */ |
| 750 | 672 | |
| @@ -799,7 +721,7 @@ static int pe_write(struct pe_info *pe) · 48 unmodified lines | ||
| 799 | 721 | break; |
| 800 | 722 | |
| 801 | 723 | case sec_data: |
| 802 | −#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64) | |
| 724 | +#if PTR_SIZE == 4 | |
| 803 | 725 | if (!pe_header.opthdr.BaseOfData) |
| 804 | 726 | pe_header.opthdr.BaseOfData = addr; |
| 805 | 727 | #endif |
| @@ -861,14 +783,14 @@ static int pe_write(struct pe_info *pe) · 55 unmodified lines | ||
| 861 | 783 | pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders; |
| 862 | 784 | pe_header.opthdr.ImageBase = pe->imagebase; |
| 863 | 785 | 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; | |
| 865 | 787 | if (s1->pe_stack_size) |
| 866 | 788 | pe_header.opthdr.SizeOfStackReserve = s1->pe_stack_size; |
| 867 | 789 | if (PE_DLL == pe->type) |
| 868 | 790 | pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL; |
| 869 | 791 | pe_header.filehdr.Characteristics |= s1->pe_characteristics; |
| 870 | 792 | if (pe->reloc) |
| 871 | − pe_header.filehdr.Characteristics &= ~PE_IMAGE_FILE_RELOCS_STRIPPED; | |
| 793 | + pe_header.filehdr.Characteristics &= ~IMAGE_FILE_RELOCS_STRIPPED; | |
| 872 | 794 | |
| 873 | 795 | if (pe->coffsym) { |
| 874 | 796 | pe_add_coffsym(pe); |
| @@ -1291,8 +1213,8 @@ static int pe_assign_addresses (struct pe_info *pe) · 416 unmodified lines | ||
| 1291 | 1213 | Section *s; |
| 1292 | 1214 | TCCState *s1 = pe->s1; |
| 1293 | 1215 | |
| 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)) | |
| 1296 | 1218 | pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0); |
| 1297 | 1219 | //pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); |
| 1298 | 1220 | |
| @@ -1483,14 +1405,10 @@ static int pe_check_symbols(struct pe_info *pe) · 184 unmodified lines | ||
| 1483 | 1405 | offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position |
| 1484 | 1406 | #elif defined(TCC_TARGET_ARM64) |
| 1485 | 1407 | 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 */ | |
| 1494 | 1412 | put_elf_reloc(symtab_section, text_section, |
| 1495 | 1413 | offset + 16, R_XXX_THUNKFIX, is->iat_index); |
| 1496 | 1414 | #else |
| @@ -1716,7 +1634,7 @@ static int get_dllexports(int fd, char **pp) · 219 unmodified lines | ||
| 1716 | 1634 | if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih)) |
| 1717 | 1635 | goto the_end; |
| 1718 | 1636 | opt_hdroffset = pef_hdroffset + sizeof ih; |
| 1719 | − if (ih.Machine == 0x014C) { | |
| 1637 | + if (ih.Machine == 0x014C || ih.Machine == 0x01C0) { | |
| 1720 | 1638 | IMAGE_OPTIONAL_HEADER32 oh; |
| 1721 | 1639 | sec_hdroffset = opt_hdroffset + sizeof oh; |
| 1722 | 1640 | if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh)) |
| @@ -1724,7 +1642,7 @@ static int get_dllexports(int fd, char **pp) · 1 unmodified line | ||
| 1724 | 1642 | if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes) |
| 1725 | 1643 | goto the_end_0; |
| 1726 | 1644 | 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) { | |
| 1728 | 1646 | IMAGE_OPTIONAL_HEADER64 oh; |
| 1729 | 1647 | sec_hdroffset = opt_hdroffset + sizeof oh; |
| 1730 | 1648 | 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 | ||
| 2209 | 2127 | { |
| 2210 | 2128 | if (PE_DLL == pe->type) { |
| 2211 | 2129 | /* 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; | |
| 2217 | 2131 | } 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; | |
| 2225 | 2133 | } |
| 2226 | 2134 | |
| 2227 | 2135 | #if defined(TCC_TARGET_ARM) |
| @@ -108,6 +108,11 @@ static void win64_del_function_table(void *); · 107 unmodified lines | ||
| 108 | 108 | //#define CONFIG_SELINUX 1 |
| 109 | 109 | #endif |
| 110 | 110 | |
| 111 | +/* use VirtualAlloc() instead of tcc_malloc() */ | |
| 112 | +#if defined _WIN32 && !defined CONFIG_RUNMEM_VIRTUALALLOC | |
| 113 | +# define CONFIG_RUNMEM_VIRTUALALLOC 1 | |
| 114 | +#endif | |
| 115 | + | |
| 111 | 116 | static int rt_mem(TCCState *s1, int size) |
| 112 | 117 | { |
| 113 | 118 | void *ptr; |
| @@ -129,16 +134,14 @@ static int rt_mem(TCCState *s1, int size) · 15 unmodified lines | ||
| 129 | 134 | ptr_diff = (char*)prw - (char*)ptr; /* = size; */ |
| 130 | 135 | //printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff); |
| 131 | 136 | 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 */ | |
| 135 | 139 | 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 | |
| 140 | 140 | if (!ptr) |
| 141 | 141 | 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 | |
| 142 | 145 | s1->run_ptr = ptr; |
| 143 | 146 | s1->run_size = size; |
| 144 | 147 | return ptr_diff; |
| @@ -191,24 +194,18 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 46 unmodified lines | ||
| 191 | 194 | if (NULL == ptr) |
| 192 | 195 | return; |
| 193 | 196 | st_unlink(s1); |
| 197 | +#ifdef _WIN64 | |
| 198 | + win64_del_function_table(s1->run_function_table); | |
| 199 | +#endif | |
| 194 | 200 | size = s1->run_size; |
| 195 | 201 | #ifdef CONFIG_SELINUX |
| 196 | 202 | munmap(ptr, size); |
| 203 | +#elif CONFIG_RUNMEM_VIRTUALALLOC | |
| 204 | + VirtualFree(ptr, size, MEM_RELEASE); | |
| 197 | 205 | #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 | |
| 205 | 206 | /* unprotect memory to make it usable for malloc again */ |
| 206 | 207 | protect_pages((void*)PAGEALIGN(ptr), size - PAGESIZE, 2 /*rw*/); |
| 207 | −# ifdef _WIN64 | |
| 208 | − win64_del_function_table(s1->run_function_table); | |
| 209 | −# endif | |
| 210 | 208 | tcc_free(ptr); |
| 211 | −# endif | |
| 212 | 209 | #endif |
| 213 | 210 | } |
| 214 | 211 | |
| @@ -312,7 +309,7 @@ static void cleanup_sections(TCCState *s1) · 97 unmodified lines | ||
| 312 | 309 | } |
| 313 | 310 | |
| 314 | 311 | /* ------------------------------------------------------------- */ |
| 315 | −/* 0 = .text rwx other rw (memory >= 2 pages a 4096 bytes) */ | |
| 312 | +/* 0 = .text rwx other rwx (memory >= 2 pages a 4096 bytes) */ | |
| 316 | 313 | /* 1 = .text rx other rw (memory >= 3 pages) */ |
| 317 | 314 | /* 2 = .text rx .rdata ro .data/.bss rw (memory >= 4 pages) */ |
| 318 | 315 | |
| @@ -506,14 +503,11 @@ static void *win64_add_function_table(TCCState *s1) · 187 unmodified lines | ||
| 506 | 503 | void *p = NULL; |
| 507 | 504 | if (s1->uw_pdata) { |
| 508 | 505 | p = (void*)s1->uw_pdata->sh_addr; |
| 509 | − if (!RtlAddFunctionTable( | |
| 506 | + RtlAddFunctionTable( | |
| 510 | 507 | (RUNTIME_FUNCTION*)p, |
| 511 | 508 | s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION), |
| 512 | 509 | s1->pe_imagebase |
| 513 | − )) { | |
| 514 | − tcc_error_noabort("RtlAddFunctionTable failed"); | |
| 515 | − p = NULL; | |
| 516 | − } | |
| 510 | + ); | |
| 517 | 511 | s1->uw_pdata = NULL; |
| 518 | 512 | } |
| 519 | 513 | return p; |
| @@ -19,9 +19,6 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) · 18 unmodified lines | ||
| 19 | 19 | SKIP += 85_asm-outside-function.test # x86 asm |
| 20 | 20 | SKIP += 127_asm_goto.test # hardcodes x86 asm |
| 21 | 21 | 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 | |
| 25 | 22 | ifeq ($(CONFIG_backtrace),no) |
| 26 | 23 | SKIP += 113_btdll.test |
| 27 | 24 | CONFIG_bcheck = no |
| @@ -57,22 +54,23 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) · 29 unmodified lines | ||
| 57 | 54 | SKIP += 114_bound_signal.test # libc problem signal/fork |
| 58 | 55 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c |
| 59 | 56 | endif |
| 60 | −ifdef CONFIG_OSX | |
| 57 | +ifeq ($(CONFIG_OSX),yes) | |
| 61 | 58 | SKIP += 144_tls.test # TLS runtime not supported on Mach-O |
| 62 | 59 | 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-) | |
| 64 | 64 | SKIP += 138_arm64_encoding.test |
| 65 | 65 | SKIP += 139_arm64_errors.test |
| 66 | 66 | SKIP += 140_arm64_extasm.test |
| 67 | 67 | 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-) | |
| 74 | 69 | SKIP += 141_riscv_asm.test # riscv64 asm |
| 75 | 70 | endif |
| 71 | +ifneq (-$(ARCH)-$(CONFIG_WIN32)-,-arm64-yes-) | |
| 72 | + SKIP += 145_winarm64_interlocked.test | |
| 73 | +endif | |
| 76 | 74 | |
| 77 | 75 | # Some tests might need arguments |
| 78 | 76 | ARGS = |