Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Dec 2011 09:09:24 -0600
From:      Nathan Whitehorn <nwhitehorn@freebsd.org>
To:        Konstantin Belousov <kib@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, powerpc@freebsd.org
Subject:   Re: svn commit: r228435 - in head/libexec/rtld-elf: . amd64 arm i386 ia64 mips powerpc powerpc64 sparc64
Message-ID:  <4EECB0A4.504@freebsd.org>
In-Reply-To: <201112121103.pBCB3FuT097580@svn.freebsd.org>
References:  <201112121103.pBCB3FuT097580@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4EECB0A4.504>