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/c53c1e974ddc
branches: trunk
changeset: 321640:c53c1e974ddc
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 bd63b82a437c -r c53c1e974ddc 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 bd63b82a437c -r c53c1e974ddc 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 bd63b82a437c -r c53c1e974ddc 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 bd63b82a437c -r c53c1e974ddc 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 bd63b82a437c -r c53c1e974ddc 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