diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 18 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 15 |
3 files changed, 38 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3d807b9..e4df74d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-09-14 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/22135 + * elf32-i386.c (elf_i386_convert_load_reloc): Add an argument + to indicate if conversion is performed. + (elf_i386_check_relocs): Cache section contents and relocations + if conversion is performed. + * elf64-x86-64.c (elf_x86_64_check_relocs): Cache section + contents and relocations if conversion is performed. + 2017-09-14 Nick Clifton <nickc@redhat.com> PR binutils/22113 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 4337ab0..d4adaf4 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1214,6 +1214,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, unsigned int *r_type_p, Elf_Internal_Rela *irel, struct elf_link_hash_entry *h, + bfd_boolean *converted, struct bfd_link_info *link_info) { struct elf_x86_link_hash_table *htab; @@ -1369,6 +1370,7 @@ convert_branch: bfd_put_32 (abfd, -4, contents + irel->r_offset); irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32); *r_type_p = R_386_PC32; + *converted = TRUE; } } else @@ -1441,6 +1443,7 @@ convert_load: bfd_put_8 (abfd, opcode, contents + roff - 2); irel->r_info = ELF32_R_INFO (r_symndx, r_type); *r_type_p = r_type; + *converted = TRUE; } } @@ -1468,6 +1471,7 @@ elf_i386_check_relocs (bfd *abfd, const Elf_Internal_Rela *rel_end; asection *sreloc; bfd_byte *contents; + bfd_boolean converted; if (bfd_link_relocatable (info)) return TRUE; @@ -1502,6 +1506,8 @@ elf_i386_check_relocs (bfd *abfd, symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = elf_sym_hashes (abfd); + converted = FALSE; + sreloc = NULL; rel_end = relocs + sec->reloc_count; @@ -1582,7 +1588,8 @@ elf_i386_check_relocs (bfd *abfd, { Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel; if (!elf_i386_convert_load_reloc (abfd, symtab_hdr, contents, - &r_type, irel, h, info)) + &r_type, irel, h, + &converted, info)) goto error_return; } @@ -1937,15 +1944,20 @@ do_size: if (elf_section_data (sec)->this_hdr.contents != contents) { - if (!info->keep_memory) + if (!converted && !info->keep_memory) free (contents); else { - /* Cache the section contents for elf_link_input_bfd. */ + /* Cache the section contents for elf_link_input_bfd if any + load is converted or --no-keep-memory isn't used. */ elf_section_data (sec)->this_hdr.contents = contents; } } + /* Cache relocations if any load is converted. */ + if (elf_section_data (sec)->relocs != relocs && converted) + elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs; + return TRUE; error_return: diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 4371a16..84a2603 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1780,6 +1780,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Rela *rel_end; asection *sreloc; bfd_byte *contents; + bfd_boolean converted; if (bfd_link_relocatable (info)) return TRUE; @@ -1814,6 +1815,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = elf_sym_hashes (abfd); + converted = FALSE; + sreloc = NULL; rel_end = relocs + sec->reloc_count; @@ -1931,6 +1934,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, irel, h, &converted_reloc, info)) goto error_return; + + if (converted_reloc) + converted = TRUE; } if (! elf_x86_64_tls_transition (info, abfd, sec, contents, @@ -2306,15 +2312,20 @@ do_size: if (elf_section_data (sec)->this_hdr.contents != contents) { - if (!info->keep_memory) + if (!converted && !info->keep_memory) free (contents); else { - /* Cache the section contents for elf_link_input_bfd. */ + /* Cache the section contents for elf_link_input_bfd if any + load is converted or --no-keep-memory isn't used. */ elf_section_data (sec)->this_hdr.contents = contents; } } + /* Cache relocations if any load is converted. */ + if (elf_section_data (sec)->relocs != relocs && converted) + elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs; + return TRUE; error_return: |