This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
On Sat, May 23, 2009 at 04:54:37PM -0700, H.J. Lu wrote:
> On Sat, May 23, 2009 at 2:44 PM, Ulrich Drepper <drepper@redhat.com> wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > H.J. Lu wrote:
> >> Which tool will generate the new relocation? Will it be internal to linker.
> >
> > The code the compiler generates contains ordinary calls. ?The assembler
> > will have to refrain from optimizing calls to static IFUNC functions.
>
> Assembler will always generate PLT relocation for @PLT. I don't think
> we need to change the assembler.
>
> > But the real logic is entirely internal to the static linker. ?For every
> > local IFUNC symbol create a PLT slot. ?This slot has no global symbol
> > attached and the relocation should be R_*_IRELATIVE (my proposed name).
> > ?This relocation works like a R_*_RELATIVE relocation but it uses the
> > return value as for SHT_GNU_IFUNC symbols. ?The reason we need such a
> > relocation is that we have no symbol at runtime. ?We cannot use a normal
> > PLT slot relocation since this would perform a global name lookup, which
> > is wrong. ?The R_*_IRELATIVE relocation is also more efficient.
> >
> >
>
> I took a look. It isn't hard to implement. Should it be R_*_IJUMP_SLOT
> since it will be processed closer to R_*_JUMP_SLOT than R_*_RELATIVE?
> My linker only patch for x86-64 is ready for test. I just need to
> verify it works
> with glibc on x86-64.
>
This patch works with the modified glibc. I am also enclosing
glibc patch for reference.
H.J.
---
bfd/
2009-05-23 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Generate
R_X86_64_IJUMP_SLOT relocation for local STT_GNU_IFUNC symbol.
* elflink.c (_bfd_elf_symbol_refs_local_p): Return FALSE on
STT_GNU_IFUNC symbol.
(_bfd_elf_link_hash_hide_symbol): Don't clean plt on
STT_GNU_IFUNC symbol.
include/elf/
2009-05-23 H.J. Lu <hongjiu.lu@intel.com>
* x86-64.h (R_X86_64_IJUMP_SLOT): New.
Index: bfd/elflink.c
===================================================================
--- bfd/elflink.c (revision 5932)
+++ bfd/elflink.c (working copy)
@@ -2845,6 +2845,10 @@ _bfd_elf_symbol_refs_local_p (struct elf
if (h == NULL)
return TRUE;
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (h->type == STT_GNU_IFUNC)
+ return FALSE;
+
/* STV_HIDDEN or STV_INTERNAL ones must be local. */
if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
|| ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
@@ -6669,8 +6673,12 @@ _bfd_elf_link_hash_hide_symbol (struct b
struct elf_link_hash_entry *h,
bfd_boolean force_local)
{
- h->plt = elf_hash_table (info)->init_plt_offset;
- h->needs_plt = 0;
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (ELF_ST_TYPE (h->type) != STT_GNU_IFUNC)
+ {
+ h->plt = elf_hash_table (info)->init_plt_offset;
+ h->needs_plt = 0;
+ }
if (force_local)
{
h->forced_local = 1;
Index: bfd/elf64-x86-64.c
===================================================================
--- bfd/elf64-x86-64.c (revision 5933)
+++ bfd/elf64-x86-64.c (working copy)
@@ -3328,7 +3328,10 @@ elf64_x86_64_finish_dynamic_symbol (bfd
/* This symbol has an entry in the procedure linkage table. Set
it up. */
- if (h->dynindx == -1
+ if ((h->dynindx == -1
+ && !(h->forced_local
+ && h->def_regular
+ && ELF_ST_TYPE (h->type) == STT_GNU_IFUNC))
|| htab->splt == NULL
|| htab->sgotplt == NULL
|| htab->srelplt == NULL)
@@ -3381,8 +3384,18 @@ elf64_x86_64_finish_dynamic_symbol (bfd
rela.r_offset = (htab->sgotplt->output_section->vma
+ htab->sgotplt->output_offset
+ got_offset);
- rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
- rela.r_addend = 0;
+ if (h->dynindx != -1)
+ {
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
+ rela.r_addend = 0;
+ }
+ else
+ {
+ rela.r_info = ELF64_R_INFO (0, R_X86_64_IJUMP_SLOT);
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
loc = htab->srelplt->contents + plt_index * sizeof (Elf64_External_Rela);
bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
Index: include/elf/x86-64.h
===================================================================
--- include/elf/x86-64.h (revision 5933)
+++ include/elf/x86-64.h (working copy)
@@ -71,6 +71,7 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_ty
RELOC_NUMBER (R_X86_64_TLSDESC_CALL, 35) /* Relaxable call through TLS
descriptor. */
RELOC_NUMBER (R_X86_64_TLSDESC, 36) /* 2x64-bit TLS descriptor. */
+ RELOC_NUMBER (R_X86_64_IJUMP_SLOT,37) /* Create indirect PLT entry */
RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */
RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */
END_RELOC_NUMBERS (R_X86_64_max)
Attachment:
libc-ifunc-3.patch
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |