This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
elf64-hppa branches
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: elf64-hppa branches
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Mon, 29 May 2000 13:37:02 +1000 (EST)
- cc: binutils at sourceware dot cygnus dot com
Hi Jeff,
Two fixes for handling of hppa elf branch relocs.
Regards, Alan Modra
--
Linuxcare. Support for the Revolution.
bfd/ChangeLog
* elf-hppa.h (elf_hppa_final_link_relocate): Use e_rsel field
selector for R_PARISC_PCREL17R. R_PARISC_DIR17R and
R_PARISC_DIR17F are for absolute branches; Handle them as such.
--- binutils-current/bfd/elf-hppa.h Thu May 25 11:26:16 2000
+++ parisc/binutils-2.10/bfd/elf-hppa.h Mon May 29 12:17:02 2000
@@ -1521,7 +1539,10 @@ elf_hppa_final_link_relocate (rel, input
+ input_section->output_section->vma);
/* Adjust for any field selectors. */
- value = hppa_field_adjust (value, -8 + addend, e_fsel);
+ if (r_type == R_PARISC_PCREL17R)
+ value = hppa_field_adjust (value, -8 + addend, e_rsel);
+ else
+ value = hppa_field_adjust (value, -8 + addend, e_fsel);
/* All branches are implicitly shifted by 2 places. */
value >>= 2;
@@ -1531,6 +1552,37 @@ elf_hppa_final_link_relocate (rel, input
break;
}
+ /* Absolute calls. */
+ case R_PARISC_DIR21L:
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR17F:
+ {
+ /* 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 == NULL || sym_sec->output_section == NULL)
+ value = (dyn_h->stub_offset + hppa_info->stub_sec->output_offset
+ + hppa_info->stub_sec->output_section->vma);
+
+ /* Adjust for any field selectors. */
+ if (r_type == R_PARISC_DIR21L)
+ value = hppa_field_adjust (value, addend, e_lrsel);
+ else
+ {
+ if (r_type == R_PARISC_DIR17R)
+ value = hppa_field_adjust (value, addend, e_rrsel);
+ else
+ value = hppa_field_adjust (value, addend, e_fsel);
+
+ /* All branches are implicitly shifted by 2 places. */
+ value >>= 2;
+ }
+
+ /* Apply the relocation to the given instruction. */
+ insn = elf_hppa_relocate_insn (insn, value, r_type);
+ break;
+ }
+
/* Indirect references to data through the DLT. */
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND14F:
@@ -1670,9 +1722,6 @@ elf_hppa_final_link_relocate (rel, input
break;
}
- case R_PARISC_DIR21L:
- case R_PARISC_DIR17R:
- case R_PARISC_DIR17F:
case R_PARISC_DIR14R:
case R_PARISC_DIR14WR:
case R_PARISC_DIR14DR:
@@ -1684,12 +1733,9 @@ elf_hppa_final_link_relocate (rel, input
except that we need different field selectors for the 21bit
version vs the 14bit versions. */
- if (r_type == R_PARISC_DIR21L)
- value = hppa_field_adjust (value, addend, e_lrsel);
- else if (r_type == R_PARISC_DIR17F
- || r_type == R_PARISC_DIR16F
- || r_type == R_PARISC_DIR16WF
- || r_type == R_PARISC_DIR16DF)
+ if (r_type == R_PARISC_DIR16F
+ || r_type == R_PARISC_DIR16WF
+ || r_type == R_PARISC_DIR16DF)
value = hppa_field_adjust (value, addend, e_fsel);
else
value = hppa_field_adjust (value, addend, e_rrsel);