summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-06-14 11:16:59 +0000
committerNick Clifton <nickc@redhat.com>2001-06-14 11:16:59 +0000
commit46b7ef954fd286ff144d96f3ae4d7aee996598ae (patch)
treecf94ad044072428a8a950ad990a4685dea216fb9
parent97c347f45ab7cdb42b217a791d8dd24980fb9671 (diff)
downloadgdb-46b7ef954fd286ff144d96f3ae4d7aee996598ae.tar.gz
Import changes from mainline into 2-11 branch
-rw-r--r--bfd/ChangeLog20
-rw-r--r--bfd/coff-arm.c64
-rw-r--r--bfd/config.bfd6
-rw-r--r--bfd/elf32-arm.h24
4 files changed, 85 insertions, 29 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a5107ec58ec..d21c4a09fa8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,23 @@
+2001-06-14 Nick Clifton <nickc@redhat.com>
+
+ Merge from mainline sources:
+ 2001-04-27 Sean McNeil <sean@mcneil.com>
+ * config.bfd: Add arm-vxworks target.
+ * coff-arm (coff_arm_relocate_section): Add in symbol value to
+ addend (fro VXworks targets).
+ 2001-03-06 Nick Clifton <nickc@redhat.com>
+ * elf32-arm.h (elf32_arm_final_link_relocate): Clear bit zero
+ of offset in BLX(1) instruction.
+ * coff-arm.c (coff_arm_relocate_section): Clear bit zero of
+ offset in BLX(1) instruction.
+ Fix formatting.
+ 2001-03-06 Nick Clifton <nickc@redhat.com>
+ * coff-arm.c (coff_arm_reloc_type_lookup): Add
+ BFD_RELOC_THUMB_PCREL_BLX.
+ 2001-05-04 Nick Clifton <nickc@cambridge.redhat.com>
+ * elf32-arm.h (elf32_arm_final_link_relocate): Set
+ EF_ARM_HASENTRY if the start address is set.
+
2001-06-11 Alan Modra <amodra@bigpond.net.au>
* configure.in (<COREFILE case stmt>): Move powerpc-*-*bsd* after
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index a315874b00f..8bb4e6c4940 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -854,6 +854,7 @@ coff_arm_reloc_type_lookup (abfd, code)
ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9);
ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
+ ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23);
#endif
default: return (CONST struct reloc_howto_struct *) 0;
}
@@ -1243,12 +1244,18 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
{
if (info->relocateable)
continue;
-#if 0 /* We must not ignore the symbol value. If the symbol is
- within the same section, the relocation should have already
- been fixed, but if it is not, we'll be handed a reloc into
- the beginning of the symbol's section, so we must not cancel
- out the symbol's value, otherwise we'll be adding it in
- twice. */
+ /* FIXME - it is not clear which targets need this next test
+ and which do not. It is known that it is needed for the
+ VXworks target (hence the #ifdef), but it is also known
+ that it was supressed for other (arm) targets. This ought
+ to be sorted out one day. */
+#ifdef VXWORKS
+ /* We must not ignore the symbol value. If the symbol is
+ within the same section, the relocation should have already
+ been fixed, but if it is not, we'll be handed a reloc into
+ the beginning of the symbol's section, so we must not cancel
+ out the symbol's value, otherwise we'll be adding it in
+ twice. */
if (sym != NULL && sym->n_scnum != 0)
addend += sym->n_value;
#endif
@@ -1588,18 +1595,18 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
BFD_ASSERT (size == 4);
- /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
+ /* howto->pc_relative should be TRUE for type 14 BRANCH23. */
relocation -= (input_section->output_section->vma
+ input_section->output_offset);
- /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
+ /* howto->pcrel_offset should be TRUE for type 14 BRANCH23. */
relocation -= address;
/* No need to negate the relocation with BRANCH23. */
/* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
/* howto->rightshift == 1 */
- /* Drop unwanted bits from the value we are relocating to. */
+ /* Drop unwanted bits from the value we are relocating to. */
check = relocation >> howto->rightshift;
/* If this is a signed value, the rightshift just dropped
@@ -1613,13 +1620,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
/* Get the value from the object file. */
if (bfd_big_endian (input_bfd))
- {
- add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
- }
+ add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
else
- {
- add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
- }
+ add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
/* Get the value from the object file with an appropriate sign.
The expression involving howto->src_mask isolates the upper
@@ -1629,18 +1632,16 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
can not get the upper bit, but that does not matter since
signed_add needs no adjustment to become negative in that
case. */
-
signed_add = add;
if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
+ /* howto->bitpos == 0 */
/* Add the value from the object file, shifted so that it is a
straight number. */
- /* howto->bitpos == 0 */
-
signed_check += signed_add;
- relocation += signed_add;
+ relocation += signed_add;
BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
@@ -1649,21 +1650,26 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
|| signed_check < reloc_signed_min)
overflow = true;
- /* Put RELOCATION into the correct bits: */
-
+ /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
+ Bit 0 can only be set if the upper insn is at a half-word boundary,
+ since the destination address, an ARM instruction, must always be
+ on a word boundary. The semantics of the BLX (1) instruction,
+ however, are that bit 0 in the offset must always be 0, and the
+ corresponding bit 1 in the target address will be set from bit
+ 1 of the source address. */
+ if ((x & 0x18000000) == 0x08000000)
+ relocation &= ~0x2;
+
+ /* Put the relocation into the correct bits. */
if (bfd_big_endian (input_bfd))
- {
- relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
- }
+ relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
else
- {
- relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
- }
+ relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
- /* Add RELOCATION to the correct bits of X: */
+ /* Add the relocation to the correct bits of X. */
x = ((x & ~howto->dst_mask) | relocation);
- /* Put the relocated value back in the object file: */
+ /* Put the relocated value back in the object file. */
bfd_put_32 (input_bfd, x, location);
rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 96d4cb77160..c2eb2741542 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -139,6 +139,12 @@ case "${targ}" in
targ_selvecs=armcoff_big_vec
targ_underscore=yes
;;
+ arm-*-vxworks*)
+ targ_defvec=armcoff_little_vec
+ targ_selvecs=armcoff_big_vec
+ targ_underscore=yes
+ targ_cflags=-DVXWORKS
+ ;;
arm-*-rtems*)
targ_defvec=bfd_elf32_littlearm_vec
targ_selvecs=bfd_elf32_bigarm_vec
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index bfc4ca3c532..66edd6d8e40 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -1019,6 +1019,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
bfd_signed_vma signed_addend;
struct elf32_arm_link_hash_table * globals;
+ /* If the start address has been set, then set the EF_ARM_HASENTRY
+ flag. Setting this more than once is redundant, but the cost is
+ not too high, and it keeps the code simple.
+
+ The test is done here, rather than somewhere else, because the
+ start address is only set just before the final link commences.
+
+ Note - if the user deliberately sets a start address of 0, the
+ flag will not be set. */
+ if (bfd_get_start_address (output_bfd) != 0)
+ elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
+
globals = elf32_arm_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
@@ -1434,6 +1446,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
+#ifndef OLD_ARM_ABI
+ if (r_type == R_ARM_THM_XPC22
+ && ((lower_insn & 0x1800) == 0x0800))
+ /* Remove bit zero of the adjusted offset. Bit zero can only be
+ set if the upper insn is at a half-word boundary, since the
+ destination address, an ARM instruction, must always be on a
+ word boundary. The semantics of the BLX (1) instruction, however,
+ are that bit zero in the offset must always be zero, and the
+ corresponding bit one in the target address will be set from bit
+ one of the source address. */
+ lower_insn &= ~1;
+#endif
/* Put the relocated value back in the object file: */
bfd_put_16 (input_bfd, upper_insn, hit_data);
bfd_put_16 (input_bfd, lower_insn, hit_data + 2);