From bedfd056d4d58a3ebaf8d396c8453f0d0468576f Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 5 May 2016 04:11:57 -0700 Subject: [PATCH] Cache the section contents in x86 check_relocs Cache the section contents in x86 check_relocs for sections without TLS relocations. * elf32-i386.c (elf_i386_check_tls_transition): Remove abfd. Don't check if contents == NULL. (elf_i386_tls_transition): Add from_relocate_section. Check from_relocate_section instead of contents != NULL. Update elf_i386_check_tls_transition call. (elf_i386_check_relocs): Cache the section contents if keep_memory is FALSE. Pass FALSE as from_relocate_section to elf_i386_tls_transition. (elf_i386_relocate_section): Pass TRUE as from_relocate_section to elf_i386_tls_transition. (elf_backend_caches_rawsize): New. * elf64-x86-64.c (elf_x86_64_check_tls_transition): Don't check if contents == NULL. (elf_x86_64_tls_transition): Add from_relocate_section. Check from_relocate_section instead of contents != NULL. (elf_x86_64_check_relocs): Cache the section contents if keep_memory is FALSE. Pass FALSE as from_relocate_section to elf_x86_64_tls_transition. (elf_x86_64_relocate_section): Pass TRUE as from_relocate_section to elf_x86_64_tls_transition. (elf_backend_caches_rawsize): New. --- bfd/ChangeLog | 24 ++++++++++++++++++ bfd/elf32-i386.c | 62 ++++++++++++++++++++++++++-------------------- bfd/elf64-x86-64.c | 60 +++++++++++++++++++++++++------------------- 3 files changed, 93 insertions(+), 53 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 41feb85d820..6f5afee6c64 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,27 @@ +2016-05-05 H.J. Lu + + * elf32-i386.c (elf_i386_check_tls_transition): Remove abfd. + Don't check if contents == NULL. + (elf_i386_tls_transition): Add from_relocate_section. Check + from_relocate_section instead of contents != NULL. Update + elf_i386_check_tls_transition call. + (elf_i386_check_relocs): Cache the section contents if + keep_memory is FALSE. Pass FALSE as from_relocate_section to + elf_i386_tls_transition. + (elf_i386_relocate_section): Pass TRUE as from_relocate_section + to elf_i386_tls_transition. + (elf_backend_caches_rawsize): New. + * elf64-x86-64.c (elf_x86_64_check_tls_transition): Don't check + if contents == NULL. + (elf_x86_64_tls_transition): Add from_relocate_section. Check + from_relocate_section instead of contents != NULL. + (elf_x86_64_check_relocs): Cache the section contents if + keep_memory is FALSE. Pass FALSE as from_relocate_section to + elf_x86_64_tls_transition. + (elf_x86_64_relocate_section): Pass TRUE as from_relocate_section + to elf_x86_64_tls_transition. + (elf_backend_caches_rawsize): New. + 2016-05-03 Maciej W. Rozycki PR 10549 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index c45697c0db2..ff0f140f388 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1208,7 +1208,7 @@ elf_i386_copy_indirect_symbol (struct bfd_link_info *info, from R_TYPE. */ static bfd_boolean -elf_i386_check_tls_transition (bfd *abfd, asection *sec, +elf_i386_check_tls_transition (asection *sec, bfd_byte *contents, Elf_Internal_Shdr *symtab_hdr, struct elf_link_hash_entry **sym_hashes, @@ -1221,22 +1221,6 @@ elf_i386_check_tls_transition (bfd *abfd, asection *sec, struct elf_link_hash_entry *h; bfd_vma offset; - /* Get the section contents. */ - if (contents == NULL) - { - if (elf_section_data (sec)->this_hdr.contents != NULL) - contents = elf_section_data (sec)->this_hdr.contents; - else - { - /* FIXME: How to better handle error condition? */ - if (!bfd_malloc_and_get_section (abfd, sec, &contents)) - return FALSE; - - /* Cache the section contents for elf_link_input_bfd. */ - elf_section_data (sec)->this_hdr.contents = contents; - } - } - offset = rel->r_offset; switch (r_type) { @@ -1397,7 +1381,8 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, const Elf_Internal_Rela *rel, const Elf_Internal_Rela *relend, struct elf_link_hash_entry *h, - unsigned long r_symndx) + unsigned long r_symndx, + bfd_boolean from_relocate_section) { unsigned int from_type = *r_type; unsigned int to_type = from_type; @@ -1426,10 +1411,9 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, to_type = R_386_TLS_IE_32; } - /* When we are called from elf_i386_relocate_section, CONTENTS - isn't NULL and there may be additional transitions based on - TLS_TYPE. */ - if (contents != NULL) + /* When we are called from elf_i386_relocate_section, there may + be additional transitions based on TLS_TYPE. */ + if (from_relocate_section) { unsigned int new_to_type = to_type; @@ -1473,7 +1457,7 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, /* Check if the transition can be performed. */ if (check - && ! elf_i386_check_tls_transition (abfd, sec, contents, + && ! elf_i386_check_tls_transition (sec, contents, symtab_hdr, sym_hashes, from_type, rel, relend)) { @@ -1536,6 +1520,7 @@ elf_i386_check_relocs (bfd *abfd, const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; asection *sreloc; + bfd_byte *contents; bfd_boolean use_plt_got; if (bfd_link_relocatable (info)) @@ -1550,6 +1535,15 @@ elf_i386_check_relocs (bfd *abfd, return FALSE; } + /* Get the section contents. */ + if (elf_section_data (sec)->this_hdr.contents != NULL) + contents = elf_section_data (sec)->this_hdr.contents; + else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) + { + sec->check_relocs_failed = 1; + return FALSE; + } + use_plt_got = (!get_elf_i386_backend_data (abfd)->is_vxworks && (get_elf_i386_backend_data (abfd) == &elf_i386_arch_bed)); @@ -1649,10 +1643,10 @@ elf_i386_check_relocs (bfd *abfd, |= elf_gnu_symbol_ifunc; } - if (! elf_i386_tls_transition (info, abfd, sec, NULL, + if (! elf_i386_tls_transition (info, abfd, sec, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, rel_end, h, r_symndx)) + rel, rel_end, h, r_symndx, FALSE)) goto error_return; switch (r_type) @@ -2029,9 +2023,22 @@ do_size: sec->need_convert_load = 1; } + if (elf_section_data (sec)->this_hdr.contents != contents) + { + if (!info->keep_memory) + free (contents); + else + { + /* Cache the section contents for elf_link_input_bfd. */ + elf_section_data (sec)->this_hdr.contents = contents; + } + } + return TRUE; error_return: + if (elf_section_data (sec)->this_hdr.contents != contents) + free (contents); sec->check_relocs_failed = 1; return FALSE; } @@ -4356,7 +4363,7 @@ r_386_got32: input_section, contents, symtab_hdr, sym_hashes, &r_type, tls_type, rel, - relend, h, r_symndx)) + relend, h, r_symndx, TRUE)) return FALSE; if (r_type == R_386_TLS_LE_32) @@ -4817,7 +4824,7 @@ r_386_got32: input_section, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, rel, - relend, h, r_symndx)) + relend, h, r_symndx, TRUE)) return FALSE; if (r_type != R_386_TLS_LDM) @@ -5818,6 +5825,7 @@ elf_i386_add_symbol_hook (bfd * abfd, #define elf_backend_got_header_size 12 #define elf_backend_plt_alignment 4 #define elf_backend_extern_protected_data 1 +#define elf_backend_caches_rawsize 1 /* Support RELA for objdump of prelink objects. */ #define elf_info_to_howto elf_i386_info_to_howto_rel diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 364379aa701..6c55a60c508 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1280,22 +1280,6 @@ elf_x86_64_check_tls_transition (bfd *abfd, bfd_vma offset; struct elf_x86_64_link_hash_table *htab; - /* Get the section contents. */ - if (contents == NULL) - { - if (elf_section_data (sec)->this_hdr.contents != NULL) - contents = elf_section_data (sec)->this_hdr.contents; - else - { - /* FIXME: How to better handle error condition? */ - if (!bfd_malloc_and_get_section (abfd, sec, &contents)) - return FALSE; - - /* Cache the section contents for elf_link_input_bfd. */ - elf_section_data (sec)->this_hdr.contents = contents; - } - } - htab = elf_x86_64_hash_table (info); offset = rel->r_offset; switch (r_type) @@ -1483,7 +1467,8 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, const Elf_Internal_Rela *rel, const Elf_Internal_Rela *relend, struct elf_link_hash_entry *h, - unsigned long r_symndx) + unsigned long r_symndx, + bfd_boolean from_relocate_section) { unsigned int from_type = *r_type; unsigned int to_type = from_type; @@ -1509,10 +1494,9 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, to_type = R_X86_64_GOTTPOFF; } - /* When we are called from elf_x86_64_relocate_section, - CONTENTS isn't NULL and there may be additional transitions - based on TLS_TYPE. */ - if (contents != NULL) + /* When we are called from elf_x86_64_relocate_section, there may + be additional transitions based on TLS_TYPE. */ + if (from_relocate_section) { unsigned int new_to_type = to_type; @@ -1665,6 +1649,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; asection *sreloc; + bfd_byte *contents; bfd_boolean use_plt_got; if (bfd_link_relocatable (info)) @@ -1679,6 +1664,15 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, return FALSE; } + /* Get the section contents. */ + if (elf_section_data (sec)->this_hdr.contents != NULL) + contents = elf_section_data (sec)->this_hdr.contents; + else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) + { + sec->check_relocs_failed = 1; + return FALSE; + } + use_plt_got = get_elf_x86_64_backend_data (abfd) == &elf_x86_64_arch_bed; symtab_hdr = &elf_symtab_hdr (abfd); @@ -1851,10 +1845,10 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, |= elf_gnu_symbol_ifunc; } - if (! elf_x86_64_tls_transition (info, abfd, sec, NULL, + if (! elf_x86_64_tls_transition (info, abfd, sec, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, rel_end, h, r_symndx)) + rel, rel_end, h, r_symndx, FALSE)) goto error_return; eh = (struct elf_x86_64_link_hash_entry *) h; @@ -2264,9 +2258,22 @@ do_size: sec->need_convert_load = 1; } + if (elf_section_data (sec)->this_hdr.contents != contents) + { + if (!info->keep_memory) + free (contents); + else + { + /* Cache the section contents for elf_link_input_bfd. */ + elf_section_data (sec)->this_hdr.contents = contents; + } + } + return TRUE; error_return: + if (elf_section_data (sec)->this_hdr.contents != contents) + free (contents); sec->check_relocs_failed = 1; return FALSE; } @@ -4808,7 +4815,7 @@ direct: input_section, contents, symtab_hdr, sym_hashes, &r_type, tls_type, rel, - relend, h, r_symndx)) + relend, h, r_symndx, TRUE)) return FALSE; if (r_type == R_X86_64_TPOFF32) @@ -5195,8 +5202,8 @@ direct: if (! elf_x86_64_tls_transition (info, input_bfd, input_section, contents, symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, relend, h, r_symndx)) + &r_type, GOT_UNKNOWN, rel, + relend, h, r_symndx, TRUE)) return FALSE; if (r_type != R_X86_64_TLSLD) @@ -6443,6 +6450,7 @@ static const struct bfd_elf_special_section #define elf_backend_rela_normal 1 #define elf_backend_plt_alignment 4 #define elf_backend_extern_protected_data 1 +#define elf_backend_caches_rawsize 1 #define elf_info_to_howto elf_x86_64_info_to_howto -- 2.30.2