Unified · Split
| @@ -572,7 +572,7 @@ static void load_value(SValue *sv, int r) · 571 unmodified lines | |||
| 572 | void load(int r, SValue *sv) | 572 | void load(int r, SValue *sv) |
| 573 | { | 573 | { |
| 574 | int v, ft, fc, fr, sign; | 574 | int v, ft, fc, fr, sign; |
| 575 | uint32_t op; | 575 | uint32_t op, base; |
| 576 | SValue v1; | 576 | SValue v1; |
| 577 | 577 | ||
| 578 | fr = sv->r; | 578 | fr = sv->r; |
| @@ -588,7 +588,15 @@ void load(int r, SValue *sv) · 9 unmodified lines | |||
| 588 | 588 | ||
| 589 | v = fr & VT_VALMASK; | 589 | v = fr & VT_VALMASK; |
| 590 | if (fr & VT_LVAL) { | 590 | if (fr & VT_LVAL) { |
| 591 | uint32_t base = 0xB; // fp | 591 | if ((fr & VT_SYM) && sv->sym->type.t & VT_TLS) { |
| 592 | uint32_t op; | ||
| 593 | o(0xee1d0fe0); /* mrc p15, 0, lr, c13, c0, 3 */ | ||
| 594 | op = 0xe510e000; /* ldr r, [lr, #0] */ | ||
| 595 | greloca(cur_text_section, sv->sym, ind, R_ARM_TLS_LE32, 0); | ||
| 596 | o(op | (intr(r) << 12)); | ||
| 597 | return; | ||
| 598 | } | ||
| 599 | base = 0xB; // fp | ||
| 592 | if(v == VT_LLOCAL) { | 600 | if(v == VT_LLOCAL) { |
| 593 | v1.type.t = VT_PTR; | 601 | v1.type.t = VT_PTR; |
| 594 | v1.r = VT_LOCAL | VT_LVAL; | 602 | v1.r = VT_LOCAL | VT_LVAL; |
| @@ -703,7 +711,7 @@ void store(int r, SValue *sv) · 108 unmodified lines | |||
| 703 | { | 711 | { |
| 704 | SValue v1; | 712 | SValue v1; |
| 705 | int v, ft, fc, fr, sign; | 713 | int v, ft, fc, fr, sign; |
| 706 | uint32_t op; | 714 | uint32_t op, base; |
| 707 | 715 | ||
| 708 | fr = sv->r; | 716 | fr = sv->r; |
| 709 | ft = sv->type.t; | 717 | ft = sv->type.t; |
| @@ -718,7 +726,15 @@ void store(int r, SValue *sv) · 8 unmodified lines | |||
| 718 | 726 | ||
| 719 | v = fr & VT_VALMASK; | 727 | v = fr & VT_VALMASK; |
| 720 | if (fr & VT_LVAL || fr == VT_LOCAL) { | 728 | if (fr & VT_LVAL || fr == VT_LOCAL) { |
| 721 | uint32_t base = 0xb; /* fp */ | 729 | if ((fr & VT_SYM) && sv->sym->type.t & VT_TLS) { |
| 730 | uint32_t op; | ||
| 731 | o(0xee1d0fe0); /* mrc p15, 0, lr, c13, c0, 3 */ | ||
| 732 | op = 0xe500e000; /* str r, [lr, #0] */ | ||
| 733 | greloca(cur_text_section, sv->sym, ind, R_ARM_TLS_LE32, 0); | ||
| 734 | o(op | (intr(r) << 12)); | ||
| 735 | return; | ||
| 736 | } | ||
| 737 | base = 0xb; /* fp */ | ||
| 722 | if(v < VT_CONST) { | 738 | if(v < VT_CONST) { |
| 723 | base=intr(v); | 739 | base=intr(v); |
| 724 | v=VT_LOCAL; | 740 | v=VT_LOCAL; |
| @@ -44,6 +44,7 @@ ST_FUNC int code_reloc (int reloc_type) · 43 unmodified lines | |||
| 44 | case R_ARM_TARGET1: | 44 | case R_ARM_TARGET1: |
| 45 | case R_ARM_MOVT_PREL: | 45 | case R_ARM_MOVT_PREL: |
| 46 | case R_ARM_MOVW_PREL_NC: | 46 | case R_ARM_MOVW_PREL_NC: |
| 47 | case R_ARM_TLS_LE32: | ||
| 47 | return 0; | 48 | return 0; |
| 48 | 49 | ||
| 49 | case R_ARM_PC24: | 50 | case R_ARM_PC24: |
| @@ -70,6 +71,7 @@ ST_FUNC int gotplt_entry_type (int reloc_type) · 20 unmodified lines | |||
| 70 | case R_ARM_COPY: | 71 | case R_ARM_COPY: |
| 71 | case R_ARM_GLOB_DAT: | 72 | case R_ARM_GLOB_DAT: |
| 72 | case R_ARM_JUMP_SLOT: | 73 | case R_ARM_JUMP_SLOT: |
| 74 | case R_ARM_TLS_LE32: | ||
| 73 | return NO_GOTPLT_ENTRY; | 75 | return NO_GOTPLT_ENTRY; |
| 74 | 76 | ||
| 75 | case R_ARM_PC24: | 77 | case R_ARM_PC24: |
| @@ -430,6 +432,36 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 354 unmodified lines | |||
| 430 | #endif | 432 | #endif |
| 431 | /* do nothing */ | 433 | /* do nothing */ |
| 432 | return; | 434 | return; |
| 435 | case R_ARM_TLS_LE32: | ||
| 436 | { | ||
| 437 | ElfW(Sym) *sym; | ||
| 438 | Section *sec; | ||
| 439 | int32_t x; | ||
| 440 | addr_t tls_start = 0, tls_end = 0, tls_align = 1; | ||
| 441 | int i; | ||
| 442 | |||
| 443 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | ||
| 444 | sec = s1->sections[sym->st_shndx]; | ||
| 445 | |||
| 446 | for (i = 1; i < s1->nb_sections; i++) { | ||
| 447 | Section *s = s1->sections[i]; | ||
| 448 | if (s->sh_flags & SHF_TLS && s->sh_size) { | ||
| 449 | if (!tls_start || s->sh_addr < tls_start) | ||
| 450 | tls_start = s->sh_addr; | ||
| 451 | if (s->sh_addr + s->sh_size > tls_end) | ||
| 452 | tls_end = s->sh_addr + s->sh_size; | ||
| 453 | if (s->sh_addralign > tls_align) | ||
| 454 | tls_align = s->sh_addralign; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | if (tls_end > tls_start) { | ||
| 458 | x = val - tls_start + 8; | ||
| 459 | } else { | ||
| 460 | x = val - sec->sh_addr - sec->data_offset + 8; | ||
| 461 | } | ||
| 462 | add32le(ptr, x); | ||
| 463 | } | ||
| 464 | return; | ||
| 433 | default: | 465 | default: |
| 434 | fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n", | 466 | fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n", |
| 435 | type, (unsigned)addr, ptr, (unsigned)val); | 467 | type, (unsigned)addr, ptr, (unsigned)val); |
| @@ -19,8 +19,8 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) · 18 unmodified lines | |||
| 19 | SKIP += 85_asm-outside-function.test # x86 asm | 19 | SKIP += 85_asm-outside-function.test # x86 asm |
| 20 | SKIP += 127_asm_goto.test # hardcodes x86 asm | 20 | SKIP += 127_asm_goto.test # hardcodes x86 asm |
| 21 | endif | 21 | endif |
| 22 | ifeq (,$(filter x86_64 riscv64 arm64,$(ARCH))) | 22 | ifeq (,$(filter x86_64 riscv64 arm64 arm,$(ARCH))) |
| 23 | SKIP += 144_tls.test # TLS only implemented on x86_64 so far | 23 | SKIP += 144_tls.test # TLS only implemented on these architectures so far |
| 24 | endif | 24 | endif |
| 25 | ifeq ($(CONFIG_backtrace),no) | 25 | ifeq ($(CONFIG_backtrace),no) |
| 26 | SKIP += 113_btdll.test | 26 | SKIP += 113_btdll.test |