From: H.J. Lu Date: Thu, 14 Sep 2017 18:41:58 +0000 (-0700) Subject: x86: Cache section contents and relocations X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5e5e02aeca4a6edccbf11b5f900d95bba59b9932;p=binutils-gdb.git x86: Cache section contents and relocations bfd/ 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. ld/ PR ld/22135 * testsuite/ld-i386/i386.exp: Run pr22135. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-i386/pr22135.d: New file. * testsuite/ld-i386/pr22135.s: Likewise. * testsuite/ld-x86-64/pr22135.d: Likewise. * testsuite/ld-x86-64/pr22135.s: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3d807b9f6c3..e4df74d3318 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-09-14 H.J. Lu + + 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 PR binutils/22113 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 4337ab0ea0b..d4adaf48dee 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 4371a1625c1..84a26033245 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: diff --git a/ld/ChangeLog b/ld/ChangeLog index 1d052f79eeb..857f4c9856e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2017-09-14 H.J. Lu + + PR ld/22135 + * testsuite/ld-i386/i386.exp: Run pr22135. + * testsuite/ld-x86-64/x86-64.exp: Likewise. + * testsuite/ld-i386/pr22135.d: New file. + * testsuite/ld-i386/pr22135.s: Likewise. + * testsuite/ld-x86-64/pr22135.d: Likewise. + * testsuite/ld-x86-64/pr22135.s: Likewise. + 2017-09-09 Alan Modra * ld.texinfo (--plt-align): Describe new behaviour of option. diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index f691c32e8d2..d79c4583e6c 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -444,6 +444,7 @@ run_dump_test "pr22115-1a" run_dump_test "pr22115-1b" run_dump_test "pr22115-1c" run_dump_test "pr22115-1d" +run_dump_test "pr22135" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] diff --git a/ld/testsuite/ld-i386/pr22135.d b/ld/testsuite/ld-i386/pr22135.d new file mode 100644 index 00000000000..a5796ba5673 --- /dev/null +++ b/ld/testsuite/ld-i386/pr22135.d @@ -0,0 +1,12 @@ +#as: --32 -mrelax-relocations=yes +#ld: -pie -melf_i386 --no-keep-memory +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 8d 81 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%ecx\),%eax +#pass diff --git a/ld/testsuite/ld-i386/pr22135.s b/ld/testsuite/ld-i386/pr22135.s new file mode 100644 index 00000000000..6afad884d1a --- /dev/null +++ b/ld/testsuite/ld-i386/pr22135.s @@ -0,0 +1,11 @@ + .text + .globl foo + .type foo, @function +foo: + ret + .size foo, .-foo + .globl _start + .type _start, @function +_start: + movl foo@GOT(%ecx), %eax + .size _start, .-_start diff --git a/ld/testsuite/ld-x86-64/pr22135.d b/ld/testsuite/ld-x86-64/pr22135.d new file mode 100644 index 00000000000..2cd6861933e --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22135.d @@ -0,0 +1,12 @@ +#as: --64 +#ld: -pie -melf_x86_64 --no-keep-memory +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +#... +[ ]*[a-f0-9]+: 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%eax # [a-f0-9]+ +#pass diff --git a/ld/testsuite/ld-x86-64/pr22135.s b/ld/testsuite/ld-x86-64/pr22135.s new file mode 100644 index 00000000000..f4dff5caa27 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22135.s @@ -0,0 +1,11 @@ + .text + .globl foo + .type foo, @function +foo: + ret + .size foo, .-foo + .globl _start + .type _start, @function +_start: + movl foo@GOTPCREL(%rip), %eax + .size _start, .-_start diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index edf88969f1b..676d44a3d0f 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -377,6 +377,7 @@ run_dump_test "pr22115-1c" run_dump_test "pr22115-1c-x32" run_dump_test "pr22115-1d" run_dump_test "pr22115-1d-x32" +run_dump_test "pr22135" if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} { return