* elf-hppa.h (elf_hppa_final_link_relocate): Handle DLTREL14R and

DLTREL21L relocs.  Pass the output bfd to elf_hppa_relocate_insn.
        Pass the relocate type rather than the insn format to
        elf_hppa_relocate_insn.
        (elf_hppa_relocate_insn): Make switch dependent on relocation type
        rather than the opcode.  Handle DLTREL21L and DLTREL14R relocs.
This commit is contained in:
Jeff Law 1999-09-08 00:09:52 +00:00
parent 2beaab59a5
commit c8933571da
2 changed files with 90 additions and 9 deletions

View File

@ -1,3 +1,12 @@
Tue Sep 7 17:25:12 1999 Jeffrey A Law (law@cygnus.com)
* elf-hppa.h (elf_hppa_final_link_relocate): Handle DLTREL14R and
DLTREL21L relocs. Pass the output bfd to elf_hppa_relocate_insn.
Pass the relocate type rather than the insn format to
elf_hppa_relocate_insn.
(elf_hppa_relocate_insn): Make switch dependent on relocation type
rather than the opcode. Handle DLTREL21L and DLTREL14R relocs.
1999-09-07 Ian Lance Taylor <ian@zembu.com>
* coffcode.h (bfd_coff_backend_data): Add _bfd_filnmlen field.

View File

@ -1078,12 +1078,45 @@ elf_hppa_final_link_relocate (howto, input_bfd, output_bfd,
input_section->output_offset +
input_section->output_section->vma);
insn = elf_hppa_relocate_insn (input_bfd, input_section, insn,
offset, value, addend, r_format,
insn = elf_hppa_relocate_insn (output_bfd, input_section, insn,
offset, value, addend, r_type,
r_field, r_pcrel);
break;
}
case R_PARISC_DLTREL14R:
{
bfd_vma location;
r_field = e_rrsel;
/* Find out where we are and where we're going. */
location = (offset +
input_section->output_offset +
input_section->output_section->vma);
insn = elf_hppa_relocate_insn (output_bfd, input_section, insn,
offset, value, addend, r_type,
r_field, r_pcrel);
break;
}
case R_PARISC_DLTREL21L:
{
bfd_vma location;
r_field = e_lrsel;
/* Find out where we are and where we're going. */
location = (offset +
input_section->output_offset +
input_section->output_section->vma);
insn = elf_hppa_relocate_insn (output_bfd, input_section, insn,
offset, value, addend, r_type,
r_field, r_pcrel);
break;
}
/* Something we don't know how to handle. */
default:
/* ?!? This is temporary as we flesh out basic linker support, once
@ -1105,25 +1138,25 @@ elf_hppa_final_link_relocate (howto, input_bfd, output_bfd,
static unsigned long
elf_hppa_relocate_insn (abfd, input_sect, insn, address, sym_value,
r_addend, r_format, r_field, pcrel)
r_addend, r_type, r_field, pcrel)
bfd *abfd;
asection *input_sect;
unsigned long insn;
unsigned long address;
long sym_value;
long r_addend;
unsigned long r_format;
unsigned long r_type;
unsigned long r_field;
unsigned long pcrel;
{
unsigned char opcode = get_opcode (insn);
long constant_value;
switch (opcode)
switch (r_type)
{
/* This is any 17 or 22bit PC-relative branch. In PA2.0 syntax it
corresponds to the "B" instruction. */
case BL:
case R_PARISC_PCREL22F:
case R_PARISC_PCREL17F:
/* Turn SYM_VALUE into a proper PC relative address. */
sym_value -= (address + input_sect->output_offset
+ input_sect->output_section->vma);
@ -1176,8 +1209,7 @@ elf_hppa_relocate_insn (abfd, input_sect, insn, address, sym_value,
}
/* This corresponds to any 17 bit absolute branch. */
case BE:
case BLE:
case R_PARISC_DIR17F:
{
unsigned int w2, w1, w;
@ -1203,6 +1235,46 @@ elf_hppa_relocate_insn (abfd, input_sect, insn, address, sym_value,
return insn;
}
case R_PARISC_DLTREL21L:
{
int w;
/* Subtract out the global pointer value. */
sym_value -= _bfd_get_gp_value (abfd);
/* Apply the desired field selector (R_FIELD). */
sym_value = hppa_field_adjust (sym_value, r_addend, r_field);
/* Mask off bits in INSN we do not want. */
insn &= 0xffe00000;
/* Turn the 21bit value into the proper format. */
dis_assemble_21 (sym_value, &w);
/* And insert the proper bits into INSN. */
return insn | w;
}
case R_PARISC_DLTREL14R:
{
int w;
/* Subtract out the global pointer value. */
sym_value -= _bfd_get_gp_value (abfd);
/* Apply the desired field selector (R_FIELD). */
sym_value = hppa_field_adjust (sym_value, r_addend, r_field);
/* Mask off bits in INSN we do not want. */
insn &= 0xffffc000;
/* Turn the 14bit value into the proper format. */
low_sign_unext (sym_value, 14, &w);
/* And insert the proper bits into INSN. */
return insn | w;
}
default:
return insn;
}