fix github CI & stuff
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run

workflows/build.yml:
- win32/64: install mingw32/64 gcc on msys (because the default
  gcc installed elsewhere seems to use ucrt, producing incompatible
  fp printf formats.)
tccgen.c:
- cleanup funcs: save any lvalues from return expressions.  Also use
  get_temp_local_var() which however was causing a problem on i386
  because its gfunc_call() removes the arguments from vstack and by
  that defeats the 'in-use'  tracking of get_temp_local_var().  Fixed by:
i386/arm/arm64/x86_64-gen.c:
- in gfunc_call(): save_regs before anything else, fixes
  problems seen in arm64/i386
tccpp.c:
- allow arm asm specific use of '#' in macros
libtcc.c:
- organize -M options, and:
tccpe.c:
- move the subsystem option parsing from libtcc.c
tccelf.c:
- improved error handling in tcc_load_ldscript()
lib/atomic.S:
- TCC_TARGET_... not defined when building the lib
- endbrNN security feature not supported by TCC
tests/tests2/136_atomic_gcc_style.c:
- never use standard assert() in tests
This commit is contained in:
grischka 2025-07-14 21:55:37 +02:00
parent 28d7fb85b2
commit 9670d10294
15 changed files with 133 additions and 95 deletions

View File

@ -29,29 +29,41 @@ jobs:
- name: make & test tcc (aarch64-osx) - name: make & test tcc (aarch64-osx)
run: ./configure && make && make test -k run: ./configure && make && make test -k
test-x86-win32: test-x86_64-win32:
runs-on: windows-2022 runs-on: windows-2025
timeout-minutes: 6 timeout-minutes: 4
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: make & test tcc (x86_64-win32) - name: make & test tcc (x86_64-win32)
shell: cmd shell: cmd
run: | run: |
echo ::group:: setup msys mingw64-gcc
set MSYS2_PATH_TYPE=inherit set MSYS2_PATH_TYPE=inherit
set MSYSTEM=MINGW64 set MSYSTEM=MINGW64
set CHERE_INVOKING=yes set CHERE_INVOKING=yes
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
echo ::endgroup::
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k" C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
test-i386-win32:
runs-on: windows-2025
timeout-minutes: 4
steps:
- uses: actions/checkout@v4
- name: make & test tcc (i386-win32) - name: make & test tcc (i386-win32)
shell: cmd shell: cmd
run: | run: |
echo ::group:: setup msys mingw32-gcc
set MSYS2_PATH_TYPE=inherit set MSYS2_PATH_TYPE=inherit
set MSYSTEM=MINGW32 set MSYSTEM=MINGW32
set CHERE_INVOKING=yes set CHERE_INVOKING=yes
C:\msys64\usr\bin\bash -l -c "./configure && make clean all && make test -k" C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"
echo ::endgroup::
C:\msys64\usr\bin\bash -l -c "./configure && make all && make test -k"
test-armv7-linux: test-armv7-linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 6 timeout-minutes: 8
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3 - uses: uraimo/run-on-arch-action@v3
@ -69,14 +81,14 @@ jobs:
test-aarch64-linux: test-aarch64-linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 6 timeout-minutes: 8
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3 - uses: uraimo/run-on-arch-action@v3
name: make & test tcc (aarch64-linux) name: make & test tcc (aarch64-linux)
with: with:
arch: aarch64 arch: aarch64
distro: ubuntu22.04 distro: ubuntu24.04
githubToken: ${{ github.token }} githubToken: ${{ github.token }}
install: | install: |
apt-get update -q -y apt-get update -q -y
@ -87,7 +99,7 @@ jobs:
test-riscv64-linux: test-riscv64-linux:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 6 timeout-minutes: 8
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3 - uses: uraimo/run-on-arch-action@v3

View File

@ -252,8 +252,11 @@ LDFLAGS += -g
endif endif
# convert "include/tccdefs.h" to "tccdefs_.h" # convert "include/tccdefs.h" to "tccdefs_.h"
%_.h : include/%.h conftest.c %_.h : include/%.h c2str.exe
$S$(CC) -DC2STR $(filter %.c,$^) -o c2str.exe && ./c2str.exe $< $@ $S./c2str.exe $< $@
c2str.exe : conftest.c
$S$(CC) -DC2STR $< -o $@
# target specific object rule # target specific object rule
$(X)%.o : %.c $(LIBTCC_INC) $(X)%.o : %.c $(LIBTCC_INC)

