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]

Re: PATCH: PR ld/14956: Unnecessary R_X86_64_NONE


On Thu, Dec 13, 2012 at 1:08 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> Hi,
>
> I checked in this patch to check local IFUNC calls so that we can
> avoid unnecessary R_*_NONE relocations.
>
>
> H.J.
> ----
> diff --git a/bfd/ChangeLog b/bfd/ChangeLog
> index 5c4ace1..1ff8574 100644
> --- a/bfd/ChangeLog
> +++ b/bfd/ChangeLog
> @@ -1,3 +1,10 @@
> +2012-12-13  H.J. Lu  <hongjiu.lu@intel.com>
> +
> +       PR ld/14956
> +       * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Check local
> +       IFUNC calls.
> +       * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
> +
>  2012-12-10  Edgar E. Iglesias <edgar.iglesias@gmail.com>
>
>         * reloc.c (MICROBLAZE): Document new relocations
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index 1b04a6e..bb41302 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -2066,10 +2066,39 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
>  {
>    struct elf_i386_link_hash_table *htab;
>    asection *s;
> +  struct elf_i386_link_hash_entry *eh;
> +  struct elf_dyn_relocs *p;
>
>    /* STT_GNU_IFUNC symbol must go through PLT. */
>    if (h->type == STT_GNU_IFUNC)
>      {
> +      /* Check local STT_GNU_IFUNC calls.  */
> +      if (h->ref_regular
> +         && SYMBOL_CALLS_LOCAL (info, h))
> +       {
> +         bfd_size_type pc_count = 0;
> +         struct elf_dyn_relocs **pp;
> +
> +         eh = (struct elf_i386_link_hash_entry *) h;
> +         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
> +           {
> +             pc_count += p->pc_count;
> +             p->count -= p->pc_count;
> +             p->pc_count = 0;
> +             if (p->count == 0)
> +               *pp = p->next;
> +             else
> +               pp = &p->next;
> +           }
> +
> +         if (pc_count)
> +           {
> +             h->needs_plt = 1;
> +             h->plt.refcount += 1;
> +             h->non_got_ref = 1;
> +           }
> +       }
> +
>        if (h->plt.refcount <= 0)
>         {
>           h->plt.offset = (bfd_vma) -1;
> @@ -2155,9 +2184,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
>    if (ELIMINATE_COPY_RELOCS
>        && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
>      {
> -      struct elf_i386_link_hash_entry * eh;
> -      struct elf_dyn_relocs *p;
> -
>        eh = (struct elf_i386_link_hash_entry *) h;
>        for (p = eh->dyn_relocs; p != NULL; p = p->next)
>         {
> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> index d58384f..ec38ddc 100644
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -2134,10 +2134,39 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
>  {
>    struct elf_x86_64_link_hash_table *htab;
>    asection *s;
> +  struct elf_x86_64_link_hash_entry *eh;
> +  struct elf_dyn_relocs *p;
>
>    /* STT_GNU_IFUNC symbol must go through PLT. */
>    if (h->type == STT_GNU_IFUNC)
>      {
> +      /* Check local STT_GNU_IFUNC calls.  */
> +      if (h->ref_regular
> +         && SYMBOL_CALLS_LOCAL (info, h))
> +       {
> +         bfd_size_type pc_count = 0;
> +         struct elf_dyn_relocs **pp;
> +
> +         eh = (struct elf_x86_64_link_hash_entry *) h;
> +         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
> +           {
> +             pc_count += p->pc_count;
> +             p->count -= p->pc_count;
> +             p->pc_count = 0;
> +             if (p->count == 0)
> +               *pp = p->next;
> +             else
> +               pp = &p->next;
> +           }
> +
> +         if (pc_count)
> +           {
> +             h->needs_plt = 1;
> +             h->plt.refcount += 1;
> +             h->non_got_ref = 1;
> +           }
> +       }
> +
>        if (h->plt.refcount <= 0)
>         {
>           h->plt.offset = (bfd_vma) -1;
> @@ -2214,9 +2243,6 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
>
>    if (ELIMINATE_COPY_RELOCS)
>      {
> -      struct elf_x86_64_link_hash_entry * eh;
> -      struct elf_dyn_relocs *p;
> -
>        eh = (struct elf_x86_64_link_hash_entry *) h;
>        for (p = eh->dyn_relocs; p != NULL; p = p->next)
>         {
> diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
> index b534021..994ee04 100644
> --- a/ld/testsuite/ChangeLog
> +++ b/ld/testsuite/ChangeLog
> @@ -1,3 +1,19 @@
> +2012-12-13  H.J. Lu  <hongjiu.lu@intel.com>
> +
> +       PR ld/14956
> +       * ld-ifunc/ifunc-14-i386.d: Renamed to ...
> +       * ld-ifunc/ifunc-14a-i386.d: This.
> +
> +       * ld-ifunc/ifunc-14-x86-64.d: Renamed to ...
> +       * ld-ifunc/ifunc-14a-x86-64.d: This.
> +
> +       * ld-ifunc/ifunc-14b-i386.d: New file.
> +       * ld-ifunc/ifunc-14b-x86-64.d: Likewise.
> +       * ld-ifunc/ifunc-14c-i386.d: Likewise.
> +       * ld-ifunc/ifunc-14c-x86-64.d: Likewise.
> +       * ld-ifunc/ifunc-14d-i386.d: Likewise.
> +       * ld-ifunc/ifunc-14d-x86-64.d: Likewise.
> +
>  2012-12-07  H.J. Lu  <hongjiu.lu@intel.com>
>
>         * ld-elf/pr14926.d: Use "readelf -S --wide".
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14-i386.d b/ld/testsuite/ld-ifunc/ifunc-14-i386.d
> deleted file mode 100644
> index 0edc9fb..0000000
> --- a/ld/testsuite/ld-ifunc/ifunc-14-i386.d
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -#source: ifunc-14a.s
> -#source: ifunc-14b.s
> -#ld: -shared -m elf_i386 -z nocombreloc
> -#as: --32
> -#readelf: -d --wide
> -#target: x86_64-*-* i?86-*-*
> -
> -#failif
> -#...
> -.*\(TEXTREL\).*
> -#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d
> deleted file mode 100644
> index 2c4ebbb..0000000
> --- a/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -#source: ifunc-14a.s
> -#source: ifunc-14b.s
> -#ld: -shared -m elf_x86_64 -z nocombreloc
> -#as: --64
> -#readelf: -d
> -#target: x86_64-*-*
> -
> -#failif
> -#...
> -.*\(TEXTREL\).*
> -#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14a-i386.d b/ld/testsuite/ld-ifunc/ifunc-14a-i386.d
> new file mode 100644
> index 0000000..0edc9fb
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14a-i386.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14a.s
> +#source: ifunc-14b.s
> +#ld: -shared -m elf_i386 -z nocombreloc
> +#as: --32
> +#readelf: -d --wide
> +#target: x86_64-*-* i?86-*-*
> +
> +#failif
> +#...
> +.*\(TEXTREL\).*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d
> new file mode 100644
> index 0000000..2c4ebbb
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14a.s
> +#source: ifunc-14b.s
> +#ld: -shared -m elf_x86_64 -z nocombreloc
> +#as: --64
> +#readelf: -d
> +#target: x86_64-*-*
> +
> +#failif
> +#...
> +.*\(TEXTREL\).*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14b-i386.d b/ld/testsuite/ld-ifunc/ifunc-14b-i386.d
> new file mode 100644
> index 0000000..948237d
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14b-i386.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14b.s
> +#source: ifunc-14a.s
> +#ld: -shared -m elf_i386 -z nocombreloc
> +#as: --32
> +#readelf: -d --wide
> +#target: x86_64-*-* i?86-*-*
> +
> +#failif
> +#...
> +.*\(TEXTREL\).*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d
> new file mode 100644
> index 0000000..cc1f5ae
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14b.s
> +#source: ifunc-14a.s
> +#ld: -shared -m elf_x86_64 -z nocombreloc
> +#as: --64
> +#readelf: -d
> +#target: x86_64-*-*
> +
> +#failif
> +#...
> +.*\(TEXTREL\).*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14c-i386.d b/ld/testsuite/ld-ifunc/ifunc-14c-i386.d
> new file mode 100644
> index 0000000..ca360a3
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14c-i386.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14a.s
> +#source: ifunc-14b.s
> +#ld: -shared -m elf_i386 -z nocombreloc
> +#as: --32
> +#readelf: -r --wide
> +#target: x86_64-*-* i?86-*-*
> +
> +#failif
> +#...
> +.* +R_386_NONE +.*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d
> new file mode 100644
> index 0000000..76bfa84
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14a.s
> +#source: ifunc-14b.s
> +#ld: -shared -m elf_x86_64 -z nocombreloc
> +#as: --64
> +#readelf: -r --wide
> +#target: x86_64-*-*
> +
> +#failif
> +#...
> +.* +R_X86_64_NONE +.*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14d-i386.d b/ld/testsuite/ld-ifunc/ifunc-14d-i386.d
> new file mode 100644
> index 0000000..2327278
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14d-i386.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14b.s
> +#source: ifunc-14a.s
> +#ld: -shared -m elf_i386 -z nocombreloc
> +#as: --32
> +#readelf: -r --wide
> +#target: x86_64-*-* i?86-*-*
> +
> +#failif
> +#...
> +.* +R_386_NONE +.*
> +#...
> diff --git a/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d
> new file mode 100644
> index 0000000..789584b
> --- /dev/null
> +++ b/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d
> @@ -0,0 +1,11 @@
> +#source: ifunc-14b.s
> +#source: ifunc-14a.s
> +#ld: -shared -m elf_x86_64 -z nocombreloc
> +#as: --64
> +#readelf: -r --wide
> +#target: x86_64-*-*
> +
> +#failif
> +#...
> +.* +R_X86_64_NONE +.*
> +#...

I also checked it into 2.23 branch.

-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]