Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Dec 2011 09:33:01 -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:  <4EECB62D.2070608@freebsd.org>
In-Reply-To: <4EECB0A4.504@freebsd.org>
References:  <201112121103.pBCB3FuT097580@svn.freebsd.org> <4EECB0A4.504@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Fixed in r228635.
-Nathan

On 12/17/11 09:09, Nathan Whitehorn wrote:
> 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?4EECB62D.2070608>