View File

@ -1311,10 +1311,6 @@ again:
if (++pass < 2) if (++pass < 2)
goto again; goto again;
/* Manually free remaining registers since next parameters are loaded
* manually, without the help of gv(int). */
save_regs(nb_args);
if(todo) { if(todo) {
o(0xE8BD0000|todo); /* pop {todo} */ o(0xE8BD0000|todo); /* pop {todo} */
for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
@ -1354,6 +1350,8 @@ void gfunc_call(int nb_args)
gbound_args(nb_args); gbound_args(nb_args);
#endif #endif
save_regs(nb_args + 1);
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
if (float_abi == ARM_HARD_FLOAT) { if (float_abi == ARM_HARD_FLOAT) {
variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS); variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);

View File

@ -997,6 +997,8 @@ ST_FUNC void gfunc_call(int nb_args)
int variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS); int variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
int var_nb_arg = n_func_args(&vtop[-nb_args].type); int var_nb_arg = n_func_args(&vtop[-nb_args].type);
save_regs(nb_args + 1);
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check) if (tcc_state->do_bounds_check)
gbound_args(nb_args); gbound_args(nb_args);
@ -1101,9 +1103,6 @@ ST_FUNC void gfunc_call(int nb_args)
// value in floating-point registers // value in floating-point registers
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
// save regs because struct may overwrite previous func call result
save_regs(0);
vtop->type.t = VT_PTR; vtop->type.t = VT_PTR;
gaddrof(); gaddrof();
gv(RC_R30); gv(RC_R30);
@ -1129,7 +1128,6 @@ ST_FUNC void gfunc_call(int nb_args)
vswap(); vswap();
} }
save_regs(0);
arm64_gen_bl_or_b(0); arm64_gen_bl_or_b(0);
--vtop; --vtop;
if (stack & 0xfff) if (stack & 0xfff)

View File

@ -406,6 +406,8 @@ ST_FUNC void gfunc_call(int nb_args)
gbound_args(nb_args); gbound_args(nb_args);
#endif #endif
save_regs(nb_args + 1);
args_size = 0; args_size = 0;
for(i = 0;i < nb_args; i++) { for(i = 0;i < nb_args; i++) {
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@ -463,7 +465,7 @@ ST_FUNC void gfunc_call(int nb_args)
} }
vtop--; vtop--;
} }
save_regs(0); /* save used temporary registers */
func_sym = vtop->type.ref; func_sym = vtop->type.ref;
func_call = func_sym->f.func_call; func_call = func_sym->f.func_call;
/* fast call case */ /* fast call case */

View File

@ -23,8 +23,10 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __i386__ #if defined __i386__
#define endbr32
.text .text
.align 2
.global _(__atomic_load_1) .global _(__atomic_load_1)
.type _(__atomic_load_1), %function .type _(__atomic_load_1), %function
@ -297,9 +299,11 @@ _(atomic_flag_clear_explicit):
#endif //__i386__ #endif //__i386__
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __x86_64__ && !defined TCC_TARGET_PE #if defined __x86_64__ && !defined _WIN32
#define endbr64
.text .text
.align 2
.global _(__atomic_load_1) .global _(__atomic_load_1)
.type _(__atomic_load_1), %function .type _(__atomic_load_1), %function
@ -508,12 +512,11 @@ _(atomic_flag_clear_explicit):
ret ret
.size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit) .size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit)
#endif //__x86_64__ && !TCC_TARGET_PE #endif //__x86_64__ && !_WIN32
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __x86_64__ && defined TCC_TARGET_PE #if defined __x86_64__ && defined _WIN32
.text .text
.align 2
.global _(__atomic_load_1) .global _(__atomic_load_1)
.type _(__atomic_load_1), %function .type _(__atomic_load_1), %function
@ -700,12 +703,11 @@ _(atomic_flag_clear_explicit):
ret ret
.size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit) .size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit)
#endif //__x86_64__ && TCC_TARGET_PE #endif //__x86_64__ && _WIN32
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __arm__ #if defined __arm__
.text .text
.align 2
#ifndef __TINYC__ #ifndef __TINYC__
.arch armv6k .arch armv6k
.syntax unified .syntax unified
@ -1496,7 +1498,6 @@ _(atomic_flag_clear_explicit):
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __aarch64__ #if defined __aarch64__
.text .text
.align 2
.global _(__atomic_load_1) .global _(__atomic_load_1)
.type _(__atomic_load_1), %function .type _(__atomic_load_1), %function
@ -2115,7 +2116,6 @@ _(atomic_flag_clear_explicit):
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#if defined __riscv #if defined __riscv
.text .text
.align 2
.global _(__atomic_load_1) .global _(__atomic_load_1)
.type _(__atomic_load_1), %function .type _(__atomic_load_1), %function

