diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-02-27 11:27:31 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-02-27 11:35:37 -0800 |
commit | c1d11331c9d84541b5002314f8cee2f302dd5763 (patch) | |
tree | 20a1c9d6079f76f679264cae50cc74d1c6a1cdf4 /bfd/elf32-i386.c | |
parent | bf36a1e7df75608045be60a5d16a1df207df3464 (diff) | |
download | binutils-c1d11331c9d84541b5002314f8cee2f302dd5763.zip binutils-c1d11331c9d84541b5002314f8cee2f302dd5763.tar.gz binutils-c1d11331c9d84541b5002314f8cee2f302dd5763.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 12 |
1 files changed, 10 insertions, 2 deletions
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; |