Source-Changes-HG archive

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

[src/trunk]: src Move the complex logic for dynamically writing branches from...



details:   https://anonhg.NetBSD.org/src/rev/f1d00f264a4e
branches:  trunk
changeset: 831408:f1d00f264a4e
user:      joerg <joerg%NetBSD.org@localhost>
date:      Thu Mar 29 13:23:39 2018 +0000

description:
Move the complex logic for dynamically writing branches from ld.elf_so
into a header for reuse in crt0.o for static ifunc support. Change the
existing logic for sparc64 to use the Bicc variant of ba,a as it allows
+-8MB displacement compared to the BPcc variant's +-1MB. Teach the sparc
variant the same trick for using ba,a and not sethi+jmp when possible.

diffstat:

 distrib/sets/lists/comp/md.sparc         |    4 +-
 distrib/sets/lists/comp/md.sparc64       |    4 +-
 lib/csu/common/crt0-common.c             |   31 ++--
 libexec/ld.elf_so/arch/sparc/mdreloc.c   |   35 +----
 libexec/ld.elf_so/arch/sparc64/mdreloc.c |  212 +------------------------------
 sys/arch/sparc/include/Makefile          |    4 +-
 sys/arch/sparc/include/elf_support.h     |   64 +++++++++
 sys/arch/sparc64/include/Makefile        |    4 +-
 sys/arch/sparc64/include/elf_support.h   |  186 +++++++++++++++++++++++++++
 9 files changed, 286 insertions(+), 258 deletions(-)

diffs (truncated from 750 to 300 lines):

diff -r 6162dfb5a174 -r f1d00f264a4e distrib/sets/lists/comp/md.sparc
--- a/distrib/sets/lists/comp/md.sparc  Thu Mar 29 08:11:41 2018 +0000
+++ b/distrib/sets/lists/comp/md.sparc  Thu Mar 29 13:23:39 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.sparc,v 1.92 2018/02/03 21:27:45 mrg Exp $
+# $NetBSD: md.sparc,v 1.93 2018/03/29 13:23:39 joerg Exp $
 ./usr/include/gcc-4.5/tgmath.h                 comp-obsolete           obsolete
 ./usr/include/gcc-4.8/tgmath.h                 comp-c-include          obsolete
 ./usr/include/gcc-4.8/visintrin.h              comp-c-include          obsolete
@@ -24,6 +24,7 @@
 ./usr/include/sparc/disklabel.h                        comp-c-include
 ./usr/include/sparc/eeprom.h                   comp-c-include
 ./usr/include/sparc/elf_machdep.h              comp-c-include
+./usr/include/sparc/elf_support.h              comp-c-include
 ./usr/include/sparc/endian.h                   comp-c-include
 ./usr/include/sparc/endian_machdep.h           comp-c-include
 ./usr/include/sparc/fbio.h                     comp-obsolete           obsolete
@@ -92,6 +93,7 @@
 ./usr/include/sparc64/disklabel.h              comp-c-include
 ./usr/include/sparc64/eeprom.h                 comp-c-include
 ./usr/include/sparc64/elf_machdep.h            comp-c-include
+./usr/include/sparc64/elf_support.h            comp-c-include
 ./usr/include/sparc64/endian.h                 comp-c-include
 ./usr/include/sparc64/endian_machdep.h         comp-c-include
 ./usr/include/sparc64/fbio.h                   comp-obsolete           obsolete
diff -r 6162dfb5a174 -r f1d00f264a4e distrib/sets/lists/comp/md.sparc64
--- a/distrib/sets/lists/comp/md.sparc64        Thu Mar 29 08:11:41 2018 +0000
+++ b/distrib/sets/lists/comp/md.sparc64        Thu Mar 29 13:23:39 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.sparc64,v 1.199 2018/02/03 21:27:45 mrg Exp $
+# $NetBSD: md.sparc64,v 1.200 2018/03/29 13:23:39 joerg Exp $
 ./usr/include/g++/bits/sparc                   comp-c-include          compat
 ./usr/include/g++/bits/sparc/c++config.h       comp-c-include          gcc,compat
 ./usr/include/g++/bits/sparc64                 comp-c-include          compat
@@ -28,6 +28,7 @@
 ./usr/include/sparc/disklabel.h                        comp-c-include
 ./usr/include/sparc/eeprom.h                   comp-c-include
 ./usr/include/sparc/elf_machdep.h              comp-c-include
+./usr/include/sparc/elf_support.h              comp-c-include
 ./usr/include/sparc/endian.h                   comp-c-include
 ./usr/include/sparc/endian_machdep.h           comp-c-include
 ./usr/include/sparc/fbio.h                     comp-obsolete           obsolete
@@ -95,6 +96,7 @@
 ./usr/include/sparc64/disklabel.h              comp-c-include
 ./usr/include/sparc64/eeprom.h                 comp-c-include
 ./usr/include/sparc64/elf_machdep.h            comp-c-include
