Date: Fri, 29 Aug 2014 09:29:11 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270798 - in head/libexec/rtld-elf: . amd64 arm i386 mips powerpc powerpc64 sparc64 Message-ID: <201408290929.s7T9TBBI039170@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Fri Aug 29 09:29:10 2014 New Revision: 270798 URL: http://svnweb.freebsd.org/changeset/base/270798 Log: IFUNC symbol type shall be processed for non-PLT relocations, e.g. when a global variable is initialized with a pointer to ifunc. Add symbol type check and call resolver for STT_GNU_IFUNC symbol types when processing non-PLT relocations, but only after non-IFUNC relocations are done. The two-phase proceessing is required since resolvers may reference other symbols, which must be ready to use when resolver calls are done. Restructure reloc_non_plt() on x86 to call find_symdef() and handle IFUNC in single place. For non-x86 reloc_non_plt(), check for call for IFUNC relocation and do nothing, to avoid processing relocs twice. PR: 193048 Sponsored by: The FreeBSD Foundation MFC after: 2 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/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 Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/amd64/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -125,213 +125,186 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry const Elf_Rela *relalim; const Elf_Rela *rela; SymCache *cache; - int r = -1; + const Elf_Sym *def; + const Obj_Entry *defobj; + Elf_Addr *where, symval; + Elf32_Addr *where32; + int r; + r = -1; /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca(). */ if (obj != obj_rtld) { - cache = calloc(obj->dynsymcount, sizeof(SymCache)); - /* No need to check for NULL here */ + cache = calloc(obj->dynsymcount, sizeof(SymCache)); + /* No need to check for NULL here */ } else - cache = NULL; + cache = NULL; - relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize); + relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize); for (rela = obj->rela; rela < relalim; rela++) { - Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset); - Elf32_Addr *where32 = (Elf32_Addr *)where; - - switch (ELF_R_TYPE(rela->r_info)) { - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where = (Elf_Addr) (defobj->relocbase + def->st_value + rela->r_addend); - } - break; - - case R_X86_64_PC32: - /* - * I don't think the dynamic linker should ever see this - * type of relocation. But the binutils-2.6 tools sometimes - * generate it. - */ - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where32 = (Elf32_Addr) (unsigned long) (defobj->relocbase + - def->st_value + rela->r_addend - (Elf_Addr) where); - } - break; - /* missing: R_X86_64_GOT32 R_X86_64_PLT32 */ - - case R_X86_64_COPY: /* - * These are deferred until all other relocations have - * been done. All we do here is make sure that the COPY - * relocation is not in a shared library. They are allowed - * only in executable files. + * First, resolve symbol for relocations which + * reference symbols. */ - if (!obj->mainprog) { - _rtld_error("%s: Unexpected R_X86_64_COPY relocation" - " in shared library", obj->path); - goto done; - } - break; - - case R_X86_64_GLOB_DAT: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where = (Elf_Addr) (defobj->relocbase + def->st_value); - } - break; - - case R_X86_64_TPOFF64: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - /* - * We lazily allocate offsets for static TLS as we - * see the first relocation that references the - * TLS block. This allows us to support (small - * amounts of) static TLS in dynamically loaded - * modules. If we run out of space, we generate an - * error. - */ - if (!defobj->tls_done) { - if (!allocate_tls_offset((Obj_Entry*) defobj)) { - _rtld_error("%s: No space available for static " - "Thread Local Storage", obj->path); - goto done; + switch (ELF_R_TYPE(rela->r_info)) { + case R_X86_64_64: + case R_X86_64_PC32: + case R_X86_64_GLOB_DAT: + case R_X86_64_TPOFF64: + case R_X86_64_TPOFF32: + case R_X86_64_DTPMOD64: + case R_X86_64_DTPOFF64: + case R_X86_64_DTPOFF32: + def = find_symdef(ELF_R_SYM(rela->r_info), obj, + &defobj, flags, cache, lockstate); + if (def == NULL) + goto done; + /* + * If symbol is IFUNC, only perform relocation + * when caller allowed it by passing + * SYMLOOK_IFUNC flag. Skip the relocations + * otherwise. + * + * Also error out in case IFUNC relocations + * are specified for TLS, which cannot be + * usefully interpreted. + */ + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { + switch (ELF_R_TYPE(rela->r_info)) { + case R_X86_64_64: + case R_X86_64_PC32: + case R_X86_64_GLOB_DAT: + if ((flags & SYMLOOK_IFUNC) == 0) + continue; + symval = (Elf_Addr)rtld_resolve_ifunc( + defobj, def); + break; + case R_X86_64_TPOFF64: + case R_X86_64_TPOFF32: + case R_X86_64_DTPMOD64: + case R_X86_64_DTPOFF64: + case R_X86_64_DTPOFF32: + _rtld_error("%s: IFUNC for TLS reloc", + obj->path); + goto done; + } + } else { + if ((flags & SYMLOOK_IFUNC) != 0) + continue; + symval = (Elf_Addr)defobj->relocbase + + def->st_value; } - } - - *where = (Elf_Addr) (def->st_value - defobj->tlsoffset + - rela->r_addend); + break; + default: + if ((flags & SYMLOOK_IFUNC) != 0) + continue; + break; } - break; - - case R_X86_64_TPOFF32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + where32 = (Elf32_Addr *)where; - /* - * We lazily allocate offsets for static TLS as we - * see the first relocation that references the - * TLS block. This allows us to support (small - * amounts of) static TLS in dynamically loaded - * modules. If we run out of space, we generate an - * error. - */ - if (!defobj->tls_done) { - if (!allocate_tls_offset((Obj_Entry*) defobj)) { - _rtld_error("%s: No space available for static " - "Thread Local Storage", obj->path); - goto done; + switch (ELF_R_TYPE(rela->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_64: + *where = symval + rela->r_addend; + break; + case R_X86_64_PC32: + /* + * I don't think the dynamic linker should + * ever see this type of relocation. But the + * binutils-2.6 tools sometimes generate it. + */ + *where32 = (Elf32_Addr)(unsigned long)(symval + + rela->r_addend - (Elf_Addr)where); + break; + /* missing: R_X86_64_GOT32 R_X86_64_PLT32 */ + case R_X86_64_COPY: + /* + * These are deferred until all other relocations have + * been done. All we do here is make sure that the COPY + * relocation is not in a shared library. They are allowed + * only in executable files. + */ + if (!obj->mainprog) { + _rtld_error("%s: Unexpected R_X86_64_COPY " + "relocation in shared library", obj->path); + goto done; } - } - - *where32 = (Elf32_Addr) (def->st_value - - defobj->tlsoffset + - rela->r_addend); - } - break; - - case R_X86_64_DTPMOD64: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where += (Elf_Addr) defobj->tlsindex; - } - break; - - case R_X86_64_DTPOFF64: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where += (Elf_Addr) (def->st_value + rela->r_addend); - } - break; - - case R_X86_64_DTPOFF32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) + break; + case R_X86_64_GLOB_DAT: + *where = symval; + break; + case R_X86_64_TPOFF64: + /* + * We lazily allocate offsets for static TLS + * as we see the first relocation that + * references the TLS block. This allows us to + * support (small amounts of) static TLS in + * dynamically loaded modules. If we run out + * of space, we generate an error. + */ + if (!defobj->tls_done) { + if (!allocate_tls_offset((Obj_Entry*) defobj)) { + _rtld_error("%s: No space available " + "for static Thread Local Storage", + obj->path); + goto done; + } + } + *where = (Elf_Addr)(def->st_value - defobj->tlsoffset + + rela->r_addend); + break; + case R_X86_64_TPOFF32: + /* + * We lazily allocate offsets for static TLS + * as we see the first relocation that + * references the TLS block. This allows us to + * support (small amounts of) static TLS in + * dynamically loaded modules. If we run out + * of space, we generate an error. + */ + if (!defobj->tls_done) { + if (!allocate_tls_offset((Obj_Entry*) defobj)) { + _rtld_error("%s: No space available " + "for static Thread Local Storage", + obj->path); + goto done; + } + } + *where32 = (Elf32_Addr)(def->st_value - + defobj->tlsoffset + rela->r_addend); + break; + case R_X86_64_DTPMOD64: + *where += (Elf_Addr)defobj->tlsindex; + break; + case R_X86_64_DTPOFF64: + *where += (Elf_Addr)(def->st_value + rela->r_addend); + break; + case R_X86_64_DTPOFF32: + *where32 += (Elf32_Addr)(def->st_value + + rela->r_addend); + break; + case R_X86_64_RELATIVE: + *where = (Elf_Addr)(obj->relocbase + rela->r_addend); + break; + /* + * missing: + * R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, + * R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8 + */ + default: + _rtld_error("%s: Unsupported relocation type %u" + " in non-PLT relocations\n", obj->path, + (unsigned int)ELF_R_TYPE(rela->r_info)); goto done; - - *where32 += (Elf32_Addr) (def->st_value + rela->r_addend); } - break; - - case R_X86_64_RELATIVE: - *where = (Elf_Addr)(obj->relocbase + rela->r_addend); - break; - - /* missing: R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8 */ - - default: - _rtld_error("%s: Unsupported relocation type %u" - " in non-PLT relocations\n", obj->path, - (unsigned int)ELF_R_TYPE(rela->r_info)); - goto done; - } } r = 0; done: - if (cache != NULL) - free(cache); + free(cache); return (r); } Modified: head/libexec/rtld-elf/arm/reloc.c ============================================================================== --- head/libexec/rtld-elf/arm/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/arm/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -324,6 +324,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry /* The relocation for the dynamic loader has already been done. */ if (obj == obj_rtld) return (0); + if ((flags & SYMLOOK_IFUNC) != 0) + /* XXX not implemented */ + return (0); + /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca(). Modified: head/libexec/rtld-elf/i386/reloc.c ============================================================================== --- head/libexec/rtld-elf/i386/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/i386/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -126,168 +126,142 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry const Elf_Rel *rellim; const Elf_Rel *rel; SymCache *cache; - int r = -1; + const Elf_Sym *def; + const Obj_Entry *defobj; + Elf_Addr *where, symval, add; + int r; + r = -1; /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca(). */ if (obj != obj_rtld) { - cache = calloc(obj->dynsymcount, sizeof(SymCache)); - /* No need to check for NULL here */ + cache = calloc(obj->dynsymcount, sizeof(SymCache)); + /* No need to check for NULL here */ } else - cache = NULL; + cache = NULL; - rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize); + rellim = (const Elf_Rel *)((caddr_t) obj->rel + obj->relsize); for (rel = obj->rel; rel < rellim; rel++) { - Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rel->r_offset); - - switch (ELF_R_TYPE(rel->r_info)) { - - case R_386_NONE: - break; - - case R_386_32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where += (Elf_Addr) (defobj->relocbase + def->st_value); - } - break; - - case R_386_PC32: - /* - * I don't think the dynamic linker should ever see this - * type of relocation. But the binutils-2.6 tools sometimes - * generate it. - */ - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where += - (Elf_Addr) (defobj->relocbase + def->st_value) - - (Elf_Addr) where; - } - break; - - case R_386_COPY: - /* - * These are deferred until all other relocations have - * been done. All we do here is make sure that the COPY - * relocation is not in a shared library. They are allowed - * only in executable files. - */ - if (!obj->mainprog) { - _rtld_error("%s: Unexpected R_386_COPY relocation" - " in shared library", obj->path); - goto done; - } - break; - - case R_386_GLOB_DAT: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where = (Elf_Addr) (defobj->relocbase + def->st_value); + switch (ELF_R_TYPE(rel->r_info)) { + case R_386_32: + case R_386_PC32: + case R_386_GLOB_DAT: + case R_386_TLS_TPOFF: + case R_386_TLS_TPOFF32: + case R_386_TLS_DTPMOD32: + case R_386_TLS_DTPOFF32: + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, + flags, cache, lockstate); + if (def == NULL) + goto done; + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { + switch (ELF_R_TYPE(rel->r_info)) { + case R_386_32: + case R_386_PC32: + case R_386_GLOB_DAT: + if ((flags & SYMLOOK_IFUNC) == 0) + continue; + symval = (Elf_Addr)rtld_resolve_ifunc( + defobj, def); + break; + case R_386_TLS_TPOFF: + case R_386_TLS_TPOFF32: + case R_386_TLS_DTPMOD32: + case R_386_TLS_DTPOFF32: + _rtld_error("%s: IFUNC for TLS reloc", + obj->path); + goto done; + } + } else { + if ((flags & SYMLOOK_IFUNC) != 0) + continue; + symval = (Elf_Addr)defobj->relocbase + + def->st_value; + } + break; + default: + if ((flags & SYMLOOK_IFUNC) != 0) + continue; + break; } - break; - - case R_386_RELATIVE: - *where += (Elf_Addr) obj->relocbase; - break; - - case R_386_TLS_TPOFF: - case R_386_TLS_TPOFF32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - Elf_Addr add; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + switch (ELF_R_TYPE(rel->r_info)) { + case R_386_NONE: + break; + case R_386_32: + *where += symval; + break; + case R_386_PC32: /* - * We lazily allocate offsets for static TLS as we - * see the first relocation that references the - * TLS block. This allows us to support (small - * amounts of) static TLS in dynamically loaded - * modules. If we run out of space, we generate an - * error. + * I don't think the dynamic linker should ever + * see this type of relocation. But the + * binutils-2.6 tools sometimes generate it. */ - if (!defobj->tls_done) { - if (!allocate_tls_offset((Obj_Entry*) defobj)) { - _rtld_error("%s: No space available for static " - "Thread Local Storage", obj->path); - goto done; + *where += symval - (Elf_Addr)where; + break; + case R_386_COPY: + /* + * These are deferred until all other + * relocations have been done. All we do here + * is make sure that the COPY relocation is + * not in a shared library. They are allowed + * only in executable files. + */ + if (!obj->mainprog) { + _rtld_error("%s: Unexpected R_386_COPY " + "relocation in shared library", obj->path); + goto done; } - } - add = (Elf_Addr) (def->st_value - defobj->tlsoffset); - if (ELF_R_TYPE(rel->r_info) == R_386_TLS_TPOFF) - *where += add; - else - *where -= add; - } - break; - - case R_386_TLS_DTPMOD32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) - goto done; - - *where += (Elf_Addr) defobj->tlsindex; - } - break; - - case R_386_TLS_DTPOFF32: - { - const Elf_Sym *def; - const Obj_Entry *defobj; - - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, - flags, cache, lockstate); - if (def == NULL) + break; + case R_386_GLOB_DAT: + *where = symval; + break; + case R_386_RELATIVE: + *where += (Elf_Addr)obj->relocbase; + break; + case R_386_TLS_TPOFF: + case R_386_TLS_TPOFF32: + /* + * We lazily allocate offsets for static TLS + * as we see the first relocation that + * references the TLS block. This allows us to + * support (small amounts of) static TLS in + * dynamically loaded modules. If we run out + * of space, we generate an error. + */ + if (!defobj->tls_done) { + if (!allocate_tls_offset((Obj_Entry*) defobj)) { + _rtld_error("%s: No space available " + "for static Thread Local Storage", + obj->path); + goto done; + } + } + add = (Elf_Addr)(def->st_value - defobj->tlsoffset); + if (ELF_R_TYPE(rel->r_info) == R_386_TLS_TPOFF) + *where += add; + else + *where -= add; + break; + case R_386_TLS_DTPMOD32: + *where += (Elf_Addr)defobj->tlsindex; + break; + case R_386_TLS_DTPOFF32: + *where += (Elf_Addr) def->st_value; + break; + default: + _rtld_error("%s: Unsupported relocation type %d" + " in non-PLT relocations\n", obj->path, + ELF_R_TYPE(rel->r_info)); goto done; - - *where += (Elf_Addr) def->st_value; } - break; - - default: - _rtld_error("%s: Unsupported relocation type %d" - " in non-PLT relocations\n", obj->path, - ELF_R_TYPE(rel->r_info)); - goto done; - } } r = 0; done: - if (cache != NULL) - free(cache); + free(cache); return (r); } Modified: head/libexec/rtld-elf/mips/reloc.c ============================================================================== --- head/libexec/rtld-elf/mips/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/mips/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -275,6 +275,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry if (obj == obj_rtld) return (0); + if ((flags & SYMLOOK_IFUNC) != 0) + /* XXX not implemented */ + return (0); + #ifdef SUPPORT_OLD_BROKEN_LD broken = 0; sym = obj->symtab; Modified: head/libexec/rtld-elf/powerpc/reloc.c ============================================================================== --- head/libexec/rtld-elf/powerpc/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/powerpc/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -294,6 +294,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry SymCache *cache; int r = -1; + if ((flags & SYMLOOK_IFUNC) != 0) + /* XXX not implemented */ + return (0); + /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca(). Modified: head/libexec/rtld-elf/powerpc64/reloc.c ============================================================================== --- head/libexec/rtld-elf/powerpc64/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/powerpc64/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -290,6 +290,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry int bytes = obj->dynsymcount * sizeof(SymCache); int r = -1; + if ((flags & SYMLOOK_IFUNC) != 0) + /* XXX not implemented */ + return (0); + /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca(). Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/rtld.c Fri Aug 29 09:29:10 2014 (r270798) @@ -2546,7 +2546,7 @@ relocate_object(Obj_Entry *obj, bool bin } } - /* Process the non-PLT relocations. */ + /* Process the non-PLT non-IFUNC relocations. */ if (reloc_non_plt(obj, rtldobj, flags, lockstate)) return (-1); @@ -2559,7 +2559,6 @@ relocate_object(Obj_Entry *obj, bool bin } } - /* Set the special PLT or GOT entries. */ init_pltgot(obj); @@ -2571,6 +2570,15 @@ relocate_object(Obj_Entry *obj, bool bin if (reloc_jmpslots(obj, flags, lockstate) == -1) return (-1); + /* + * Process the non-PLT IFUNC relocations. The relocations are + * processed in two phases, because IFUNC resolvers may + * reference other symbols, which must be readily processed + * before resolvers are called. + */ + if (reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate)) + return (-1); + if (obj->relro_size > 0) { if (mprotect(obj->relro_page, obj->relro_size, PROT_READ) == -1) { Modified: head/libexec/rtld-elf/rtld.h ============================================================================== --- head/libexec/rtld-elf/rtld.h Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/rtld.h Fri Aug 29 09:29:10 2014 (r270798) @@ -293,6 +293,8 @@ typedef struct Struct_Obj_Entry { #define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol. Used by dlsym. */ #define SYMLOOK_EARLY 0x04 /* Symlook is done during initialization. */ +#define SYMLOOK_IFUNC 0x08 /* Allow IFUNC processing in + reloc_non_plt(). */ /* Flags for load_object(). */ #define RTLD_LO_NOLOAD 0x01 /* dlopen() specified RTLD_NOLOAD. */ Modified: head/libexec/rtld-elf/sparc64/reloc.c ============================================================================== --- head/libexec/rtld-elf/sparc64/reloc.c Fri Aug 29 09:04:24 2014 (r270797) +++ head/libexec/rtld-elf/sparc64/reloc.c Fri Aug 29 09:29:10 2014 (r270798) @@ -300,6 +300,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry SymCache *cache; int r = -1; + if ((flags & SYMLOOK_IFUNC) != 0) + /* XXX not implemented */ + return (0); + /* * The dynamic loader may be called from a thread, we have * limited amounts of stack available so we cannot use alloca().
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408290929.s7T9TBBI039170>