This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

elf64-hppa branches


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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]