svn commit: r228435 - in head/libexec/rtld-elf: . amd64 arm i386
ia64 mips powerpc powerpc64 sparc64
Nathan Whitehorn
nwhitehorn at freebsd.org
Sat Dec 17 15:09:28 UTC 2011
This broke PowerPC really, really badly. Basically every
dynamically-linked executable dies with an illegal instruction trap.
-Nathan
On 12/12/11 05:03, Konstantin Belousov wrote:
> Author: kib
> Date: Mon Dec 12 11:03:14 2011
> New Revision: 228435
> URL: http://svn.freebsd.org/changeset/base/228435
>
> Log:
> Add support for STT_GNU_IFUNC and R_MACHINE_IRELATIVE GNU extensions to
> rtld on 386 and amd64. This adds runtime bits neccessary for the use
> of the dispatch functions from the dynamically-linked executables and
> shared libraries.
>
> To allow use of external references from the dispatch function, resolution
> of the R_MACHINE_IRESOLVE relocations in PLT is postponed until GOT entries
> for PLT are prepared, and normal resolution of the GOT entries is finished.
> Similar to how it is done by GNU, IRELATIVE relocations are resolved in
> advance, instead of normal lazy handling for PLT.
>
> Move the init_pltgot() call before the relocations for the object are
> processed.
>
> MFC after: 3 weeks
>
> Modified:
> head/libexec/rtld-elf/amd64/reloc.c
> head/libexec/rtld-elf/arm/reloc.c
> head/libexec/rtld-elf/i386/reloc.c
> head/libexec/rtld-elf/ia64/reloc.c
> head/libexec/rtld-elf/mips/reloc.c
> head/libexec/rtld-elf/powerpc/reloc.c
> head/libexec/rtld-elf/powerpc64/reloc.c
> head/libexec/rtld-elf/rtld.c
> head/libexec/rtld-elf/rtld.h
> head/libexec/rtld-elf/sparc64/reloc.c
>
> Modified: head/libexec/rtld-elf/amd64/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/amd64/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/amd64/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -344,11 +344,22 @@ reloc_plt(Obj_Entry *obj)
> for (rela = obj->pltrela; rela< relalim; rela++) {
> Elf_Addr *where;
>
> - assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT);
> -
> - /* Relocate the GOT slot pointing into the PLT. */
> - where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
> - *where += (Elf_Addr)obj->relocbase;
> + switch(ELF_R_TYPE(rela->r_info)) {
> + case R_X86_64_JMP_SLOT:
> + /* Relocate the GOT slot pointing into the PLT. */
> + where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
> + *where += (Elf_Addr)obj->relocbase;
> + break;
> +
> + case R_X86_64_IRELATIVE:
> + obj->irelative = true;
> + break;
> +
> + default:
> + _rtld_error("Unknown relocation type %x in PLT",
> + (unsigned int)ELF_R_TYPE(rela->r_info));
> + return (-1);
> + }
> }
> return 0;
> }
> @@ -368,19 +379,91 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockS
> const Elf_Sym *def;
> const Obj_Entry *defobj;
>
> - assert(ELF_R_TYPE(rela->r_info) == 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);
> - if (def == NULL)
> - return -1;
> - target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
> - reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
> + 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);
> + if (def == NULL)
> + return (-1);
> + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
> + obj->gnu_ifunc = true;
> + continue;
> + }
> + target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
> + reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
> + break;
> +
> + case R_X86_64_IRELATIVE:
> + break;
> +
> + default:
> + _rtld_error("Unknown relocation type %x in PLT",
> + (unsigned int)ELF_R_TYPE(rela->r_info));
> + return (-1);
> + }
> }
> obj->jmpslots_done = true;
> return 0;
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
> +{
> + const Elf_Rela *relalim;
> + const Elf_Rela *rela;
> +
> + relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
> + for (rela = obj->pltrela; rela< relalim; rela++) {
> + Elf_Addr *where, target, *ptr;
> +
> + switch (ELF_R_TYPE(rela->r_info)) {
> + case R_X86_64_JMP_SLOT:
> + break;
> +
> + case R_X86_64_IRELATIVE:
> + ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
> + where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
> + target = ((Elf_Addr (*)(void))ptr)();
> + *where = target;
> + break;
> + }
> + }
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
> +{
> + const Elf_Rela *relalim;
> + const Elf_Rela *rela;
> +
> + if (!obj->gnu_ifunc)
> + return (0);
> + relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
> + for (rela = obj->pltrela; rela< relalim; rela++) {
> + Elf_Addr *where, target;
> + const Elf_Sym *def;
> + const Obj_Entry *defobj;
> +
> + 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);
> + if (def == NULL)
> + return (-1);
> + if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
> + continue;
> + target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
> + reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
> + break;
> + }
> + }
> + obj->gnu_ifunc = false;
> + return 0;
> +}
> +
> void
> allocate_initial_tls(Obj_Entry *objs)
> {
>
> Modified: head/libexec/rtld-elf/arm/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/arm/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/arm/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -337,6 +337,22 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockS
> return (0);
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> Elf_Addr
> reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
> const Obj_Entry *obj, const Elf_Rel *rel)
>
> Modified: head/libexec/rtld-elf/i386/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/i386/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/i386/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -298,13 +298,24 @@ reloc_plt(Obj_Entry *obj)
>
> rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
> for (rel = obj->pltrel; rel< rellim; rel++) {
> - Elf_Addr *where;
> + Elf_Addr *where/*, val*/;
>
> - assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT);
> -
> - /* Relocate the GOT slot pointing into the PLT. */
> - where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
> - *where += (Elf_Addr)obj->relocbase;
> + switch (ELF_R_TYPE(rel->r_info)) {
> + case R_386_JMP_SLOT:
> + /* Relocate the GOT slot pointing into the PLT. */
> + where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
> + *where += (Elf_Addr)obj->relocbase;
> + break;
> +
> + case R_386_IRELATIVE:
> + obj->irelative = true;
> + break;
> +
> + default:
> + _rtld_error("Unknown relocation type %x in PLT",
> + ELF_R_TYPE(rel->r_info));
> + return (-1);
> + }
> }
> return 0;
> }
> @@ -324,19 +335,88 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockS
> const Elf_Sym *def;
> const Obj_Entry *defobj;
>
> - assert(ELF_R_TYPE(rel->r_info) == 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);
> - if (def == NULL)
> - return -1;
> - target = (Elf_Addr)(defobj->relocbase + def->st_value);
> - reloc_jmpslot(where, target, defobj, obj, rel);
> + 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);
> + if (def == NULL)
> + return (-1);
> + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
> + obj->gnu_ifunc = true;
> + continue;
> + }
> + target = (Elf_Addr)(defobj->relocbase + def->st_value);
> + reloc_jmpslot(where, target, defobj, obj, rel);
> + break;
> +
> + case R_386_IRELATIVE:
> + break;
> +
> + default:
> + _rtld_error("Unknown relocation type %x in PLT",
> + ELF_R_TYPE(rel->r_info));
> + return (-1);
> + }
> }
> +
> obj->jmpslots_done = true;
> return 0;
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
> +{
> + const Elf_Rel *rellim;
> + const Elf_Rel *rel;
> + Elf_Addr *where, target;
> +
> + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
> + for (rel = obj->pltrel; rel< rellim; rel++) {
> + switch (ELF_R_TYPE(rel->r_info)) {
> + case R_386_IRELATIVE:
> + where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
> + target = ((Elf_Addr (*)(void))(*where))();
> + *where = target;
> + break;
> + }
> + }
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate)
> +{
> + const Elf_Rel *rellim;
> + const Elf_Rel *rel;
> +
> + if (!obj->gnu_ifunc)
> + return (0);
> + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
> + for (rel = obj->pltrel; rel< rellim; rel++) {
> + Elf_Addr *where, target;
> + const Elf_Sym *def;
> + const Obj_Entry *defobj;
> +
> + 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);
> + if (def == NULL)
> + return (-1);
> + if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
> + continue;
> + target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
> + reloc_jmpslot(where, target, defobj, obj, rel);
> + break;
> + }
> + }
> +
> + obj->gnu_ifunc = false;
> + return (0);
> +}
> +
> void
> allocate_initial_tls(Obj_Entry *objs)
> {
>
> Modified: head/libexec/rtld-elf/ia64/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/ia64/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/ia64/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -435,6 +435,22 @@ reloc_plt(Obj_Entry *obj)
> return 0;
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> /* Relocate the jump slots in an object. */
> int
> reloc_jmpslots(Obj_Entry *obj, RtldLockState *lockstate)
>
> Modified: head/libexec/rtld-elf/mips/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/mips/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/mips/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -498,6 +498,22 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockS
> return (0);
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> Elf_Addr
> reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
> const Obj_Entry *obj, const Elf_Rel *rel)
>
> Modified: head/libexec/rtld-elf/powerpc/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/powerpc/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/powerpc/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -504,6 +504,21 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
> return (target);
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
>
> /*
> * Setup the plt glue routines.
>
> Modified: head/libexec/rtld-elf/powerpc64/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/powerpc64/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/powerpc64/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -456,6 +456,22 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
> return (target);
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> void
> init_pltgot(Obj_Entry *obj)
> {
>
> Modified: head/libexec/rtld-elf/rtld.c
> ==============================================================================
> --- head/libexec/rtld-elf/rtld.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/rtld.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -561,6 +561,17 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
> return (func_ptr_type) obj_main->entry;
> }
>
> +void *
> +rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
> +{
> + void *ptr;
> + Elf_Addr target;
> +
> + ptr = (void *)make_function_pointer(def, obj);
> + target = ((Elf_Addr (*)(void))ptr)();
> + return ((void *)target);
> +}
> +
> Elf_Addr
> _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
> {
> @@ -584,8 +595,10 @@ _rtld_bind(Obj_Entry *obj, Elf_Size relo
> &lockstate);
> if (def == NULL)
> die();
> -
> - target = (Elf_Addr)(defobj->relocbase + def->st_value);
> + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
> + target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
> + else
> + target = (Elf_Addr)(defobj->relocbase + def->st_value);
>
> dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
> defobj->strtab + def->st_name, basename(obj->path),
> @@ -1944,6 +1957,10 @@ relocate_objects(Obj_Entry *first, bool
> }
> }
>
> +
> + /* Set the special PLT or GOT entries. */
> + init_pltgot(obj);
> +
> /* Process the PLT relocations. */
> if (reloc_plt(obj) == -1)
> return -1;
> @@ -1952,7 +1969,6 @@ relocate_objects(Obj_Entry *first, bool
> if (reloc_jmpslots(obj, lockstate) == -1)
> return -1;
>
> -
> /*
> * Set up the magic number and version in the Obj_Entry. These
> * were checked in the crt1.o from the original ElfKit, so we
> @@ -1960,11 +1976,26 @@ relocate_objects(Obj_Entry *first, bool
> */
> obj->magic = RTLD_MAGIC;
> obj->version = RTLD_VERSION;
> -
> - /* Set the special PLT or GOT entries. */
> - init_pltgot(obj);
> }
>
> + /*
> + * The handling of R_MACHINE_IRELATIVE relocations and jumpslots
> + * referencing STT_GNU_IFUNC symbols is postponed till the other
> + * relocations are done. The indirect functions specified as
> + * ifunc are allowed to call other symbols, so we need to have
> + * objects relocated before asking for resolution from indirects.
> + *
> + * The R_MACHINE_IRELATIVE slots are resolved in greedy fashion,
> + * instead of the usual lazy handling of PLT slots. It is
> + * consistent with how GNU does it.
> + */
> + for (obj = first; obj != NULL; obj = obj->next) {
> + 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)
> + return (-1);
> + }
> return 0;
> }
>
> @@ -2376,9 +2407,11 @@ do_dlsym(void *handle, const char *name,
> * the relocated value of the symbol.
> */
> if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
> - return make_function_pointer(def, defobj);
> + return (make_function_pointer(def, defobj));
> + else if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
> + return (rtld_resolve_ifunc(defobj, def));
> else
> - return defobj->relocbase + def->st_value;
> + return (defobj->relocbase + def->st_value);
> }
>
> _rtld_error("Undefined symbol \"%s\"", name);
> @@ -2822,6 +2855,8 @@ get_program_var_addr(const char *name, R
> if (ELF_ST_TYPE(req.sym_out->st_info) == STT_FUNC)
> return ((const void **)make_function_pointer(req.sym_out,
> req.defobj_out));
> + else if (ELF_ST_TYPE(req.sym_out->st_info) == STT_GNU_IFUNC)
> + return ((const void **)rtld_resolve_ifunc(req.defobj_out, req.sym_out));
> else
> return ((const void **)(req.defobj_out->relocbase +
> req.sym_out->st_value));
> @@ -3088,6 +3123,7 @@ symlook_obj1(SymLook *req, const Obj_Ent
> case STT_FUNC:
> case STT_NOTYPE:
> case STT_OBJECT:
> + case STT_GNU_IFUNC:
> if (symp->st_value == 0)
> continue;
> /* fallthrough */
>
> Modified: head/libexec/rtld-elf/rtld.h
> ==============================================================================
> --- head/libexec/rtld-elf/rtld.h Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/rtld.h Mon Dec 12 11:03:14 2011 (r228435)
> @@ -230,6 +230,8 @@ typedef struct Struct_Obj_Entry {
> bool on_fini_list: 1; /* Object is already on fini list. */
> bool dag_inited : 1; /* Object has its DAG initialized. */
> bool filtees_loaded : 1; /* Filtees loaded */
> + bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */
> + bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */
>
> struct link_map linkmap; /* For GDB and dlinfo() */
> Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
> @@ -317,6 +319,7 @@ void lockdflt_init(void);
> void obj_free(Obj_Entry *);
> Obj_Entry *obj_new(void);
> void _rtld_bind_start(void);
> +void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def);
> void symlook_init(SymLook *, const char *);
> int symlook_obj(SymLook *, const Obj_Entry *);
> void *tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset);
> @@ -334,6 +337,8 @@ int do_copy_relocations(Obj_Entry *);
> int reloc_non_plt(Obj_Entry *, Obj_Entry *, struct Struct_RtldLockState *);
> int reloc_plt(Obj_Entry *);
> int reloc_jmpslots(Obj_Entry *, struct Struct_RtldLockState *);
> +int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *);
> +int reloc_gnu_ifunc(Obj_Entry *, struct Struct_RtldLockState *);
> void allocate_initial_tls(Obj_Entry *);
>
> #endif /* } */
>
> Modified: head/libexec/rtld-elf/sparc64/reloc.c
> ==============================================================================
> --- head/libexec/rtld-elf/sparc64/reloc.c Mon Dec 12 10:10:49 2011 (r228434)
> +++ head/libexec/rtld-elf/sparc64/reloc.c Mon Dec 12 11:03:14 2011 (r228435)
> @@ -550,6 +550,22 @@ reloc_jmpslots(Obj_Entry *obj, RtldLockS
> return (0);
> }
>
> +int
> +reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> +int
> +reloc_gnu_ifunc(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
> +{
> +
> + /* XXX not implemented */
> + return (0);
> +}
> +
> Elf_Addr
> reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *obj,
> const Obj_Entry *refobj, const Elf_Rel *rel)
More information about the svn-src-all
mailing list