* elf32-v850.c (bfd_elf32_v850_reloc): Fix handling of

low order sign bit propogationfor R_V850_HI16_S.
Fixes c-torture execute/950221-1.c, maybe others.
This commit is contained in:
Jeff Law 1996-09-04 03:03:53 +00:00
parent 0cd98b92ab
commit e73b6ae634
2 changed files with 124 additions and 17 deletions

View File

@ -5,7 +5,6 @@ Tue Sep 3 12:16:20 1996 Doug Evans <dje@canuck.cygnus.com>
* config.bfd (sparclet-*-aout*): Add case.
* configure.in (sparcle_aout_vec): Add case.
* configure: Regenerated.
* libaout.h (machine_type): Add M_SPARCLET_LE.
* targets.c (sparcle_aout_vec): Declare.
(bfd_target_vector): Add sparcle_aout_vec.
* aout-sparcle.c: New file.
@ -13,7 +12,10 @@ Tue Sep 3 12:16:20 1996 Doug Evans <dje@canuck.cygnus.com>
start-sanitize-v850
Tue Sep 3 00:57:02 1996 Jeffrey A Law (law@cygnus.com)
* elf32-v850.c (bfd_elf3_v850_reloc): New function for
* elf32-v850.c (bfd_elf32_v850_reloc): Fix handling of
low order sign bit propogation for R_V850_HI16_S.
* elf32-v850.c (bfd_elf32_v850_reloc): New function for
handling V850 specific relocs.
(elf_v850_howto_table): Use the new function for some
relocations. Twiddle masks & shifts for some relocs.

View File

@ -26,6 +26,9 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
static void v850_info_to_howto_rel
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
static bfd_reloc_status_type bfd_elf32_v850_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
/* Try to minimize the amount of space occupied by relocation tables
@ -71,7 +74,7 @@ static reloc_howto_type elf_v850_howto_table[] =
true, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
bfd_elf32_v850_reloc, /* special_function */
"R_V850_9_PCREL", /* name */
false, /* partial_inplace */
0x00ffffff, /* src_mask */
@ -86,7 +89,7 @@ static reloc_howto_type elf_v850_howto_table[] =
true, /* pc_relative */
7, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
bfd_elf32_v850_reloc, /* special_function */
"R_V850_22_PCREL", /* name */
false, /* partial_inplace */
0x07ffff80, /* src_mask */
@ -99,9 +102,9 @@ static reloc_howto_type elf_v850_howto_table[] =
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
16, /* bitpos */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
bfd_elf32_v850_reloc, /* special_function */
"R_V850_HI16_S", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
@ -114,9 +117,9 @@ static reloc_howto_type elf_v850_howto_table[] =
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
16, /* bitpos */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
bfd_elf32_v850_reloc, /* special_function */
"R_V850_HI16", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
@ -129,7 +132,7 @@ static reloc_howto_type elf_v850_howto_table[] =
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
false, /* pc_relative */
16, /* bitpos */
0, /* bitpos */
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_LO16", /* name */
@ -148,8 +151,8 @@ static reloc_howto_type elf_v850_howto_table[] =
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_32", /* name */
false, /* partial_inplace */
0, /* src_mask */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
@ -163,8 +166,8 @@ static reloc_howto_type elf_v850_howto_table[] =
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_16", /* name */
false, /* partial_inplace */
0, /* src_mask */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
@ -178,8 +181,8 @@ static reloc_howto_type elf_v850_howto_table[] =
complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_V850_8", /* name */
false, /* partial_inplace */
0, /* src_mask */
true, /* partial_inplace */
0xff, /* src_mask */
0xff, /* dst_mask */
false), /* pcrel_offset */
};
@ -238,8 +241,110 @@ v850_info_to_howto_rel (abfd, cache_ptr, dst)
cache_ptr->howto = &elf_v850_howto_table[r_type];
}
#define TARGET_BIG_SYM bfd_elf32_v850_vec
#define TARGET_BIG_NAME "elf32-v850"
static bfd_reloc_status_type
bfd_elf32_v850_reloc (abfd, reloc, symbol, data, isection, obfd, err)
bfd *abfd;
arelent *reloc;
asymbol *symbol;
PTR data;
asection *isection;
bfd *obfd;
char **err;
{
if (obfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& (! reloc->howto->partial_inplace
|| reloc->addend == 0))
{
reloc->address += isection->output_offset;
return bfd_reloc_ok;
}
else if (obfd != NULL)
{
return bfd_reloc_continue;
}
/* 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;
if (reloc->howto->type == 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 |= (((relocation & 0xfffe) << 16)
| ((relocation & 0x3f0000) >> 16));
bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
return bfd_reloc_ok;
}
else if (reloc->howto->type == 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 |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
return bfd_reloc_ok;
}
else if (reloc->howto->type == R_V850_HI16_S)
{
relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
return bfd_reloc_ok;
}
else if (reloc->howto->type == R_V850_HI16)
{
relocation = (relocation >> 16);
bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
return bfd_reloc_ok;
}
}
return bfd_reloc_continue;
}
#define TARGET_LITTLE_SYM bfd_elf32_v850_vec
#define TARGET_LITTLE_NAME "elf32-v850"
#define ELF_ARCH bfd_arch_v850
#define ELF_MACHINE_CODE EM_CYGNUS_V850
#define ELF_MAXPAGESIZE 0x1000