]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
hppa: Fix handling of relocations that apply to data
authorJohn David Anglin <danglin@gcc.gnu.org>
Sun, 14 Jul 2024 11:22:13 +0000 (07:22 -0400)
committerJohn David Anglin <danglin@gcc.gnu.org>
Sun, 14 Jul 2024 11:22:13 +0000 (07:22 -0400)
Commit d125f9675372b1ae01ceb1893c06ccb27bc7bf22 introduced a bug
in handling relocations for data.  The R_PARISC_DIR32 relocation
operates on 32-bit data and not instructions.  The HOWTO table
needs to be used to determine the format of relocations that apply
to data.  The R_PARISC_SEGBASE relocation is another special case
as it only changes segment base.

This was noticed in Debian cmor package build.

2024-07-14  John David Anglin  <danglin@gcc.gnu.org>

bfd/ChangeLog:

* elf32-hppa.c (final_link_relocate): Use HOWTO table to
determine reload format for relocations that apply to data.

bfd/elf32-hppa.c

index 3a959a0fc2511bfe4ca854796c8481605f9a28b4..4d004323e63c7312f1f48389437ba33832dfee39 100644 (file)
@@ -3432,48 +3432,62 @@ final_link_relocate (asection *input_section,
       break;
     }
 
-  r_format = bfd_hppa_insn2fmt (input_bfd, insn);
-  switch (r_format)
+  switch (r_type)
     {
-    case 10:
-    case -10:
-      if (val & 7)
-       {
-         _bfd_error_handler
-           /* xgettext:c-format */
-           (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
-              "is not a multiple of 8 (gp %#x)"),
-            input_bfd,
-            input_section,
-            (uint64_t) offset,
-            val,
-            insn,
-            (unsigned int) elf_gp (input_section->output_section->owner));
-         bfd_set_error (bfd_error_bad_value);
-         return bfd_reloc_notsupported;
-       }
+    case R_PARISC_DIR32:
+    case R_PARISC_SECREL32:
+    case R_PARISC_SEGBASE:
+    case R_PARISC_SEGREL32:
+    case R_PARISC_PLABEL32:
+      /* These relocations apply to data.  */
+      r_format = howto->bitsize;
       break;
 
-    case -11:
-    case -16:
-      if (val & 3)
+    default:
+      r_format = bfd_hppa_insn2fmt (input_bfd, insn);
+      switch (r_format)
        {
-         _bfd_error_handler
-           /* xgettext:c-format */
-           (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
-              "is not a multiple of 4 (gp %#x)"),
-            input_bfd,
-            input_section,
-            (uint64_t) offset,
-            val,
-            insn,
-            (unsigned int) elf_gp (input_section->output_section->owner));
-         bfd_set_error (bfd_error_bad_value);
-         return bfd_reloc_notsupported;
-       }
-      break;
+       case 10:
+       case -10:
+         if (val & 7)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
+                  "is not a multiple of 8 (gp %#x)"),
+                input_bfd,
+                input_section,
+                (uint64_t) offset,
+                val,
+                insn,
+                (unsigned int) elf_gp (input_section->output_section->owner));
+             bfd_set_error (bfd_error_bad_value);
+             return bfd_reloc_notsupported;
+           }
+         break;
 
-    default:
+       case -11:
+       case -16:
+         if (val & 3)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA+%#" PRIx64 "): displacement %#x for insn %#x "
+                  "is not a multiple of 4 (gp %#x)"),
+                input_bfd,
+                input_section,
+                (uint64_t) offset,
+                val,
+                insn,
+                (unsigned int) elf_gp (input_section->output_section->owner));
+             bfd_set_error (bfd_error_bad_value);
+             return bfd_reloc_notsupported;
+           }
+         break;
+
+       default:
+         break;
+        }
       break;
     }
   insn = hppa_rebuild_insn (insn, val, r_format);