diff options
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/elf-hppa.h | 118 |
2 files changed, 110 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index de48586..e4670a8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,9 @@ Wed Sep 8 17:56:11 1999 Jeffrey A Law (law@cygnus.com) + * elf-hppa.h (elf_hppa_final_link_relocate): Handle PCREL* relocs. + Consistently deal with addends. Handle DLTIND14F and DLTREL14F. + (elf_hppa_relocate_insn): Handle PCREL* relocs. + * elf-hppa.h (elf_hppa_final_link_relocate): Handle LT_OFF_FPTR*, DIR32, DIR64 and FPTR64 relocations. (elf_hppa_relocate_insn): Similarly. diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index a73d273..657bf00 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1012,22 +1012,57 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, The list will be deleted eventually. 27210 R_PARISC_SEGREL32 - 1120 R_PARISC_PCREL64 1096 R_PARISC_LTOFF_TP14DR 982 R_PARISC_LTOFF_TP21L 791 R_PARISC_GPREL64 772 R_PARISC_PLTOFF14DR 386 R_PARISC_PLTOFF21L 6 R_PARISC_LTOFF64 - 5 R_PARISC_SEGREL64 - 1 R_PARISC_PCREL21L - 1 R_PARISC_PCREL14R */ + 5 R_PARISC_SEGREL64 */ switch (r_type) { case R_PARISC_NONE: break; + /* Random PC relative relocs. */ + case R_PARISC_PCREL21L; + case R_PARISC_PCREL14R; + case R_PARISC_PCREL14F; + case R_PARISC_PCREL14WR: + case R_PARISC_PCREL14DR: + case R_PARISC_PCREL16F: + case R_PARISC_PCREL16WF: + case R_PARISC_PCREL16DF: + { + if (r_type == R_PARISC_PCREL21L) + r_field = e_lsel; + else if (r_type == R_PARISC_PCREL14F + || r_type == R_PARISC_PCREL16F + || r_type == R_PARISC_PCREL16WF + || r_type == R_PARISC_PCREL16DF) + r_field = e_fsel; + else + r_field = e_rsel; + + /* If this is a call to a function defined in another dynamic + library, then redirect the call to the local stub for this + function. */ + if (sym_sec->output_section == NULL) + value = dyn_h->stub_offset; + + /* Turn VALUE into a proper PC relative address. */ + value -= (offset + input_section->output_offset + + input_section->output_section->vma); + + /* Adjust for any field selectors. */ + value = hppa_field_adjust (value, -8 + addend, r_field); + + /* Apply the relocation to the given instruction. */ + insn = elf_hppa_relocate_insn (insn, value, r_type); + break; + } + /* Basic function call support. I'm not entirely sure if PCREL14F is actually needed or even handled correctly. @@ -1035,8 +1070,15 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, we want to redirect the call to a stub. */ case R_PARISC_PCREL22F: case R_PARISC_PCREL17F: - case R_PARISC_PCREL14F: + case R_PARISC_PCREL22C: + case R_PARISC_PCREL17C: + case R_PARISC_PCREL17R: { + if (r_type == R_PARISC_PCREL17R) + r_field = e_rsel; + else + r_field = e_fsel; + /* If this is a call to a function defined in another dynamic library, then redirect the call to the local stub for this function. */ @@ -1048,7 +1090,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, + input_section->output_section->vma); /* Adjust for any field selectors. */ - value = hppa_field_adjust (value, -8, e_fsel); + value = hppa_field_adjust (value, -8 + addend, e_fsel); /* All branches are implicitly shifted by 2 places. */ value >>= 2; @@ -1060,6 +1102,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, /* Indirect references to data through the DLT. */ case R_PARISC_DLTIND14R: + case R_PARISC_DLTIND14F: case R_PARISC_DLTIND14DR: case R_PARISC_DLTIND14WR: case R_PARISC_DLTIND21L: @@ -1070,7 +1113,6 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, case R_PARISC_LTOFF_FPTR16F: case R_PARISC_LTOFF_FPTR16WF: case R_PARISC_LTOFF_FPTR16DF: - { /* We want the value of the DLT offset for this symbol, not the symbol's actual address. */ @@ -1082,8 +1124,10 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, if (r_type == R_PARISC_DLTIND21L || r_type == R_PARISC_LTOFF_FPTR21L) value = hppa_field_adjust (value, addend, e_lrsel); - else if (r_type == R_PARISC_LTOFF_FPTR16F - || R_PARISC_LTOFF_FPTR16WF) + else if (r_type == R_PARISC_DLTIND14F + || r_type == R_PARISC_LTOFF_FPTR16F + || r_type == R_PARISC_LTOFF_FPTR16WF + || r_type == R_PARISC_LTOFF_FPTR16DF) value = hppa_field_adjust (value, addend, e_fsel); else value = hppa_field_adjust (value, addend, e_rrsel); @@ -1093,6 +1137,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, } case R_PARISC_DLTREL14R: + case R_PARISC_DLTREL14F: case R_PARISC_DLTREL14DR: case R_PARISC_DLTREL14WR: case R_PARISC_DLTREL21L: @@ -1106,6 +1151,8 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, version vs the 14bit versions. */ if (r_type == R_PARISC_DLTREL21L) value = hppa_field_adjust (value, addend, e_lrsel); + else if (r_type == R_PARISC_DLTREL14F) + value = hppa_field_adjust (value, addend, e_fsel); else value = hppa_field_adjust (value, addend, e_rrsel); @@ -1122,7 +1169,6 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, return bfd_reloc_ok; } - case R_PARISC_LTOFF_FPTR64: { /* We want the value of the DLT offset for this symbol, not @@ -1133,13 +1179,50 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, } case R_PARISC_DIR32: - bfd_put_32 (input_bfd, value, hit_data); + bfd_put_32 (input_bfd, value + addend, hit_data); return bfd_reloc_ok; case R_PARISC_DIR64: - bfd_put_64 (input_bfd, value, hit_data); + bfd_put_64 (input_bfd, value + addend, hit_data); return bfd_reloc_ok; + case R_PARISC_PCREL32: + { + /* If this is a call to a function defined in another dynamic + library, then redirect the call to the local stub for this + function. */ + if (sym_sec->output_section == NULL) + value = dyn_h->stub_offset; + + /* Turn VALUE into a proper PC relative address. */ + value -= (offset + input_section->output_offset + + input_section->output_section->vma); + + value += addend + value -= 8; + bfd_put_64 (input_bfd, value, hit_data); + return bfd_reloc_ok; + } + + case R_PARISC_PCREL64: + { + /* If this is a call to a function defined in another dynamic + library, then redirect the call to the local stub for this + function. */ + if (sym_sec->output_section == NULL) + value = dyn_h->stub_offset; + + /* Turn VALUE into a proper PC relative address. */ + value -= (offset + input_section->output_offset + + input_section->output_section->vma); + + value += addend + value -= 8; + bfd_put_64 (input_bfd, value, hit_data); + return bfd_reloc_ok; + } + + /* These do not require any work here. They are simply passed through as dynamic relocations. */ case R_PARISC_FPTR64: @@ -1181,6 +1264,7 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) /* This is any 22bit branch. In PA2.0 syntax it corresponds to the "B" instruction. */ case R_PARISC_PCREL22F: + case R_PARISC_PCREL22C: { unsigned int w3, w2, w1, w; @@ -1204,6 +1288,8 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) the "B" instruction as well as BE. */ case R_PARISC_PCREL17F: case R_PARISC_DIR17F: + case R_PARISC_PCREL17C: + case R_PARISC_PCREL17R: { unsigned int w2, w1, w; @@ -1227,6 +1313,7 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) case R_PARISC_DLTREL21L: case R_PARISC_DLTIND21L: case R_PARISC_LTOFF_FPTR21L: + case R_PARISC_PCREL21L; { int w; @@ -1247,6 +1334,9 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) case R_PARISC_DLTIND14F: case R_PARISC_LTOFF_FPTR14R: case R_PARISC_LTOFF_FPTR16F: + case R_PARISC_PCREL14R; + case R_PARISC_PCREL14F: + case R_PARISC_PCREL16F: { int w; @@ -1265,6 +1355,8 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) case R_PARISC_DLTIND14DR: case R_PARISC_LTOFF_FPTR14DR: case R_PARISC_LTOFF_FPTR16DF: + case R_PARISC_PCREL14DR: + case R_PARISC_PCREL16DF: { int w; @@ -1289,6 +1381,8 @@ elf_hppa_relocate_insn (insn, sym_value, r_type) case R_PARISC_DLTIND14WR: case R_PARISC_LTOFF_FPTR14WR: case R_PARISC_LTOFF_FPTR16WF: + case R_PARISC_PCREL14WR: + case R_PARISC_PCREL16WF: { int w; |