+./usr/include/sparc64/elf_support.h            comp-c-include
 ./usr/include/sparc64/endian.h                 comp-c-include
 ./usr/include/sparc64/endian_machdep.h         comp-c-include
 ./usr/include/sparc64/fbio.h                   comp-obsolete           obsolete
diff -r 6162dfb5a174 -r f1d00f264a4e lib/csu/common/crt0-common.c
--- a/lib/csu/common/crt0-common.c      Thu Mar 29 08:11:41 2018 +0000
+++ b/lib/csu/common/crt0-common.c      Thu Mar 29 13:23:39 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crt0-common.c,v 1.15 2018/03/09 20:20:47 joerg Exp $ */
+/* $NetBSD: crt0-common.c,v 1.16 2018/03/29 13:23:39 joerg Exp $ */
 
 /*
  * Copyright (c) 1998 Christos Zoulas
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: crt0-common.c,v 1.15 2018/03/09 20:20:47 joerg Exp $");
+__RCSID("$NetBSD: crt0-common.c,v 1.16 2018/03/29 13:23:39 joerg Exp $");
 
 #include <sys/types.h>
 #include <sys/exec.h>
@@ -140,6 +140,14 @@
 #include <stdio.h>
 extern const Elf_Rela __rela_iplt_start[] __dso_hidden __weak;
 extern const Elf_Rela __rela_iplt_end[] __dso_hidden __weak;
+#ifdef __sparc__
+#define IFUNC_RELOCATION R_TYPE(JMP_IREL)
+#include <machine/elf_support.h>
+#define write_plt(where, value) sparc_write_branch((void *)where, (void *)value)
+#else
+#define IFUNC_RELOCATION R_TYPE(IRELATIVE)
+#define write_plt(where, value) *where = value
+#endif
 
 static void
 fix_iplta(void)
@@ -150,31 +158,20 @@
 
        rela = __rela_iplt_start;
        relalim = __rela_iplt_end;
-#if DEBUG
-       printf("%p - %p\n", rela, relalim);
-#endif
        for (; rela < relalim; ++rela) {
-               if (ELF_R_TYPE(rela->r_info) != R_TYPE(IRELATIVE))
+               if (ELF_R_TYPE(rela->r_info) != IFUNC_RELOCATION)
                        abort();
                where = (Elf_Addr *)(relocbase + rela->r_offset);
-#if DEBUG
-               printf("location: %p\n", where);
-#endif
                target = (Elf_Addr)(relocbase + rela->r_addend);
-#if DEBUG
-               printf("target: %p\n", (void *)target);
-#endif
                target = ((Elf_Addr(*)(void))target)();
-#if DEBUG
-               printf("...resolves to: %p\n", (void *)target);
-#endif
-               *where = target;
+               write_plt(where, target);
        }
 }
 #endif
 #ifdef HAS_IPLT
 extern const Elf_Rel __rel_iplt_start[] __dso_hidden __weak;
 extern const Elf_Rel __rel_iplt_end[] __dso_hidden __weak;
+#define IFUNC_RELOCATION R_TYPE(IRELATIVE)
 
 static void
 fix_iplt(void)
@@ -186,7 +183,7 @@
        rel = __rel_iplt_start;
        rellim = __rel_iplt_end;
        for (; rel < rellim; ++rel) {
-               if (ELF_R_TYPE(rel->r_info) != R_TYPE(IRELATIVE))
+               if (ELF_R_TYPE(rel->r_info) != IFUNC_RELOCATION)
                        abort();
                where = (Elf_Addr *)(relocbase + rel->r_offset);
                target = ((Elf_Addr(*)(void))*where)();
diff -r 6162dfb5a174 -r f1d00f264a4e libexec/ld.elf_so/arch/sparc/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc/mdreloc.c    Thu Mar 29 08:11:41 2018 +0000
+++ b/libexec/ld.elf_so/arch/sparc/mdreloc.c    Thu Mar 29 13:23:39 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mdreloc.c,v 1.53 2018/03/25 18:56:01 joerg Exp $       */
+/*     $NetBSD: mdreloc.c,v 1.54 2018/03/29 13:23:39 joerg Exp $       */
 
 /*-
  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
@@ -31,9 +31,11 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.53 2018/03/25 18:56:01 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.54 2018/03/29 13:23:39 joerg Exp $");
 #endif /* not lint */
 
+#include <machine/elf_support.h>
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -404,31 +406,6 @@
        return 0;
 }
 
