Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so/arch/aarch64 Various fixes / changes from ...



details:   https://anonhg.NetBSD.org/src/rev/2d24e8fd5925
branches:  trunk
changeset: 829516:2d24e8fd5925
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Feb 04 21:49:51 2018 +0000

description:
Various fixes / changes from Ryo Shimizu / Toru Nishimura to make this
work.

_rtld_call_ifunc copied from other rela platforms by me - not tested in
any way.

diffstat:

 libexec/ld.elf_so/arch/aarch64/mdreloc.c    |  98 +++++++++++++++++++---------
 libexec/ld.elf_so/arch/aarch64/rtld_start.S |  85 ++++++++++++++----------
 2 files changed, 116 insertions(+), 67 deletions(-)

diffs (truncated from 316 to 300 lines):

diff -r 4295dff9fc00 -r 2d24e8fd5925 libexec/ld.elf_so/arch/aarch64/mdreloc.c
--- a/libexec/ld.elf_so/arch/aarch64/mdreloc.c  Sun Feb 04 20:38:41 2018 +0000
+++ b/libexec/ld.elf_so/arch/aarch64/mdreloc.c  Sun Feb 04 21:49:51 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.6 2017/08/28 06:59:25 nisimura Exp $ */
+/* $NetBSD: mdreloc.c,v 1.7 2018/02/04 21:49:51 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.6 2017/08/28 06:59:25 nisimura Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.7 2018/02/04 21:49:51 skrll Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -43,6 +43,7 @@
 void _rtld_bind_start(void);
 void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
 Elf_Addr _rtld_bind(const Obj_Entry *, Elf_Word);
+void *_rtld_tlsdesc(void *);
 
 /*
  * AARCH64 PLT looks like this;
@@ -81,23 +82,23 @@
 void
 _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
 {
-       const Elf_Rel *rel = 0, *rellim;
-       Elf_Addr relsz = 0;
+       const Elf_Rela *rela = 0, *relalim;
+       Elf_Addr relasz = 0;
        Elf_Addr *where;
 
        for (; dynp->d_tag != DT_NULL; dynp++) {
                switch (dynp->d_tag) {
-               case DT_REL:
-                       rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
+               case DT_RELA:
+                       rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
                        break;
-               case DT_RELSZ:
-                       relsz = dynp->d_un.d_val;
+               case DT_RELASZ:
+                       relasz = dynp->d_un.d_val;
                        break;
                }
        }
-       rellim = (const Elf_Rel *)((const uint8_t *)rel + relsz);
-       for (; rel < rellim; rel++) {
-               where = (Elf_Addr *)(relocbase + rel->r_offset);
+       relalim = (const Elf_Rela *)((const uint8_t *)rela + relasz);
+       for (; rela < relalim; rela++) {
+               where = (Elf_Addr *)(relocbase + rela->r_offset);
                *where += (Elf_Addr)relocbase;
        }
 }
@@ -117,8 +118,8 @@
                where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
 
                switch (ELF_R_TYPE(rela->r_info)) {
-               case R_TYPE(ABS64):     /* word B + S + A */
-               case R_TYPE(GLOB_DAT):  /* word B + S */
+               case R_TYPE(ABS64):     /* word S + A */
+               case R_TYPE(GLOB_DAT):  /* word S + A */
                case R_TLS_TYPE(TLS_DTPREL):
                case R_TLS_TYPE(TLS_DTPMOD):
                case R_TLS_TYPE(TLS_TPREL):
@@ -139,8 +140,8 @@
                case R_TYPE(NONE):
                        break;
 
-               case R_TYPE(ABS64):     /* word B + S + A */
-               case R_TYPE(GLOB_DAT):  /* word B + S */
+               case R_TYPE(ABS64):     /* word S + A */
+               case R_TYPE(GLOB_DAT):  /* word S + A */
                        tmp = (Elf_Addr)defobj->relocbase + def->st_value +
                            rela->r_addend;
                        if (*where != tmp)
@@ -225,28 +226,61 @@
        if (!obj->relocbase)
                return 0;
 
