This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[committed, PATCH] Convert mov to lea only if needed
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Fri, 27 Feb 2015 11:36:34 -0800
- Subject: [committed, PATCH] Convert mov to lea only if needed
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
We can convert mov to lea only if there are R_386_GOT32/R_X86_64_GOTPCREL
relocations against non IFUNC symbols. I checked it into master.
H.J.
--
* 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 | 11 +++++++++++
bfd/elf32-i386.c | 12 ++++++++++--
bfd/elf64-x86-64.c | 12 ++++++++++--
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1b223f9..8cd5741 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 8028b05..3f16fc1 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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;
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index eef0d60..a4974ce 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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;
--
1.9.3