View File

@ -1465,31 +1465,9 @@ static int tcc_set_linker(TCCState *s, const char *optarg)
} else if (link_option(&o, "stack=")) { } else if (link_option(&o, "stack=")) {
s->pe_stack_size = strtoul(o.arg, &end, 10); s->pe_stack_size = strtoul(o.arg, &end, 10);
} else if (link_option(&o, "subsystem=")) { } else if (link_option(&o, "subsystem=")) {
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) if (pe_setsubsy(s, o.arg) < 0)
if (0==strcmp("native", o.arg)) {
s->pe_subsystem = 1;
} else if (0==strcmp("console", o.arg)) {
s->pe_subsystem = 3;
} else if (0==strcmp("gui", o.arg) || 0==strcmp("windows", o.arg)) {
s->pe_subsystem = 2;
} else if (0==strcmp("posix", o.arg)) {
s->pe_subsystem = 7;
} else if (0==strcmp("efiapp", o.arg)) {
s->pe_subsystem = 10;
} else if (0==strcmp("efiboot", o.arg)) {
s->pe_subsystem = 11;
} else if (0==strcmp("efiruntime", o.arg)) {
s->pe_subsystem = 12;
} else if (0==strcmp("efirom", o.arg)) {
s->pe_subsystem = 13;
#elif defined(TCC_TARGET_ARM)
if (0==strcmp("wince", o.arg)) {
s->pe_subsystem = 9;
#endif
} else
goto err; goto err;
#endif /* PE */ #elif defined TCC_TARGET_MACHO
#ifdef TCC_TARGET_MACHO
} else if (link_option(&o, "all_load")) { } else if (link_option(&o, "all_load")) {
s->filetype |= AFF_WHOLE_ARCHIVE; s->filetype |= AFF_WHOLE_ARCHIVE;
} else if (link_option(&o, "force_load=")) { } else if (link_option(&o, "force_load=")) {
@ -1653,11 +1631,10 @@ static const TCCOption tcc_options[] = {
{ "w", TCC_OPTION_w, 0 }, { "w", TCC_OPTION_w, 0 },
{ "E", TCC_OPTION_E, 0}, { "E", TCC_OPTION_E, 0},
{ "M", TCC_OPTION_M, 0}, { "M", TCC_OPTION_M, 0},
{ "MD", TCC_OPTION_MD, 0},
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
{ "MM", TCC_OPTION_MM, 0}, { "MM", TCC_OPTION_MM, 0},
{ "MMD,", TCC_OPTION_MMD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "MD", TCC_OPTION_MD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "MMD", TCC_OPTION_MMD, 0}, { "MMD", TCC_OPTION_MMD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
{ "MP", TCC_OPTION_MP, 0}, { "MP", TCC_OPTION_MP, 0},
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
/* tcctools */ /* tcctools */
@ -2075,6 +2052,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
case TCC_OPTION_P: case TCC_OPTION_P:
s->Pflag = atoi(optarg) + 1; s->Pflag = atoi(optarg) + 1;
break; break;
case TCC_OPTION_M: case TCC_OPTION_M:
s->include_sys_deps = 1; s->include_sys_deps = 1;
// fall through // fall through
@ -2084,29 +2062,31 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
if (!s->deps_outfile) if (!s->deps_outfile)
tcc_set_str(&s->deps_outfile, "-"); tcc_set_str(&s->deps_outfile, "-");
break; break;
case TCC_OPTION_MD:
s->include_sys_deps = 1;
// fall through
case TCC_OPTION_MMD: case TCC_OPTION_MMD:
s->gen_deps = 1; s->gen_deps = 1;
/* usually, only "-MMD" is used */ /* usually, only "-MMD" is used */
/* but the Linux Kernel uses "-MMD,depfile" */ /* but the Linux Kernel uses "-MMD,depfile" */
if ((optarg) && (*optarg != '\0')) if (*optarg != ',')
tcc_set_str(&s->deps_outfile, optarg); break;
break; ++optarg;
case TCC_OPTION_MD: // fall through
s->gen_deps = 1;
s->include_sys_deps = 1;
break;
case TCC_OPTION_MF: case TCC_OPTION_MF:
tcc_set_str(&s->deps_outfile, optarg); tcc_set_str(&s->deps_outfile, optarg);
break; break;
case TCC_OPTION_MP: case TCC_OPTION_MP:
s->gen_phony_deps = 1; s->gen_phony_deps = 1;
break; break;
case TCC_OPTION_dumpmachine: case TCC_OPTION_dumpmachine:
printf("%s\n", dumpmachine_str); printf("%s\n", dumpmachine_str);
exit(0); exit(0);
case TCC_OPTION_dumpversion: case TCC_OPTION_dumpversion:
printf ("%s\n", TCC_VERSION); printf ("%s\n", TCC_VERSION);
exit(0); exit(0);
case TCC_OPTION_x: case TCC_OPTION_x:
x = 0; x = 0;
if (*optarg == 'c') if (*optarg == 'c')

1
tcc.h
View File

@ -1790,6 +1790,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename); ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename);
ST_FUNC int pe_output_file(TCCState * s1, const char *filename); ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg);
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#endif #endif
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64

