diff options
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/aarch64/dlsym.s | 5 | ||||
-rw-r--r-- | src/ldso/aarch64/start.s | 18 | ||||
-rw-r--r-- | src/ldso/aarch64/tlsdesc.s | 92 |
3 files changed, 115 insertions, 0 deletions
diff --git a/src/ldso/aarch64/dlsym.s b/src/ldso/aarch64/dlsym.s new file mode 100644 index 00000000..be2dce52 --- /dev/null +++ b/src/ldso/aarch64/dlsym.s @@ -0,0 +1,5 @@ +.global dlsym +.type dlsym,%function +dlsym: + mov x2,x30 + b __dlsym diff --git a/src/ldso/aarch64/start.s b/src/ldso/aarch64/start.s new file mode 100644 index 00000000..41d1d1e2 --- /dev/null +++ b/src/ldso/aarch64/start.s @@ -0,0 +1,18 @@ +.global _dlstart +_dlstart: + ldr x0,[sp] + add x1,sp,#8 + bl __dynlink + mov x1,sp + ldr x2,[x1],#8 +1: sub x2,x2,1 + ldr x3,[x1],#8 + cmn x3,#1 + b.eq 1b + add x2,x2,1 + str x3,[x1,#-8]! + str x2,[x1,#-8]! + mov sp,x1 + mov x1,x0 + mov x0,#0 + blr x1 diff --git a/src/ldso/aarch64/tlsdesc.s b/src/ldso/aarch64/tlsdesc.s new file mode 100644 index 00000000..32064bd7 --- /dev/null +++ b/src/ldso/aarch64/tlsdesc.s @@ -0,0 +1,92 @@ +// long __tlsdesc_static(long *a) +// { +// return a[1]; +// } +.global __tlsdesc_static +.type __tlsdesc_static,@function +__tlsdesc_static: + ldr x0,[x0,#8] + ret + +// long __tlsdesc_dynamic(long *a) +// { +// struct {size_t modidx,off;} *p = (void*)a[1]; +// size_t *dtv = *(size_t**)(tp + 16 - 8); +// if (p->modidx <= dtv[0]) +// return dtv[p->modidx] + p->off - tp; +// return __tls_get_addr(p) - tp; +// } +.global __tlsdesc_dynamic +.type __tlsdesc_dynamic,@function +__tlsdesc_dynamic: + stp x1,x2,[sp,#-32]! + stp x3,x4,[sp,#16] + mrs x1,tpidr_el0 // tp + ldr x0,[x0,#8] // p + ldr x2,[x0] // p->modidx + add x3,x1,#8 + ldr x3,[x3] // dtv + ldr x4,[x3] // dtv[0] + cmp x2,x4 + b.hi 1f + ldr x2,[x3,x2,lsl #3] // dtv[p->modidx] + ldr x0,[x0,#8] // p->off + add x0,x0,x2 +2: sub x0,x0,x1 + ldp x3,x4,[sp,#16] + ldp x1,x2,[sp],#32 + ret + + // save all registers __tls_get_addr may clobber + // ugly because addr offset must be in [-512,509] +1: stp x29,x30,[sp,#-160]! + stp x5,x6,[sp,#16] + stp x7,x8,[sp,#32] + stp x9,x10,[sp,#48] + stp x11,x12,[sp,#64] + stp x13,x14,[sp,#80] + stp x15,x16,[sp,#96] + stp x17,x18,[sp,#112] + stp q0,q1,[sp,#128] + stp q2,q3,[sp,#-480]! + stp q4,q5,[sp,#32] + stp q6,q7,[sp,#64] + stp q8,q9,[sp,#96] + stp q10,q11,[sp,#128] + stp q12,q13,[sp,#160] + stp q14,q15,[sp,#192] + stp q16,q17,[sp,#224] + stp q18,q19,[sp,#256] + stp q20,q21,[sp,#288] + stp q22,q23,[sp,#320] + stp q24,q25,[sp,#352] + stp q26,q27,[sp,#384] + stp q28,q29,[sp,#416] + stp q30,q31,[sp,#448] + bl __tls_get_addr + mrs x1,tpidr_el0 + ldp q4,q5,[sp,#32] + ldp q6,q7,[sp,#64] + ldp q8,q9,[sp,#96] + ldp q10,q11,[sp,#128] + ldp q12,q13,[sp,#160] + ldp q14,q15,[sp,#192] + ldp q16,q17,[sp,#224] + ldp q18,q19,[sp,#256] + ldp q20,q21,[sp,#288] + ldp q22,q23,[sp,#320] + ldp q24,q25,[sp,#352] + ldp q26,q27,[sp,#384] + ldp q28,q29,[sp,#416] + ldp q30,q31,[sp,#448] + ldp q2,q3,[sp],#480 + ldp x5,x6,[sp,#16] + ldp x7,x8,[sp,#32] + ldp x9,x10,[sp,#48] + ldp x11,x12,[sp,#64] + ldp x13,x14,[sp,#80] + ldp x15,x16,[sp,#96] + ldp x17,x18,[sp,#112] + ldp q0,q1,[sp,#128] + ldp x29,x30,[sp],#160 + b 2b |