PR26429 UBSAN: elf32-arm.c load /store misaligned address
authorAlan Modra <amodra@gmail.com>
Mon, 31 Aug 2020 23:29:05 +0000 (08:59 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 1 Sep 2020 06:32:48 +0000 (16:02 +0930)
PR 26429
* elf32-arm.c (elf32_arm_allocate_local_sym_info): Allocate arrays
in descending order of alignment.

bfd/ChangeLog
bfd/elf32-arm.c

index 20918707f28126709e446feded9f5e66c7812bc7..1d65c6829f51b72b4e44fe0bd86d2fab39e0fe2d 100644 (file)
@@ -1,3 +1,9 @@
+2020-09-01  Alan Modra  <amodra@gmail.com>
+
+       PR 26429
+       * elf32-arm.c (elf32_arm_allocate_local_sym_info): Allocate arrays
+       in descending order of alignment.
+
 2020-09-01  Alan Modra  <amodra@gmail.com>
 
        PR 26423
index 4366b76636162ab54e541a0d18cce609755b01e5..6202695ed300c9c3be76af1d02b54981fa419dbe 100644 (file)
@@ -3593,27 +3593,40 @@ elf32_arm_allocate_local_sym_info (bfd *abfd)
 
       num_syms = elf_tdata (abfd)->symtab_hdr.sh_info;
       size = num_syms * (sizeof (bfd_signed_vma)
-                        + sizeof (struct arm_local_iplt_info *)
                         + sizeof (bfd_vma)
-                        + sizeof (char)
-                        + sizeof (struct fdpic_local));
+                        + sizeof (struct arm_local_iplt_info *)
+                        + sizeof (struct fdpic_local)
+                        + sizeof (char));
       data = bfd_zalloc (abfd, size);
       if (data == NULL)
        return FALSE;
 
-      elf32_arm_local_fdpic_cnts (abfd) = (struct fdpic_local *) data;
-      data += num_syms * sizeof (struct fdpic_local);
-
+      /* It is important that these all be allocated in descending
+        order of required alignment, so that arrays allocated later
+        will be sufficiently aligned.  */
       elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data;
       data += num_syms * sizeof (bfd_signed_vma);
 
+      elf32_arm_local_tlsdesc_gotent (abfd) = (bfd_vma *) data;
+      data += num_syms * sizeof (bfd_vma);
+
       elf32_arm_local_iplt (abfd) = (struct arm_local_iplt_info **) data;
       data += num_syms * sizeof (struct arm_local_iplt_info *);
 
-      elf32_arm_local_tlsdesc_gotent (abfd) = (bfd_vma *) data;
-      data += num_syms * sizeof (bfd_vma);
+      elf32_arm_local_fdpic_cnts (abfd) = (struct fdpic_local *) data;
+      data += num_syms * sizeof (struct fdpic_local);
 
       elf32_arm_local_got_tls_type (abfd) = data;
+#if GCC_VERSION >= 3000
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_tlsdesc_gotent (abfd))
+                 <= __alignof__ (*elf_local_got_refcounts (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_iplt (abfd))
+                 <= __alignof__ (*elf32_arm_local_tlsdesc_gotent (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_fdpic_cnts (abfd))
+                 <= __alignof__ (*elf32_arm_local_iplt (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_got_tls_type (abfd))
+                 <= __alignof__ (*elf32_arm_local_fdpic_cnts (abfd)));
+#endif
     }
   return TRUE;
 }