-static inline void
-_rtld_write_plt(Elf_Word *where, Elf_Addr value)
-{
-       /*
-        * At the PLT entry pointed at by `where', we now construct
-        * a direct transfer to the now fully resolved function
-        * address.  The resulting code in the jump slot is:
-        *
-        *      sethi   %hi(roffset), %g1
-        *      sethi   %hi(addr), %g1
-        *      jmp     %g1+%lo(addr)
-        *
-        * We write the third instruction first, since that leaves the
-        * previous `b,a' at the second word in place. Hence the whole
-        * PLT slot can be atomically change to the new sequence by
-        * writing the `sethi' instruction at word 2.
-        */
-       const uint32_t SETHI = 0x03000000U;
-       const uint32_t JMP = 0x81c06000U;
-       where[2] = JMP   | (value & 0x000003ff);
-       where[1] = SETHI | ((value >> 10) & 0x003fffff);
-       __asm volatile("iflush %0+8" : : "r" (where));
-       __asm volatile("iflush %0+4" : : "r" (where));
-}
-
 void
 _rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
 {
@@ -444,7 +421,7 @@
                _rtld_exclusive_exit(mask);
                target = _rtld_resolve_ifunc2(obj, target);
                _rtld_exclusive_enter(mask);
-               _rtld_write_plt(where, target);
+               sparc_write_branch(where + 1, (void *)target);
        }
 
        while (obj->ifunc_remaining_nonplt > 0 && _rtld_objgen == cur_objgen) {
@@ -521,7 +498,7 @@
        rdbg(("bind now/fixup in %s --> new=%p", 
            defobj->strtab + def->st_name, (void *)value));
 
-       _rtld_write_plt(where, value);
+       sparc_write_branch(where + 1, (void *)value);
 
        if (tp)
                *tp = value;
diff -r 6162dfb5a174 -r f1d00f264a4e libexec/ld.elf_so/arch/sparc64/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Thu Mar 29 08:11:41 2018 +0000
+++ b/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Thu Mar 29 13:23:39 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mdreloc.c,v 1.67 2017/12/25 17:00:15 joerg Exp $       */
+/*     $NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $       */
 
 /*-
  * Copyright (c) 2000 Eduardo Horvath.
@@ -32,9 +32,11 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.67 2017/12/25 17:00:15 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.68 2018/03/29 13:23:39 joerg Exp $");
 #endif /* not lint */
 
+#include <machine/elf_support.h>
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -192,19 +194,6 @@
 /*
  * Instruction templates:
  */
-#define        BAA     0x30680000      /*      ba,a    %xcc, 0 */
-#define        SETHI   0x03000000      /*      sethi   %hi(0), %g1 */
-#define        JMP     0x81c06000      /*      jmpl    %g1+%lo(0), %g0 */
-#define        NOP     0x01000000      /*      sethi   %hi(0), %g0 */
-#define        OR      0x82106000      /*      or      %g1, 0, %g1 */
-#define        XOR     0x82186000      /*      xor     %g1, 0, %g1 */
-#define        MOV71   0x8213e000      /*      or      %o7, 0, %g1 */
-#define        MOV17   0x9e106000      /*      or      %g1, 0, %o7 */
-#define        CALL    0x40000000      /*      call    0 */
-#define        SLLX    0x83287000      /*      sllx    %g1, 0, %g1 */
-#define        NEG     0x82200001      /*      neg     %g1 */
-#define        SETHIG5 0x0b000000      /*      sethi   %hi(0), %g5 */
-#define        ORG5    0x82104005      /*      or      %g1, %g5, %g1 */
 
 
 /* %hi(v)/%lo(v) with variable shift */
@@ -589,34 +578,6 @@
 _rtld_write_plt(Elf_Word *where, Elf_Addr value, const Elf_Rela *rela,
     const Obj_Entry *obj)
 {
-       Elf_Addr offset, offBAA;
-
-       /*
-        * At the PLT entry pointed at by `where', we now construct a direct
-        * transfer to the now fully resolved function address.
-        *
-        * A PLT entry is supposed to start by looking like this:
-        *
-        *      sethi   %hi(. - .PLT0), %g1
-        *      ba,a    %xcc, .PLT1
-        *      nop
-        *      nop
-        *      nop
-        *      nop
-        *      nop
-        *      nop
-        *
-        * When we replace these entries we start from the last instruction
-        * and do it in reverse order so the last thing we do is replace the
-        * branch.  That allows us to change this atomically.
-        *
-        * We now need to find out how far we need to jump.  We have a choice
-        * of several different relocation techniques which are increasingly
-        * expensive.
-        */
-
-       offset = ((Elf_Addr)where) - value;
-       offBAA = value - (((Elf_Addr)where) + 4);       /* ba,a at where[1] */
        if (rela && rela->r_addend) {
                Elf_Addr *ptr = (Elf_Addr *)where;
                /*
@@ -625,169 +586,8 @@
                 * PLT section.  Update it to point to the target function.
                 */
                ptr[0] += value - (Elf_Addr)obj->pltgot;
-       } else if (offBAA <= (1L<<20) && (Elf_SOff)offBAA >= -(1L<<20)) {
-               /* 
-                * We're within 1MB -- we can use a direct branch insn.
-                *
-                * We can generate this pattern:
-                *
-                *      sethi   %hi(. - .PLT0), %g1
-                *      ba,a    %xcc, addr
-                *      nop
-                *      nop
-                *      nop
-                *      nop
-                *      nop
-                *      nop
-                *
-                */
-               where[1] = BAA | ((offBAA >> 2) & 0x7ffff);
-               __asm volatile("iflush %0+4" : : "r" (where));
-       } else if (value < (1L<<32)) {
-               /* 



Home | Main Index | Thread Index | Old Index