From 248775ba37b0ef8b8ef46b34b231a569722e628c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 14 Jan 2011 22:48:12 +0000 Subject: [PATCH] Handle R_X86_64_32 like R_X86_64_64 for ILP32. bfd/ 2011-01-14 H.J. Lu * elf64-x86-64.c (elf_x86_64_link_hash_table): Add pointer_r_type. (elf_x86_64_link_hash_table_create): Set pointer_r_type. (elf_x86_64_check_relocs): Handle R_X86_64_32 like R_X86_64_64 for ILP32. Remove ABI_64_P PIC check for R_X86_64_8, R_X86_64_16, R_X86_64_32 and R_X86_64_32S. (elf_x86_64_relocate_section): Handle R_X86_64_32 like R_X86_64_64 for ILP32. ld/testsuite/ 2011-01-14 H.J. Lu * ld-x86-64/ilp32-5.d: New. * ld-x86-64/ilp32-5.s: Likewise. * ld-x86-64/x86-64.exp: Run ilp32-5. --- bfd/ChangeLog | 10 ++++++++++ bfd/elf64-x86-64.c | 20 +++++++++++++++----- ld/testsuite/ChangeLog | 7 +++++++ ld/testsuite/ld-x86-64/ilp32-5.d | 8 ++++++++ ld/testsuite/ld-x86-64/ilp32-5.s | 8 ++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 1 + 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-x86-64/ilp32-5.d create mode 100644 ld/testsuite/ld-x86-64/ilp32-5.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f14a7cb272..37c49a370b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2011-01-14 H.J. Lu + + * elf64-x86-64.c (elf_x86_64_link_hash_table): Add pointer_r_type. + (elf_x86_64_link_hash_table_create): Set pointer_r_type. + (elf_x86_64_check_relocs): Handle R_X86_64_32 like R_X86_64_64 + for ILP32. Remove ABI_64_P PIC check for R_X86_64_8, + R_X86_64_16, R_X86_64_32 and R_X86_64_32S. + (elf_x86_64_relocate_section): Handle R_X86_64_32 like R_X86_64_64 + for ILP32. + 2011-01-14 Alan Modra * bfd.c (bfd_perror): Flush stdout before and stderr after printing diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 6066330f4c..579f59cd7f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -495,6 +495,7 @@ struct elf_x86_64_link_hash_table bfd_vma (*r_info) (bfd_vma, bfd_vma); bfd_vma (*r_sym) (bfd_vma); + unsigned int pointer_r_type; const char *dynamic_interpreter; int dynamic_interpreter_size; @@ -658,6 +659,7 @@ elf_x86_64_link_hash_table_create (bfd *abfd) { ret->r_info = elf64_r_info; ret->r_sym = elf64_r_sym; + ret->pointer_r_type = R_X86_64_64; ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER; ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER; } @@ -665,6 +667,7 @@ elf_x86_64_link_hash_table_create (bfd *abfd) { ret->r_info = elf32_r_info; ret->r_sym = elf32_r_sym; + ret->pointer_r_type = R_X86_64_32; ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER; ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER; } @@ -1232,6 +1235,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, bfd_set_error (bfd_error_bad_value); return FALSE; + case R_X86_64_32: + if (ABI_64_P (abfd)) + goto not_pointer; case R_X86_64_64: h->non_got_ref = 1; h->pointer_equality_needed = 1; @@ -1249,9 +1255,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, break; case R_X86_64_32S: - case R_X86_64_32: case R_X86_64_PC32: case R_X86_64_PC64: +not_pointer: h->non_got_ref = 1; if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64) @@ -1448,16 +1454,17 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, } goto create_got; + case R_X86_64_32: + if (!ABI_64_P (abfd)) + goto pointer; case R_X86_64_8: case R_X86_64_16: - case R_X86_64_32: case R_X86_64_32S: /* Let's help debug shared library creation. These relocs cannot be used in shared libs. Don't error out for sections we don't care about, such as debug sections or non-constant sections. */ if (info->shared - && ABI_64_P (abfd) && (sec->flags & SEC_ALLOC) != 0 && (sec->flags & SEC_READONLY) != 0) { @@ -1478,6 +1485,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_PC32: case R_X86_64_PC64: case R_X86_64_64: +pointer: if (h != NULL && info->executable) { /* If this reloc is in a read-only section, we might @@ -2830,6 +2838,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, abort (); goto do_relocation; + case R_X86_64_32: + if (ABI_64_P (output_bfd)) + goto do_relocation; case R_X86_64_64: if (rel->r_addend != 0) { @@ -2894,7 +2905,6 @@ elf_x86_64_relocate_section (bfd *output_bfd, continue; } - case R_X86_64_32: case R_X86_64_PC32: case R_X86_64_PC64: case R_X86_64_PLT32: @@ -3307,7 +3317,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, else { /* This symbol is local, or marked to become local. */ - if (r_type == R_X86_64_64) + if (r_type == htab->pointer_r_type) { relocate = TRUE; outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 02c0c34327..897e3db8f0 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-01-14 H.J. Lu + + * ld-x86-64/ilp32-5.d: New. + * ld-x86-64/ilp32-5.s: Likewise. + + * ld-x86-64/x86-64.exp: Run ilp32-5. + 2011-01-13 H.J. Lu * ld-x86-64/ilp32-4.d: New. diff --git a/ld/testsuite/ld-x86-64/ilp32-5.d b/ld/testsuite/ld-x86-64/ilp32-5.d new file mode 100644 index 0000000000..8f5025ebe9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-5.d @@ -0,0 +1,8 @@ +#as: --n32 +#ld: -m elf32_x86_64 -shared +#readelf: -r --wide + +#... +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_PC32 +[0-9a-f]+ +foo - 4 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +foo \+ 0 diff --git a/ld/testsuite/ld-x86-64/ilp32-5.s b/ld/testsuite/ld-x86-64/ilp32-5.s new file mode 100644 index 0000000000..0d97807395 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-5.s @@ -0,0 +1,8 @@ + .globl bar +bar: + mov foo(%rip), %rax + + .data +xxx: + .long foo + .long xxx diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 3aec797619..e69ade6c42 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -176,6 +176,7 @@ run_dump_test "ilp32-1" run_dump_test "ilp32-2" run_dump_test "ilp32-3" run_dump_test "ilp32-4" +run_dump_test "ilp32-5" run_dump_test "ia32-1" run_dump_test "ia32-2" run_dump_test "ia32-3"