From c1d11331c9d84541b5002314f8cee2f302dd5763 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 27 Feb 2015 11:27:31 -0800 Subject: [PATCH] Convert mov to lea only if needed 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 | 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 1b223f989e8..8cd57411632 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2015-02-27 H.J. Lu + + * 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 PR binutils/17910 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 8028b05bb5d..3f16fc1013b 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 eef0d60036b..a4974cee52c 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; -- 2.30.2