* elf-hppa.h (elf_hppa_final_link_relocate): Handle PCREL* relocs.
authorJeff Law <law@redhat.com>
Thu, 9 Sep 1999 13:32:38 +0000 (13:32 +0000)
committerJeff Law <law@redhat.com>
Thu, 9 Sep 1999 13:32:38 +0000 (13:32 +0000)
        Consistently deal with addends.  Handle DLTIND14F and DLTREL14F.
        (elf_hppa_relocate_insn): Handle PCREL* relocs.

bfd/ChangeLog
bfd/elf-hppa.h

index de48586476692f5a40a1fe1a0318a7fe8ff4f025..e4670a8c69372d1b71fc3556ee2893ced3b8c71a 100644 (file)
@@ -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.
index a73d2732735ee663101f9505110e148a7d1ab9a4..657bf00e0646da65f46d33e1bc60f45e380bc0cd 100644 (file)
@@ -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;