This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Fix x86-64 relocations
- To: patches at x86-64 dot org
- Subject: Fix x86-64 relocations
- From: Andreas Jaeger <aj at suse dot de>
- Date: 31 May 2001 17:17:54 +0200
- Cc: binutils at sources dot redhat dot com
On x86-64 we generated 32 bit relocations even for some 8/16 and 64
bit relocations and used the 64 bit relative condition without
checking for sizes.
This code follows the code from m68k (guess who looked over the
code;-) and produces working dynamic binaries (at least one works, now
I'll have fix the next bug).
I'll commit this later after some more testing and incorporating any
comments I get.
Andreas
2001-05-31 Andreas Jaeger <aj@suse.de>
* elf64-x86-64.c (elf64_x86_64_relocate_section): Don't use 32 bit
relocations for all types, fix logic.
============================================================
Index: bfd/elf64-x86-64.c
--- bfd/elf64-x86-64.c 2001/05/30 18:44:46 1.17
+++ bfd/elf64-x86-64.c 2001/05/31 12:47:33
@@ -1264,12 +1264,12 @@
&& ((! info->symbolic && h->dynindx != -1)
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)
- && ( r_type == R_X86_64_8 ||
- r_type == R_X86_64_16 ||
- r_type == R_X86_64_32 ||
- r_type == R_X86_64_64 ||
- r_type == R_X86_64_PC16 ||
- r_type == R_X86_64_PC32)
+ && ( r_type == R_X86_64_8
+ || r_type == R_X86_64_16
+ || r_type == R_X86_64_32
+ || r_type == R_X86_64_64
+ || r_type == R_X86_64_PC16
+ || r_type == R_X86_64_PC32)
&& ((input_section->flags & SEC_ALLOC) != 0
/* DWARF will emit R_X86_64_32 relocations in its
sections against symbols defined externally
@@ -1433,24 +1433,26 @@
+ h->plt.offset);
break;
+ case R_X86_64_PC8:
+ case R_X86_64_PC16:
+ case R_X86_64_PC32:
+ if (h == NULL)
+ break;
+ /* Fall through. */
case R_X86_64_8:
case R_X86_64_16:
case R_X86_64_32:
case R_X86_64_64:
- case R_X86_64_PC8:
- case R_X86_64_PC16:
- case R_X86_64_PC32:
- /* FIXME: The abi says the linker should make sure the value is
+ /* FIXME: The ABI says the linker should make sure the value is
the same when it's zeroextended to 64 bit. */
if (info->shared
&& (input_section->flags & SEC_ALLOC) != 0
- && ((r_type != R_X86_64_PC8 && r_type != R_X86_64_PC16
+ && ((r_type != R_X86_64_PC8
+ && r_type != R_X86_64_PC16
&& r_type != R_X86_64_PC32)
- || (h != NULL
- && h->dynindx != -1
- && (! info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ || (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))
{
Elf_Internal_Rela outrel;
boolean skip, relocate;
@@ -1505,22 +1507,21 @@
memset (&outrel, 0, sizeof outrel);
relocate = false;
}
- else if ((r_type == R_X86_64_PC8) || (r_type == R_X86_64_PC16)
- || (r_type == R_X86_64_PC32))
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ else if (h != NULL
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
{
- BFD_ASSERT (h != NULL && h->dynindx != -1);
+ BFD_ASSERT (h->dynindx != -1);
relocate = false;
outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
outrel.r_addend = relocation + rela->r_addend;
}
else
{
- /* h->dynindx may be -1 if this symbol was marked to
- become local. */
- if (h == NULL
- || ((info->symbolic || h->dynindx == -1)
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ if (r_type == R_X86_64_64)
{
relocate = true;
outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
@@ -1528,9 +1529,35 @@
}
else
{
- BFD_ASSERT (h->dynindx != -1);
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ BFD_ASSERT (indx > 0);
+ }
+
relocate = false;
- outrel.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_32);
+ outrel.r_info = ELF64_R_INFO (indx, r_type);
outrel.r_addend = relocation + rela->r_addend;
}
}
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.inka.de
http://www.suse.de/~aj