aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf-hppa.h
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1999-09-08 00:09:52 +0000
committerJeff Law <law@redhat.com>1999-09-08 00:09:52 +0000
commitc8933571dafbff45330fb62e27fcece1bc360824 (patch)
treeeadc884f744a12cfe483eb2a14cca18a725aa79d /bfd/elf-hppa.h
parent2beaab59a5f374261d27b8400d522c271f7d917f (diff)
downloadgdb-c8933571dafbff45330fb62e27fcece1bc360824.zip
gdb-c8933571dafbff45330fb62e27fcece1bc360824.tar.gz
gdb-c8933571dafbff45330fb62e27fcece1bc360824.tar.bz2
* 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.
Diffstat (limited to 'bfd/elf-hppa.h')
-rw-r--r--bfd/elf-hppa.h90
1 files changed, 81 insertions, 9 deletions
diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h
index 196a1ac..93ceaa8 100644
--- a/bfd/elf-hppa.h
+++ b/bfd/elf-hppa.h
@@ -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;
}