Create _rtld_relocate_plt_object and use it in _rtld_bind and

_rtld_relocate_plt_objects.

No functional change.
This commit is contained in:
skrll 2006-10-17 08:33:36 +00:00
parent 152e43d87a
commit 6f388cd224
1 changed files with 45 additions and 49 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: hppa_reloc.c,v 1.24 2006/10/17 08:28:06 skrll Exp $ */ /* $NetBSD: hppa_reloc.c,v 1.25 2006/10/17 08:33:36 skrll Exp $ */
/*- /*-
* Copyright (c) 2002, 2004 The NetBSD Foundation, Inc. * Copyright (c) 2002, 2004 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
__RCSID("$NetBSD: hppa_reloc.c,v 1.24 2006/10/17 08:28:06 skrll Exp $"); __RCSID("$NetBSD: hppa_reloc.c,v 1.25 2006/10/17 08:33:36 skrll Exp $");
#endif /* not lint */ #endif /* not lint */
#include <stdlib.h> #include <stdlib.h>
@ -130,6 +130,9 @@ static int hppa_plabel_pre_next = 0;
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr); void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
int _rtld_relocate_plt_objects(const Obj_Entry *); int _rtld_relocate_plt_objects(const Obj_Entry *);
static inline int _rtld_relocate_plt_object(const Obj_Entry *,
const Elf_Rela *, Elf_Addr *);
/* /*
* This bootstraps the dynamic linker by relocating its GOT. * This bootstraps the dynamic linker by relocating its GOT.
* On the hppa, unlike on other architectures, static strings * On the hppa, unlike on other architectures, static strings
@ -546,29 +549,32 @@ _rtld_relocate_plt_lazy(const Obj_Entry *obj)
return 0; return 0;
} }
caddr_t static inline int
_rtld_bind(const Obj_Entry *obj, Elf_Addr reloff) _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *tp)
{ {
const Elf_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset); Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
const Elf_Sym *def; const Elf_Sym *def;
const Obj_Entry *defobj; const Obj_Entry *defobj;
Elf_Addr func_pc, func_sl; Elf_Addr func_pc, func_sl;
assert(ELF_R_TYPE(rela->r_info) == R_TYPE(IPLT)); assert(ELF_R_TYPE(rela->r_info) == R_TYPE(IPLT));
assert(ELF_R_SYM(rela->r_info) != 0);
def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true); if (ELF_R_SYM(rela->r_info) == 0) {
if (def == NULL) func_pc = (Elf_Addr)(obj->relocbase + rela->r_addend);
_rtld_die(); func_sl = (Elf_Addr)(obj->pltgot);
} else {
def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
if (def == NULL)
return -1;
func_pc = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); func_pc = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
func_sl = (Elf_Addr)(defobj->pltgot); func_sl = (Elf_Addr)(defobj->pltgot);
rdbg(("bind now/fixup in %s --> old=(%p,%p) new=(%p,%p)", rdbg(("bind now/fixup in %s --> old=(%p,%p) new=(%p,%p)",
defobj->strtab + def->st_name, defobj->strtab + def->st_name,
(void *)where[0], (void *)where[1], (void *)where[0], (void *)where[1],
(void *)func_pc, (void *)func_sl)); (void *)func_pc, (void *)func_sl));
}
/* /*
* Fill this PLT entry and return. * Fill this PLT entry and return.
*/ */
@ -577,46 +583,36 @@ _rtld_bind(const Obj_Entry *obj, Elf_Addr reloff)
if (where[1] != func_sl) if (where[1] != func_sl)
where[1] = func_sl; where[1] = func_sl;
return (caddr_t)where; if (tp)
*tp = (Elf_Addr)where;
return 0;
}
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
const Elf_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
Elf_Addr new_value;
int err;
assert(ELF_R_SYM(rela->r_info) != 0);
err = _rtld_relocate_plt_object(obj, rela, &new_value);
if (err)
_rtld_die();
return (caddr_t)new_value;
} }
int int
_rtld_relocate_plt_objects(const Obj_Entry *obj) _rtld_relocate_plt_objects(const Obj_Entry *obj)
{ {
const Elf_Rela *rela; const Elf_Rela *rela = obj->pltrela;
for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) { for (; rela < obj->pltrelalim; rela++) {
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); if (_rtld_relocate_plt_object(obj, rela, NULL) < 0)
const Elf_Sym *def; return -1;
const Obj_Entry *defobj;
Elf_Addr func_pc, func_sl;
assert(ELF_R_TYPE(rela->r_info) == R_TYPE(IPLT));
if (ELF_R_SYM(rela->r_info) == 0) {
func_pc = (Elf_Addr)(obj->relocbase + rela->r_addend);
func_sl = (Elf_Addr)(obj->pltgot);
} else {
def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
true);
if (def == NULL)
return -1;
func_pc = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
func_sl = (Elf_Addr)(defobj->pltgot);
rdbg(("bind now/fixup in %s --> old=(%p,%p) new=(%p,%p)",
defobj->strtab + def->st_name,
(void *)where[0], (void *)where[1],
(void *)func_pc, (void *)func_sl));
}
/*
* Fill this PLT entry and return.
*/
if (where[0] != func_pc)
where[0] = func_pc;
if (where[1] != func_sl)
where[1] = func_sl;
} }
return 0; return 0;
} }