History

feat(arm64): add TLS Local Exec code generation and linker relocations

Meng Zhuo committed 6 months ago

Commit 8abaf101 parent 11f5c6e3 files · +75 −1Browse files

Unified · Split

3 files
  1. arm64-gen.c +49 −0
  2. arm64-link.c +25 −0
  3. tests/tests2/Makefile +1 −1
arm64-gen.c+49−0
@@ -552,6 +552,23 @@ ST_FUNC void load(int r, SValue *sv) · 551 unmodified lines
552 }552 }
553 553
554 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {554 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
555 if (sv->sym->type.t & VT_TLS) {
556 o(0xd53bd05e); /* mrs x30, tpidr_el0 */
557 greloca(cur_text_section, sv->sym, ind,
558 R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
559 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
560 ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0, lsl #12 */
561 greloca(cur_text_section, sv->sym, ind,
562 R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
563 o(ARM64_ADD_IMM | ARM64_SF(1) |
564 ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0 */
565 if (IS_FREG(r))
566 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, svcoff);
567 else
568 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt),
569 intr(r), 30, svcoff);
570 return;
571 }
555 arm64_sym(30, sv->sym, // use x30 for address572 arm64_sym(30, sv->sym, // use x30 for address
556 arm64_check_offset(0, arm64_type_size(svtt), svcoff));573 arm64_check_offset(0, arm64_type_size(svtt), svcoff));
557 if (IS_FREG(r))574 if (IS_FREG(r))
@@ -645,6 +662,22 @@ ST_FUNC void store(int r, SValue *sv) · 87 unmodified lines
645 if (svr == (VT_CONST | VT_LVAL)) {662 if (svr == (VT_CONST | VT_LVAL)) {
646 uint64_t i = sv->c.i;663 uint64_t i = sv->c.i;
647 664
665 if (sv->sym && (sv->sym->type.t & VT_TLS)) {
666 o(0xd53bd05e);
667 greloca(cur_text_section, sv->sym, ind,
668 R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
669 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
670 ARM64_RN(30) | ARM64_RD(30));
671 greloca(cur_text_section, sv->sym, ind,
672 R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
673 o(ARM64_ADD_IMM | ARM64_SF(1) |
674 ARM64_RN(30) | ARM64_RD(30));
675 if (IS_FREG(r))
676 arm64_strv(arm64_type_size(svtt), fltr(r), 30, i);
677 else
678 arm64_strx(arm64_type_size(svtt), intr(r), 30, i);
679 return;
680 }
648 if (sv->sym)681 if (sv->sym)
649 arm64_sym(30, sv->sym, // use x30 for address682 arm64_sym(30, sv->sym, // use x30 for address
650 arm64_check_offset(0, arm64_type_size(svtt), i));683 arm64_check_offset(0, arm64_type_size(svtt), i));
@@ -668,6 +701,22 @@ ST_FUNC void store(int r, SValue *sv) · 17 unmodified lines
668 }701 }
669 702
670 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {703 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
704 if (sv->sym->type.t & VT_TLS) {
705 o(0xd53bd05e); /* mrs x30, tpidr_el0 */
706 greloca(cur_text_section, sv->sym, ind,
707 R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
708 o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
709 ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0, lsl #12 */
710 greloca(cur_text_section, sv->sym, ind,
711 R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
712 o(ARM64_ADD_IMM | ARM64_SF(1) |
713 ARM64_RN(30) | ARM64_RD(30)); /* add x30, x30, #0 */
714 if (IS_FREG(r))
715 arm64_strv(arm64_type_size(svtt), fltr(r), 30, svcoff);
716 else
717 arm64_strx(arm64_type_size(svtt), intr(r), 30, svcoff);
718 return;
719 }
671 arm64_sym(30, sv->sym, // use x30 for address720 arm64_sym(30, sv->sym, // use x30 for address
672 arm64_check_offset(0, arm64_type_size(svtt), svcoff));721 arm64_check_offset(0, arm64_type_size(svtt), svcoff));
673 if (IS_FREG(r))722 if (IS_FREG(r))
arm64-link.c+25−0
@@ -43,6 +43,8 @@ ST_FUNC int code_reloc (int reloc_type) · 42 unmodified lines
43 case R_AARCH64_LDST32_ABS_LO12_NC:43 case R_AARCH64_LDST32_ABS_LO12_NC:
44 case R_AARCH64_LDST16_ABS_LO12_NC:44 case R_AARCH64_LDST16_ABS_LO12_NC:
45 case R_AARCH64_LDST8_ABS_LO12_NC:45 case R_AARCH64_LDST8_ABS_LO12_NC:
46 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
47 case R_AARCH64_TLSLE_ADD_TPREL_LO12:
46 case R_AARCH64_GLOB_DAT:48 case R_AARCH64_GLOB_DAT:
47 case R_AARCH64_COPY:49 case R_AARCH64_COPY:
48 return 0;50 return 0;
@@ -80,6 +82,8 @@ ST_FUNC int gotplt_entry_type (int reloc_type) · 31 unmodified lines
80 case R_AARCH64_COPY:82 case R_AARCH64_COPY:
81 case R_AARCH64_CONDBR19:83 case R_AARCH64_CONDBR19:
82 case R_AARCH64_TSTBR14:84 case R_AARCH64_TSTBR14:
85 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
86 case R_AARCH64_TLSLE_ADD_TPREL_LO12:
83 return NO_GOTPLT_ENTRY;87 return NO_GOTPLT_ENTRY;
84 88
85 case R_AARCH64_ABS32:89 case R_AARCH64_ABS32:
@@ -365,6 +369,27 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 279 unmodified lines
365#endif369#endif
366 write64le(ptr, val - rel->r_addend);370 write64le(ptr, val - rel->r_addend);
367 return;371 return;
372 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
373 case R_AARCH64_TLSLE_ADD_TPREL_LO12: {
374 addr_t tls_start = 0;
375 int i;
376 for (i = 1; i < s1->nb_sections; i++) {
377 Section *s = s1->sections[i];
378 if (s->sh_flags & SHF_TLS && s->sh_size) {
379 if (!tls_start || s->sh_addr < tls_start)
380 tls_start = s->sh_addr;
381 }
382 }
383 /* glibc arm64: tp points to tcbhead_t (DTV), TLS data starts after it */
384 int64_t tp_offset = val - tls_start + 16;
385 int64_t imm;
386 if (type == R_AARCH64_TLSLE_ADD_TPREL_HI12)
387 imm = (tp_offset >> 12) & 0xfff;
388 else
389 imm = tp_offset & 0xfff;
390 write32le(ptr, ((read32le(ptr) & 0xffc003ff) | (imm << 10)));
391 return;
392 }
368 case R_AARCH64_RELATIVE:393 case R_AARCH64_RELATIVE:
369#ifdef TCC_TARGET_PE394#ifdef TCC_TARGET_PE
370 add32le(ptr, val - s1->pe_imagebase);395 add32le(ptr, val - s1->pe_imagebase);
tests/tests2/Makefile+1−1
@@ -19,7 +19,7 @@ ifeq (,$(filter i386 x86_64,$(ARCH))) · 18 unmodified lines
19 SKIP += 85_asm-outside-function.test # x86 asm19 SKIP += 85_asm-outside-function.test # x86 asm
20 SKIP += 127_asm_goto.test # hardcodes x86 asm20 SKIP += 127_asm_goto.test # hardcodes x86 asm
21endif21endif
22ifeq (,$(filter x86_64 riscv64,$(ARCH)))22ifeq (,$(filter x86_64 riscv64 arm64,$(ARCH)))
23 SKIP += 144_tls.test # TLS only implemented on x86_64 so far23 SKIP += 144_tls.test # TLS only implemented on x86_64 so far
24endif24endif
25ifeq ($(CONFIG_backtrace),no)25ifeq ($(CONFIG_backtrace),no)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t