summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-04-02 02:19:02 +0000
committerjake <jake@FreeBSD.org>2002-04-02 02:19:02 +0000
commit6f01a2296f0fcd6e8dd625aa2b6ee0d2da57686a (patch)
tree6e1afa0654591fac90c27fc61b23707eaca9ee52 /libexec
parentf6a3790f10b11d31fb0e40c5640411147785a19f (diff)
downloadFreeBSD-src-6f01a2296f0fcd6e8dd625aa2b6ee0d2da57686a.zip
FreeBSD-src-6f01a2296f0fcd6e8dd625aa2b6ee0d2da57686a.tar.gz
Minor changes to make this work on sparc64.
Approved by: jdp Tested on: alpha, i386, sparc64
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c79
1 files changed, 46 insertions, 33 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 619791e..c4cc5e8 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -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)
OpenPOWER on IntegriCloud