Provide COMBRELOC support for amd64 in answer to PR/35589.

Some statistics:

base + COMBRELOC
$ time (for i in `seq 100`;do noatun --help>/dev/null;done)
(; for i in `seq 100`; do; noatun --help > /dev/null; done; )  148.64s
user 4.82s system 99% cpu 2:33.93 total

base + DF caching:
$ time (for i in `seq 100`;do noatun --help>/dev/null;done)
(; for i in `seq 100`; do; noatun --help > /dev/null; done; )  151.15s
user 5.53s system 99% cpu 2:37.23 total

base:
$ time (for i in `seq 100`;do noatun --help>/dev/null;done)
(; for i in `seq 100`; do; noatun --help > /dev/null; done; )  492.36s user
5.34s system 99% cpu 8:19.17 total
This commit is contained in:
skrll 2007-02-15 15:44:28 +00:00
parent 9abeea588a
commit 1fddd99f52
1 changed files with 52 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.27 2006/05/20 23:38:27 dan Exp $ */
/* $NetBSD: mdreloc.c,v 1.28 2007/02/15 15:44:28 skrll Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -68,7 +68,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.27 2006/05/20 23:38:27 dan Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.28 2007/02/15 15:44:28 skrll Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -131,12 +131,16 @@ int
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
{
const Elf_Rela *rela;
#define COMBRELOC
#ifdef COMBRELOC
unsigned long lastsym = -1;
#endif
const Elf_Sym *def = NULL;
const Obj_Entry *defobj =NULL;
for (rela = obj->rela; rela < obj->relalim; rela++) {
Elf64_Addr *where64;
Elf32_Addr *where32;
const Elf_Sym *def;
const Obj_Entry *defobj;
Elf64_Addr tmp64;
Elf32_Addr tmp32;
unsigned long symnum;
@ -152,9 +156,17 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
case R_TYPE(32): /* word32 S + A, truncate */
case R_TYPE(32S): /* word32 S + A, signed truncate */
case R_TYPE(GOT32): /* word32 G + A (XXX can we see these?) */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
if (symnum != lastsym) {
#endif
def = _rtld_find_symdef(symnum, obj, &defobj,
false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
lastsym = symnum;
}
#endif
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase +
def->st_value + rela->r_addend);
@ -166,10 +178,17 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
defobj->path));
break;
case R_TYPE(64): /* word64 S + A */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
if (symnum != lastsym) {
#endif
def = _rtld_find_symdef(symnum, obj, &defobj,
false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
lastsym = symnum;
}
#endif
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
@ -180,9 +199,17 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
obj->path, (void *)*where64, defobj->path));
break;
case R_TYPE(PC32): /* word32 S + A - P */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
if (symnum != lastsym) {
#endif
def = _rtld_find_symdef(symnum, obj, &defobj,
false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
lastsym = symnum;
}
#endif
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase +
def->st_value + rela->r_addend -
(Elf64_Addr)where64);
@ -194,10 +221,17 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
defobj->path));
break;
case R_TYPE(GLOB_DAT): /* word64 S */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
if (symnum != lastsym) {
#endif
def = _rtld_find_symdef(symnum, obj, &defobj,
false);
if (def == NULL)
return -1;
#ifdef COMBRELOC
lastsym = symnum;
}
#endif
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value);
if (*where64 != tmp64)