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 Replace COMBREL with just-in-time check in...
details: https://anonhg.NetBSD.org/src/rev/984aaddefbea
branches: trunk
changeset: 354510:984aaddefbea
user: joerg <joerg%NetBSD.org@localhost>
date: Mon Jun 19 11:57:01 2017 +0000
description:
Replace COMBREL with just-in-time check in _rtld_relocate_nonplt_objects.
The COMBREL logic predates thread-safety of the dynamic linker and
breaks the use of shared locks for the common symbol lookup case. It is
unlikely to provide any benefit for lazy binding or PLT lookups, so
provide equivalent functionality in the non-PLT relocation handling loop
by checking if the symbol used by the current relocation is the same as
the one used during the last lookup. No inter-object cachine is done as
it is also unlikely to be benefical.
Testing with Firefox startup on AMD64 shows a small performance gain by
the new method.
diffstat:
libexec/ld.elf_so/Makefile | 3 +-
libexec/ld.elf_so/arch/aarch64/mdreloc.c | 49 +++++----
libexec/ld.elf_so/arch/alpha/alpha_reloc.c | 48 +++++----
libexec/ld.elf_so/arch/arm/mdreloc.c | 53 +++++-----
libexec/ld.elf_so/arch/hppa/hppa_reloc.c | 140 +++++++++++++++-------------
libexec/ld.elf_so/arch/i386/mdreloc.c | 58 ++++++-----
libexec/ld.elf_so/arch/m68k/mdreloc.c | 54 +++++-----
libexec/ld.elf_so/arch/mips/mips_reloc.c | 49 ++++++---
libexec/ld.elf_so/arch/or1k/mdreloc.c | 48 +++++----
libexec/ld.elf_so/arch/powerpc/ppc_reloc.c | 52 ++++++----
libexec/ld.elf_so/arch/riscv/mdreloc.c | 43 +++++---
libexec/ld.elf_so/arch/sh3/mdreloc.c | 57 +++++------
libexec/ld.elf_so/arch/sparc/mdreloc.c | 42 +++-----
libexec/ld.elf_so/arch/sparc64/mdreloc.c | 41 +++-----
libexec/ld.elf_so/arch/vax/mdreloc.c | 35 ++++--
libexec/ld.elf_so/arch/x86_64/mdreloc.c | 60 ++++++------
libexec/ld.elf_so/map_object.c | 7 +-
libexec/ld.elf_so/rtld.h | 5 +-
libexec/ld.elf_so/symbol.c | 50 +---------
19 files changed, 440 insertions(+), 454 deletions(-)
diffs (truncated from 1934 to 300 lines):
diff -r 4102676b0886 -r 984aaddefbea libexec/ld.elf_so/Makefile
--- a/libexec/ld.elf_so/Makefile Mon Jun 19 11:55:07 2017 +0000
+++ b/libexec/ld.elf_so/Makefile Mon Jun 19 11:57:01 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.136 2016/12/01 14:29:15 christos Exp $
+# $NetBSD: Makefile,v 1.137 2017/06/19 11:57:01 joerg Exp $
#
# NOTE: when changing ld.so, ensure that ldd still compiles.
#
@@ -97,7 +97,6 @@
CPPFLAGS+= -DRTLD_LOADER
CPPFLAGS+= -DGNU_RELRO
CPPFLAGS+= -D_RTLD_SOURCE
-CPPFLAGS+= -DCOMBRELOC
#CPPFLAGS+= -DDEBUG
#CPPFLAGS+= -DRTLD_DEBUG
#CPPFLAGS+= -DRTLD_DEBUG_RELOC
diff -r 4102676b0886 -r 984aaddefbea libexec/ld.elf_so/arch/aarch64/mdreloc.c
--- a/libexec/ld.elf_so/arch/aarch64/mdreloc.c Mon Jun 19 11:55:07 2017 +0000
+++ b/libexec/ld.elf_so/arch/aarch64/mdreloc.c Mon Jun 19 11:57:01 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/06/19 11:57:01 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -78,27 +78,43 @@
int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
-
+ const Elf_Sym *def = NULL;
+ const Obj_Entry *defobj = NULL;
+ unsigned long last_symnum = ULONG_MAX;
+
for (const Elf_Rela *rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr *where;
- const Elf_Sym *def;
- const Obj_Entry *defobj;
unsigned long symnum;
Elf_Addr addend;
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- symnum = ELF_R_SYM(rela->r_info);
addend = rela->r_addend;
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_TLS_TYPE(TLS_DTPREL):
+ case R_TLS_TYPE(TLS_DTPMOD):
+ case R_TLS_TYPE(TLS_TPREL):
+ symnum = ELF_R_SYM(rela->r_info);
+ if (last_symnum != symnum) {
+ last_symnum = symnum;
+ def = _rtld_find_symdef(symnum, obj, &defobj,
+ false);
+ if (def == NULL)
+ return -1;
+ }
+
+ default:
+ break;
+ }
+
+ switch (ELF_R_TYPE(rela->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(ABS64): /* word B + S + A */
case R_TYPE(GLOB_DAT): /* word B + S */
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
*where = addend + (Elf_Addr)defobj->relocbase +
def->st_value;
rdbg(("ABS64/GLOB_DAT %s in %s --> %p @ %p in %s",
@@ -129,10 +145,6 @@
break;
case R_TLS_TYPE(TLS_DTPREL):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
*where = addend + (Elf_Addr)(def->st_value);
rdbg(("TLS_DTPOFF32 %s in %s --> %p",
@@ -141,10 +153,6 @@
break;
case R_TLS_TYPE(TLS_DTPMOD):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
*where = (Elf_Addr)(defobj->tlsindex);
rdbg(("TLS_DTPMOD %s in %s --> %p",
@@ -154,10 +162,6 @@
break;
case R_TLS_TYPE(TLS_TPREL):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
return -1;
@@ -172,7 +176,8 @@
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"contents = %p, symbol = %s",
- symnum, (u_long)ELF_R_TYPE(rela->r_info),
+ (u_long)ELF_R_SYM(rela->r_info),
+ (u_long)ELF_R_TYPE(rela->r_info),
(void *)rela->r_offset, *where,
obj->strtab + obj->symtab[symnum].st_name));
_rtld_error("%s: Unsupported relocation type %ld "
diff -r 4102676b0886 -r 984aaddefbea libexec/ld.elf_so/arch/alpha/alpha_reloc.c
--- a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Mon Jun 19 11:55:07 2017 +0000
+++ b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Mon Jun 19 11:57:01 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $ */
+/* $NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $");
+__RCSID("$NetBSD: alpha_reloc.c,v 1.42 2017/06/19 11:57:01 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -200,16 +200,36 @@
{
const Elf_Rela *rela;
Elf_Addr target = -1;
+ const Elf_Sym *def = NULL;
+ const Obj_Entry *defobj = NULL;
+ unsigned long last_symnum = ULONG_MAX;
for (rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr *where;
- const Elf_Sym *def;
- const Obj_Entry *defobj;
Elf_Addr tmp;
unsigned long symnum;
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- symnum = ELF_R_SYM(rela->r_info);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_TYPE(REFQUAD):
+ case R_TYPE(GLOB_DAT):
+ case R_TYPE(TPREL64):
+ case R_TYPE(DTPMOD64):
+ case R_TYPE(DTPREL64):
+ symnum = ELF_R_SYM(rela->r_info);
+ if (last_symnum != symnum) {
+ last_symnum = symnum;
+ def = _rtld_find_symdef(symnum, obj, &defobj,
+ false);
+ if (def == NULL)
+ return -1;
+ }
+ break;
+
+ default:
+ break;
+ }
switch (ELF_R_TYPE(rela->r_info)) {
case R_TYPE(NONE):
@@ -217,9 +237,6 @@
case R_TYPE(REFQUAD):
case R_TYPE(GLOB_DAT):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
target = (Elf_Addr)(defobj->relocbase +
def->st_value);
@@ -263,10 +280,6 @@
break;
case R_TYPE(TPREL64):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
return -1;
@@ -287,10 +300,6 @@
break;
case R_TYPE(DTPMOD64):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
tmp = (Elf64_Addr)defobj->tlsindex;
if (__predict_true(RELOC_ALIGNED_P(where)))
*where = tmp;
@@ -304,10 +313,6 @@
break;
case R_TYPE(DTPREL64):
- def = _rtld_find_symdef(symnum, obj, &defobj, false);
- if (def == NULL)
- return -1;
-
tmp = (Elf64_Addr)(def->st_value + rela->r_addend);
if (__predict_true(RELOC_ALIGNED_P(where)))
*where = tmp;
@@ -323,7 +328,8 @@
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"addend = %p, contents = %p, symbol = %s",
- symnum, (u_long)ELF_R_TYPE(rela->r_info),
+ (u_long)ELF_R_SYM(rela->r_info),
+ (u_long)ELF_R_TYPE(rela->r_info),
(void *)rela->r_offset, (void *)rela->r_addend,
(void *)load_ptr(where),
obj->strtab + obj->symtab[symnum].st_name));
diff -r 4102676b0886 -r 984aaddefbea libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c Mon Jun 19 11:55:07 2017 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c Mon Jun 19 11:57:01 2017 +0000
@@ -1,8 +1,8 @@
-/* $NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $ */
+/* $NetBSD: mdreloc.c,v 1.39 2017/06/19 11:57:01 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.39 2017/06/19 11:57:01 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -74,16 +74,37 @@
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
const Elf_Rel *rel;
+ const Elf_Sym *def = NULL;
+ const Obj_Entry *defobj = NULL;
+ unsigned long last_symnum = ULONG_MAX;
for (rel = obj->rel; rel < obj->rellim; rel++) {
Elf_Addr *where;
- const Elf_Sym *def;
- const Obj_Entry *defobj;
Elf_Addr tmp;
unsigned long symnum;
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
- symnum = ELF_R_SYM(rel->r_info);
+
+ switch (ELF_R_TYPE(rel->r_info)) {
+ case R_TYPE(PC24): /* word32 S - P + A */
+ case R_TYPE(ABS32): /* word32 B + S + A */
+ case R_TYPE(GLOB_DAT): /* word32 B + S */
+ case R_TYPE(TLS_DTPOFF32):
+ case R_TYPE(TLS_DTPMOD32):
+ case R_TYPE(TLS_TPOFF32):
+ symnum = ELF_R_SYM(rel->r_info);
+ if (last_symnum != symnum) {
+ last_symnum = symnum;
+ def = _rtld_find_symdef(symnum, obj, &defobj,
+ false);
+ if (def == NULL)
+ return -1;
+ }
+ break;
+
+ default:
+ break;
+ }
switch (ELF_R_TYPE(rel->r_info)) {
case R_TYPE(NONE):
@@ -99,10 +120,6 @@
addend = *where;
if (addend & 0x00800000)
addend |= 0xff000000;
-
Home |
Main Index |
Thread Index |
Old Index