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
This commit is contained in:
parent
d4cf88ddc4
commit
14a55adf36
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user