]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
aarch64: Add DT_RELR support for ILP32 ABI
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 12 Jun 2024 14:17:09 +0000 (15:17 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Tue, 25 Jun 2024 10:07:51 +0000 (11:07 +0100)
Extend the 64bit DT_RELR support to work on 32bit ELF too. For this
only a few changes were needed in the sizing and creation of the
relr relocations.

bfd/elfnn-aarch64.c
ld/emulparams/aarch64elf32.sh
ld/emulparams/aarch64linux32.sh

index 2221de0a4805093b9e79a8dce60ddb029dce41af..000564672df22de18f8a78a64f81f1548272c4e7 100644 (file)
@@ -9451,6 +9451,11 @@ sort_relr (struct bfd_link_info *info,
   return true;
 }
 
+/* Size of a relr entry and a relocated location.  */
+#define RELR_SZ (ARCH_SIZE / 8)
+/* Number of consecutive locations a relr bitmap entry references.  */
+#define RELR_N (ARCH_SIZE - 1)
+
 /* Size .relr.dyn whenever the layout changes, the number of packed
    relocs are unchanged but the packed representation can.  */
 
@@ -9473,19 +9478,19 @@ elfNN_aarch64_size_relative_relocs (struct bfd_link_info *info,
     {
       bfd_vma base = addr[i];
       i++;
-      srelrdyn->size += 8;
-      base += 8;
+      srelrdyn->size += RELR_SZ;
+      base += RELR_SZ;
       for (;;)
        {
          bfd_size_type start_i = i;
          while (i < htab->relr_count
-                && addr[i] - base < 63 * 8
-                && (addr[i] - base) % 8 == 0)
+                && addr[i] - base < RELR_N * RELR_SZ
+                && (addr[i] - base) % RELR_SZ == 0)
            i++;
          if (i == start_i)
            break;
-         srelrdyn->size += 8;
-         base += 63 * 8;
+         srelrdyn->size += RELR_SZ;
+         base += RELR_N * RELR_SZ;
        }
     }
   if (srelrdyn->size != oldsize)
@@ -9522,25 +9527,25 @@ elfNN_aarch64_finish_relative_relocs (struct bfd_link_info *info)
     {
       bfd_vma base = addr[i];
       i++;
-      bfd_put_64 (dynobj, base, loc);
-      loc += 8;
-      base += 8;
+      bfd_put_NN (dynobj, base, loc);
+      loc += RELR_SZ;
+      base += RELR_SZ;
       for (;;)
        {
          bfd_vma bits = 0;
          while (i < htab->relr_count)
            {
              bfd_vma delta = addr[i] - base;
-             if (delta >= 63 * 8 || delta % 8 != 0)
+             if (delta >= RELR_N * RELR_SZ || delta % RELR_SZ != 0)
                break;
-             bits |= (bfd_vma) 1 << (delta / 8);
+             bits |= (bfd_vma) 1 << (delta / RELR_SZ);
              i++;
            }
          if (bits == 0)
            break;
-         bfd_put_64 (dynobj, (bits << 1) | 1, loc);
-         loc += 8;
-         base += 63 * 8;
+         bfd_put_NN (dynobj, (bits << 1) | 1, loc);
+         loc += RELR_SZ;
+         base += RELR_N * RELR_SZ;
        }
     }
   free (addr);
@@ -9548,8 +9553,8 @@ elfNN_aarch64_finish_relative_relocs (struct bfd_link_info *info)
   /* Pad any excess with 1's, a do-nothing encoding.  */
   while (loc < srelrdyn->contents + srelrdyn->size)
     {
-      bfd_put_64 (dynobj, 1, loc);
-      loc += 8;
+      bfd_put_NN (dynobj, 1, loc);
+      loc += RELR_SZ;
     }
   return true;
 }
index 5a08d9e29f1d1376438b2449698835cf76073799..45bf31a179ae5059ea8c374da3440eaf43f034da 100644 (file)
@@ -1,3 +1,5 @@
+source_sh ${srcdir}/emulparams/dt-relr.sh
+
 ARCH="aarch64:ilp32"
 MACHINE=
 NOP=0x1f2003d5
index 3e75d1492e6890be10f69b8d3fe5fcb65b49368a..3292c7ca32ad14c5a5e0028a9375acafa206e031 100644 (file)
@@ -1,3 +1,5 @@
+source_sh ${srcdir}/emulparams/dt-relr.sh
+
 ARCH="aarch64:ilp32"
 MACHINE=
 NOP=0x1f2003d5