View File

@ -3937,7 +3937,7 @@ static int ld_add_file(TCCState *s1, const char filename[])
{ {
if (filename[0] == '-' && filename[1] == 'l') if (filename[0] == '-' && filename[1] == 'l')
return tcc_add_library(s1, filename + 2); return tcc_add_library(s1, filename + 2);
{ if (CONFIG_SYSROOT[0] != '\0' || !IS_ABSPATH(filename)) {
/* lookup via library paths */ /* lookup via library paths */
int ret = tcc_add_dll(s1, tcc_basename(filename), 0); int ret = tcc_add_dll(s1, tcc_basename(filename), 0);
if (ret != FILE_NOT_FOUND) if (ret != FILE_NOT_FOUND)
@ -3981,19 +3981,19 @@ repeat:
} else if (t != LD_TOK_NAME) { } else if (t != LD_TOK_NAME) {
return tcc_error_noabort("unexpected token '%c'", t); return tcc_error_noabort("unexpected token '%c'", t);
} else if (!strcmp(filename, "AS_NEEDED")) { } else if (!strcmp(filename, "AS_NEEDED")) {
ret = ld_add_file_list(s1, filename); ret |= ld_add_file_list(s1, filename);
} else if (c == 'I' || c == 'G' || c == 'A') { } else if (c == 'I' || c == 'G' || c == 'A') {
ret = ld_add_file(s1, filename); ret |= !!ld_add_file(s1, filename);
} }
if (ret) if (ret < 0)
return -1; return ret;
t = ld_next(s1, filename, sizeof(filename)); t = ld_next(s1, filename, sizeof(filename));
if (t == ',') if (t == ',')
t = ld_next(s1, filename, sizeof(filename)); t = ld_next(s1, filename, sizeof(filename));
} }
if (c == 'G' && new_undef_sym(s1, sym_offset)) if (c == 'G' && ret == 0 && new_undef_sym(s1, sym_offset))
goto repeat; goto repeat;
return 0; return ret;
} }
/* interpret a subset of GNU ldscripts to handle the dummy libc.so /* interpret a subset of GNU ldscripts to handle the dummy libc.so
@ -4001,7 +4001,7 @@ repeat:
ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd) ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
{ {
char cmd[64]; char cmd[64];
int t, ret = FILE_NOT_RECOGNIZED; int t, ret = 0, noscript = 1;
unsigned char *text_ptr, *saved_ptr; unsigned char *text_ptr, *saved_ptr;
saved_ptr = s1->ld_p; saved_ptr = s1->ld_p;
@ -4012,19 +4012,22 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
break; break;
if (!strcmp(cmd, "INPUT") || if (!strcmp(cmd, "INPUT") ||
!strcmp(cmd, "GROUP")) { !strcmp(cmd, "GROUP")) {
ret = ld_add_file_list(s1, cmd); ret |= ld_add_file_list(s1, cmd);
} else if (!strcmp(cmd, "OUTPUT_FORMAT") || } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
!strcmp(cmd, "TARGET")) { !strcmp(cmd, "TARGET")) {
/* ignore some commands */ /* ignore some commands */
ret = ld_add_file_list(s1, cmd); ret |= ld_add_file_list(s1, cmd);
} else if (0 == ret) { } else if (noscript) {
ret = FILE_NOT_RECOGNIZED;
} else {
ret = tcc_error_noabort("unexpected '%s'", cmd); ret = tcc_error_noabort("unexpected '%s'", cmd);
} }
if (ret) if (ret < 0)
break; break;
noscript = 0;
} }
tcc_free(text_ptr); tcc_free(text_ptr);
s1->ld_p = saved_ptr; s1->ld_p = saved_ptr;
return ret; return ret < 0 ? ret : -ret;
} }
#endif /* !ELF_OBJ_ONLY */ #endif /* !ELF_OBJ_ONLY */

