aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-09-06 05:06:35 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-09-06 05:06:35 -0700
commit78984959cb385388e29dcc88dc169449344f22d7 (patch)
tree728839140d195a3653a3e33e5957ecab476f09e8
parent419414eafcee7cd749ee4622ef25020e48b52cc4 (diff)
downloadgdb-78984959cb385388e29dcc88dc169449344f22d7.zip
gdb-78984959cb385388e29dcc88dc169449344f22d7.tar.gz
gdb-78984959cb385388e29dcc88dc169449344f22d7.tar.bz2
x86-64: Add R_X86_64_converted_reloc_bit
Add R_X86_64_converted_reloc_bit to relocation type to indicate if a relocation is converted from a GOTPCREL relocation. Linker now generates failed to convert GOTPCREL relocation; relink with --no-relax for all cases, including relocations against local symbols. bfd/ * elf64-x86-64.c (R_X86_64_converted_reloc_bit): New. (elf_x86_64_info_to_howto): Get the real relocation type by masking out R_X86_64_converted_reloc_bit. (elf_x86_64_check_tls_transition): Get the real relocation type by masking out R_X86_64_converted_reloc_bit. (elf_x86_64_convert_load_reloc): Set R_X86_64_converted_reloc_bit instead of setting converted_reloc. (elf_x86_64_relocate_section): Check R_X86_64_converted_reloc_bit instead of converted_reloc. Get the real relocation type by masking out R_X86_64_converted_reloc_bit. (elf_x86_64_link_setup_gnu_properties): Verify that the value of R_X86_64_converted_reloc_bit is valid. * elfxx-x86.h (converted_reloc): Removed. ld/ * testsuite/ld-x86-64/pr19609-2a.d: Updated. * testsuite/ld-x86-64/pr19609-2b.d: Likewise. * testsuite/ld-x86-64/pr19609-4a.d: Likewise. * testsuite/ld-x86-64/pr19609-4c.d: Likewise.
-rw-r--r--bfd/ChangeLog16
-rw-r--r--bfd/elf64-x86-64.c42
-rw-r--r--bfd/elfxx-x86.h5
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-x86-64/pr19609-2a.d2
-rw-r--r--ld/testsuite/ld-x86-64/pr19609-2b.d2
-rw-r--r--ld/testsuite/ld-x86-64/pr19609-4a.d3
-rw-r--r--ld/testsuite/ld-x86-64/pr19609-4c.d3
8 files changed, 58 insertions, 22 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f323dfa..9622383 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,21 @@
2017-09-06 H.J. Lu <hongjiu.lu@intel.com>
+ * elf64-x86-64.c (R_X86_64_converted_reloc_bit): New.
+ (elf_x86_64_info_to_howto): Get the real relocation type by
+ masking out R_X86_64_converted_reloc_bit.
+ (elf_x86_64_check_tls_transition): Get the real relocation type
+ by masking out R_X86_64_converted_reloc_bit.
+ (elf_x86_64_convert_load_reloc): Set R_X86_64_converted_reloc_bit
+ instead of setting converted_reloc.
+ (elf_x86_64_relocate_section): Check R_X86_64_converted_reloc_bit
+ instead of converted_reloc. Get the real relocation type by
+ masking out R_X86_64_converted_reloc_bit.
+ (elf_x86_64_link_setup_gnu_properties): Verify that the value of
+ R_X86_64_converted_reloc_bit is valid.
+ * elfxx-x86.h (converted_reloc): Removed.
+
+2017-09-06 H.J. Lu <hongjiu.lu@intel.com>
+
* elf32-i386.c (elf_i386_relocate_section): Don't change r_type
when calling elf_i386_tls_transition. Don't use ELF32_R_TYPE
to get the relocation type again.
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 8807447..8f1ac1a 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -196,6 +196,9 @@ static reloc_howto_type x86_64_elf_howto_table[] =
FALSE)
};
+/* Set if a relocation is converted from a GOTPCREL relocation. */
+#define R_X86_64_converted_reloc_bit (1 << 7)
+
#define IS_X86_64_PCREL_TYPE(TYPE) \
( ((TYPE) == R_X86_64_PC8) \
|| ((TYPE) == R_X86_64_PC16) \
@@ -337,6 +340,9 @@ elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
unsigned r_type;
r_type = ELF32_R_TYPE (dst->r_info);
+ if (r_type != (unsigned int) R_X86_64_GNU_VTINHERIT
+ && r_type != (unsigned int) R_X86_64_GNU_VTENTRY)
+ r_type &= ~R_X86_64_converted_reloc_bit;
cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
BFD_ASSERT (r_type == cache_ptr->howto->type);
}
@@ -1145,13 +1151,17 @@ elf_x86_64_check_tls_transition (bfd *abfd,
if (h == NULL
|| !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
return FALSE;
- else if (largepic)
- return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLTOFF64;
- else if (indirect_call)
- return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_GOTPCRELX;
else
- return (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
- || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
+ {
+ r_type = (ELF32_R_TYPE (rel[1].r_info)
+ & ~R_X86_64_converted_reloc_bit);
+ if (largepic)
+ return r_type == R_X86_64_PLTOFF64;
+ else if (indirect_call)
+ return r_type == R_X86_64_GOTPCRELX;
+ else
+ return (r_type == R_X86_64_PC32 || r_type == R_X86_64_PLT32);
+ }
case R_X86_64_GOTTPOFF:
/* Check transition from IE access model:
@@ -1598,9 +1608,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
return TRUE;
convert:
- if (h != NULL)
- ((struct elf_x86_link_hash_entry *) h)->converted_reloc = 1;
-
if (opcode == 0xff)
{
/* We have "call/jmp *foo@GOTPCREL(%rip)". */
@@ -1742,7 +1749,8 @@ rewrite_modrm_rex:
bfd_put_8 (abfd, opcode, contents + roff - 2);
}
- irel->r_info = htab->r_info (r_symndx, r_type);
+ irel->r_info = htab->r_info (r_symndx,
+ r_type | R_X86_64_converted_reloc_bit);
*converted = TRUE;
@@ -2527,6 +2535,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
bfd_vma st_size;
bfd_boolean resolved_to_zero;
bfd_boolean relative_reloc;
+ bfd_boolean converted_reloc;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_X86_64_GNU_VTINHERIT
@@ -2537,6 +2546,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
continue;
}
+ converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0;
+ r_type &= ~R_X86_64_converted_reloc_bit;
+
if (r_type >= (int) R_X86_64_standard)
return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
@@ -4011,7 +4023,7 @@ check_relocation_error:
if (r == bfd_reloc_overflow)
{
- if (eh != NULL && eh->converted_reloc)
+ if (converted_reloc)
{
info->callbacks->einfo
(_("%F%P: failed to convert GOTPCREL relocation; relink with --no-relax\n"));
@@ -5250,6 +5262,14 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
{
struct elf_x86_plt_layout_table plt_layout;
+ if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit
+ || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit
+ || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit)
+ != (int) R_X86_64_GNU_VTINHERIT)
+ || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit)
+ != (int) R_X86_64_GNU_VTENTRY))
+ abort ();
+
plt_layout.is_vxworks = FALSE;
if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal)
{
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 775e025..9c0dcbbe 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -110,11 +110,6 @@ struct elf_x86_link_hash_entry
is only used by x86-64. */
unsigned int needs_copy : 1;
- /* TRUE if a symbol with GOTPCREL relocations which have been converted
- to R_X86_64_PC32, R_X86_64_32 or R_X86_64_32S. This is only used by
- x86-64 for now. */
- unsigned int converted_reloc : 1;
-
/* Reference count of C/C++ function pointer relocations in read-write
section which can be resolved at run-time. */
bfd_signed_vma func_pointer_refcount;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7313795..98318e9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2017-09-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * testsuite/ld-x86-64/pr19609-2a.d: Updated.
+ * testsuite/ld-x86-64/pr19609-2b.d: Likewise.
+ * testsuite/ld-x86-64/pr19609-4a.d: Likewise.
+ * testsuite/ld-x86-64/pr19609-4c.d: Likewise.
+
2017-09-05 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-x86-64/pr19609-5d.d: Updated.
diff --git a/ld/testsuite/ld-x86-64/pr19609-2a.d b/ld/testsuite/ld-x86-64/pr19609-2a.d
index e2c6c89..2bed641 100644
--- a/ld/testsuite/ld-x86-64/pr19609-2a.d
+++ b/ld/testsuite/ld-x86-64/pr19609-2a.d
@@ -1,4 +1,4 @@
#source: pr19609-2.s
#as: --64 -mrelax-relocations=yes
#ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
diff --git a/ld/testsuite/ld-x86-64/pr19609-2b.d b/ld/testsuite/ld-x86-64/pr19609-2b.d
index ead4987..3741ebb 100644
--- a/ld/testsuite/ld-x86-64/pr19609-2b.d
+++ b/ld/testsuite/ld-x86-64/pr19609-2b.d
@@ -1,4 +1,4 @@
#source: pr19609-2.s
#as: --x32 -mrelax-relocations=yes
#ld: -melf32_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
diff --git a/ld/testsuite/ld-x86-64/pr19609-4a.d b/ld/testsuite/ld-x86-64/pr19609-4a.d
index ce952ed..f08843c 100644
--- a/ld/testsuite/ld-x86-64/pr19609-4a.d
+++ b/ld/testsuite/ld-x86-64/pr19609-4a.d
@@ -1,5 +1,4 @@
#source: pr19609-4.s
#as: --64 -mrelax-relocations=yes
#ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax
diff --git a/ld/testsuite/ld-x86-64/pr19609-4c.d b/ld/testsuite/ld-x86-64/pr19609-4c.d
index ce952ed..f08843c 100644
--- a/ld/testsuite/ld-x86-64/pr19609-4c.d
+++ b/ld/testsuite/ld-x86-64/pr19609-4c.d
@@ -1,5 +1,4 @@
#source: pr19609-4.s
#as: --64 -mrelax-relocations=yes
#ld: -melf_x86_64 -Ttext=0x70000000 -Tdata=0xa0000000
-#error: .*relocation truncated to fit: R_X86_64_32S .*
-#error: .*relocation truncated to fit: R_X86_64_32S .*
+#error: failed to convert GOTPCREL relocation; relink with --no-relax