Minor changes to make this work on sparc64.
Approved by: jdp Tested on: alpha, i386, sparc64
This commit is contained in:
parent
6c35e80948
commit
2da08e795e
@ -73,7 +73,7 @@ typedef struct Struct_DoneList {
|
||||
*/
|
||||
static const char *basename(const char *);
|
||||
static void die(void);
|
||||
static void digest_dynamic(Obj_Entry *);
|
||||
static void digest_dynamic(Obj_Entry *, int);
|
||||
static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
|
||||
static Obj_Entry *dlcheck(void *);
|
||||
static bool donelist_check(DoneList *, const Obj_Entry *);
|
||||
@ -104,7 +104,7 @@ 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 objlist_remove_unref(Objlist *);
|
||||
static int relocate_objects(Obj_Entry *, bool);
|
||||
static int relocate_objects(Obj_Entry *, bool, Obj_Entry *);
|
||||
static void rtld_exit(void);
|
||||
static char *search_library_path(const char *, const char *);
|
||||
static const void **get_program_var_addr(const char *name);
|
||||
@ -342,7 +342,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
obj_rtld.path = xstrdup(obj_main->interp);
|
||||
}
|
||||
|
||||
digest_dynamic(obj_main);
|
||||
digest_dynamic(obj_main, 0);
|
||||
|
||||
linkmap_add(obj_main);
|
||||
linkmap_add(&obj_rtld);
|
||||
@ -378,7 +378,7 @@ _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') == -1)
|
||||
ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld) == -1)
|
||||
die();
|
||||
|
||||
dbg("doing copy relocations");
|
||||
@ -513,7 +513,7 @@ die(void)
|
||||
* information in its Obj_Entry structure.
|
||||
*/
|
||||
static void
|
||||
digest_dynamic(Obj_Entry *obj)
|
||||
digest_dynamic(Obj_Entry *obj, int early)
|
||||
{
|
||||
const Elf_Dyn *dynp;
|
||||
Needed_Entry **needed_tail = &obj->needed;
|
||||
@ -635,13 +635,16 @@ digest_dynamic(Obj_Entry *obj)
|
||||
|
||||
case DT_DEBUG:
|
||||
/* XXX - not implemented yet */
|
||||
dbg("Filling in DT_DEBUG entry");
|
||||
if (!early)
|
||||
dbg("Filling in DT_DEBUG entry");
|
||||
((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
|
||||
(long)dynp->d_tag);
|
||||
if (!early) {
|
||||
dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
|
||||
(long)dynp->d_tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -854,7 +857,17 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
hash = elf_hash(name);
|
||||
defobj = NULL;
|
||||
|
||||
def = symlook_default(name, hash, refobj, &defobj, in_plt);
|
||||
/* Handle STT_SECTION specially. */
|
||||
if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) {
|
||||
if (ELF_ST_BIND(ref->st_info) != STB_LOCAL ||
|
||||
ref->st_shndx != symnum) {
|
||||
_rtld_error("%s: Bogus symbol table entry %lu", refobj->path,
|
||||
symnum);
|
||||
}
|
||||
def = ref;
|
||||
defobj = refobj;
|
||||
} else
|
||||
def = symlook_default(name, hash, refobj, &defobj, in_plt);
|
||||
|
||||
/*
|
||||
* If we found no definition and the reference is weak, treat the
|
||||
@ -949,43 +962,42 @@ init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *dlp)
|
||||
static void
|
||||
init_rtld(caddr_t mapbase)
|
||||
{
|
||||
Obj_Entry objtmp; /* Temporary rtld object */
|
||||
|
||||
/*
|
||||
* Conjure up an Obj_Entry structure for the dynamic linker.
|
||||
*
|
||||
* The "path" member is supposed to be dynamically-allocated, but we
|
||||
* aren't yet initialized sufficiently to do that. Below we will
|
||||
* replace the static version with a dynamically-allocated copy.
|
||||
* The "path" member can't be initialized yet because string constatns
|
||||
* cannot yet be acessed. Below we will set it correctly.
|
||||
*/
|
||||
obj_rtld.path = PATH_RTLD;
|
||||
obj_rtld.rtld = true;
|
||||
obj_rtld.mapbase = mapbase;
|
||||
objtmp.path = NULL;
|
||||
objtmp.rtld = true;
|
||||
objtmp.mapbase = mapbase;
|
||||
#ifdef PIC
|
||||
obj_rtld.relocbase = mapbase;
|
||||
objtmp.relocbase = mapbase;
|
||||
#endif
|
||||
if (&_DYNAMIC != 0) {
|
||||
obj_rtld.dynamic = rtld_dynamic(&obj_rtld);
|
||||
digest_dynamic(&obj_rtld);
|
||||
assert(obj_rtld.needed == NULL);
|
||||
assert(!obj_rtld.textrel);
|
||||
objtmp.dynamic = rtld_dynamic(&objtmp);
|
||||
digest_dynamic(&objtmp, 1);
|
||||
assert(objtmp.needed == NULL);
|
||||
assert(!objtmp.textrel);
|
||||
|
||||
/*
|
||||
* Temporarily put the dynamic linker entry into the object list, so
|
||||
* that symbols can be found.
|
||||
*/
|
||||
obj_list = &obj_rtld;
|
||||
obj_tail = &obj_rtld.next;
|
||||
obj_count = 1;
|
||||
|
||||
relocate_objects(&obj_rtld, true);
|
||||
relocate_objects(&objtmp, true, &objtmp);
|
||||
}
|
||||
|
||||
/* Make the object list empty again. */
|
||||
obj_list = NULL;
|
||||
/* Initialize the object list. */
|
||||
obj_tail = &obj_list;
|
||||
obj_count = 0;
|
||||
|
||||
/* Now that non-local variables can be accesses, copy out obj_rtld. */
|
||||
memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld));
|
||||
|
||||
/* Replace the path with a dynamically allocated copy. */
|
||||
obj_rtld.path = xstrdup(obj_rtld.path);
|
||||
obj_rtld.path = xstrdup(PATH_RTLD);
|
||||
|
||||
r_debug.r_brk = r_debug_state;
|
||||
r_debug.r_state = RT_CONSISTENT;
|
||||
@ -1174,7 +1186,7 @@ load_object(char *path)
|
||||
}
|
||||
|
||||
obj->path = path;
|
||||
digest_dynamic(obj);
|
||||
digest_dynamic(obj, 0);
|
||||
|
||||
*obj_tail = obj;
|
||||
obj_tail = &obj->next;
|
||||
@ -1370,12 +1382,12 @@ objlist_remove_unref(Objlist *list)
|
||||
* or -1 on failure.
|
||||
*/
|
||||
static int
|
||||
relocate_objects(Obj_Entry *first, bool bind_now)
|
||||
relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj)
|
||||
{
|
||||
Obj_Entry *obj;
|
||||
|
||||
for (obj = first; obj != NULL; obj = obj->next) {
|
||||
if (obj != &obj_rtld)
|
||||
if (obj != rtldobj)
|
||||
dbg("relocating \"%s\"", obj->path);
|
||||
if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
|
||||
obj->symtab == NULL || obj->strtab == NULL) {
|
||||
@ -1395,7 +1407,7 @@ relocate_objects(Obj_Entry *first, bool bind_now)
|
||||
}
|
||||
|
||||
/* Process the non-PLT relocations. */
|
||||
if (reloc_non_plt(obj, &obj_rtld))
|
||||
if (reloc_non_plt(obj, rtldobj))
|
||||
return -1;
|
||||
|
||||
if (obj->textrel) { /* Re-protected the text segment. */
|
||||
@ -1595,7 +1607,8 @@ dlopen(const char *name, int mode)
|
||||
}
|
||||
|
||||
if (result == -1 ||
|
||||
(init_dag(obj), relocate_objects(obj, mode == RTLD_NOW)) == -1) {
|
||||
(init_dag(obj), relocate_objects(obj, mode == RTLD_NOW,
|
||||
&obj_rtld)) == -1) {
|
||||
obj->dl_refcount--;
|
||||
unref_dag(obj);
|
||||
if (obj->refcount == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user