View File

@ -6839,15 +6839,15 @@ static void end_switch(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* __attribute__((cleanup(fn))) */ /* __attribute__((cleanup(fn))) */
/* save SValue of symbol to local stack */ /* protect symbol lvalues from further modification */
static void save_cleanup_sym(Sym *s) static void save_lvalues(void)
{ {
SValue *sv = vtop; SValue *sv = vtop;
while (sv >= vstack) { while (sv >= vstack) {
if (sv->sym == s) { if (sv->sym && (sv->r & VT_LVAL)) {
int align, size = type_size(&sv->type, &align); int align, size = type_size(&sv->type, &align);
loc = (loc - size) & -align; int r2, l = get_temp_local_var(size, align, &r2);
vset(&sv->type, VT_LOCAL | VT_LVAL, loc); vset(&sv->type, VT_LOCAL | VT_LVAL, l), vtop->r2 = r2;
vpushv(sv), *sv = vtop[-1], vstore(), --vtop; vpushv(sv), *sv = vtop[-1], vstore(), --vtop;
} }
--sv; --sv;
@ -6860,7 +6860,7 @@ static void try_call_scope_cleanup(Sym *stop)
for (; cls != stop; cls = cls->next) { for (; cls != stop; cls = cls->next) {
Sym *fs = cls->cleanup_func; Sym *fs = cls->cleanup_func;
Sym *vs = cls->prev_tok; Sym *vs = cls->prev_tok;
save_cleanup_sym(vs); save_lvalues();
vpushsym(&fs->type, fs); vpushsym(&fs->type, fs);
vset(&vs->type, vs->r, vs->c); vset(&vs->type, vs->r, vs->c);
vtop->sym = vs; vtop->sym = vs;

30
tccpe.c
View File

@ -1254,7 +1254,7 @@ static int pe_check_symbols(struct pe_info *pe)
if (sym->st_shndx == SHN_UNDEF) { if (sym->st_shndx == SHN_UNDEF) {
const char *name = (char*)symtab_section->link->data + sym->st_name; const char *name = (char*)symtab_section->link->data + sym->st_name;
unsigned type = ELFW(ST_TYPE)(sym->st_info); unsigned type = ELFW(ST_TYPE)(sym->st_info);
int imp_sym; int imp_sym = 0;
struct import_symbol *is; struct import_symbol *is;
int _imp_, n; int _imp_, n;
@ -1928,6 +1928,34 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
pe->type = pe_type; pe->type = pe_type;
} }
ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg)
{
static const struct subsy { const char* p; int v; } x[] = {
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
{ "native", 1 },
{ "gui", 2 },
{ "windows", 2 },
{ "console", 3 },
{ "posix", 7 },
{ "efiapp", 10 },
{ "efiboot", 11 },
{ "efiruntime", 12 },
{ "efirom", 13 },
#elif defined(TCC_TARGET_ARM)
{ "wince", 9 },
#endif
{ 0, -1 }};
const struct subsy *y;
for (y = x;; ++y) {
if (!y->p)
return -1;
if (0 == strcmp(y->p, arg)) {
s1->pe_subsystem = y->v;
return 0;
}
}
}
static void pe_set_options(TCCState * s1, struct pe_info *pe) static void pe_set_options(TCCState * s1, struct pe_info *pe)
{ {
if (PE_DLL == pe->type) { if (PE_DLL == pe->type) {

View File

@ -3076,6 +3076,11 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
cval.str.size = tokcstr.size; cval.str.size = tokcstr.size;
cval.str.data = tokcstr.data; cval.str.data = tokcstr.data;
tok_str_add2(&str, TOK_PPSTR, &cval); tok_str_add2(&str, TOK_PPSTR, &cval);
#ifdef TCC_TARGET_ARM
} else if ((parse_flags & PARSE_FLAG_ASM_FILE) && t == TOK_PPNUM) {
/* for example: mov r1,#0 */
--macro_str, tok_str_add(&str, '#');
#endif
} else { } else {
expect("macro parameter after '#'"); expect("macro parameter after '#'");
} }

View File

@ -1,8 +1,11 @@
#include <stdatomic.h> #include <stdatomic.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#include <stdio.h> #include <stdio.h>
// standard assert would popup a dialog box on windows
#define assert(x) \
printf("assert \"%s\" : %s\n", #x, (x) ? "yes" : "no");
int main() { int main() {
// Test 1: Basic functionality of __atomic_store_n and __atomic_load_n // Test 1: Basic functionality of __atomic_store_n and __atomic_load_n
{ {

View File

@ -1 +1,11 @@
assert "loaded == 42" : yes
assert "success" : yes
assert "atomic_var == 200" : yes
assert "expected == 100" : yes
assert "!success" : yes
assert "atomic_var == 100" : yes
assert "expected == 100" : yes
assert "atomic_var == 60" : yes
assert "loaded_ptr == NULL" : yes
assert "__atomic_load_n(&atomic_var, __ATOMIC_RELAXED) == 10" : yes
All atomic tests passed! All atomic tests passed!

View File

@ -809,6 +809,8 @@ void gfunc_call(int nb_args)
gbound_args(nb_args); gbound_args(nb_args);
#endif #endif
save_regs(nb_args);
args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE; args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
arg = nb_args; arg = nb_args;
@ -906,7 +908,7 @@ void gfunc_call(int nb_args)
} }
vtop--; vtop--;
} }
save_regs(0);
/* Copy R10 and R11 into RCX and RDX, respectively */ /* Copy R10 and R11 into RCX and RDX, respectively */
if (nb_args > 0) { if (nb_args > 0) {
o(0xd1894c); /* mov %r10, %rcx */ o(0xd1894c); /* mov %r10, %rcx */
@ -1249,6 +1251,8 @@ void gfunc_call(int nb_args)
gbound_args(nb_args); gbound_args(nb_args);
#endif #endif
save_regs(nb_args);
/* calculate the number of integer/float register arguments, remember /* calculate the number of integer/float register arguments, remember
arguments to be passed via stack (in onstack[]), and also remember arguments to be passed via stack (in onstack[]), and also remember
if we have to align the stack pointer to 16 (onstack[i] == 2). Needs if we have to align the stack pointer to 16 (onstack[i] == 2). Needs
@ -1364,9 +1368,6 @@ void gfunc_call(int nb_args)
tcc_free(onstack); tcc_free(onstack);
/* XXX This should be superfluous. */
save_regs(0); /* save used temporary registers */
/* then, we prepare register passing arguments. /* then, we prepare register passing arguments.
Note that we cannot set RDX and RCX in this loop because gv() Note that we cannot set RDX and RCX in this loop because gv()
may break these temporary registers. Let's use R10 and R11 may break these temporary registers. Let's use R10 and R11
@ -1416,12 +1417,6 @@ void gfunc_call(int nb_args)
assert(gen_reg == 0); assert(gen_reg == 0);
assert(sse_reg == 0); assert(sse_reg == 0);
/* We shouldn't have many operands on the stack anymore, but the
call address itself is still there, and it might be in %eax
(or edx/ecx) currently, which the below writes would clobber.
So evict all remaining operands here. */
save_regs(0);
/* Copy R10 and R11 into RDX and RCX, respectively */ /* Copy R10 and R11 into RDX and RCX, respectively */
if (nb_reg_args > 2) { if (nb_reg_args > 2) {
o(0xd2894c); /* mov %r10, %rdx */ o(0xd2894c); /* mov %r10, %rdx */