mirror of
git://repo.or.cz/tinycc.git
synced 2026-11-04 21:26:36 +08:00
tls: fix local-exec addresses and external symbols
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
Preserve symbolic offsets when materializing i386 TLS addresses, generate ARM64 TLS addresses from the thread pointer, and carry RISC-V addends on both halves of the TPREL relocation pair. Keep undefined ELF TLS symbols typed as STT_TLS so objects produced by TCC can be linked by the system linker. Extend the TLS regression coverage for narrow signed and unsigned accesses, address-taking, runtime indexing, thread isolation, large RISC-V offsets, unsupported runtimes, and external TLS definitions.
This commit is contained in:
parent
04206d2903
commit
97a6d8c75f
69
arm64-gen.c
69
arm64-gen.c
@ -468,20 +468,8 @@ static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm64_sym(int r, Sym *sym, unsigned long addend)
|
static void arm64_add_offset(int r, unsigned long addend)
|
||||||
{
|
{
|
||||||
#ifdef TCC_TARGET_PE
|
|
||||||
/* PE links symbol addresses directly; there is no ELF-style GOT here. */
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, 0);
|
|
||||||
o(ARM64_ADRP | r); // adrp xr, #sym
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, 0);
|
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym
|
|
||||||
#else
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
|
||||||
o(ARM64_ADRP | r); // adrp xr, #sym
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
|
||||||
o(ARM64_LDR_X | ARM64_RN(r) | r); // ld xr,[xr, #sym]
|
|
||||||
#endif
|
|
||||||
if (addend) {
|
if (addend) {
|
||||||
// add xr, xr, #addend
|
// add xr, xr, #addend
|
||||||
if (addend & 0xffful)
|
if (addend & 0xffful)
|
||||||
@ -504,17 +492,35 @@ static void arm64_sym(int r, Sym *sym, unsigned long addend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arm64_sym(int r, Sym *sym, unsigned long addend)
|
||||||
|
{
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
/* PE links symbol addresses directly; there is no ELF-style GOT here. */
|
||||||
|
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, 0);
|
||||||
|
o(ARM64_ADRP | r); // adrp xr, #sym
|
||||||
|
greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, 0);
|
||||||
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym
|
||||||
|
#else
|
||||||
|
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||||
|
o(ARM64_ADRP | r); // adrp xr, #sym
|
||||||
|
greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||||
|
o(ARM64_LDR_X | ARM64_RN(r) | r); // ld xr,[xr, #sym]
|
||||||
|
#endif
|
||||||
|
arm64_add_offset(r, addend);
|
||||||
|
}
|
||||||
|
|
||||||
static void arm64_load_cmp(int r, SValue *sv);
|
static void arm64_load_cmp(int r, SValue *sv);
|
||||||
|
|
||||||
static void arm64_tls_x30(SValue *sv)
|
static void arm64_tls_sym(int r, Sym *sym, unsigned long addend)
|
||||||
{
|
{
|
||||||
o(0xd53bd05e); /* mrs x30, tpidr_el0 */
|
o(0xd53bd040 | r); /* mrs xr, tpidr_el0 */
|
||||||
greloca(cur_text_section, sv->sym, ind, R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
|
greloca(cur_text_section, sym, ind, R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
|
||||||
/* add x30, x30, #0, lsl #12 */
|
/* add xr, xr, #0, lsl #12 */
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | ARM64_RN(30) | ARM64_RD(30));
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | ARM64_RN(r) | ARM64_RD(r));
|
||||||
greloca(cur_text_section, sv->sym, ind, R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
|
greloca(cur_text_section, sym, ind, R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
|
||||||
/* add x30, x30, #0 */
|
/* add xr, xr, #0 */
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(30) | ARM64_RD(30));
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | ARM64_RD(r));
|
||||||
|
arm64_add_offset(r, addend);
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void load(int r, SValue *sv)
|
ST_FUNC void load(int r, SValue *sv)
|
||||||
@ -537,7 +543,9 @@ ST_FUNC void load(int r, SValue *sv)
|
|||||||
if (svr == (VT_CONST | VT_LVAL)) {
|
if (svr == (VT_CONST | VT_LVAL)) {
|
||||||
uint64_t i = sv->c.i;
|
uint64_t i = sv->c.i;
|
||||||
|
|
||||||
if (sv->sym)
|
if (sv->sym && (sv->sym->type.t & VT_TLS))
|
||||||
|
arm64_tls_sym(30, sv->sym, 0);
|
||||||
|
else if (sv->sym)
|
||||||
arm64_sym(30, sv->sym, // use x30 for address
|
arm64_sym(30, sv->sym, // use x30 for address
|
||||||
arm64_check_offset(0, arm64_type_size(svtt), i));
|
arm64_check_offset(0, arm64_type_size(svtt), i));
|
||||||
else
|
else
|
||||||
@ -564,7 +572,7 @@ ST_FUNC void load(int r, SValue *sv)
|
|||||||
|
|
||||||
if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
|
if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
|
||||||
if (sv->sym->type.t & VT_TLS)
|
if (sv->sym->type.t & VT_TLS)
|
||||||
arm64_tls_x30(sv);
|
arm64_tls_sym(30, sv->sym, 0);
|
||||||
else
|
else
|
||||||
arm64_sym(30, sv->sym, // use x30 for address
|
arm64_sym(30, sv->sym, // use x30 for address
|
||||||
arm64_check_offset(0, arm64_type_size(svtt), svcoff));
|
arm64_check_offset(0, arm64_type_size(svtt), svcoff));
|
||||||
@ -578,6 +586,9 @@ ST_FUNC void load(int r, SValue *sv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (svr == (VT_CONST | VT_SYM)) {
|
if (svr == (VT_CONST | VT_SYM)) {
|
||||||
|
if (sv->sym->type.t & VT_TLS)
|
||||||
|
arm64_tls_sym(intr(r), sv->sym, svcul);
|
||||||
|
else
|
||||||
arm64_sym(intr(r), sv->sym, svcul);
|
arm64_sym(intr(r), sv->sym, svcul);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -659,7 +670,7 @@ ST_FUNC void store(int r, SValue *sv)
|
|||||||
if (svr == (VT_CONST | VT_LVAL)) {
|
if (svr == (VT_CONST | VT_LVAL)) {
|
||||||
uint64_t i = sv->c.i;
|
uint64_t i = sv->c.i;
|
||||||
if (sv->sym && (sv->sym->type.t & VT_TLS))
|
if (sv->sym && (sv->sym->type.t & VT_TLS))
|
||||||
arm64_tls_x30(sv);
|
arm64_tls_sym(30, sv->sym, 0);
|
||||||
else
|
else
|
||||||
if (sv->sym)
|
if (sv->sym)
|
||||||
arm64_sym(30, sv->sym, // use x30 for address
|
arm64_sym(30, sv->sym, // use x30 for address
|
||||||
@ -686,15 +697,7 @@ ST_FUNC void store(int r, SValue *sv)
|
|||||||
|
|
||||||
if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
|
if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
|
||||||
if (sv->sym->type.t & VT_TLS) {
|
if (sv->sym->type.t & VT_TLS) {
|
||||||
o(0xd53bd05e); /* mrs x30, tpidr_el0 */
|
arm64_tls_sym(30, sv->sym, 0);
|
||||||
greloca(cur_text_section, sv->sym, ind,
|
|
||||||
R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
|
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
|
|
||||||
ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0, lsl #12 */
|
|
||||||
greloca(cur_text_section, sv->sym, ind,
|
|
||||||
R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
|
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) |
|
|
||||||
ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0 */
|
|
||||||
if (IS_FREG(r))
|
if (IS_FREG(r))
|
||||||
arm64_strv(arm64_type_size(svtt), fltr(r), 30, svcoff);
|
arm64_strv(arm64_type_size(svtt), fltr(r), 30, svcoff);
|
||||||
else
|
else
|
||||||
|
|||||||
@ -354,7 +354,7 @@ ST_FUNC void load(int r, SValue *sv)
|
|||||||
} else {
|
} else {
|
||||||
if ((fr & VT_SYM) && (sv->sym->type.t & VT_TLS)) {
|
if ((fr & VT_SYM) && (sv->sym->type.t & VT_TLS)) {
|
||||||
oad(0x058b65 | REG_VALUE(r) << 19, 0); /* mov gs:0,r */
|
oad(0x058b65 | REG_VALUE(r) << 19, 0); /* mov gs:0,r */
|
||||||
oad(0xC081 | REG_VALUE(r) << 8, 0); /* add tpoffs,r */
|
oad(0xC081 | REG_VALUE(r) << 8, fc); /* add tpoffs,r */
|
||||||
greloc(cur_text_section, sv->sym, ind - 4, R_386_TLS_LE);
|
greloc(cur_text_section, sv->sym, ind - 4, R_386_TLS_LE);
|
||||||
#if defined CONFIG_TCC_PIC
|
#if defined CONFIG_TCC_PIC
|
||||||
} else if ((fr & (VT_VALMASK|VT_SYM)) == (VT_CONST|VT_SYM)) {
|
} else if ((fr & (VT_VALMASK|VT_SYM)) == (VT_CONST|VT_SYM)) {
|
||||||
|
|||||||
@ -186,10 +186,8 @@ static int load_symofs(int r, SValue *sv, int forstore, int *new_fc)
|
|||||||
R_RISCV_TPREL_HI20, sv->c.i);
|
R_RISCV_TPREL_HI20, sv->c.i);
|
||||||
o(0x37 | (rr << 7)); // lui RR, 0 %tprel_hi(sym)
|
o(0x37 | (rr << 7)); // lui RR, 0 %tprel_hi(sym)
|
||||||
greloca(cur_text_section, sv->sym, ind,
|
greloca(cur_text_section, sv->sym, ind,
|
||||||
R_RISCV_TPREL_LO12_I, 0);
|
R_RISCV_TPREL_LO12_I, sv->c.i);
|
||||||
EI(0x13, 0, rr, rr, 0); // addi RR, RR, 0 %tprel_lo(sym)
|
EI(0x13, 0, rr, rr, 0); // addi RR, RR, 0 %tprel_lo(sym)
|
||||||
if (fc)
|
|
||||||
EI(0x13, 0, rr, rr, fc); // addi RR, RR, fc
|
|
||||||
ER(0x33, 0, rr, rr, 4, 0); // add RR, RR, tp
|
ER(0x33, 0, rr, rr, 4, 0); // add RR, RR, tp
|
||||||
*new_fc = 0;
|
*new_fc = 0;
|
||||||
return rr;
|
return rr;
|
||||||
|
|||||||
4
tccelf.c
4
tccelf.c
@ -205,7 +205,9 @@ ST_FUNC void tccelf_end_file(TCCState *s1)
|
|||||||
#ifndef TCC_TARGET_PE
|
#ifndef TCC_TARGET_PE
|
||||||
if (sym_bind == STB_GLOBAL && s1->output_type == TCC_OUTPUT_OBJ) {
|
if (sym_bind == STB_GLOBAL && s1->output_type == TCC_OUTPUT_OBJ) {
|
||||||
/* undefined symbols with STT_FUNC are confusing gnu ld when
|
/* undefined symbols with STT_FUNC are confusing gnu ld when
|
||||||
linking statically to STT_GNU_IFUNC */
|
linking statically to STT_GNU_IFUNC. Keep TLS typed,
|
||||||
|
otherwise gnu ld rejects non-TLS refs to TLS definitions. */
|
||||||
|
if (sym_type != STT_TLS)
|
||||||
sym_type = STT_NOTYPE;
|
sym_type = STT_NOTYPE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,6 +6,11 @@
|
|||||||
typedef enum { tls_a, tls_b, tls_c } tls_enum_type;
|
typedef enum { tls_a, tls_b, tls_c } tls_enum_type;
|
||||||
typedef struct { int tls_d, tls_e, tls_f; } tls_struct_type;
|
typedef struct { int tls_d, tls_e, tls_f; } tls_struct_type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *init;
|
||||||
|
signed short *element;
|
||||||
|
} tls_address_type;
|
||||||
|
|
||||||
__thread char tls_char = 42;
|
__thread char tls_char = 42;
|
||||||
__thread short tls_short = 43;
|
__thread short tls_short = 43;
|
||||||
__thread int tls_init = 44;
|
__thread int tls_init = 44;
|
||||||
@ -17,6 +22,41 @@ __thread long double tls_long_double = 48.0;
|
|||||||
__thread int *tls_ptr = (int *)49;
|
__thread int *tls_ptr = (int *)49;
|
||||||
__thread tls_enum_type tls_enum = tls_b;
|
__thread tls_enum_type tls_enum = tls_b;
|
||||||
__thread tls_struct_type tls_struct = { 50, 51, 52 };
|
__thread tls_struct_type tls_struct = { 50, 51, 52 };
|
||||||
|
__thread signed char tls_signed_char = -5;
|
||||||
|
__thread unsigned char tls_unsigned_char = 250;
|
||||||
|
__thread signed short tls_signed_short = -1234;
|
||||||
|
__thread unsigned short tls_unsigned_short = 60000;
|
||||||
|
__thread signed short tls_array[4] = { -1000, 2000, -3000, 4000 };
|
||||||
|
|
||||||
|
#if defined __riscv && __riscv_xlen == 64
|
||||||
|
typedef struct {
|
||||||
|
char padding[4096];
|
||||||
|
int value;
|
||||||
|
} tls_large_type;
|
||||||
|
|
||||||
|
__thread tls_large_type tls_large = { { 0 }, 123456 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int check_extra(int changed)
|
||||||
|
{
|
||||||
|
volatile int index = 2;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
return tls_signed_char != -7 || tls_unsigned_char != 42
|
||||||
|
|| tls_signed_short != -2222 || tls_unsigned_short != 12345
|
||||||
|
|| tls_array[1] != 2222 || tls_array[index] != -3333;
|
||||||
|
|
||||||
|
if (tls_signed_char != -5 || tls_unsigned_char != 250
|
||||||
|
|| tls_signed_short != -1234 || tls_unsigned_short != 60000
|
||||||
|
|| tls_array[1] != 2000 || tls_array[index] != -3000)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#if defined __riscv && __riscv_xlen == 64
|
||||||
|
if (tls_large.value != 123456)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int check(void)
|
static int check(void)
|
||||||
{
|
{
|
||||||
@ -40,9 +80,18 @@ static int check(void)
|
|||||||
|
|
||||||
static void *thread_func(void *arg)
|
static void *thread_func(void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
tls_address_type *main_addresses = arg;
|
||||||
|
int *init_address = &tls_init;
|
||||||
|
signed short *element_address = &tls_array[1];
|
||||||
|
volatile int index = 2;
|
||||||
long errors = check();
|
long errors = check();
|
||||||
|
|
||||||
|
if (init_address == main_addresses->init
|
||||||
|
|| element_address == main_addresses->element
|
||||||
|
|| *init_address != 44 || *element_address != 2000
|
||||||
|
|| tls_array[index] != -3000 || check_extra(0))
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
tls_char = 10;
|
tls_char = 10;
|
||||||
tls_short = 20;
|
tls_short = 20;
|
||||||
tls_init = 30;
|
tls_init = 30;
|
||||||
@ -56,6 +105,12 @@ static void *thread_func(void *arg)
|
|||||||
tls_struct.tls_d = 100;
|
tls_struct.tls_d = 100;
|
||||||
tls_struct.tls_e = 110;
|
tls_struct.tls_e = 110;
|
||||||
tls_struct.tls_f = 120;
|
tls_struct.tls_f = 120;
|
||||||
|
*element_address = 2222;
|
||||||
|
tls_array[index] = -3333;
|
||||||
|
tls_signed_char = -7;
|
||||||
|
tls_unsigned_char = 42;
|
||||||
|
tls_signed_short = -2222;
|
||||||
|
tls_unsigned_short = 12345;
|
||||||
|
|
||||||
CHECK(tls_char, "%d", 10);
|
CHECK(tls_char, "%d", 10);
|
||||||
CHECK(tls_short, "%d", 20);
|
CHECK(tls_short, "%d", 20);
|
||||||
@ -71,6 +126,10 @@ static void *thread_func(void *arg)
|
|||||||
CHECK(tls_struct.tls_e, "%d", 110);
|
CHECK(tls_struct.tls_e, "%d", 110);
|
||||||
CHECK(tls_struct.tls_f, "%d", 120);
|
CHECK(tls_struct.tls_f, "%d", 120);
|
||||||
|
|
||||||
|
if (*init_address != 30 || *element_address != 2222
|
||||||
|
|| tls_array[index] != -3333 || check_extra(1))
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
return (void *)errors;
|
return (void *)errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,9 +138,20 @@ int main()
|
|||||||
pthread_t t;
|
pthread_t t;
|
||||||
void *ret;
|
void *ret;
|
||||||
int errors = check();
|
int errors = check();
|
||||||
|
tls_address_type addresses = { &tls_init, &tls_array[1] };
|
||||||
|
|
||||||
pthread_create(&t, NULL, thread_func, NULL);
|
if (*addresses.init != 44 || *addresses.element != 2000
|
||||||
|
|| check_extra(0))
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
|
pthread_create(&t, NULL, thread_func, &addresses);
|
||||||
pthread_join(t, &ret);
|
pthread_join(t, &ret);
|
||||||
|
|
||||||
return (ret ? 1 : 0) | errors | check();
|
errors |= (ret ? 1 : 0) | check();
|
||||||
|
if (*addresses.init != 44 || *addresses.element != 2000
|
||||||
|
|| check_extra(0))
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
|
printf("errors: %d\n", errors);
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,3 +50,4 @@
|
|||||||
50
|
50
|
||||||
51
|
51
|
||||||
52
|
52
|
||||||
|
errors: 0
|
||||||
|
|||||||
2
tests/tests2/146+_tls_extern.c
Normal file
2
tests/tests2/146+_tls_extern.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__thread signed short extern_tls_short = 1234;
|
||||||
|
__thread float extern_tls_float = 1.5f;
|
||||||
22
tests/tests2/146_tls_extern.c
Normal file
22
tests/tests2/146_tls_extern.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern __thread signed short extern_tls_short;
|
||||||
|
extern __thread float extern_tls_float;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
if (extern_tls_short != 1234 || extern_tls_float != 1.5f)
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
|
extern_tls_short = -2222;
|
||||||
|
extern_tls_float = 2.5f;
|
||||||
|
extern_tls_float += 1.0f;
|
||||||
|
|
||||||
|
if (extern_tls_short != -2222 || extern_tls_float != 3.5f)
|
||||||
|
errors = 1;
|
||||||
|
|
||||||
|
printf("extern tls errors: %d\n", errors);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
1
tests/tests2/146_tls_extern.expect
Normal file
1
tests/tests2/146_tls_extern.expect
Normal file
@ -0,0 +1 @@
|
|||||||
|
extern tls errors: 0
|
||||||
@ -15,6 +15,9 @@ endif
|
|||||||
ifeq (,$(filter i386,$(ARCH)))
|
ifeq (,$(filter i386,$(ARCH)))
|
||||||
SKIP += 98_al_ax_extend.test 99_fastcall.test
|
SKIP += 98_al_ax_extend.test 99_fastcall.test
|
||||||
endif
|
endif
|
||||||
|
ifeq (,$(filter x86_64 riscv64 arm64 i386,$(ARCH)))
|
||||||
|
SKIP += 146_tls_extern.test # TLS only implemented on these architectures
|
||||||
|
endif
|
||||||
ifeq (,$(filter i386 x86_64,$(ARCH)))
|
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
|
||||||
@ -39,6 +42,9 @@ endif
|
|||||||
ifeq (-$(findstring gcc,$(CC))-,--)
|
ifeq (-$(findstring gcc,$(CC))-,--)
|
||||||
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
|
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CC_NAME),tcc)
|
||||||
|
SKIP += 146_tls_extern.test # needs an external system linker
|
||||||
|
endif
|
||||||
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
|
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
|
||||||
SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows
|
SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows
|
||||||
endif
|
endif
|
||||||
@ -47,19 +53,22 @@ ifeq (-$(CONFIG_WIN32)-,-yes-)
|
|||||||
SKIP += 114_bound_signal.test # No pthread support
|
SKIP += 114_bound_signal.test # No pthread support
|
||||||
SKIP += 117_builtins.test # win32 port doesn't define __builtins
|
SKIP += 117_builtins.test # win32 port doesn't define __builtins
|
||||||
SKIP += 124_atomic_counter.test # No pthread support
|
SKIP += 124_atomic_counter.test # No pthread support
|
||||||
SKIP += 144_tls.test # No pthread support
|
SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
|
ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
|
||||||
SKIP += 106_versym.test # no pthread_condattr_setpshared
|
SKIP += 106_versym.test # no pthread_condattr_setpshared
|
||||||
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
|
||||||
SKIP += 144_tls.test # No tls support
|
SKIP += 144_tls.test 146_tls_extern.test # No tls support
|
||||||
|
endif
|
||||||
|
ifeq ($(TARGETOS),DragonFly)
|
||||||
|
SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_OSX),yes)
|
ifeq ($(CONFIG_OSX),yes)
|
||||||
SKIP += 144_tls.test # TLS runtime not supported on Mach-O
|
SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported on Mach-O
|
||||||
endif
|
endif
|
||||||
ifeq (-$(ARCH)-,-arm-)
|
ifeq (-$(ARCH)-,-arm-)
|
||||||
SKIP += 144_tls.test # doesn't work currently
|
SKIP += 144_tls.test 146_tls_extern.test # doesn't work currently
|
||||||
endif
|
endif
|
||||||
ifneq (-$(ARCH)-,-arm64-)
|
ifneq (-$(ARCH)-,-arm64-)
|
||||||
SKIP += 138_arm64_encoding.test
|
SKIP += 138_arm64_encoding.test
|
||||||
@ -122,6 +131,15 @@ GEN-ALWAYS =
|
|||||||
144_tls.test: FLAGS += -pthread
|
144_tls.test: FLAGS += -pthread
|
||||||
144_tls.test: NORUN = true
|
144_tls.test: NORUN = true
|
||||||
|
|
||||||
|
# Verify that undefined TLS symbols in TCC objects work with the system linker.
|
||||||
|
146_tls_extern.test: NORUN = true
|
||||||
|
146_tls_extern.test: T1 = \
|
||||||
|
$(TCC) -c $1 -o 146_tls_extern-main.o && \
|
||||||
|
$(TCC) -c $(subst 146,146+,$1) -o 146_tls_extern-def.o && \
|
||||||
|
$(CC) -no-pie -Wl,-z,noexecstack 146_tls_extern-main.o \
|
||||||
|
146_tls_extern-def.o -o $(basename $@).exe && \
|
||||||
|
./$(basename $@).exe
|
||||||
|
|
||||||
112_backtrace.test: FLAGS += -dt -b
|
112_backtrace.test: FLAGS += -dt -b
|
||||||
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
|
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
|
||||||
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \
|
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \
|
||||||
@ -204,4 +222,4 @@ $(sort $(GEN-ALWAYS) $(UPDATE)) : force
|
|||||||
force:
|
force:
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f fred.txt *.output *.exe *.dll *.so *.def $(GEN-ALWAYS)
|
rm -f fred.txt *.output *.o *.exe *.dll *.so *.def $(GEN-ALWAYS)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user