aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-02-26 18:24:10 +0000
committerIan Lance Taylor <ian@airs.com>1994-02-26 18:24:10 +0000
commit3d51f02f4c683aa29fb45e9083ddddd1a1b9ce97 (patch)
treed2d028084c44778ad33674931c612fa8d7885e7f /bfd
parenta2961423ae6ad940625597be1c8f4103772987a9 (diff)
downloadgdb-3d51f02f4c683aa29fb45e9083ddddd1a1b9ce97.zip
gdb-3d51f02f4c683aa29fb45e9083ddddd1a1b9ce97.tar.gz
gdb-3d51f02f4c683aa29fb45e9083ddddd1a1b9ce97.tar.bz2
* reloc.c (_bfd_relocate_contents): Adjust handling of overflow to
avoid depending upon right shifts of signed numbers, and to correct handling of src_mask with lower bits zero.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/reloc.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 675bb29..4323d9a 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -616,7 +616,8 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
reloc_entry->address += input_section->output_offset;
/* WTF?? */
- if (abfd->xvec->flavour == bfd_target_coff_flavour)
+ if (abfd->xvec->flavour == bfd_target_coff_flavour
+ && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
{
#if 1
/* For m68k-coff, the addend was being subtracted twice during
@@ -1054,13 +1055,23 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
&~ ((bfd_vma) -1 >> howto->rightshift)));
}
- /* Add in the value from the object file, shifted down so that
- it is a straight number. */
+ /* Get the value from the object file. */
add = x & howto->src_mask;
- if ((add & (((~ howto->src_mask) >> 1) & howto->src_mask)) == 0)
- signed_add = add;
- else
- signed_add = add | ((bfd_vma) -1 &~ howto->src_mask);
+
+ /* Get the value from the object file with an appropriate sign.
+ The expression involving howto->src_mask isolates the upper
+ bit of src_mask. If that bit is set in the value we are
+ adding, it is negative, and we subtract out that number times
+ two. If src_mask includes the highest possible bit, then we
+ 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 & (((~ howto->src_mask) >> 1) & howto->src_mask)) != 0)
+ signed_add -= (((~ howto->src_mask) >> 1) & howto->src_mask) << 1;
+
+ /* Add the value from the object file, shifted so that it is a
+ straight number. */
if (howto->bitpos == 0)
{
check += add;
@@ -1069,10 +1080,14 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
else
{
check += add >> howto->bitpos;
+
+ /* For the signed case we use ADD, rather than SIGNED_ADD,
+ to avoid warnings from SVR4 cc. This is OK since we
+ explictly handle the sign bits. */
if (signed_add >= 0)
- signed_check += signed_add >> howto->bitpos;
+ signed_check += add >> howto->bitpos;
else
- signed_check += ((signed_add >> howto->bitpos)
+ signed_check += ((add >> howto->bitpos)
| ((bfd_vma) -1
&~ ((bfd_vma) -1 >> howto->bitpos)));
}
@@ -1447,6 +1462,15 @@ CODE_FRAGMENT
. BFD_RELOC_386_GOTOFF,
. BFD_RELOC_386_GOTPC,
.
+. {* PowerPC/POWER (RS/6000) relocs. *}
+. {* 26 bit relative branch. Low two bits must be zero. High 24
+. bits installed in bits 6 through 29 of instruction. *}
+. BFD_RELOC_PPC_B26,
+. {* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute. *}
+. BFD_RELOC_PPC_BA26,
+. {* 16 bit TOC relative reference. *}
+. BFD_RELOC_PPC_TOC16,
+.
. {* this must be the highest numeric value *}
. BFD_RELOC_UNUSED
. } bfd_reloc_code_real_type;