From c8933571dafbff45330fb62e27fcece1bc360824 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 8 Sep 1999 00:09:52 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 9 +++++ bfd/elf-hppa.h | 90 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c525397c070..72e040096fb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 * coffcode.h (bfd_coff_backend_data): Add _bfd_filnmlen field. diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index 196a1acf996..93ceaa86f8f 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; } -- 2.30.2