Unified · Split
| @@ -572,7 +572,7 @@ static void load_value(SValue *sv, int r) · 571 unmodified lines | ||
| 572 | 572 | void load(int r, SValue *sv) |
| 573 | 573 | { |
| 574 | 574 | int v, ft, fc, fr, sign; |
| 575 | − uint32_t op; | |
| 575 | + uint32_t op, base; | |
| 576 | 576 | SValue v1; |
| 577 | 577 | |
| 578 | 578 | fr = sv->r; |
| @@ -588,7 +588,15 @@ void load(int r, SValue *sv) · 9 unmodified lines | ||
| 588 | 588 | |
| 589 | 589 | v = fr & VT_VALMASK; |
| 590 | 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 | 600 | if(v == VT_LLOCAL) { |
| 593 | 601 | v1.type.t = VT_PTR; |
| 594 | 602 | v1.r = VT_LOCAL | VT_LVAL; |
| @@ -703,7 +711,7 @@ void store(int r, SValue *sv) · 108 unmodified lines | ||
| 703 | 711 | { |
| 704 | 712 | SValue v1; |
| 705 | 713 | int v, ft, fc, fr, sign; |
| 706 | − uint32_t op; | |
| 714 | + uint32_t op, base; | |
| 707 | 715 | |
| 708 | 716 | fr = sv->r; |
| 709 | 717 | ft = sv->type.t; |
| @@ -718,7 +726,15 @@ void store(int r, SValue *sv) · 8 unmodified lines | ||
| 718 | 726 | |
| 719 | 727 | v = fr & VT_VALMASK; |
| 720 | 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 | 738 | if(v < VT_CONST) { |
| 723 | 739 | base=intr(v); |
| 724 | 740 | v=VT_LOCAL; |
| @@ -44,6 +44,7 @@ ST_FUNC int code_reloc (int reloc_type) · 43 unmodified lines | ||
| 44 | 44 | case R_ARM_TARGET1: |
| 45 | 45 | case R_ARM_MOVT_PREL: |
| 46 | 46 | case R_ARM_MOVW_PREL_NC: |
| 47 | + case R_ARM_TLS_LE32: | |
| 47 | 48 | return 0; |
| 48 | 49 | |
| 49 | 50 | case R_ARM_PC24: |
| @@ -70,6 +71,7 @@ ST_FUNC int gotplt_entry_type (int reloc_type) · 20 unmodified lines | ||
| 70 | 71 | case R_ARM_COPY: |
| 71 | 72 | case R_ARM_GLOB_DAT: |
| 72 | 73 | case R_ARM_JUMP_SLOT: |
| 74 | + case R_ARM_TLS_LE32: | |
| 73 | 75 | return NO_GOTPLT_ENTRY; |
| 74 | 76 | |
| 75 | 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 | 432 | #endif |
| 431 | 433 | /* do nothing */ |
| 432 | 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 | 465 | default: |
| 434 | 466 | fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n", |
| 435 | 467 | type, (unsigned)addr, ptr, (unsigned)val); |
| @@ -19,8 +19,8 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) · 18 unmodified lines | ||
| 19 | 19 | SKIP += 85_asm-outside-function.test # x86 asm |
| 20 | 20 | SKIP += 127_asm_goto.test # hardcodes x86 asm |
| 21 | 21 | endif |
| 22 | −ifeq (,$(filter x86_64 riscv64 arm64,$(ARCH))) | |
| 23 | − SKIP += 144_tls.test # TLS only implemented on x86_64 so far | |
| 22 | +ifeq (,$(filter x86_64 riscv64 arm64 arm,$(ARCH))) | |
| 23 | + SKIP += 144_tls.test # TLS only implemented on these architectures so far | |
| 24 | 24 | endif |
| 25 | 25 | ifeq ($(CONFIG_backtrace),no) |
| 26 | 26 | SKIP += 113_btdll.test |