diff options
author | Nick Clifton <nickc@redhat.com> | 2001-06-14 11:16:59 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2001-06-14 11:16:59 +0000 |
commit | 46b7ef954fd286ff144d96f3ae4d7aee996598ae (patch) | |
tree | cf94ad044072428a8a950ad990a4685dea216fb9 | |
parent | 97c347f45ab7cdb42b217a791d8dd24980fb9671 (diff) | |
download | gdb-46b7ef954fd286ff144d96f3ae4d7aee996598ae.tar.gz |
Import changes from mainline into 2-11 branch
-rw-r--r-- | bfd/ChangeLog | 20 | ||||
-rw-r--r-- | bfd/coff-arm.c | 64 | ||||
-rw-r--r-- | bfd/config.bfd | 6 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 24 |
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); |