aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-v850.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>1997-09-09 23:52:39 +0000
committerNick Clifton <nickc@redhat.com>1997-09-09 23:52:39 +0000
commit5ddf2a9e6ced26ce7cc37e57839371ce8c78cbf0 (patch)
tree945a3492972e79ddd57711f9a9cf0be68563da96 /bfd/elf32-v850.c
parentc58dbe95a66b9aeeb347d332cafd1b772d7d5c0e (diff)
downloadgdb-5ddf2a9e6ced26ce7cc37e57839371ce8c78cbf0.zip
gdb-5ddf2a9e6ced26ce7cc37e57839371ce8c78cbf0.tar.gz
gdb-5ddf2a9e6ced26ce7cc37e57839371ce8c78cbf0.tar.bz2
Do not complain if an R_V850_LO16 reloc has bit 15 set.
Diffstat (limited to 'bfd/elf32-v850.c')
-rw-r--r--bfd/elf32-v850.c371
1 files changed, 190 insertions, 181 deletions
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index c29d145..92cee14 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -596,6 +596,10 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
bfd * obfd;
char ** err;
{
+ long relocation;
+ long insn;
+
+
/* If there is an output BFD,
and the symbol is not a section name (which is only defined at final link time),
and either we are not putting the addend into the instruction
@@ -623,191 +627,196 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
return bfd_reloc_undefined;
/* We handle final linking of some relocs ourselves. */
- {
- long relocation, insn;
- /* Is the address of the relocation really within the section? */
- if (reloc->address > isection->_cooked_size)
- return bfd_reloc_outofrange;
-
- /* Work out which section the relocation is targetted at and the
- initial relocation command value. */
-
- /* Get symbol value. (Common symbols are special.) */
- if (bfd_is_com_section (symbol->section))
- relocation = 0;
- else
- relocation = symbol->value;
-
- /* Convert input-section-relative symbol value to absolute + addend. */
- relocation += symbol->section->output_section->vma;
- relocation += symbol->section->output_offset;
- relocation += reloc->addend;
-
- if (reloc->howto->pc_relative == true)
- {
- /* Here the variable relocation holds the final address of the
- symbol we are relocating against, plus any addend. */
- relocation -= isection->output_section->vma + isection->output_offset;
-
- /* Deal with pcrel_offset */
- relocation -= reloc->address;
- }
-
- /* I've got no clue... */
- reloc->addend = 0;
-
- switch (reloc->howto->type)
- {
- default:
- /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
- return bfd_reloc_notsupported;
-
- case R_V850_22_PCREL:
- if (relocation > 0x1ffff || relocation < -0x200000)
- return bfd_reloc_overflow;
-
- if ((relocation % 2) != 0)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
- insn &= ~0xfffe003f;
- insn |= (((relocation & 0xfffe) << 16)
- | ((relocation & 0x3f0000) >> 16));
- bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_9_PCREL:
- if (relocation > 0xff || relocation < -0x100)
- return bfd_reloc_overflow;
-
- if ((relocation % 2) != 0)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= ~ 0xf870;
- insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_HI16_S:
- relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
- bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_HI16:
- relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- relocation = (relocation >> 16);
- bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_16:
- case R_V850_LO16:
- relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
-
- case R_V850_SDA_16_16_OFFSET:
- case R_V850_ZDA_16_16_OFFSET:
- if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
- return bfd_reloc_overflow;
- bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_SDA_15_16_OFFSET:
- case R_V850_ZDA_15_16_OFFSET:
- if ((long)relocation > 0x7ffe || (long)relocation < -0x8000)
- return bfd_reloc_overflow;
-
- if (relocation & 1)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 1;
- insn |= (relocation >> 1) & ~1;
-
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_TDA_6_8_OFFSET:
- if ((long) relocation > 0xfc || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- if (relocation & 3)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 0xff81;
- insn |= (relocation >> 1);
-
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_TDA_7_8_OFFSET:
- if ((long) relocation > 0xfe || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- if (relocation & 1)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 0xff80;
- insn |= (relocation >> 1);
-
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_TDA_7_7_OFFSET:
- if ((long) relocation > 0x7f || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 0xff80;
- insn |= relocation;
+ /* Is the address of the relocation really within the section? */
+ if (reloc->address > isection->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ /* Convert input-section-relative symbol value to absolute + addend. */
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc->addend;
+
+ if (reloc->howto->pc_relative == true)
+ {
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+ relocation -= isection->output_section->vma + isection->output_offset;
+
+ /* Deal with pcrel_offset */
+ relocation -= reloc->address;
+ }
+
+ /* I've got no clue... */
+ reloc->addend = 0;
+
+ switch (reloc->howto->type)
+ {
+ default:
+ /* fprintf (stderr, "reloc type %d not SUPPORTED\n", reloc->howto->type ); */
+ return bfd_reloc_notsupported;
+
+ case R_V850_22_PCREL:
+ if (relocation > 0x1ffff || relocation < -0x200000)
+ return bfd_reloc_overflow;
+
+ if ((relocation % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= ~0xfffe003f;
+ insn |= (((relocation & 0xfffe) << 16)
+ | ((relocation & 0x3f0000) >> 16));
+ bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_9_PCREL:
+ if (relocation > 0xff || relocation < -0x100)
+ return bfd_reloc_overflow;
+
+ if ((relocation % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= ~ 0xf870;
+ insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_HI16_S:
+ relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
+ bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_HI16:
+ relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ relocation = (relocation >> 16);
+ bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_LO16:
+ relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ /* Do not complain if value has top bit set, as this has been anticipated. */
+ if ((unsigned long)relocation > 0xffff)
+ return bfd_reloc_overflow;
+ bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
+ case R_V850_16:
+ relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ /* drop through */
+
+ case R_V850_SDA_16_16_OFFSET:
+ case R_V850_ZDA_16_16_OFFSET:
+ if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
+ return bfd_reloc_overflow;
+ bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_SDA_15_16_OFFSET:
+ case R_V850_ZDA_15_16_OFFSET:
+ if ((long)relocation > 0x7ffe || (long)relocation < -0x8000)
+ return bfd_reloc_overflow;
+
+ if (relocation & 1)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 1;
+ insn |= (relocation >> 1) & ~1;
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_TDA_6_8_OFFSET:
+ if ((long) relocation > 0xfc || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ if (relocation & 3)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 0xff81;
+ insn |= (relocation >> 1);
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_TDA_7_8_OFFSET:
+ if ((long) relocation > 0xfe || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ if (relocation & 1)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 0xff80;
+ insn |= (relocation >> 1);
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_TDA_7_7_OFFSET:
+ if ((long) relocation > 0x7f || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 0xff80;
+ insn |= relocation;
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
/* start-sanitize-v850e */
- case R_V850_TDA_4_5_OFFSET:
- if ((long) relocation > 0x1e || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- if (relocation & 1)
- return bfd_reloc_dangerous;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 0xfff0;
- insn |= (relocation >> 1);
-
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_TDA_4_4_OFFSET:
- if ((long) relocation > 0xf || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
- insn &= 0xfff0;
- insn |= relocation;
-
- bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
-
- case R_V850_ZDA_16_16_SPLIT_OFFSET:
- case R_V850_SDA_16_16_SPLIT_OFFSET:
- if ((long) relocation > 0xffff || (long) relocation < 0)
- return bfd_reloc_overflow;
-
- insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
-
- insn &= 0x0001ffdf;
- insn |= (relocation & 1) << 5;
- insn |= (relocation & ~1) << 16;
-
- bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
- return bfd_reloc_ok;
+ case R_V850_TDA_4_5_OFFSET:
+ if ((long) relocation > 0x1e || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ if (relocation & 1)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 0xfff0;
+ insn |= (relocation >> 1);
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_TDA_4_4_OFFSET:
+ if ((long) relocation > 0xf || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+ insn &= 0xfff0;
+ insn |= relocation;
+
+ bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
+
+ case R_V850_ZDA_16_16_SPLIT_OFFSET:
+ case R_V850_SDA_16_16_SPLIT_OFFSET:
+ if ((long) relocation > 0xffff || (long) relocation < 0)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
+
+ insn &= 0x0001ffdf;
+ insn |= (relocation & 1) << 5;
+ insn |= (relocation & ~1) << 16;
+
+ bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
+ return bfd_reloc_ok;
/* end-sanitize-v850e */
- }
}
return bfd_reloc_continue;