mirror of
git://repo.or.cz/tinycc.git
synced 2026-07-11 05:48:41 +08:00
review some recent changes
tccrun.c: - simplify usage of VirtualAlloc on win32/64 from6728a64f1btccpe.c: - revert changes to pe_create_pdb() (doesn't work and/or too much complication) from37b7247796- reduce #ifdef amount tccgen.c: - fix fix for cast to void fromfad812360btccelf.c: - put create_riscv_attribute_section() into right place fromc77339ab41tcc.h/libtcc.c: - simplify link-option parser for pe dll_characteristics from1a54e47ddai386-gen.c: - fix tls from8502540b4aworkflow/build.yml: - add i386-linux - disable riscv64-linux-native (seems not supported currently)
This commit is contained in:
parent
a338258d30
commit
7f7845cd7e
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@ -34,16 +34,13 @@ jobs:
|
|||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: build tcc (x86_64-win32)
|
- name: build & test (x86_64-win32)
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
cd win32
|
cd win32
|
||||||
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64
|
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64
|
||||||
call build-tcc.bat -c cl -t x86_64
|
call build-tcc.bat -c cl -t x86_64
|
||||||
- name: test (x86_64-win32)
|
cd ..\tests
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
call test-win32.bat all -k
|
call test-win32.bat all -k
|
||||||
|
|
||||||
test-i386-win32:
|
test-i386-win32:
|
||||||
@ -51,16 +48,13 @@ jobs:
|
|||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: build tcc (i386-win32)
|
- name: build & test (i386-win32)
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
cd win32
|
cd win32
|
||||||
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" x86
|
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" x86
|
||||||
call build-tcc.bat -c cl -t i386
|
call build-tcc.bat -c cl -t i386
|
||||||
- name: test (i386-win32)
|
cd ..\tests
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
call test-win32.bat -p c:\mingw32\bin all -k
|
call test-win32.bat -p c:\mingw32\bin all -k
|
||||||
|
|
||||||
test-arm64-win32:
|
test-arm64-win32:
|
||||||
@ -72,9 +66,8 @@ jobs:
|
|||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
cd win32
|
cd win32
|
||||||
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
|
for /f "delims=" %%i in ('vswhere.exe -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" arm64
|
||||||
call build-tcc.bat -c cl -t arm64
|
call build-tcc.bat -c cl -t arm64
|
||||||
set "PATH=C:\Program Files\LLVM\bin;%CD%;%PATH%"
|
|
||||||
cd ..\tests
|
cd ..\tests
|
||||||
call test-win32.bat -c clang all -k
|
call test-win32.bat -c clang all -k
|
||||||
|
|
||||||
@ -132,12 +125,25 @@ jobs:
|
|||||||
echo "::endgroup::" # flatten 'run container'
|
echo "::endgroup::" # flatten 'run container'
|
||||||
./configure && make && make test -k
|
./configure && make && make test -k
|
||||||
|
|
||||||
test-riscv64-linux-native:
|
# test-riscv64-linux-native:
|
||||||
runs-on: ubuntu-24.04-riscv
|
# runs-on: ubuntu-24.04-riscv
|
||||||
timeout-minutes: 8
|
# timeout-minutes: 8
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# - name: make & test tcc (riscv64-linux native)
|
||||||
|
# run: |
|
||||||
|
# uname -m # riscv64
|
||||||
|
# ./configure && make && make test -k
|
||||||
|
|
||||||
|
test-i386-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 3
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: make & test tcc (riscv64-linux native)
|
- name: install i386-gcc
|
||||||
run: |
|
run: |
|
||||||
uname -m # riscv64
|
sudo dpkg --add-architecture i386
|
||||||
./configure && make && make test -k
|
sudo apt-get update -q -y
|
||||||
|
sudo apt-get install -q -y gcc-multilib libc6-dev:i386
|
||||||
|
- name: make & test tcc (i386-linux)
|
||||||
|
run: ./configure --cpu=i386 --cc="gcc -m32" && make && make test -k
|
||||||
|
|||||||
@ -439,7 +439,7 @@ ST_FUNC void store(int r, SValue *v)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fr & VT_SYM) && v->sym->type.t & VT_TLS) {
|
if ((v->r & VT_SYM) && v->sym->type.t & VT_TLS) {
|
||||||
o(0x65); /* gs segment prefix */
|
o(0x65); /* gs segment prefix */
|
||||||
o(opc);
|
o(opc);
|
||||||
o(0x04 | (REG_VALUE(r) << 3)); /* modrm: [sib] | srcreg */
|
o(0x04 | (REG_VALUE(r) << 3)); /* modrm: [sib] | srcreg */
|
||||||
@ -467,7 +467,7 @@ static void gadd_sp(int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE || defined CONFIG_TCC_PIC
|
#if defined TCC_TARGET_PE || defined CONFIG_TCC_PIC
|
||||||
static void gen_static_call(int v)
|
static void gen_static_call(int v)
|
||||||
{
|
{
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|||||||
@ -73,7 +73,7 @@ OBJ-arm-vfp = $(OBJ-arm)
|
|||||||
OBJ-arm-eabi = $(OBJ-arm)
|
OBJ-arm-eabi = $(OBJ-arm)
|
||||||
OBJ-arm-eabihf = $(OBJ-arm)
|
OBJ-arm-eabihf = $(OBJ-arm)
|
||||||
OBJ-arm-wince = $(ARM_O) $(WIN_O)
|
OBJ-arm-wince = $(ARM_O) $(WIN_O)
|
||||||
OBJ-riscv64 = $(RISCV64_O) lib-riscv.o $(LIN_O)
|
OBJ-riscv64 = $(RISCV64_O) armflush.o $(LIN_O)
|
||||||
|
|
||||||
OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
|
OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
|
||||||
OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
|
OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
|
||||||
|
|||||||
@ -61,4 +61,10 @@ void __clear_cache(void *beg, void *end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
#elif defined __riscv
|
||||||
|
void __clear_cache(void *beg, void *end)
|
||||||
|
{
|
||||||
|
__riscv64_clear_cache(beg, end);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* TCC runtime library for riscv64.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2026
|
|
||||||
*
|
|
||||||
* Copying and distribution of this file, with or without modification,
|
|
||||||
* are permitted in any medium without royalty provided the copyright
|
|
||||||
* notice and this notice are preserved. This file is offered as-is,
|
|
||||||
* without any warranty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/* __clear_cache is used in tccrun.c. It is a built-in
|
|
||||||
intrinsic with gcc. However tcc in order to compile
|
|
||||||
itself needs this function */
|
|
||||||
|
|
||||||
void __clear_cache(void *beg, void *end)
|
|
||||||
{
|
|
||||||
__riscv64_clear_cache(beg, end);
|
|
||||||
}
|
|
||||||
73
libtcc.c
73
libtcc.c
@ -899,6 +899,9 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||||||
#ifdef TCC_ARM_HARDFLOAT
|
#ifdef TCC_ARM_HARDFLOAT
|
||||||
s->float_abi = ARM_HARD_FLOAT;
|
s->float_abi = ARM_HARD_FLOAT;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined TCC_TARGET_ARM64 && defined TCC_TARGET_PE
|
||||||
|
s->pe_dll_characteristics = 0x8160;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_NEW_DTAGS
|
#ifdef CONFIG_NEW_DTAGS
|
||||||
s->enable_new_dtags = 1;
|
s->enable_new_dtags = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -1365,7 +1368,7 @@ struct lopt {
|
|||||||
static int link_option(struct lopt *o, const char *q)
|
static int link_option(struct lopt *o, const char *q)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
int c;
|
int c, r;
|
||||||
redo:
|
redo:
|
||||||
/* there should be 1 or 2 dashes */
|
/* there should be 1 or 2 dashes */
|
||||||
p = o->opt;
|
p = o->opt;
|
||||||
@ -1373,6 +1376,16 @@ redo:
|
|||||||
return 0;
|
return 0;
|
||||||
if (*p == '-')
|
if (*p == '-')
|
||||||
p++;
|
p++;
|
||||||
|
r = 1;
|
||||||
|
if (q[0] == '?') { /* check for no-/disable- prefix */
|
||||||
|
++q;
|
||||||
|
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
|
||||||
|
p += 3, r = -1;
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
else if (0 == memcmp(p, "disable-", 8))
|
||||||
|
p += 8, r = -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
while ((c = *q) == *p) {
|
while ((c = *q) == *p) {
|
||||||
if (c == '\0')
|
if (c == '\0')
|
||||||
goto succ; /* -Wl,-opt */
|
goto succ; /* -Wl,-opt */
|
||||||
@ -1401,24 +1414,13 @@ redo:
|
|||||||
succ:
|
succ:
|
||||||
o->arg = p;
|
o->arg = p;
|
||||||
//printf("set %s '%s'\n", o->opt, o->arg);
|
//printf("set %s '%s'\n", o->opt, o->arg);
|
||||||
return 1;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void args_parser_add_file(TCCState *s, const char* filename, int filetype);
|
static void args_parser_add_file(TCCState *s, const char* filename, int filetype);
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#define SET_OR_CLEAR(v,f) (v = r > 0 ? v | f : v & ~f)
|
||||||
static void tcc_pe_set_dll_characteristics(TCCState *s, unsigned flags)
|
#define SET_OR_CLEAR_2(v,f1,f2) (v = r > 0 ? v | f1 : v & ~f2)
|
||||||
{
|
|
||||||
s->pe_dll_characteristics |= flags;
|
|
||||||
s->pe_dll_characteristics_clear &= ~flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tcc_pe_clear_dll_characteristics(TCCState *s, unsigned flags)
|
|
||||||
{
|
|
||||||
s->pe_dll_characteristics &= ~flags;
|
|
||||||
s->pe_dll_characteristics_clear |= flags;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* set linker options */
|
/* set linker options */
|
||||||
static int tcc_set_linker(TCCState *s, const char *optarg)
|
static int tcc_set_linker(TCCState *s, const char *optarg)
|
||||||
@ -1431,6 +1433,7 @@ static int tcc_set_linker(TCCState *s, const char *optarg)
|
|||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
int ignoring = 0;
|
int ignoring = 0;
|
||||||
struct lopt o = {0};
|
struct lopt o = {0};
|
||||||
|
int r;
|
||||||
o.s = s;
|
o.s = s;
|
||||||
o.opt = s->link_argv[s->link_optind];
|
o.opt = s->link_argv[s->link_optind];
|
||||||
|
|
||||||
@ -1481,39 +1484,21 @@ static int tcc_set_linker(TCCState *s, const char *optarg)
|
|||||||
s->section_align = strtoul(o.arg, &end, 16);
|
s->section_align = strtoul(o.arg, &end, 16);
|
||||||
} else if (link_option(&o, "soname=|install_name=")) {
|
} else if (link_option(&o, "soname=|install_name=")) {
|
||||||
tcc_set_str(&s->soname, o.arg);
|
tcc_set_str(&s->soname, o.arg);
|
||||||
} else if (link_option(&o, "whole-archive")) {
|
} else if (!!(r = link_option(&o, "?whole-archive"))) {
|
||||||
s->filetype |= AFF_WHOLE_ARCHIVE;
|
SET_OR_CLEAR(s->filetype, AFF_WHOLE_ARCHIVE);
|
||||||
} else if (link_option(&o, "no-whole-archive")) {
|
|
||||||
s->filetype &= ~AFF_WHOLE_ARCHIVE;
|
|
||||||
} else if (link_option(&o, "znodelete")) {
|
} else if (link_option(&o, "znodelete")) {
|
||||||
s->znodelete = 1;
|
s->znodelete = 1;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
} else if (link_option(&o, "large-address-aware")) {
|
} else if (link_option(&o, "large-address-aware")) {
|
||||||
s->pe_characteristics |= PE_IMAGE_FILE_LARGE_ADDRESS_AWARE;
|
s->pe_characteristics |= 0x20;
|
||||||
} else if (link_option(&o, "dynamicbase")) {
|
} else if (!!(r = link_option(&o, "?dynamicbase"))) {
|
||||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
|
SET_OR_CLEAR_2(s1->pe_dll_characteristics, 0x40, 0x60);
|
||||||
} else if (link_option(&o, "disable-dynamicbase|no-dynamicbase")) {
|
} else if (!!(r = link_option(&o, "?high-entropy-va"))) {
|
||||||
tcc_pe_clear_dll_characteristics(s,
|
SET_OR_CLEAR_2(s1->pe_dll_characteristics, 0x60, 0x20);
|
||||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
} else if (!!(r = link_option(&o, "?nxcompat"))) {
|
||||||
PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
|
SET_OR_CLEAR(s1->pe_dll_characteristics, 0x100);
|
||||||
} else if (link_option(&o, "nxcompat")) {
|
} else if (!!(r = link_option(&o, "?tsaware"))) {
|
||||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
|
SET_OR_CLEAR(s1->pe_dll_characteristics, 0x8000);
|
||||||
} else if (link_option(&o, "disable-nxcompat|no-nxcompat")) {
|
|
||||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
|
|
||||||
} else if (link_option(&o, "high-entropy-va")) {
|
|
||||||
# if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
|
||||||
tcc_pe_set_dll_characteristics(s,
|
|
||||||
PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
|
||||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
|
|
||||||
# else
|
|
||||||
goto err;
|
|
||||||
# endif
|
|
||||||
} else if (link_option(&o, "disable-high-entropy-va|no-high-entropy-va")) {
|
|
||||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
|
|
||||||
} else if (link_option(&o, "tsaware")) {
|
|
||||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
|
|
||||||
} else if (link_option(&o, "disable-tsaware|no-tsaware")) {
|
|
||||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
|
|
||||||
} else if (link_option(&o, "file-alignment=")) {
|
} else if (link_option(&o, "file-alignment=")) {
|
||||||
s->pe_file_align = strtoul(o.arg, &end, 16);
|
s->pe_file_align = strtoul(o.arg, &end, 16);
|
||||||
} else if (link_option(&o, "stack=")) {
|
} else if (link_option(&o, "stack=")) {
|
||||||
|
|||||||
@ -386,9 +386,7 @@ Set type for PE (Windows) executables.
|
|||||||
@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
|
@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
|
||||||
Modify executable layout.
|
Modify executable layout.
|
||||||
|
|
||||||
@item -Wl,-[dynamicbase | nxcompat | high-entropy-va | tsaware]
|
@item -Wl,-(no-|disable-)[dynamicbase | nxcompat | high-entropy-va | tsaware]
|
||||||
@item -Wl,-[no-dynamicbase | no-nxcompat | no-high-entropy-va | no-tsaware]
|
|
||||||
@item -Wl,-[disable-dynamicbase | disable-nxcompat | disable-high-entropy-va | disable-tsaware]
|
|
||||||
Set or clear PE (Windows) executable header hardening flags. The
|
Set or clear PE (Windows) executable header hardening flags. The
|
||||||
@option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE
|
@option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE
|
||||||
targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also
|
targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also
|
||||||
|
|||||||
10
tcc.h
10
tcc.h
@ -727,15 +727,6 @@ struct sym_attr {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
|
||||||
#define PE_IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
|
||||||
#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
|
|
||||||
#define PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
|
|
||||||
#define PE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
|
||||||
#define PE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
|
||||||
#define PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct TCCState {
|
struct TCCState {
|
||||||
unsigned char verbose; /* if true, display some information during compilation */
|
unsigned char verbose; /* if true, display some information during compilation */
|
||||||
unsigned char nostdinc; /* if true, no standard headers are added */
|
unsigned char nostdinc; /* if true, no standard headers are added */
|
||||||
@ -949,7 +940,6 @@ struct TCCState {
|
|||||||
int pe_subsystem;
|
int pe_subsystem;
|
||||||
unsigned pe_characteristics;
|
unsigned pe_characteristics;
|
||||||
unsigned pe_dll_characteristics;
|
unsigned pe_dll_characteristics;
|
||||||
unsigned pe_dll_characteristics_clear;
|
|
||||||
unsigned pe_file_align;
|
unsigned pe_file_align;
|
||||||
unsigned pe_stack_size;
|
unsigned pe_stack_size;
|
||||||
addr_t pe_imagebase;
|
addr_t pe_imagebase;
|
||||||
|
|||||||
7
tccelf.c
7
tccelf.c
@ -2992,6 +2992,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
create_arm_attribute_section (s1);
|
create_arm_attribute_section (s1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_RISCV64
|
||||||
|
create_riscv_attribute_section(s1);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if TARGETOS_OpenBSD
|
#if TARGETOS_OpenBSD
|
||||||
dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
|
dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
|
||||||
#endif
|
#endif
|
||||||
@ -3172,9 +3176,6 @@ static int elf_output_obj(TCCState *s1, const char *filename)
|
|||||||
{
|
{
|
||||||
Section *s;
|
Section *s;
|
||||||
int i, ret, file_offset;
|
int i, ret, file_offset;
|
||||||
#ifdef TCC_TARGET_RISCV64
|
|
||||||
create_riscv_attribute_section(s1);
|
|
||||||
#endif
|
|
||||||
/* Allocate strings for section names */
|
/* Allocate strings for section names */
|
||||||
alloc_sec_names(s1, 1);
|
alloc_sec_names(s1, 1);
|
||||||
file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
|
file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
|
||||||
|
|||||||
2
tccgen.c
2
tccgen.c
@ -3280,6 +3280,8 @@ again:
|
|||||||
dbt_bt = dbt & VT_BTYPE;
|
dbt_bt = dbt & VT_BTYPE;
|
||||||
sbt_bt = sbt & VT_BTYPE;
|
sbt_bt = sbt & VT_BTYPE;
|
||||||
if (dbt_bt == VT_VOID) {
|
if (dbt_bt == VT_VOID) {
|
||||||
|
/* do not confuse backends with VT_VOID in registers */
|
||||||
|
vpop(), vpushi(0);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (sbt_bt == VT_VOID) {
|
if (sbt_bt == VT_VOID) {
|
||||||
|
|||||||
256
tccpe.c
256
tccpe.c
@ -27,54 +27,78 @@
|
|||||||
#define stricmp strcasecmp
|
#define stricmp strcasecmp
|
||||||
#define strnicmp strncasecmp
|
#define strnicmp strncasecmp
|
||||||
#include <sys/stat.h> /* chmod() */
|
#include <sys/stat.h> /* chmod() */
|
||||||
#else
|
|
||||||
#include <process.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TCC_TARGET_X86_64
|
#if defined TCC_TARGET_X86_64
|
||||||
# define ADDR3264 ULONGLONG
|
|
||||||
# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
|
|
||||||
# define REL_TYPE_DIRECT R_X86_64_64
|
# define REL_TYPE_DIRECT R_X86_64_64
|
||||||
# define R_XXX_THUNKFIX R_X86_64_PC32
|
# define R_XXX_THUNKFIX R_X86_64_PC32
|
||||||
# define R_XXX_RELATIVE R_X86_64_RELATIVE
|
# define R_XXX_RELATIVE R_X86_64_RELATIVE
|
||||||
# define R_XXX_FUNCCALL R_X86_64_PLT32
|
# define R_XXX_FUNCCALL R_X86_64_PLT32
|
||||||
# define IMAGE_FILE_MACHINE 0x8664
|
|
||||||
# define RSRC_RELTYPE 3
|
# define RSRC_RELTYPE 3
|
||||||
|
# define IMAGE_FILE_MACHINE 0x8664
|
||||||
|
# define CHARACTERISTICS_EXE 0x022F
|
||||||
|
# define CHARACTERISTICS_DLL 0x222E
|
||||||
|
# define IMAGE_BASE_EXE 0x00400000
|
||||||
|
# define IMAGE_BASE_DLL 0x10000000
|
||||||
|
# define DLLCHARACTERISTICS 0
|
||||||
|
# define OS_VER 0x0400
|
||||||
|
|
||||||
#elif defined TCC_TARGET_ARM
|
#elif defined TCC_TARGET_ARM
|
||||||
# define ADDR3264 DWORD
|
|
||||||
# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
|
|
||||||
# define REL_TYPE_DIRECT R_ARM_ABS32
|
# define REL_TYPE_DIRECT R_ARM_ABS32
|
||||||
# define R_XXX_THUNKFIX R_ARM_ABS32
|
# define R_XXX_THUNKFIX R_ARM_ABS32
|
||||||
# define R_XXX_RELATIVE R_ARM_RELATIVE
|
# define R_XXX_RELATIVE R_ARM_RELATIVE
|
||||||
# define R_XXX_FUNCCALL R_ARM_PC24
|
# define R_XXX_FUNCCALL R_ARM_PC24
|
||||||
# define R_XXX_FUNCCALL2 R_ARM_ABS32
|
# define R_XXX_FUNCCALL2 R_ARM_ABS32
|
||||||
# define IMAGE_FILE_MACHINE 0x01C0
|
|
||||||
# define RSRC_RELTYPE 7 /* ??? (not tested) */
|
# define RSRC_RELTYPE 7 /* ??? (not tested) */
|
||||||
|
# define IMAGE_FILE_MACHINE 0x01C0
|
||||||
|
# define CHARACTERISTICS_EXE 0x010F
|
||||||
|
# define CHARACTERISTICS_DLL 0x230F
|
||||||
|
# define IMAGE_BASE_EXE 0x00100000
|
||||||
|
# define IMAGE_BASE_DLL 0x10000000
|
||||||
|
# define DLLCHARACTERISTICS 0
|
||||||
|
# define OS_VER 0x0400
|
||||||
|
|
||||||
#elif defined TCC_TARGET_ARM64
|
#elif defined TCC_TARGET_ARM64
|
||||||
# define ADDR3264 ULONGLONG
|
|
||||||
# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
|
|
||||||
# define REL_TYPE_DIRECT R_AARCH64_ABS64
|
# define REL_TYPE_DIRECT R_AARCH64_ABS64
|
||||||
# define R_XXX_THUNKFIX R_AARCH64_ABS64
|
# define R_XXX_THUNKFIX R_AARCH64_ABS64
|
||||||
# define R_XXX_RELATIVE R_AARCH64_RELATIVE
|
# define R_XXX_RELATIVE R_AARCH64_RELATIVE
|
||||||
# define R_XXX_FUNCCALL R_AARCH64_CALL26
|
# define R_XXX_FUNCCALL R_AARCH64_CALL26
|
||||||
# define IMAGE_FILE_MACHINE 0xAA64
|
|
||||||
# define RSRC_RELTYPE 3
|
# define RSRC_RELTYPE 3
|
||||||
|
# define IMAGE_FILE_MACHINE 0xAA64
|
||||||
|
# define CHARACTERISTICS_EXE 0x0022
|
||||||
|
# define CHARACTERISTICS_DLL 0x2022
|
||||||
|
# define IMAGE_BASE_EXE 0x140000000ULL
|
||||||
|
# define IMAGE_BASE_DLL 0x180000000ULL
|
||||||
|
# define OS_VER 0x0602
|
||||||
|
# define DLLCHARACTERISTICS 0x8160
|
||||||
|
|
||||||
#elif defined TCC_TARGET_I386
|
#elif defined TCC_TARGET_I386
|
||||||
# define ADDR3264 DWORD
|
|
||||||
# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
|
|
||||||
# define REL_TYPE_DIRECT R_386_32
|
# define REL_TYPE_DIRECT R_386_32
|
||||||
# define R_XXX_THUNKFIX R_386_32
|
# define R_XXX_THUNKFIX R_386_32
|
||||||
# define R_XXX_RELATIVE R_386_RELATIVE
|
# define R_XXX_RELATIVE R_386_RELATIVE
|
||||||
# define R_XXX_FUNCCALL R_386_PC32
|
# define R_XXX_FUNCCALL R_386_PC32
|
||||||
# define IMAGE_FILE_MACHINE 0x014C
|
|
||||||
# define RSRC_RELTYPE 7 /* DIR32NB */
|
# define RSRC_RELTYPE 7 /* DIR32NB */
|
||||||
|
# define IMAGE_FILE_MACHINE 0x014C
|
||||||
|
# define CHARACTERISTICS_EXE 0x030F
|
||||||
|
# define CHARACTERISTICS_DLL 0x230E
|
||||||
|
# define IMAGE_BASE_EXE 0x00400000
|
||||||
|
# define IMAGE_BASE_DLL 0x10000000
|
||||||
|
# define OS_VER 0x0400
|
||||||
|
# define DLLCHARACTERISTICS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PTR_SIZE == 8
|
||||||
|
# define ADDR3264 ULONGLONG
|
||||||
|
# define PE_MAGIC 0x020B
|
||||||
|
# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
|
||||||
|
#else
|
||||||
|
# define ADDR3264 DWORD
|
||||||
|
# define PE_MAGIC 0x010B
|
||||||
|
# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef IMAGE_NT_SIGNATURE
|
#ifndef IMAGE_NT_SIGNATURE
|
||||||
|
/* cross compiler: windows.h was not included */
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
/* definitions below are from winnt.h */
|
/* definitions below are from winnt.h */
|
||||||
|
|
||||||
@ -107,7 +131,6 @@ typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */
|
|||||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||||
|
|
||||||
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
|
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
|
||||||
#define SIZE_OF_NT_SIGNATURE 4
|
|
||||||
|
|
||||||
typedef struct _IMAGE_FILE_HEADER {
|
typedef struct _IMAGE_FILE_HEADER {
|
||||||
WORD Machine;
|
WORD Machine;
|
||||||
@ -138,7 +161,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER {
|
|||||||
DWORD SizeOfUninitializedData;
|
DWORD SizeOfUninitializedData;
|
||||||
DWORD AddressOfEntryPoint;
|
DWORD AddressOfEntryPoint;
|
||||||
DWORD BaseOfCode;
|
DWORD BaseOfCode;
|
||||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
#if PTR_SIZE == 4
|
||||||
DWORD BaseOfData;
|
DWORD BaseOfData;
|
||||||
#endif
|
#endif
|
||||||
/* NT additional fields. */
|
/* NT additional fields. */
|
||||||
@ -237,19 +260,6 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
|||||||
|
|
||||||
#define IMAGE_SIZEOF_BASE_RELOCATION 8
|
#define IMAGE_SIZEOF_BASE_RELOCATION 8
|
||||||
|
|
||||||
#ifndef IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
|
|
||||||
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
|
|
||||||
#endif
|
|
||||||
#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
|
||||||
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE PE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
|
||||||
#endif
|
|
||||||
#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
|
|
||||||
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT PE_DLLCHARACTERISTICS_NX_COMPAT
|
|
||||||
#endif
|
|
||||||
#ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
|
||||||
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IMAGE_REL_BASED_ABSOLUTE 0
|
#define IMAGE_REL_BASED_ABSOLUTE 0
|
||||||
#define IMAGE_REL_BASED_HIGH 1
|
#define IMAGE_REL_BASED_HIGH 1
|
||||||
#define IMAGE_REL_BASED_LOW 2
|
#define IMAGE_REL_BASED_LOW 2
|
||||||
@ -269,34 +279,19 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
|||||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||||
|
|
||||||
|
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
|
||||||
|
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
||||||
|
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
||||||
|
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
|
||||||
|
|
||||||
|
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
#endif /* ndef IMAGE_NT_SIGNATURE */
|
#endif /* ndef IMAGE_NT_SIGNATURE */
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
|
|
||||||
static WORD pe_get_dll_characteristics(TCCState *s1)
|
|
||||||
{
|
|
||||||
unsigned v = 0;
|
|
||||||
|
|
||||||
#ifdef TCC_TARGET_ARM64
|
|
||||||
v = PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
|
||||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
|
||||||
PE_DLLCHARACTERISTICS_NX_COMPAT |
|
|
||||||
PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
|
|
||||||
#endif
|
|
||||||
v |= s1->pe_dll_characteristics;
|
|
||||||
v &= ~s1->pe_dll_characteristics_clear;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef IMAGE_FILE_MACHINE_ARM64
|
|
||||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
|
||||||
#endif
|
|
||||||
#ifndef IMAGE_REL_BASED_DIR64
|
|
||||||
# define IMAGE_REL_BASED_DIR64 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct pe_header
|
struct pe_header
|
||||||
{
|
{
|
||||||
@ -304,7 +299,7 @@ struct pe_header
|
|||||||
BYTE dosstub[0x40];
|
BYTE dosstub[0x40];
|
||||||
DWORD nt_sig;
|
DWORD nt_sig;
|
||||||
IMAGE_FILE_HEADER filehdr;
|
IMAGE_FILE_HEADER filehdr;
|
||||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
#if PTR_SIZE == 8
|
||||||
IMAGE_OPTIONAL_HEADER64 opthdr;
|
IMAGE_OPTIONAL_HEADER64 opthdr;
|
||||||
#else
|
#else
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@ -580,55 +575,17 @@ static void pe_add_coffsym(struct pe_info *pe)
|
|||||||
|
|
||||||
/* Run cv2pdb, available at https://github.com/rainers/cv2pdb. It reads
|
/* Run cv2pdb, available at https://github.com/rainers/cv2pdb. It reads
|
||||||
and strips the dwarf info and creates a <exename>.pdb file instead */
|
and strips the dwarf info and creates a <exename>.pdb file instead */
|
||||||
#ifndef _WIN32
|
|
||||||
static void pe_shell_quote(CString *cmd, const char *arg)
|
|
||||||
{
|
|
||||||
cstr_cat(cmd, "'", 1);
|
|
||||||
while (*arg) {
|
|
||||||
if (*arg == '\'')
|
|
||||||
cstr_cat(cmd, "'\\''", 4);
|
|
||||||
else
|
|
||||||
cstr_cat(cmd, arg, 1);
|
|
||||||
++arg;
|
|
||||||
}
|
|
||||||
cstr_cat(cmd, "'", 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static intptr_t pe_run_cv2pdb(const char *exename)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
const char *argv[] = { "cv2pdb.exe", exename, NULL };
|
|
||||||
return _spawnvp(_P_WAIT, "cv2pdb.exe", argv);
|
|
||||||
#else
|
|
||||||
CString cmd;
|
|
||||||
intptr_t ret;
|
|
||||||
|
|
||||||
cstr_new(&cmd);
|
|
||||||
cstr_cat(&cmd, "cv2pdb.exe ", -1);
|
|
||||||
pe_shell_quote(&cmd, exename);
|
|
||||||
cstr_ccat(&cmd, 0);
|
|
||||||
ret = system(cmd.data);
|
|
||||||
cstr_free(&cmd);
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pe_create_pdb(TCCState *s1, const char *exename)
|
static void pe_create_pdb(TCCState *s1, const char *exename)
|
||||||
{
|
{
|
||||||
size_t len = strlen(exename);
|
char buf[300]; int r;
|
||||||
char *pdbfile = tcc_malloc(len + sizeof(".pdb"));
|
snprintf(buf, sizeof buf, "cv2pdb.exe \"%s\"", exename);
|
||||||
intptr_t r;
|
r = system(buf);
|
||||||
|
strcpy(tcc_fileextension(strcpy(buf, exename)), ".pdb");
|
||||||
strcpy(pdbfile, exename);
|
|
||||||
strcpy(tcc_fileextension(pdbfile), ".pdb");
|
|
||||||
r = pe_run_cv2pdb(exename);
|
|
||||||
if (r) {
|
if (r) {
|
||||||
tcc_error_noabort("could not create '%s'\n(need working cv2pdb from https://github.com/rainers/cv2pdb)", pdbfile);
|
tcc_error_noabort("could not create '%s'\n(need working cv2pdb from https://github.com/rainers/cv2pdb)", buf);
|
||||||
} else if (s1->verbose) {
|
} else if (s1->verbose) {
|
||||||
printf("<- %s\n", pdbfile);
|
printf("<- %s\n", buf);
|
||||||
}
|
}
|
||||||
tcc_free(pdbfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -674,31 +631,12 @@ static int pe_write(struct pe_info *pe)
|
|||||||
0x00000000, /*DWORD TimeDateStamp; */
|
0x00000000, /*DWORD TimeDateStamp; */
|
||||||
0x00000000, /*DWORD PointerToSymbolTable; */
|
0x00000000, /*DWORD PointerToSymbolTable; */
|
||||||
0x00000000, /*DWORD NumberOfSymbols; */
|
0x00000000, /*DWORD NumberOfSymbols; */
|
||||||
#if defined(TCC_TARGET_X86_64)
|
0x00E0 + (PTR_SIZE-4)*4, /*WORD SizeOfOptionalHeader; */
|
||||||
0x00F0, /*WORD SizeOfOptionalHeader; */
|
CHARACTERISTICS_EXE, /*WORD Characteristics; */
|
||||||
0x022F /*WORD Characteristics; */
|
},{
|
||||||
#define CHARACTERISTICS_DLL 0x222E
|
|
||||||
#elif defined(TCC_TARGET_I386)
|
|
||||||
0x00E0, /*WORD SizeOfOptionalHeader; */
|
|
||||||
0x030F /*WORD Characteristics; */
|
|
||||||
#define CHARACTERISTICS_DLL 0x230E
|
|
||||||
#elif defined(TCC_TARGET_ARM)
|
|
||||||
0x00E0, /*WORD SizeOfOptionalHeader; */
|
|
||||||
0x010F, /*WORD Characteristics; */
|
|
||||||
#define CHARACTERISTICS_DLL 0x230F
|
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
|
||||||
0x00F0, /*WORD SizeOfOptionalHeader; */
|
|
||||||
0x0022 /*WORD Characteristics; */
|
|
||||||
#define CHARACTERISTICS_DLL 0x2022
|
|
||||||
#endif
|
|
||||||
},{
|
|
||||||
/* IMAGE_OPTIONAL_HEADER opthdr */
|
/* IMAGE_OPTIONAL_HEADER opthdr */
|
||||||
/* Standard fields. */
|
/* Standard fields. */
|
||||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
PE_MAGIC, /*WORD Magic; */
|
||||||
0x020B, /*WORD Magic; */
|
|
||||||
#else
|
|
||||||
0x010B, /*WORD Magic; */
|
|
||||||
#endif
|
|
||||||
0x06, /*BYTE MajorLinkerVersion; */
|
0x06, /*BYTE MajorLinkerVersion; */
|
||||||
0x00, /*BYTE MinorLinkerVersion; */
|
0x00, /*BYTE MinorLinkerVersion; */
|
||||||
0x00000000, /*DWORD SizeOfCode; */
|
0x00000000, /*DWORD SizeOfCode; */
|
||||||
@ -706,45 +644,29 @@ static int pe_write(struct pe_info *pe)
|
|||||||
0x00000000, /*DWORD SizeOfUninitializedData; */
|
0x00000000, /*DWORD SizeOfUninitializedData; */
|
||||||
0x00000000, /*DWORD AddressOfEntryPoint; */
|
0x00000000, /*DWORD AddressOfEntryPoint; */
|
||||||
0x00000000, /*DWORD BaseOfCode; */
|
0x00000000, /*DWORD BaseOfCode; */
|
||||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
#if PTR_SIZE == 4
|
||||||
0x00000000, /*DWORD BaseOfData; */
|
0x00000000, /*DWORD BaseOfData; */
|
||||||
#endif
|
#endif
|
||||||
/* NT additional fields. */
|
/* NT additional fields. */
|
||||||
#if defined(TCC_TARGET_ARM)
|
0x00000000, /*ADDR3264 ImageBase; */
|
||||||
0x00100000, /*DWORD ImageBase; */
|
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
|
||||||
0x140000000ULL, /*ULONGLONG ImageBase; */
|
|
||||||
#else
|
|
||||||
0x00400000, /*DWORD ImageBase; */
|
|
||||||
#endif
|
|
||||||
0x00001000, /*DWORD SectionAlignment; */
|
0x00001000, /*DWORD SectionAlignment; */
|
||||||
0x00000200, /*DWORD FileAlignment; */
|
0x00000200, /*DWORD FileAlignment; */
|
||||||
#if defined(TCC_TARGET_ARM64)
|
OS_VER >> 8, /*WORD MajorOperatingSystemVersion; */
|
||||||
0x0006, /*WORD MajorOperatingSystemVersion; */
|
OS_VER & 255, /*WORD MinorOperatingSystemVersion; */
|
||||||
0x0002, /*WORD MinorOperatingSystemVersion; */
|
|
||||||
#else
|
|
||||||
0x0004, /*WORD MajorOperatingSystemVersion; */
|
|
||||||
0x0000, /*WORD MinorOperatingSystemVersion; */
|
|
||||||
#endif
|
|
||||||
0x0000, /*WORD MajorImageVersion; */
|
0x0000, /*WORD MajorImageVersion; */
|
||||||
0x0000, /*WORD MinorImageVersion; */
|
0x0000, /*WORD MinorImageVersion; */
|
||||||
#if defined(TCC_TARGET_ARM64)
|
OS_VER >> 8, /*WORD MajorSubsystemVersion; */
|
||||||
0x0006, /*WORD MajorSubsystemVersion; */
|
OS_VER & 255, /*WORD MinorSubsystemVersion; */
|
||||||
0x0002, /*WORD MinorSubsystemVersion; */
|
|
||||||
#else
|
|
||||||
0x0004, /*WORD MajorSubsystemVersion; */
|
|
||||||
0x0000, /*WORD MinorSubsystemVersion; */
|
|
||||||
#endif
|
|
||||||
0x00000000, /*DWORD Win32VersionValue; */
|
0x00000000, /*DWORD Win32VersionValue; */
|
||||||
0x00000000, /*DWORD SizeOfImage; */
|
0x00000000, /*DWORD SizeOfImage; */
|
||||||
0x00000200, /*DWORD SizeOfHeaders; */
|
0x00000200, /*DWORD SizeOfHeaders; */
|
||||||
0x00000000, /*DWORD CheckSum; */
|
0x00000000, /*DWORD CheckSum; */
|
||||||
0x0002, /*WORD Subsystem; */
|
0x0002, /*WORD Subsystem; */
|
||||||
0x0000, /*WORD DllCharacteristics; */
|
DLLCHARACTERISTICS, /*WORD DllCharacteristics; */
|
||||||
0x00100000, /*DWORD SizeOfStackReserve; */
|
0x00100000, /*ADDR3264 SizeOfStackReserve; */
|
||||||
0x00001000, /*DWORD SizeOfStackCommit; */
|
0x00001000, /*ADDR3264 SizeOfStackCommit; */
|
||||||
0x00100000, /*DWORD SizeOfHeapReserve; */
|
0x00100000, /*ADDR3264 SizeOfHeapReserve; */
|
||||||
0x00001000, /*DWORD SizeOfHeapCommit; */
|
0x00001000, /*ADDR3264 SizeOfHeapCommit; */
|
||||||
0x00000000, /*DWORD LoaderFlags; */
|
0x00000000, /*DWORD LoaderFlags; */
|
||||||
0x00000010, /*DWORD NumberOfRvaAndSizes; */
|
0x00000010, /*DWORD NumberOfRvaAndSizes; */
|
||||||
|
|
||||||
@ -799,7 +721,7 @@ static int pe_write(struct pe_info *pe)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case sec_data:
|
case sec_data:
|
||||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
#if PTR_SIZE == 4
|
||||||
if (!pe_header.opthdr.BaseOfData)
|
if (!pe_header.opthdr.BaseOfData)
|
||||||
pe_header.opthdr.BaseOfData = addr;
|
pe_header.opthdr.BaseOfData = addr;
|
||||||
#endif
|
#endif
|
||||||
@ -861,14 +783,14 @@ static int pe_write(struct pe_info *pe)
|
|||||||
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
||||||
pe_header.opthdr.ImageBase = pe->imagebase;
|
pe_header.opthdr.ImageBase = pe->imagebase;
|
||||||
pe_header.opthdr.Subsystem = pe->subsystem;
|
pe_header.opthdr.Subsystem = pe->subsystem;
|
||||||
pe_header.opthdr.DllCharacteristics = pe_get_dll_characteristics(s1);
|
pe_header.opthdr.DllCharacteristics = s1->pe_dll_characteristics;
|
||||||
if (s1->pe_stack_size)
|
if (s1->pe_stack_size)
|
||||||
pe_header.opthdr.SizeOfStackReserve = s1->pe_stack_size;
|
pe_header.opthdr.SizeOfStackReserve = s1->pe_stack_size;
|
||||||
if (PE_DLL == pe->type)
|
if (PE_DLL == pe->type)
|
||||||
pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
|
pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
|
||||||
pe_header.filehdr.Characteristics |= s1->pe_characteristics;
|
pe_header.filehdr.Characteristics |= s1->pe_characteristics;
|
||||||
if (pe->reloc)
|
if (pe->reloc)
|
||||||
pe_header.filehdr.Characteristics &= ~PE_IMAGE_FILE_RELOCS_STRIPPED;
|
pe_header.filehdr.Characteristics &= ~IMAGE_FILE_RELOCS_STRIPPED;
|
||||||
|
|
||||||
if (pe->coffsym) {
|
if (pe->coffsym) {
|
||||||
pe_add_coffsym(pe);
|
pe_add_coffsym(pe);
|
||||||
@ -1291,8 +1213,8 @@ static int pe_assign_addresses (struct pe_info *pe)
|
|||||||
Section *s;
|
Section *s;
|
||||||
TCCState *s1 = pe->s1;
|
TCCState *s1 = pe->s1;
|
||||||
|
|
||||||
if (PE_DLL == pe->type ||
|
if (PE_DLL == pe->type
|
||||||
(pe_get_dll_characteristics(s1) & PE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
|| (s1->pe_dll_characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
||||||
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
||||||
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
||||||
|
|
||||||
@ -1483,14 +1405,10 @@ static int pe_check_symbols(struct pe_info *pe)
|
|||||||
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
#elif defined(TCC_TARGET_ARM64)
|
||||||
p = section_ptr_add(text_section, 24);
|
p = section_ptr_add(text_section, 24);
|
||||||
/* ldr x16, [pc, #16] */
|
write32le(p + 0, 0x58000090); /* ldr x16, [pc, #16] */
|
||||||
write32le(p + 0, 0x58000090);
|
write32le(p + 4, 0xf9400210); /* ldr x16, [x16] */
|
||||||
/* ldr x16, [x16] */
|
write32le(p + 8, 0xd61f0200); /* br x16 */
|
||||||
write32le(p + 4, 0xf9400210);
|
write32le(p + 12, 0xd503201f); /* nop for alignment */
|
||||||
/* br x16 */
|
|
||||||
write32le(p + 8, 0xd61f0200);
|
|
||||||
/* nop for 8-byte literal alignment */
|
|
||||||
write32le(p + 12, 0xd503201f);
|
|
||||||
put_elf_reloc(symtab_section, text_section,
|
put_elf_reloc(symtab_section, text_section,
|
||||||
offset + 16, R_XXX_THUNKFIX, is->iat_index);
|
offset + 16, R_XXX_THUNKFIX, is->iat_index);
|
||||||
#else
|
#else
|
||||||
@ -1716,7 +1634,7 @@ static int get_dllexports(int fd, char **pp)
|
|||||||
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
||||||
goto the_end;
|
goto the_end;
|
||||||
opt_hdroffset = pef_hdroffset + sizeof ih;
|
opt_hdroffset = pef_hdroffset + sizeof ih;
|
||||||
if (ih.Machine == 0x014C) {
|
if (ih.Machine == 0x014C || ih.Machine == 0x01C0) {
|
||||||
IMAGE_OPTIONAL_HEADER32 oh;
|
IMAGE_OPTIONAL_HEADER32 oh;
|
||||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||||
@ -1724,7 +1642,7 @@ static int get_dllexports(int fd, char **pp)
|
|||||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||||
goto the_end_0;
|
goto the_end_0;
|
||||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||||
} else if (ih.Machine == 0x8664 || ih.Machine == IMAGE_FILE_MACHINE_ARM64) {
|
} else if (ih.Machine == 0x8664 || ih.Machine == 0xAA64) {
|
||||||
IMAGE_OPTIONAL_HEADER64 oh;
|
IMAGE_OPTIONAL_HEADER64 oh;
|
||||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||||
@ -2209,19 +2127,9 @@ static void pe_set_options(TCCState * s1, struct pe_info *pe)
|
|||||||
{
|
{
|
||||||
if (PE_DLL == pe->type) {
|
if (PE_DLL == pe->type) {
|
||||||
/* XXX: check if is correct for arm-pe target */
|
/* XXX: check if is correct for arm-pe target */
|
||||||
#if defined(TCC_TARGET_ARM64)
|
pe->imagebase = IMAGE_BASE_DLL;
|
||||||
pe->imagebase = 0x180000000ULL;
|
|
||||||
#else
|
|
||||||
pe->imagebase = 0x10000000;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
#if defined(TCC_TARGET_ARM)
|
pe->imagebase = IMAGE_BASE_EXE;
|
||||||
pe->imagebase = 0x00010000;
|
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
|
||||||
pe->imagebase = 0x140000000ULL;
|
|
||||||
#else
|
|
||||||
pe->imagebase = 0x00400000;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TCC_TARGET_ARM)
|
#if defined(TCC_TARGET_ARM)
|
||||||
|
|||||||
42
tccrun.c
42
tccrun.c
@ -108,6 +108,11 @@ static void win64_del_function_table(void *);
|
|||||||
//#define CONFIG_SELINUX 1
|
//#define CONFIG_SELINUX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* use VirtualAlloc() instead of tcc_malloc() */
|
||||||
|
#if defined _WIN32 && !defined CONFIG_RUNMEM_VIRTUALALLOC
|
||||||
|
# define CONFIG_RUNMEM_VIRTUALALLOC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
static int rt_mem(TCCState *s1, int size)
|
static int rt_mem(TCCState *s1, int size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@ -129,16 +134,14 @@ static int rt_mem(TCCState *s1, int size)
|
|||||||
ptr_diff = (char*)prw - (char*)ptr; /* = size; */
|
ptr_diff = (char*)prw - (char*)ptr; /* = size; */
|
||||||
//printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
|
//printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
|
||||||
size *= 2;
|
size *= 2;
|
||||||
#else
|
#elif CONFIG_RUNMEM_VIRTUALALLOC
|
||||||
# ifdef _WIN32
|
/* always page-aligned */
|
||||||
/* Generated code is page-protected below; avoid changing CRT heap pages. */
|
|
||||||
ptr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
ptr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
# else
|
|
||||||
ptr = tcc_malloc(size += PAGESIZE); /* one extra page to align malloc memory */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return tcc_error_noabort("tccrun: could not allocate memory");
|
return tcc_error_noabort("tccrun: could not allocate memory");
|
||||||
|
#else
|
||||||
|
ptr = tcc_malloc(size += PAGESIZE); /* one extra page to align malloc memory */
|
||||||
|
#endif
|
||||||
s1->run_ptr = ptr;
|
s1->run_ptr = ptr;
|
||||||
s1->run_size = size;
|
s1->run_size = size;
|
||||||
return ptr_diff;
|
return ptr_diff;
|
||||||
@ -191,24 +194,18 @@ ST_FUNC void tcc_run_free(TCCState *s1)
|
|||||||
if (NULL == ptr)
|
if (NULL == ptr)
|
||||||
return;
|
return;
|
||||||
st_unlink(s1);
|
st_unlink(s1);
|
||||||
|
#ifdef _WIN64
|
||||||
|
win64_del_function_table(s1->run_function_table);
|
||||||
|
#endif
|
||||||
size = s1->run_size;
|
size = s1->run_size;
|
||||||
#ifdef CONFIG_SELINUX
|
#ifdef CONFIG_SELINUX
|
||||||
munmap(ptr, size);
|
munmap(ptr, size);
|
||||||
|
#elif CONFIG_RUNMEM_VIRTUALALLOC
|
||||||
|
VirtualFree(ptr, size, MEM_RELEASE);
|
||||||
#else
|
#else
|
||||||
# ifdef _WIN32
|
|
||||||
(void)size;
|
|
||||||
# ifdef _WIN64
|
|
||||||
win64_del_function_table(s1->run_function_table);
|
|
||||||
# endif
|
|
||||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
|
||||||
# else
|
|
||||||
/* unprotect memory to make it usable for malloc again */
|
/* unprotect memory to make it usable for malloc again */
|
||||||
protect_pages((void*)PAGEALIGN(ptr), size - PAGESIZE, 2 /*rw*/);
|
protect_pages((void*)PAGEALIGN(ptr), size - PAGESIZE, 2 /*rw*/);
|
||||||
# ifdef _WIN64
|
|
||||||
win64_del_function_table(s1->run_function_table);
|
|
||||||
# endif
|
|
||||||
tcc_free(ptr);
|
tcc_free(ptr);
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +309,7 @@ static void cleanup_sections(TCCState *s1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* 0 = .text rwx other rw (memory >= 2 pages a 4096 bytes) */
|
/* 0 = .text rwx other rwx (memory >= 2 pages a 4096 bytes) */
|
||||||
/* 1 = .text rx other rw (memory >= 3 pages) */
|
/* 1 = .text rx other rw (memory >= 3 pages) */
|
||||||
/* 2 = .text rx .rdata ro .data/.bss rw (memory >= 4 pages) */
|
/* 2 = .text rx .rdata ro .data/.bss rw (memory >= 4 pages) */
|
||||||
|
|
||||||
@ -506,14 +503,11 @@ static void *win64_add_function_table(TCCState *s1)
|
|||||||
void *p = NULL;
|
void *p = NULL;
|
||||||
if (s1->uw_pdata) {
|
if (s1->uw_pdata) {
|
||||||
p = (void*)s1->uw_pdata->sh_addr;
|
p = (void*)s1->uw_pdata->sh_addr;
|
||||||
if (!RtlAddFunctionTable(
|
RtlAddFunctionTable(
|
||||||
(RUNTIME_FUNCTION*)p,
|
(RUNTIME_FUNCTION*)p,
|
||||||
s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
|
s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
|
||||||
s1->pe_imagebase
|
s1->pe_imagebase
|
||||||
)) {
|
);
|
||||||
tcc_error_noabort("RtlAddFunctionTable failed");
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
s1->uw_pdata = NULL;
|
s1->uw_pdata = NULL;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
|
|||||||
@ -19,9 +19,6 @@ ifeq (,$(filter i386 x86_64,$(ARCH)))
|
|||||||
SKIP += 85_asm-outside-function.test # x86 asm
|
SKIP += 85_asm-outside-function.test # x86 asm
|
||||||
SKIP += 127_asm_goto.test # hardcodes x86 asm
|
SKIP += 127_asm_goto.test # hardcodes x86 asm
|
||||||
endif
|
endif
|
||||||
ifeq (,$(filter x86_64 riscv64 arm64 i386,$(ARCH)))
|
|
||||||
SKIP += 144_tls.test # TLS only implemented on these architectures so far
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_backtrace),no)
|
ifeq ($(CONFIG_backtrace),no)
|
||||||
SKIP += 113_btdll.test
|
SKIP += 113_btdll.test
|
||||||
CONFIG_bcheck = no
|
CONFIG_bcheck = no
|
||||||
@ -57,22 +54,23 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
|
|||||||
SKIP += 114_bound_signal.test # libc problem signal/fork
|
SKIP += 114_bound_signal.test # libc problem signal/fork
|
||||||
SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
|
SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
|
||||||
endif
|
endif
|
||||||
ifdef CONFIG_OSX
|
ifeq ($(CONFIG_OSX),yes)
|
||||||
SKIP += 144_tls.test # TLS runtime not supported on Mach-O
|
SKIP += 144_tls.test # TLS runtime not supported on Mach-O
|
||||||
endif
|
endif
|
||||||
ifeq (,$(filter arm64 aarch64,$(ARCH)))
|
ifeq (,$(filter i386 x86_64 riscv64 arm64,$(ARCH)))
|
||||||
|
SKIP += 144_tls.test # TLS only implemented on these architectures so far
|
||||||
|
endif
|
||||||
|
ifneq (-$(ARCH)-,-arm64-)
|
||||||
SKIP += 138_arm64_encoding.test
|
SKIP += 138_arm64_encoding.test
|
||||||
SKIP += 139_arm64_errors.test
|
SKIP += 139_arm64_errors.test
|
||||||
SKIP += 140_arm64_extasm.test
|
SKIP += 140_arm64_extasm.test
|
||||||
endif
|
endif
|
||||||
ifneq ($(CONFIG_WIN32),yes)
|
ifneq (-$(ARCH)-,-riscv64-)
|
||||||
SKIP += 145_winarm64_interlocked.test
|
|
||||||
else ifeq (,$(filter arm64 aarch64,$(ARCH)))
|
|
||||||
SKIP += 145_winarm64_interlocked.test
|
|
||||||
endif
|
|
||||||
ifeq (,$(filter riscv64,$(ARCH)))
|
|
||||||
SKIP += 141_riscv_asm.test # riscv64 asm
|
SKIP += 141_riscv_asm.test # riscv64 asm
|
||||||
endif
|
endif
|
||||||
|
ifneq (-$(ARCH)-$(CONFIG_WIN32)-,-arm64-yes-)
|
||||||
|
SKIP += 145_winarm64_interlocked.test
|
||||||
|
endif
|
||||||
|
|
||||||
# Some tests might need arguments
|
# Some tests might need arguments
|
||||||
ARGS =
|
ARGS =
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user