summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/powerpc64
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-12-25 08:51:20 +0000
committerkib <kib@FreeBSD.org>2010-12-25 08:51:20 +0000
commitcefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3 (patch)
tree487c080e0cb090d960945a4f112301253d4a6e9f /libexec/rtld-elf/powerpc64
parent377233e6cca2d48c8ecba755aa46304a8ae7731b (diff)
downloadFreeBSD-src-cefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3.zip
FreeBSD-src-cefd8b2a41e4b4bf7a16e2dea1e0c719a30d56a3.tar.gz
Implement support for ELF filters in rtld. Both normal and auxillary
filters are implemented. Filtees are loaded on demand, unless LD_LOADFLTR environment variable is set or -z loadfltr was specified during the linking. This forces rtld to upgrade read-locked rtld_bind_lock to write lock when it encounters an object with filter during symbol lookup. Consolidate common arguments of the symbol lookup functions in the SymLook structure. Track the state of the rtld locks in the RtldLockState structure. Pass local RtldLockState through the rtld symbol lookup calls to allow lock upgrades. Reviewed by: kan Tested by: Mykola Dzham <i levsha me>, nwhitehorn (powerpc)
Diffstat (limited to 'libexec/rtld-elf/powerpc64')
-rw-r--r--libexec/rtld-elf/powerpc64/reloc.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index d2430e7..b2236f2 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -69,12 +69,12 @@ do_copy_relocations(Obj_Entry *dstobj)
void *dstaddr;
const Elf_Sym *dstsym;
const char *name;
- unsigned long hash;
size_t size;
const void *srcaddr;
const Elf_Sym *srcsym = NULL;
- Obj_Entry *srcobj;
- const Ver_Entry *ve;
+ const Obj_Entry *srcobj, *defobj;
+ SymLook req;
+ int res;
if (ELF_R_TYPE(rela->r_info) != R_PPC_COPY) {
continue;
@@ -83,14 +83,16 @@ do_copy_relocations(Obj_Entry *dstobj)
dstaddr = (void *) (dstobj->relocbase + rela->r_offset);
dstsym = dstobj->symtab + ELF_R_SYM(rela->r_info);
name = dstobj->strtab + dstsym->st_name;
- hash = elf_hash(name);
size = dstsym->st_size;
- ve = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
+ symlook_init(&req, name);
+ req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
for (srcobj = dstobj->next; srcobj != NULL;
srcobj = srcobj->next) {
- if ((srcsym = symlook_obj(name, hash, srcobj, ve, 0))
- != NULL) {
+ res = symlook_obj(&req, srcobj);
+ if (res == 0) {
+ srcsym = req.sym_out;
+ defobj = req.defobj_out;
break;
}
}
@@ -102,7 +104,7 @@ do_copy_relocations(Obj_Entry *dstobj)
return (-1);
}
- srcaddr = (const void *) (srcobj->relocbase+srcsym->st_value);
+ srcaddr = (const void *) (defobj->relocbase+srcsym->st_value);
memcpy(dstaddr, srcaddr, size);
dbg("copy_reloc: src=%p,dst=%p,size=%zd\n",srcaddr,dstaddr,size);
}
@@ -151,7 +153,7 @@ reloc_non_plt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
*/
static int
reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
- SymCache *cache)
+ SymCache *cache, RtldLockState *lockstate)
{
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
const Elf_Sym *def;
@@ -166,7 +168,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC64_ADDR64: /* doubleword64 S + A */
case R_PPC_GLOB_DAT:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache);
+ false, cache, lockstate);
if (def == NULL) {
return (-1);
}
@@ -213,7 +215,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC64_DTPMOD64:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache);
+ false, cache, lockstate);
if (def == NULL)
return (-1);
@@ -224,7 +226,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC64_TPREL64:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache);
+ false, cache, lockstate);
if (def == NULL)
return (-1);
@@ -253,7 +255,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC64_DTPREL64:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache);
+ false, cache, lockstate);
if (def == NULL)
return (-1);
@@ -277,7 +279,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
* Process non-PLT relocations
*/
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -304,7 +306,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
*/
relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize);
for (rela = obj->rela; rela < relalim; rela++) {
- if (reloc_nonplt_object(obj_rtld, obj, rela, cache) < 0)
+ if (reloc_nonplt_object(obj_rtld, obj, rela, cache, lockstate)
+ < 0)
goto done;
}
r = 0;
@@ -376,7 +379,7 @@ reloc_plt(Obj_Entry *obj)
* LD_BIND_NOW was set - force relocation for all jump slots
*/
int
-reloc_jmpslots(Obj_Entry *obj)
+reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Rela *relalim;
@@ -390,7 +393,7 @@ reloc_jmpslots(Obj_Entry *obj)
assert(ELF_R_TYPE(rela->r_info) == R_PPC_JMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- true, NULL);
+ true, NULL, lockstate);
if (def == NULL) {
dbg("reloc_jmpslots: sym not found");
return (-1);
OpenPOWER on IntegriCloud