mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
feat(arm): add TLS Local Exec code generation and linker relocations
This commit is contained in:
parent
8abaf10ab5
commit
841ce0da03
24
arm-gen.c
24
arm-gen.c
@ -572,7 +572,7 @@ static void load_value(SValue *sv, int r)
|
|||||||
void load(int r, SValue *sv)
|
void load(int r, SValue *sv)
|
||||||
{
|
{
|
||||||
int v, ft, fc, fr, sign;
|
int v, ft, fc, fr, sign;
|
||||||
uint32_t op;
|
uint32_t op, base;
|
||||||
SValue v1;
|
SValue v1;
|
||||||
|
|
||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
@ -588,7 +588,15 @@ void load(int r, SValue *sv)
|
|||||||
|
|
||||||
v = fr & VT_VALMASK;
|
v = fr & VT_VALMASK;
|
||||||
if (fr & VT_LVAL) {
|
if (fr & VT_LVAL) {
|
||||||
uint32_t base = 0xB; // fp
|
if ((fr & VT_SYM) && sv->sym->type.t & VT_TLS) {
|
||||||
|
uint32_t op;
|
||||||
|
o(0xee1d0fe0); /* mrc p15, 0, lr, c13, c0, 3 */
|
||||||
|
op = 0xe510e000; /* ldr r, [lr, #0] */
|
||||||
|
greloca(cur_text_section, sv->sym, ind, R_ARM_TLS_LE32, 0);
|
||||||
|
o(op | (intr(r) << 12));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base = 0xB; // fp
|
||||||
if(v == VT_LLOCAL) {
|
if(v == VT_LLOCAL) {
|
||||||
v1.type.t = VT_PTR;
|
v1.type.t = VT_PTR;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
@ -703,7 +711,7 @@ void store(int r, SValue *sv)
|
|||||||
{
|
{
|
||||||
SValue v1;
|
SValue v1;
|
||||||
int v, ft, fc, fr, sign;
|
int v, ft, fc, fr, sign;
|
||||||
uint32_t op;
|
uint32_t op, base;
|
||||||
|
|
||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
ft = sv->type.t;
|
ft = sv->type.t;
|
||||||
@ -718,7 +726,15 @@ void store(int r, SValue *sv)
|
|||||||
|
|
||||||
v = fr & VT_VALMASK;
|
v = fr & VT_VALMASK;
|
||||||
if (fr & VT_LVAL || fr == VT_LOCAL) {
|
if (fr & VT_LVAL || fr == VT_LOCAL) {
|
||||||
uint32_t base = 0xb; /* fp */
|
if ((fr & VT_SYM) && sv->sym->type.t & VT_TLS) {
|
||||||
|
uint32_t op;
|
||||||
|
o(0xee1d0fe0); /* mrc p15, 0, lr, c13, c0, 3 */
|
||||||
|
op = 0xe500e000; /* str r, [lr, #0] */
|
||||||
|
greloca(cur_text_section, sv->sym, ind, R_ARM_TLS_LE32, 0);
|
||||||
|
o(op | (intr(r) << 12));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base = 0xb; /* fp */
|
||||||
if(v < VT_CONST) {
|
if(v < VT_CONST) {
|
||||||
base=intr(v);
|
base=intr(v);
|
||||||
v=VT_LOCAL;
|
v=VT_LOCAL;
|
||||||
|
|||||||
32
arm-link.c
32
arm-link.c
@ -44,6 +44,7 @@ ST_FUNC int code_reloc (int reloc_type)
|
|||||||
case R_ARM_TARGET1:
|
case R_ARM_TARGET1:
|
||||||
case R_ARM_MOVT_PREL:
|
case R_ARM_MOVT_PREL:
|
||||||
case R_ARM_MOVW_PREL_NC:
|
case R_ARM_MOVW_PREL_NC:
|
||||||
|
case R_ARM_TLS_LE32:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
@ -70,6 +71,7 @@ ST_FUNC int gotplt_entry_type (int reloc_type)
|
|||||||
case R_ARM_COPY:
|
case R_ARM_COPY:
|
||||||
case R_ARM_GLOB_DAT:
|
case R_ARM_GLOB_DAT:
|
||||||
case R_ARM_JUMP_SLOT:
|
case R_ARM_JUMP_SLOT:
|
||||||
|
case R_ARM_TLS_LE32:
|
||||||
return NO_GOTPLT_ENTRY;
|
return NO_GOTPLT_ENTRY;
|
||||||
|
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
@ -430,6 +432,36 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
|
|||||||
#endif
|
#endif
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
return;
|
return;
|
||||||
|
case R_ARM_TLS_LE32:
|
||||||
|
{
|
||||||
|
ElfW(Sym) *sym;
|
||||||
|
Section *sec;
|
||||||
|
int32_t x;
|
||||||
|
addr_t tls_start = 0, tls_end = 0, tls_align = 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
|
sec = s1->sections[sym->st_shndx];
|
||||||
|
|
||||||
|
for (i = 1; i < s1->nb_sections; i++) {
|
||||||
|
Section *s = s1->sections[i];
|
||||||
|
if (s->sh_flags & SHF_TLS && s->sh_size) {
|
||||||
|
if (!tls_start || s->sh_addr < tls_start)
|
||||||
|
tls_start = s->sh_addr;
|
||||||
|
if (s->sh_addr + s->sh_size > tls_end)
|
||||||
|
tls_end = s->sh_addr + s->sh_size;
|
||||||
|
if (s->sh_addralign > tls_align)
|
||||||
|
tls_align = s->sh_addralign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tls_end > tls_start) {
|
||||||
|
x = val - tls_start + 8;
|
||||||
|
} else {
|
||||||
|
x = val - sec->sh_addr - sec->data_offset + 8;
|
||||||
|
}
|
||||||
|
add32le(ptr, x);
|
||||||
|
}
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
|
fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
|
||||||
type, (unsigned)addr, ptr, (unsigned)val);
|
type, (unsigned)addr, ptr, (unsigned)val);
|
||||||
|
|||||||
@ -19,8 +19,8 @@ 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
|
||||||
endif
|
endif
|
||||||
ifeq (,$(filter x86_64 riscv64 arm64,$(ARCH)))
|
ifeq (,$(filter x86_64 riscv64 arm64 arm,$(ARCH)))
|
||||||
SKIP += 144_tls.test # TLS only implemented on x86_64 so far
|
SKIP += 144_tls.test # TLS only implemented on these architectures so far
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_backtrace),no)
|
ifeq ($(CONFIG_backtrace),no)
|
||||||
SKIP += 113_btdll.test
|
SKIP += 113_btdll.test
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user