-       for (const Elf_Rel *rel = obj->pltrel; rel < obj->pltrellim; rel++) {
-               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+       for (const Elf_Rela *rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
+               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+
+               assert((ELF_R_TYPE(rela->r_info) == R_TYPE(JUMP_SLOT)) ||
+                   (ELF_R_TYPE(rela->r_info) == R_TYPE(TLSDESC)));
 
-               assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JUMP_SLOT));
-
-               /* Just relocate the GOT slots pointing into the PLT */
-               *where += (Elf_Addr)obj->relocbase;
-               rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
+               switch (ELF_R_TYPE(rela->r_info)) {
+               case R_TYPE(JUMP_SLOT):
+                       /* Just relocate the GOT slots pointing into the PLT */
+                       *where += (Elf_Addr)obj->relocbase;
+                       rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
+                       break;
+               case R_TYPE(TLSDESC):
+                       assert(ELF_R_SYM(rela->r_info) == 0);   /* XXX */
+                       if (ELF_R_SYM(rela->r_info) == 0) {
+                               where[0] = (Elf_Addr)_rtld_tlsdesc;
+                               where[1] = obj->tlsoffset + rela->r_addend + sizeof(struct tls_tcb);
+                       }
+                       break;
+               }
        }
 
        return 0;
 }
 
+void
+_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
+{
+       const Elf_Rela *rela;
+       Elf_Addr *where, target;
+
+       while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
+               rela = obj->pltrelalim - obj->ifunc_remaining;
+               --obj->ifunc_remaining;
+               if (ELF_R_TYPE(rela->r_info) == R_TYPE(IRELATIVE)) {
+                       where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+                       target = (Elf_Addr)(obj->relocbase + rela->r_addend);
+                       _rtld_exclusive_exit(mask);
+                       target = _rtld_resolve_ifunc2(obj, target);
+                       _rtld_exclusive_enter(mask);
+                       if (*where != target)
+                               *where = target;
+               }
+       }
+}
+
 static int
-_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
+_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
        Elf_Addr *tp)
 {
-       Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+       Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
        Elf_Addr new_value;
        const Elf_Sym  *def;
        const Obj_Entry *defobj;
-       unsigned long info = rel->r_info;
+       unsigned long info = rela->r_info;
 
        assert(ELF_R_TYPE(info) == R_TYPE(JUMP_SLOT));
 
@@ -274,13 +308,13 @@
 }
 
 Elf_Addr
