aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2003-06-17 14:22:46 +0000
committerAlan Modra <amodra@gmail.com>2003-06-17 14:22:46 +0000
commit1cf1f67042cebf68c4f0b6cce034d86b10f94342 (patch)
tree40c00701f2e3b466e742a218844a62ccbcf5e4bb /bfd/elf64-ppc.c
parent734b6cf9ae66bb2f7ced350c570aa339fb5ab707 (diff)
downloadgdb-1cf1f67042cebf68c4f0b6cce034d86b10f94342.zip
gdb-1cf1f67042cebf68c4f0b6cce034d86b10f94342.tar.gz
gdb-1cf1f67042cebf68c4f0b6cce034d86b10f94342.tar.bz2
* elf64-ppc.c (ppc64_elf_relocate_section): Do unaligned reloc
optimizations earlier.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 97fd482..6ac58cc 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -8212,6 +8212,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean skip, relocate;
asection *sreloc;
bfd_byte *loc;
+ bfd_vma out_off;
/* When generating a dynamic object, these relocations
are copied into the output file to be resolved at run
@@ -8220,17 +8221,28 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
skip = FALSE;
relocate = FALSE;
- outrel.r_offset =
- _bfd_elf_section_offset (output_bfd, info, input_section,
- rel->r_offset);
- if (outrel.r_offset == (bfd_vma) -1)
+ out_off = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+ if (out_off == (bfd_vma) -1)
skip = TRUE;
- else if (outrel.r_offset == (bfd_vma) -2)
+ else if (out_off == (bfd_vma) -2)
skip = TRUE, relocate = TRUE;
- outrel.r_offset += (input_section->output_section->vma
- + input_section->output_offset);
+ out_off += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel.r_offset = out_off;
outrel.r_addend = rel->r_addend;
+ /* Optimize unaligned reloc use. */
+ if ((r_type == R_PPC64_ADDR64 && (out_off & 7) != 0)
+ || (r_type == R_PPC64_UADDR64 && (out_off & 7) == 0))
+ r_type ^= R_PPC64_ADDR64 ^ R_PPC64_UADDR64;
+ else if ((r_type == R_PPC64_ADDR32 && (out_off & 3) != 0)
+ || (r_type == R_PPC64_UADDR32 && (out_off & 3) == 0))
+ r_type ^= R_PPC64_ADDR32 ^ R_PPC64_UADDR32;
+ else if ((r_type == R_PPC64_ADDR16 && (out_off & 1) != 0)
+ || (r_type == R_PPC64_UADDR16 && (out_off & 1) == 0))
+ r_type ^= R_PPC64_ADDR16 ^ R_PPC64_UADDR16;
+
if (skip)
memset (&outrel, 0, sizeof outrel);
else if (h != NULL
@@ -8297,26 +8309,6 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
- /* Optimize unaligned reloc use. */
- if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR64
- && (outrel.r_offset & 7) != 0)
- || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR64
- && (outrel.r_offset & 7) == 0))
- outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR64)
- ^ ELF64_R_INFO (0, R_PPC64_UADDR64));
- else if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR32
- && (outrel.r_offset & 3) != 0)
- || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR32
- && (outrel.r_offset & 3) == 0))
- outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR32)
- ^ ELF64_R_INFO (0, R_PPC64_UADDR32));
- else if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR16
- && (outrel.r_offset & 1) != 0)
- || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR16
- && (outrel.r_offset & 1) == 0))
- outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR16)
- ^ ELF64_R_INFO (0, R_PPC64_UADDR16));
-
sreloc = elf_section_data (input_section)->sreloc;
if (sreloc == NULL)
abort ();