Convert mov to lea only if needed
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 27 Feb 2015 19:27:31 +0000 (11:27 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 27 Feb 2015 19:35:37 +0000 (11:35 -0800)
We can convert mov to lea only if there are R_386_GOT32/R_X86_64_GOTPCREL
relocations against non IFUNC symbols.

* elf32-i386.c (need_convert_mov_to_lea): New.
(elf_i386_check_relocs): Set need_convert_mov_to_lea if needed.
(elf_i386_convert_mov_to_lea): Return TRUE if
need_convert_mov_to_lea is unset.
* elf64-x86-64.c (need_convert_mov_to_lea): New.
(elf_x86_64_check_relocs): Set need_convert_mov_to_lea if needed.
(elf_x86_64_convert_mov_to_lea): Return TRUE if
need_convert_mov_to_lea is unset.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c

index 1b223f9..8cd5741 100644 (file)
@@ -1,3 +1,14 @@
+2015-02-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf32-i386.c (need_convert_mov_to_lea): New.
+       (elf_i386_check_relocs): Set need_convert_mov_to_lea if needed.
+       (elf_i386_convert_mov_to_lea): Return TRUE if
+       need_convert_mov_to_lea is unset.
+       * elf64-x86-64.c (need_convert_mov_to_lea): New.
+       (elf_x86_64_check_relocs): Set need_convert_mov_to_lea if needed.
+       (elf_x86_64_convert_mov_to_lea): Return TRUE if
+       need_convert_mov_to_lea is unset.
+
 2015-02-27  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/17910
index 8028b05..3f16fc1 100644 (file)
@@ -1429,6 +1429,10 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
   return TRUE;
 }
 
+/* Rename some of the generic section flags to better document how they
+   are used here.  */
+#define need_convert_mov_to_lea sec_flg0
+
 /* Look through the relocs for a section during the first phase, and
    calculate needed space in the global offset table, procedure linkage
    table, and dynamic reloc sections.  */
@@ -1884,6 +1888,10 @@ do_size:
                                             plt_got_align))
            return FALSE;
        }
+
+      if (r_type == R_386_GOT32
+         && (h == NULL || h->type != STT_GNU_IFUNC))
+       sec->need_convert_mov_to_lea = 1;
     }
 
   return TRUE;
@@ -2636,9 +2644,9 @@ elf_i386_convert_mov_to_lea (bfd *abfd, asection *sec,
   if (!is_elf_hash_table (link_info->hash))
     return FALSE;
 
-  /* Nothing to do if there are no codes, no relocations or no output.  */
+  /* Nothing to do if there is no need or no output.  */
   if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
-      || sec->reloc_count == 0
+      || sec->need_convert_mov_to_lea == 0
       || bfd_is_abs_section (sec->output_section))
     return TRUE;
 
index eef0d60..a4974ce 100644 (file)
@@ -1529,6 +1529,10 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
   return TRUE;
 }
 
+/* Rename some of the generic section flags to better document how they
+   are used here.  */
+#define need_convert_mov_to_lea sec_flg0
+
 /* Look through the relocs for a section during the first phase, and
    calculate needed space in the global offset table, procedure
    linkage table, and dynamic reloc sections.  */
@@ -2105,6 +2109,10 @@ do_size:
                                             plt_got_align))
            return FALSE;
        }
+
+      if (r_type == R_X86_64_GOTPCREL
+         && (h == NULL || h->type != STT_GNU_IFUNC))
+       sec->need_convert_mov_to_lea = 1;
     }
 
   return TRUE;
@@ -2886,9 +2894,9 @@ elf_x86_64_convert_mov_to_lea (bfd *abfd, asection *sec,
   if (!is_elf_hash_table (link_info->hash))
     return FALSE;
 
-  /* Nothing to do if there are no codes, no relocations or no output.  */
+  /* Nothing to do if there is no need or no output.  */
   if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
-      || sec->reloc_count == 0
+      || sec->need_convert_mov_to_lea == 0
       || bfd_is_abs_section (sec->output_section))
     return TRUE;