-_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
+_rtld_bind(const Obj_Entry *obj, Elf_Word relaidx)
 {
-       const Elf_Rel *rel = obj->pltrel + reloff;
-       Elf_Addr new_value = 0; /* XXX gcc */
+       const Elf_Rela *rela = obj->pltrela + relaidx;
+       Elf_Addr new_value;
 
        _rtld_shared_enter();
-       int err = _rtld_relocate_plt_object(obj, rel, &new_value);
+       int err = _rtld_relocate_plt_object(obj, rela, &new_value);
        if (err)
                _rtld_die();
        _rtld_shared_exit();
@@ -290,11 +324,11 @@
 int
 _rtld_relocate_plt_objects(const Obj_Entry *obj)
 {
-       const Elf_Rel *rel;
+       const Elf_Rela *rela;
        int err = 0;
        
-       for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
-               err = _rtld_relocate_plt_object(obj, rel, NULL);
+       for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
+               err = _rtld_relocate_plt_object(obj, rela, NULL);
                if (err)
                        break;
        }
diff -r 4295dff9fc00 -r 2d24e8fd5925 libexec/ld.elf_so/arch/aarch64/rtld_start.S
--- a/libexec/ld.elf_so/arch/aarch64/rtld_start.S       Sun Feb 04 20:38:41 2018 +0000
+++ b/libexec/ld.elf_so/arch/aarch64/rtld_start.S       Sun Feb 04 21:49:51 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $ */
+/* $NetBSD: rtld_start.S,v 1.2 2018/02/04 21:49:51 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <machine/asm.h>
 
-RCSID("$NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $")
+RCSID("$NetBSD: rtld_start.S,v 1.2 2018/02/04 21:49:51 skrll Exp $")
 
 /*
  * void _rtld_start(void (*cleanup)(void), const Obj_Entry *obj,
@@ -43,28 +43,23 @@
  * X30 (LR)    = 0
  * X29 (FP)    = 0
  */
-
 ENTRY_NP(_rtld_start)
        mov     x24, x2                 /* save ps_strings */
 
-#if 1
-       adrp    x1, _PROCEDURE_LINKAGE_TABLE_   /* load _DYNAMIC offset from GOT */
-       ldr     x1, [x1, #:got_lo12:_PROCEDURE_LINKAGE_TABLE_]
-#else
        adrp    x1, :got:_DYNAMIC       /* load _DYNAMIC offset from GOT */
        ldr     x1, [x1, #:got_lo12:_DYNAMIC]
-#endif
 
        adrp    x0, _DYNAMIC            /* get &_DYNAMIC */
        add     x0, x0, #:lo12:_DYNAMIC
+
        sub     x25, x0, x1             /* relocbase = &_DYNAMIC - GOT:_DYNAMIC */
        mov     x1, x25                 /* pass as 2nd argument */
-       bl      _rtld_relocate_nonplt_self
+       bl      _C_LABEL(_rtld_relocate_nonplt_self)
 
        sub     sp, sp, #16             /* reserve space for returns */
        mov     x0, sp                  /* pointer to reserved space */
        mov     x1, x25                 /* pass relocbase */
-       bl      _rtld
+       bl      _C_LABEL(_rtld)
        mov     x17, x0                 /* save entry point */
 
        ldp     x0, x1, [sp], #16       /* pop cleanup & obj_main */
@@ -75,34 +70,54 @@
 
 /*
  * Upon entry from plt0 entry:
- * X17 = &PLTGOT[n]
- * X16 = &PLTGOT[2]
+ *
+ * SP+0                = &PLTGOT[n + 3]
+ * SP+8                = return addr
+ * X16         = &PLTGOT[2]
  */
 ENTRY_NP(_rtld_bind_start)
-       sub     sp, sp, #96             /* reserve stack space */
-       stp     x29, x30, [sp, #80]     /* save FP & LR */
-       add     x29, sp, #80            /* get new FP */
-       str     x24, [sp, #64]          /* save caller-saved register */
-       stp     x6, x7, [sp, #48]       /* save arguments */
-       stp     x4, x5, [sp, #32]       /* save arguments */
-       stp     x2, x3, [sp, #16]       /* save arguments */
-       stp     x0, x1, [sp, #0]        /* save arguments */
+       ldr     x9, [sp]                /* x9 = &PLTGOT[n+3] */
+
+       /* save x0-x8 for arguments */
+       stp     x0, x1, [sp, #-16]!
+       stp     x2, x3, [sp, #-16]!
+       stp     x4, x5, [sp, #-16]!
+       stp     x6, x7, [sp, #-16]!
+       stp     x8, xzr, [sp, #-16]!
+
+       /* save q0-q7 for arguments */
+       stp     q0, q1, [sp, #-32]!
+       stp     q2, q3, [sp, #-32]!
+       stp     q4, q5, [sp, #-32]!
+       stp     q6, q7, [sp, #-32]!
 
-       sub     x16, x16, #16           /* adjust to &PLTGOT[0] */
-       mov     x24, x17                /* preserve across _rtld_bind */
-       sub     x1, x17, x16            /* x1 = &PLTGOT[N] - &PLTGOT[2] */
-       lsr     x1, x1, #3              /* x1 = N - 2 */
-       ldr     x0, [x16, #8]           /* get obj ptr from &PLTGOT[1] */
-       bl      _rtld_bind
-       str     x0, [x24]               /* save address in PLTGOT[N] */
-       mov     x17, x0                 /* save address */
+       ldr     x0, [x16, #-8]  /* x0 = PLTGOT[1] */
+       sub     x1, x9, x16     /* x1 = &PLTGOT[n+3] - &PLTGOT[1] = offset+8 */
+       sub     x1, x1, #8      /* x1 = offset */
+       lsr     x1, x1, #3      /* x1 /= sizeof(void *) */
+
+       bl      _C_LABEL(_rtld_bind)
+       mov     x17, x0         /* save result */
 
-       ldp     x0, x1, [sp, #0]        /* restore arguments */
-       ldp     x2, x3, [sp, #16]       /* restore arguments */
-       ldp     x4, x5, [sp, #32]       /* restore arguments */
-       ldp     x6, x7, [sp, #48]       /* restore arguments */
-       ldr     x24, [sp, #64]          /* save caller-saved register */
-       ldp     x29, x30, [sp, #80]     /* restore FP & LR */
-       add     sp, sp, #96             /* reclaim stack */
+       /* restore q0-q7 for arguments */
+       ldp     q6, q7, [sp], #32
+       ldp     q4, q5, [sp], #32
+       ldp     q2, q3, [sp], #32
+       ldp     q0, q1, [sp], #32
+



Home | Main Index | Thread Index | Old Index