mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 19:09:31 +08:00
* 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.
This commit is contained in:
42
bfd/reloc.c
42
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;
|
reloc_entry->address += input_section->output_offset;
|
||||||
|
|
||||||
/* WTF?? */
|
/* 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
|
#if 1
|
||||||
/* For m68k-coff, the addend was being subtracted twice during
|
/* 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)));
|
&~ ((bfd_vma) -1 >> howto->rightshift)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add in the value from the object file, shifted down so that
|
/* Get the value from the object file. */
|
||||||
it is a straight number. */
|
|
||||||
add = x & howto->src_mask;
|
add = x & howto->src_mask;
|
||||||
if ((add & (((~ howto->src_mask) >> 1) & howto->src_mask)) == 0)
|
|
||||||
signed_add = add;
|
/* Get the value from the object file with an appropriate sign.
|
||||||
else
|
The expression involving howto->src_mask isolates the upper
|
||||||
signed_add = add | ((bfd_vma) -1 &~ howto->src_mask);
|
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)
|
if (howto->bitpos == 0)
|
||||||
{
|
{
|
||||||
check += add;
|
check += add;
|
||||||
@ -1069,10 +1080,14 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
check += add >> howto->bitpos;
|
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)
|
if (signed_add >= 0)
|
||||||
signed_check += signed_add >> howto->bitpos;
|
signed_check += add >> howto->bitpos;
|
||||||
else
|
else
|
||||||
signed_check += ((signed_add >> howto->bitpos)
|
signed_check += ((add >> howto->bitpos)
|
||||||
| ((bfd_vma) -1
|
| ((bfd_vma) -1
|
||||||
&~ ((bfd_vma) -1 >> howto->bitpos)));
|
&~ ((bfd_vma) -1 >> howto->bitpos)));
|
||||||
}
|
}
|
||||||
@ -1447,6 +1462,15 @@ CODE_FRAGMENT
|
|||||||
. BFD_RELOC_386_GOTOFF,
|
. BFD_RELOC_386_GOTOFF,
|
||||||
. BFD_RELOC_386_GOTPC,
|
. 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 *}
|
. {* this must be the highest numeric value *}
|
||||||
. BFD_RELOC_UNUSED
|
. BFD_RELOC_UNUSED
|
||||||
. } bfd_reloc_code_real_type;
|
. } bfd_reloc_code_real_type;
|
||||||
|
Reference in New Issue
Block a user