summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libexec/rtld-elf/amd64/reloc.c34
-rw-r--r--libexec/rtld-elf/arm/reloc.c26
-rw-r--r--libexec/rtld-elf/i386/reloc.c30
-rw-r--r--libexec/rtld-elf/ia64/reloc.c31
-rw-r--r--libexec/rtld-elf/mips/reloc.c18
-rw-r--r--libexec/rtld-elf/powerpc/reloc.c25
-rw-r--r--libexec/rtld-elf/powerpc64/reloc.c25
-rw-r--r--libexec/rtld-elf/rtld.c78
-rw-r--r--libexec/rtld-elf/rtld.h11
-rw-r--r--libexec/rtld-elf/sparc64/reloc.c19
10 files changed, 179 insertions, 118 deletions
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index 5f40847..9c755bc 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -82,6 +82,7 @@ do_copy_relocations(Obj_Entry *dstobj)
size = dstsym->st_size;
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
+ req.flags = SYMLOOK_EARLY;
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next) {
res = symlook_obj(&req, srcobj);
@@ -118,7 +119,8 @@ init_pltgot(Obj_Entry *obj)
/* Process the non-PLT relocations. */
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -151,7 +153,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -170,7 +172,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -200,7 +202,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -214,7 +216,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -245,7 +247,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -277,7 +279,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -291,7 +293,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -305,7 +307,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -330,7 +332,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
done:
if (cache != NULL)
free(cache);
- return(r);
+ return (r);
}
/* Process the PLT relocations. */
@@ -366,7 +368,7 @@ reloc_plt(Obj_Entry *obj)
/* Relocate the jump slots in an object. */
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -382,8 +384,8 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
switch (ELF_R_TYPE(rela->r_info)) {
case R_X86_64_JMP_SLOT:
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL,
- lockstate);
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return (-1);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
@@ -438,7 +440,7 @@ reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -454,8 +456,8 @@ reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
switch (ELF_R_TYPE(rela->r_info)) {
case R_X86_64_JMP_SLOT:
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL,
- lockstate);
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return (-1);
if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c
index 11b962a..aaad2da 100644
--- a/libexec/rtld-elf/arm/reloc.c
+++ b/libexec/rtld-elf/arm/reloc.c
@@ -54,6 +54,8 @@ do_copy_relocations(Obj_Entry *dstobj)
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj,
ELF_R_SYM(rel->r_info));
+ req.flags = SYMLOOK_EARLY;
+
for (srcobj = dstobj->next; srcobj != NULL;
srcobj = srcobj->next) {
res = symlook_obj(&req, srcobj);
@@ -135,7 +137,7 @@ store_ptr(void *where, Elf_Addr val)
static int
reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
- RtldLockState *lockstate)
+ int flags, RtldLockState *lockstate)
{
Elf_Addr *where;
const Elf_Sym *def;
@@ -161,7 +163,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
if (addend & 0x00800000)
addend |= 0xff000000;
- def = find_symdef(symnum, obj, &defobj, false, cache,
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
lockstate);
if (def == NULL)
return -1;
@@ -188,7 +190,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
case R_ARM_ABS32: /* word32 B + S + A */
case R_ARM_GLOB_DAT: /* word32 B + S */
- def = find_symdef(symnum, obj, &defobj, false, cache,
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
lockstate);
if (def == NULL)
return -1;
@@ -237,7 +239,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
break;
case R_ARM_TLS_DTPOFF32:
- def = find_symdef(symnum, obj, &defobj, false, cache,
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
lockstate);
if (def == NULL)
return -1;
@@ -254,7 +256,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
break;
case R_ARM_TLS_DTPMOD32:
- def = find_symdef(symnum, obj, &defobj, false, cache,
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
lockstate);
if (def == NULL)
return -1;
@@ -272,7 +274,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
break;
case R_ARM_TLS_TPOFF32:
- def = find_symdef(symnum, obj, &defobj, false, cache,
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
lockstate);
if (def == NULL)
return -1;
@@ -311,7 +313,8 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
* * Process non-PLT relocations
* */
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -330,7 +333,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
- if (reloc_nonplt_object(obj, rel, cache, lockstate) < 0)
+ if (reloc_nonplt_object(obj, rel, cache, flags, lockstate) < 0)
goto done;
}
r = 0;
@@ -367,7 +370,7 @@ reloc_plt(Obj_Entry *obj)
* * LD_BIND_NOW was set - force relocation for all jump slots
* */
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Rel *rellim;
@@ -381,7 +384,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- true, NULL, lockstate);
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL) {
dbg("reloc_jmpslots: sym not found");
return (-1);
@@ -406,7 +409,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index a2c8c98..5f4e247 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -83,6 +83,7 @@ do_copy_relocations(Obj_Entry *dstobj)
size = dstsym->st_size;
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rel->r_info));
+ req.flags = SYMLOOK_EARLY;
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next) {
res = symlook_obj(&req, srcobj);
@@ -119,7 +120,8 @@ init_pltgot(Obj_Entry *obj)
/* Process the non-PLT relocations. */
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -151,7 +153,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -170,7 +172,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -200,7 +202,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -220,7 +222,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
Elf_Addr add;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -253,7 +255,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -267,7 +269,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
goto done;
@@ -286,7 +288,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
done:
if (cache != NULL)
free(cache);
- return(r);
+ return (r);
}
/* Process the PLT relocations. */
@@ -322,7 +324,7 @@ reloc_plt(Obj_Entry *obj)
/* Relocate the jump slots in an object. */
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -338,8 +340,8 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
switch (ELF_R_TYPE(rel->r_info)) {
case R_386_JMP_SLOT:
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
- def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL,
- lockstate);
+ def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return (-1);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
@@ -390,7 +392,7 @@ reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -406,8 +408,8 @@ reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
switch (ELF_R_TYPE(rel->r_info)) {
case R_386_JMP_SLOT:
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
- def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL,
- lockstate);
+ def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return (-1);
if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index d5b45b7..1afcecf 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -151,7 +151,7 @@ free_fptrs(Obj_Entry *obj, bool mapped)
/* Relocate a non-PLT object with addend. */
static int
reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
- SymCache *cache, RtldLockState *lockstate)
+ SymCache *cache, int flags, RtldLockState *lockstate)
{
struct fptr **fptrs;
Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
@@ -172,7 +172,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
Elf_Addr target;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return -1;
@@ -195,7 +195,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
int sym_index;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- true, cache, lockstate);
+ SYMLOOK_IN_PLT | flags, cache, lockstate);
if (def == NULL) {
/*
* XXX r_debug_state is problematic and find_symdef()
@@ -254,7 +254,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
Elf_Addr target, gp;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return -1;
@@ -277,7 +277,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return -1;
@@ -290,7 +290,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return -1;
@@ -303,7 +303,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return -1;
@@ -342,7 +342,8 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
/* Process the non-PLT relocations. */
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@@ -368,7 +369,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
locrela.r_info = rel->r_info;
locrela.r_offset = rel->r_offset;
locrela.r_addend = 0;
- if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache,
+ if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache, flags,
lockstate))
goto done;
}
@@ -376,7 +377,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
/* Perform relocations with addend if there are any: */
relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize);
for (rela = obj->rela; obj->rela != NULL && rela < relalim; rela++) {
- if (reloc_non_plt_obj(obj_rtld, obj, rela, cache, lockstate))
+ if (reloc_non_plt_obj(obj_rtld, obj, rela, cache, flags,
+ lockstate))
goto done;
}
@@ -444,7 +446,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
@@ -453,7 +456,7 @@ reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
/* Relocate the jump slots in an object. */
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
if (obj->jmpslots_done)
return 0;
@@ -472,7 +475,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
assert(ELF_R_TYPE(rel->r_info) == R_IA_64_IPLTLSB);
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
def = find_symdef(ELF_R_SYM(rel->r_info), obj,
- &defobj, true, NULL, lockstate);
+ &defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return -1;
reloc_jmpslot(where,
@@ -493,7 +496,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
def = find_symdef(ELF_R_SYM(rela->r_info), obj,
- &defobj, true, NULL, lockstate);
+ &defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return -1;
reloc_jmpslot(where,
diff --git a/libexec/rtld-elf/mips/reloc.c b/libexec/rtld-elf/mips/reloc.c
index fd108f9..24e56ce 100644
--- a/libexec/rtld-elf/mips/reloc.c
+++ b/libexec/rtld-elf/mips/reloc.c
@@ -258,7 +258,8 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
}
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rel *rel;
const Elf_Rel *rellim;
@@ -317,7 +318,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
* to 0 if there are non-PLT references, but older
* versions of GNU ld do not do this.
*/
- def = find_symdef(i, obj, &defobj, false, NULL,
+ def = find_symdef(i, obj, &defobj, flags, NULL,
lockstate);
if (def == NULL)
return -1;
@@ -359,7 +360,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
}
} else {
/* TODO: add cache here */
- def = find_symdef(i, obj, &defobj, false, NULL,
+ def = find_symdef(i, obj, &defobj, flags, NULL,
lockstate);
if (def == NULL) {
dbg("Warning4, can't find symbole %d", i);
@@ -458,7 +459,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
Elf_Addr old = load_ptr(where, rlen);
Elf_Addr val = old;
- def = find_symdef(r_symndx, obj, &defobj, false, NULL,
+ def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
lockstate);
if (def == NULL)
return -1;
@@ -482,7 +483,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
Elf_Addr old = load_ptr(where, rlen);
Elf_Addr val = old;
- def = find_symdef(r_symndx, obj, &defobj, false, NULL,
+ def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
lockstate);
if (def == NULL)
return -1;
@@ -509,7 +510,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
Elf_Addr old = load_ptr(where, rlen);
Elf_Addr val = old;
- def = find_symdef(r_symndx, obj, &defobj, false, NULL,
+ def = find_symdef(r_symndx, obj, &defobj, flags, NULL,
lockstate);
if (def == NULL)
@@ -577,7 +578,7 @@ reloc_plt(Obj_Entry *obj)
* LD_BIND_NOW was set - force relocation for all jump slots
*/
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
/* Do nothing */
obj->jmpslots_done = true;
@@ -594,7 +595,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index d0637f4..979e43e 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -92,6 +92,7 @@ do_copy_relocations(Obj_Entry *dstobj)
size = dstsym->st_size;
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
+ req.flags = SYMLOOK_EARLY;
for (srcobj = dstobj->next; srcobj != NULL;
srcobj = srcobj->next) {
@@ -159,7 +160,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, RtldLockState *lockstate)
+ SymCache *cache, int flags, RtldLockState *lockstate)
{
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
const Elf_Sym *def;
@@ -174,7 +175,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC_ADDR32: /* word32 S + A */
case R_PPC_GLOB_DAT: /* word32 S + A */
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL) {
return (-1);
}
@@ -221,7 +222,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC_DTPMOD32:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -232,7 +233,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC_TPREL32:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -261,7 +262,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC_DTPREL32:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -285,7 +286,8 @@ 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, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -309,8 +311,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
*/
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, lockstate)
- < 0)
+ if (reloc_nonplt_object(obj_rtld, obj, rela, cache, flags,
+ lockstate) < 0)
goto done;
}
r = 0;
@@ -416,7 +418,7 @@ reloc_plt(Obj_Entry *obj)
* LD_BIND_NOW was set - force relocation for all jump slots
*/
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Rela *relalim;
@@ -430,7 +432,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
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, lockstate);
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL) {
dbg("reloc_jmpslots: sym not found");
return (-1);
@@ -525,7 +527,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index 47368a8..46e2c62 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -86,6 +86,7 @@ do_copy_relocations(Obj_Entry *dstobj)
size = dstsym->st_size;
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
+ req.flags = SYMLOOK_EARLY;
for (srcobj = dstobj->next; srcobj != NULL;
srcobj = srcobj->next) {
@@ -153,7 +154,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, RtldLockState *lockstate)
+ SymCache *cache, int flags, RtldLockState *lockstate)
{
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
const Elf_Sym *def;
@@ -169,7 +170,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
case R_PPC64_ADDR64:
case R_PPC_GLOB_DAT:
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL) {
return (-1);
}
@@ -216,7 +217,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, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -227,7 +228,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, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -256,7 +257,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, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -280,7 +281,8 @@ 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, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -307,8 +309,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
*/
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, lockstate)
- < 0)
+ if (reloc_nonplt_object(obj_rtld, obj, rela, cache, flags,
+ lockstate) < 0)
goto done;
}
r = 0;
@@ -379,7 +381,7 @@ reloc_plt(Obj_Entry *obj)
* LD_BIND_NOW was set - force relocation for all jump slots
*/
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Rela *relalim;
@@ -393,7 +395,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
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, lockstate);
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL) {
dbg("reloc_jmpslots: sym not found");
return (-1);
@@ -468,7 +470,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 3432232..f2ad554 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -116,9 +116,10 @@ static void objlist_push_head(Objlist *, Obj_Entry *);
static void objlist_push_tail(Objlist *, Obj_Entry *);
static void objlist_remove(Objlist *, Obj_Entry *);
static void *path_enumerate(const char *, path_enum_proc, void *);
-static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, RtldLockState *);
+static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int,
+ RtldLockState *);
static int resolve_objects_ifunc(Obj_Entry *first, bool bind_now,
- RtldLockState *lockstate);
+ int flags, RtldLockState *lockstate);
static int rtld_dirname(const char *, char *);
static int rtld_dirname_abs(const char *, char *);
static void *rtld_dlopen(const char *name, int fd, int mode);
@@ -545,7 +546,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
}
if (relocate_objects(obj_main,
- ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld, NULL) == -1)
+ ld_bind_now != NULL && *ld_bind_now != '\0',
+ &obj_rtld, SYMLOOK_EARLY, NULL) == -1)
die();
dbg("doing copy relocations");
@@ -580,7 +582,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
dbg("resolving ifuncs");
if (resolve_objects_ifunc(obj_main,
- ld_bind_now != NULL && *ld_bind_now != '\0', NULL) == -1)
+ ld_bind_now != NULL && *ld_bind_now != '\0', SYMLOOK_EARLY,
+ NULL) == -1)
die();
if (!obj_main->crt_no_init) {
@@ -1552,7 +1555,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info)
* that symbols can be found.
*/
- relocate_objects(&objtmp, true, &objtmp, NULL);
+ relocate_objects(&objtmp, true, &objtmp, 0, NULL);
}
/* Initialize the object list. */
@@ -1605,6 +1608,7 @@ initlist_add_neededs(Needed_Entry *needed, Objlist *list)
static void
initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list)
{
+
if (obj->init_scanned || obj->init_done)
return;
obj->init_scanned = true;
@@ -1616,6 +1620,10 @@ initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list)
/* Recursively process the needed objects. */
if (obj->needed != NULL)
initlist_add_neededs(obj->needed, list);
+ if (obj->needed_filtees != NULL)
+ initlist_add_neededs(obj->needed_filtees, list);
+ if (obj->needed_aux_filtees != NULL)
+ initlist_add_neededs(obj->needed_aux_filtees, list);
/* Add the object to the init list. */
if (obj->preinit_array != (Elf_Addr)NULL || obj->init != (Elf_Addr)NULL ||
@@ -2144,13 +2152,17 @@ objlist_remove(Objlist *list, Obj_Entry *obj)
*/
static int
relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
- RtldLockState *lockstate)
+ int flags, RtldLockState *lockstate)
{
Obj_Entry *obj;
for (obj = first; obj != NULL; obj = obj->next) {
+ if (obj->relocated)
+ continue;
+ obj->relocated = true;
if (obj != rtldobj)
dbg("relocating \"%s\"", obj->path);
+
if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
obj->symtab == NULL || obj->strtab == NULL) {
_rtld_error("%s: Shared object has no run-time symbol table",
@@ -2169,7 +2181,7 @@ relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
}
/* Process the non-PLT relocations. */
- if (reloc_non_plt(obj, rtldobj, lockstate))
+ if (reloc_non_plt(obj, rtldobj, flags, lockstate))
return -1;
if (obj->textrel) { /* Re-protected the text segment. */
@@ -2190,7 +2202,7 @@ relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
return -1;
/* Relocate the jump slots if we are doing immediate binding. */
if (obj->bind_now || bind_now)
- if (reloc_jmpslots(obj, lockstate) == -1)
+ if (reloc_jmpslots(obj, flags, lockstate) == -1)
return -1;
if (obj->relro_size > 0) {
@@ -2225,35 +2237,39 @@ relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
* consistent with how GNU does it.
*/
static int
-resolve_object_ifunc(Obj_Entry *obj, bool bind_now, RtldLockState *lockstate)
+resolve_object_ifunc(Obj_Entry *obj, bool bind_now, int flags,
+ RtldLockState *lockstate)
{
if (obj->irelative && reloc_iresolve(obj, lockstate) == -1)
return (-1);
if ((obj->bind_now || bind_now) && obj->gnu_ifunc &&
- reloc_gnu_ifunc(obj, lockstate) == -1)
+ reloc_gnu_ifunc(obj, flags, lockstate) == -1)
return (-1);
return (0);
}
static int
-resolve_objects_ifunc(Obj_Entry *first, bool bind_now, RtldLockState *lockstate)
+resolve_objects_ifunc(Obj_Entry *first, bool bind_now, int flags,
+ RtldLockState *lockstate)
{
Obj_Entry *obj;
for (obj = first; obj != NULL; obj = obj->next) {
- if (resolve_object_ifunc(obj, bind_now, lockstate) == -1)
+ if (resolve_object_ifunc(obj, bind_now, flags, lockstate) == -1)
return (-1);
}
return (0);
}
static int
-initlist_objects_ifunc(Objlist *list, bool bind_now, RtldLockState *lockstate)
+initlist_objects_ifunc(Objlist *list, bool bind_now, int flags,
+ RtldLockState *lockstate)
{
Objlist_Entry *elm;
STAILQ_FOREACH(elm, list, link) {
- if (resolve_object_ifunc(elm->obj, bind_now, lockstate) == -1)
+ if (resolve_object_ifunc(elm->obj, bind_now, flags,
+ lockstate) == -1)
return (-1);
}
return (0);
@@ -2515,17 +2531,30 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
objlist_push_tail(&list_global, obj);
if (*old_obj_tail != NULL) { /* We loaded something new. */
assert(*old_obj_tail == obj);
- result = load_needed_objects(obj, lo_flags & RTLD_LO_DLOPEN);
+ result = load_needed_objects(obj,
+ lo_flags & (RTLD_LO_DLOPEN | RTLD_LO_EARLY));
init_dag(obj);
ref_dag(obj);
if (result != -1)
result = rtld_verify_versions(&obj->dagmembers);
if (result != -1 && ld_tracing)
goto trace;
- if (result == -1 || (relocate_objects(obj, (mode & RTLD_MODEMASK)
- == RTLD_NOW, &obj_rtld, &lockstate)) == -1) {
+ if (result == -1 || (relocate_objects(obj,
+ (mode & RTLD_MODEMASK) == RTLD_NOW, &obj_rtld,
+ (lo_flags & RTLD_LO_EARLY) ? SYMLOOK_EARLY : 0,
+ &lockstate)) == -1) {
dlopen_cleanup(obj);
obj = NULL;
+ } else if (lo_flags & RTLD_LO_EARLY) {
+ /*
+ * Do not call the init functions for early loaded
+ * filtees. The image is still not initialized enough
+ * for them to work.
+ *
+ * Our object is found by the global object list and
+ * will be ordered among all init calls done right
+ * before transferring control to main.
+ */
} else {
/* Make list of init functions to call. */
initlist_add_objects(obj, &obj->next, &initlist);
@@ -2559,6 +2588,7 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
map_stacks_exec(&lockstate);
if (initlist_objects_ifunc(&initlist, (mode & RTLD_MODEMASK) == RTLD_NOW,
+ (lo_flags & RTLD_LO_EARLY) ? SYMLOOK_EARLY : 0,
&lockstate) == -1) {
objlist_clear(&initlist);
dlopen_cleanup(obj);
@@ -2566,8 +2596,10 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
return (NULL);
}
- /* Call the init functions. */
- objlist_call_init(&initlist, &lockstate);
+ if (!(lo_flags & RTLD_LO_EARLY)) {
+ /* Call the init functions. */
+ objlist_call_init(&initlist, &lockstate);
+ }
objlist_clear(&initlist);
lock_release(rtld_bind_lock, &lockstate);
return obj;
@@ -3354,12 +3386,13 @@ symlook_obj(SymLook *req, const Obj_Entry *obj)
{
DoneList donelist;
SymLook req1;
- int res, mres;
+ int flags, res, mres;
mres = symlook_obj1(req, obj);
if (mres == 0) {
if (obj->needed_filtees != NULL) {
- load_filtees(__DECONST(Obj_Entry *, obj), 0, req->lockstate);
+ flags = (req->flags & SYMLOOK_EARLY) ? RTLD_LO_EARLY : 0;
+ load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate);
donelist_init(&donelist);
symlook_init_from_req(&req1, req);
res = symlook_needed(&req1, obj->needed_filtees, &donelist);
@@ -3370,7 +3403,8 @@ symlook_obj(SymLook *req, const Obj_Entry *obj)
return (res);
}
if (obj->needed_aux_filtees != NULL) {
- load_filtees(__DECONST(Obj_Entry *, obj), 0, req->lockstate);
+ flags = (req->flags & SYMLOOK_EARLY) ? RTLD_LO_EARLY : 0;
+ load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate);
donelist_init(&donelist);
symlook_init_from_req(&req1, req);
res = symlook_needed(&req1, obj->needed_aux_filtees, &donelist);
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 9dfa0a2..2aabffe 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -229,6 +229,7 @@ typedef struct Struct_Obj_Entry {
bool mainprog : 1; /* True if this is the main program */
bool rtld : 1; /* True if this is the dynamic linker */
+ bool relocated : 1; /* True if processed by relocate_objects() */
bool textrel : 1; /* True if there are relocations to text seg */
bool symbolic : 1; /* True if generated with "-Bsymbolic" */
bool bind_now : 1; /* True if all relocations should be made first */
@@ -267,6 +268,7 @@ typedef struct Struct_Obj_Entry {
#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */
#define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol. Used by
dlsym. */
+#define SYMLOOK_EARLY 0x04 /* Symlook is done during initialization. */
/* Flags for load_object(). */
#define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */
@@ -274,6 +276,8 @@ typedef struct Struct_Obj_Entry {
#define RTLD_LO_TRACE 0x04 /* Only tracing. */
#define RTLD_LO_NODELETE 0x08 /* Loaded object cannot be closed. */
#define RTLD_LO_FILTEES 0x10 /* Loading filtee. */
+#define RTLD_LO_EARLY 0x20 /* Do not call ctors, postpone it to the
+ initialization during the image start. */
/*
* Symbol cache entry used during relocation to avoid multiple lookups
@@ -353,11 +357,12 @@ const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
* MD function declarations.
*/
int do_copy_relocations(Obj_Entry *);
-int reloc_non_plt(Obj_Entry *, Obj_Entry *, struct Struct_RtldLockState *);
+int reloc_non_plt(Obj_Entry *, Obj_Entry *, int flags,
+ struct Struct_RtldLockState *);
int reloc_plt(Obj_Entry *);
-int reloc_jmpslots(Obj_Entry *, struct Struct_RtldLockState *);
+int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *);
int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *);
-int reloc_gnu_ifunc(Obj_Entry *, struct Struct_RtldLockState *);
+int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *);
void allocate_initial_tls(Obj_Entry *);
#endif /* } */
diff --git a/libexec/rtld-elf/sparc64/reloc.c b/libexec/rtld-elf/sparc64/reloc.c
index 4ab0eae..ce0d945 100644
--- a/libexec/rtld-elf/sparc64/reloc.c
+++ b/libexec/rtld-elf/sparc64/reloc.c
@@ -231,7 +231,7 @@ static const long reloc_target_bitmask[] = {
__asm __volatile("flush %0 + %1" : : "r" (va), "I" (offs));
static int reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela,
- SymCache *cache, RtldLockState *lockstate);
+ SymCache *cache, int flags, RtldLockState *lockstate);
static void install_plt(Elf_Word *pltgot, Elf_Addr proc);
extern char _rtld_bind_start_0[];
@@ -264,6 +264,7 @@ do_copy_relocations(Obj_Entry *dstobj)
symlook_init(&req, name);
req.ventry = fetch_ventry(dstobj,
ELF_R_SYM(rela->r_info));
+ req.flags = SYMLOOK_EARLY;
for (srcobj = dstobj->next; srcobj != NULL;
srcobj = srcobj->next) {
@@ -291,7 +292,8 @@ do_copy_relocations(Obj_Entry *dstobj)
}
int
-reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
+reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
+ RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -310,7 +312,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, RtldLockState *lockstate)
relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize);
for (rela = obj->rela; rela < relalim; rela++) {
- if (reloc_nonplt_object(obj, rela, cache, lockstate) < 0)
+ if (reloc_nonplt_object(obj, rela, cache, flags, lockstate) < 0)
goto done;
}
r = 0;
@@ -322,7 +324,7 @@ done:
static int
reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache,
- RtldLockState *lockstate)
+ int flags, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Sym *def;
@@ -385,7 +387,7 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache,
if (RELOC_RESOLVE_SYMBOL(type)) {
/* Find the symbol. */
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- false, cache, lockstate);
+ flags, cache, lockstate);
if (def == NULL)
return (-1);
@@ -526,7 +528,7 @@ reloc_plt(Obj_Entry *obj)
#define LOVAL(v) ((v) & 0x000003ff)
int
-reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
+reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Obj_Entry *defobj;
const Elf_Rela *relalim;
@@ -540,7 +542,7 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
assert(ELF64_R_TYPE_ID(rela->r_info) == R_SPARC_JMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
- true, NULL, lockstate);
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL)
return -1;
target = (Elf_Addr)(defobj->relocbase + def->st_value);
@@ -559,7 +561,8 @@ reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
}
int
-reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+reloc_gnu_ifunc(Obj_Entry *obj, int flags,
+ struct Struct_RtldLockState *lockstate)
{
/* XXX not implemented */
OpenPOWER on IntegriCloud