From owner-svn-src-all@FreeBSD.ORG Sat Dec 17 15:33:05 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 57350106566C; Sat, 17 Dec 2011 15:33:05 +0000 (UTC) (envelope-from nwhitehorn@freebsd.org) Received: from argol.doit.wisc.edu (argol.doit.wisc.edu [144.92.197.212]) by mx1.freebsd.org (Postfix) with ESMTP id 1DB0B8FC14; Sat, 17 Dec 2011 15:33:04 +0000 (UTC) MIME-version: 1.0 Content-transfer-encoding: 7BIT Content-type: text/plain; CHARSET=US-ASCII; format=flowed Received: from avs-daemon.smtpauth3.wiscmail.wisc.edu by smtpauth3.wiscmail.wisc.edu (Sun Java(tm) System Messaging Server 7u2-7.05 32bit (built Jul 30 2009)) id <0LWC00G00TV4E200@smtpauth3.wiscmail.wisc.edu>; Sat, 17 Dec 2011 09:33:04 -0600 (CST) Received: from comporellon.tachypleus.net ([unknown] [76.210.77.223]) by smtpauth3.wiscmail.wisc.edu (Sun Java(tm) System Messaging Server 7u2-7.05 32bit (built Jul 30 2009)) with ESMTPSA id <0LWC00ENNTV1D500@smtpauth3.wiscmail.wisc.edu>; Sat, 17 Dec 2011 09:33:02 -0600 (CST) Date: Sat, 17 Dec 2011 09:33:01 -0600 From: Nathan Whitehorn In-reply-to: <4EECB0A4.504@freebsd.org> To: Konstantin Belousov Message-id: <4EECB62D.2070608@freebsd.org> X-Spam-Report: AuthenticatedSender=yes, SenderIP=76.210.77.223 X-Spam-PmxInfo: Server=avs-9, Version=5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2011.12.17.152414, SenderIP=76.210.77.223 References: <201112121103.pBCB3FuT097580@svn.freebsd.org> <4EECB0A4.504@freebsd.org> User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:8.0) Gecko/20111113 Thunderbird/8.0 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 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Dec 2011 15:33:05 -0000 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) >