summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-10-29 10:10:10 +0000
committerpeter <peter@FreeBSD.org>2001-10-29 10:10:10 +0000
commit7f637f2bb2ae5510edd8461a7ccc1ab9bb20c34d (patch)
treec6f2e920ed301497d5c70408b7fe99cd0e111427 /libexec
parent0135add4a6138b4850540eb42f6a4345c3956c2a (diff)
downloadFreeBSD-src-7f637f2bb2ae5510edd8461a7ccc1ab9bb20c34d.zip
FreeBSD-src-7f637f2bb2ae5510edd8461a7ccc1ab9bb20c34d.tar.gz
Update rtld for the "new" ia64 ABI. In the old toolchain, the
DT_INIT and DT_FINI tags pointed to fptr records. In 2.11.2, it points to the actuall address of the function. On IA64 you cannot just take an address of a function, store it in a function pointer variable and call it.. the function pointers point to a fptr data block that has the target gp and address in it. This is absolutely necessary for using the in-tree binutils toolchain, but (unfortunately) will not work with old shared libraries. Save your old ld-elf.so.1 if you want to use old ones still. Do not mix-and-match. This is a no-op change for i386 and alpha. Reviewed by: dfr
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/alpha/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/amd64/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/i386/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/ia64/reloc.c12
-rw-r--r--libexec/rtld-elf/ia64/rtld_machdep.h1
-rw-r--r--libexec/rtld-elf/rtld.c17
-rw-r--r--libexec/rtld-elf/rtld.h4
7 files changed, 34 insertions, 9 deletions
diff --git a/libexec/rtld-elf/alpha/rtld_machdep.h b/libexec/rtld-elf/alpha/rtld_machdep.h
index a461deb..11dd60c 100644
--- a/libexec/rtld-elf/alpha/rtld_machdep.h
+++ b/libexec/rtld-elf/alpha/rtld_machdep.h
@@ -40,6 +40,9 @@ Elf_Addr reloc_jmpslot(Elf_Addr *, Elf_Addr,
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
+#define call_initfini_pointer(obj, target) \
+ (((InitFunc)(target))())
+
/* Atomic operations. */
int cmp0_and_store_int(volatile int *, int);
void atomic_add_int(volatile int *, int);
diff --git a/libexec/rtld-elf/amd64/rtld_machdep.h b/libexec/rtld-elf/amd64/rtld_machdep.h
index a26394f..e51194c 100644
--- a/libexec/rtld-elf/amd64/rtld_machdep.h
+++ b/libexec/rtld-elf/amd64/rtld_machdep.h
@@ -49,6 +49,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
+#define call_initfini_pointer(obj, target) \
+ (((InitFunc)(target))())
+
static inline void
atomic_decr_int(volatile int *p)
{
diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h
index a26394f..e51194c 100644
--- a/libexec/rtld-elf/i386/rtld_machdep.h
+++ b/libexec/rtld-elf/i386/rtld_machdep.h
@@ -49,6 +49,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
+#define call_initfini_pointer(obj, target) \
+ (((InitFunc)(target))())
+
static inline void
atomic_decr_int(volatile int *p)
{
diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index 86b7ce6..8ec6860 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -407,6 +407,18 @@ make_function_pointer(const Elf_Sym *sym, const Obj_Entry *obj)
return fptrs[index];
}
+void
+call_initfini_pointer(const Obj_Entry *obj, Elf_Addr target)
+{
+ struct fptr fptr;
+
+ fptr.gp = (Elf_Addr) obj->pltgot;
+ fptr.target = target;
+ dbg(" initfini: target=%p, gp=%p",
+ (void *) fptr.target, (void *) fptr.gp);
+ ((InitFunc) &fptr)();
+}
+
/* Initialize the special PLT entries. */
void
init_pltgot(Obj_Entry *obj)
diff --git a/libexec/rtld-elf/ia64/rtld_machdep.h b/libexec/rtld-elf/ia64/rtld_machdep.h
index 74a3f62..b4f8e2c 100644
--- a/libexec/rtld-elf/ia64/rtld_machdep.h
+++ b/libexec/rtld-elf/ia64/rtld_machdep.h
@@ -47,6 +47,7 @@ struct Struct_Obj_Entry;
Elf_Addr reloc_jmpslot(Elf_Addr *, Elf_Addr, const struct Struct_Obj_Entry *);
void *make_function_pointer(const Elf_Sym *, const struct Struct_Obj_Entry *);
+void call_initfini_pointer(const struct Struct_Obj_Entry *, Elf_Addr);
/* Atomic operations. */
int cmp0_and_store_int(volatile int *, int);
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index fc6f2fa..94ea8fd 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -625,11 +625,11 @@ digest_dynamic(Obj_Entry *obj)
break;
case DT_INIT:
- obj->init = (InitFunc) (obj->relocbase + dynp->d_un.d_ptr);
+ obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
break;
case DT_FINI:
- obj->fini = (InitFunc) (obj->relocbase + dynp->d_un.d_ptr);
+ obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
break;
case DT_DEBUG:
@@ -639,7 +639,8 @@ digest_dynamic(Obj_Entry *obj)
break;
default:
- dbg("Ignoring d_tag %d = %#x", dynp->d_tag, dynp->d_tag);
+ dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
+ (long)dynp->d_tag);
break;
}
}
@@ -1248,8 +1249,9 @@ objlist_call_fini(Objlist *list)
saved_msg = errmsg_save();
STAILQ_FOREACH(elm, list, link) {
if (elm->obj->refcount == 0) {
- dbg("calling fini function for %s", elm->obj->path);
- (*elm->obj->fini)();
+ dbg("calling fini function for %s at %p", elm->obj->path,
+ (void *)elm->obj->fini);
+ call_initfini_pointer(elm->obj, elm->obj->fini);
}
}
errmsg_restore(saved_msg);
@@ -1272,8 +1274,9 @@ objlist_call_init(Objlist *list)
*/
saved_msg = errmsg_save();
STAILQ_FOREACH(elm, list, link) {
- dbg("calling init function for %s", elm->obj->path);
- (*elm->obj->init)();
+ dbg("calling init function for %s at %p", elm->obj->path,
+ (void *)elm->obj->init);
+ call_initfini_pointer(elm->obj, elm->obj->init);
}
errmsg_restore(saved_msg);
}
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index c8cb398..b425013 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -145,8 +145,8 @@ typedef struct Struct_Obj_Entry {
const char *rpath; /* Search path specified in object */
Needed_Entry *needed; /* Shared objects needed by this one (%) */
- InitFunc init; /* Initialization function to call */
- InitFunc fini; /* Termination function to call */
+ Elf_Addr init; /* Initialization function to call */
+ Elf_Addr fini; /* Termination function to call */
bool mainprog; /* True if this is the main program */
bool rtld; /* True if this is the dynamic linker */
OpenPOWER on IntegriCloud