PR25675: SIGSEGV in bfd_octets_per_byte
authorAlan Modra <amodra@gmail.com>
Mon, 16 Mar 2020 09:04:00 +0000 (19:34 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 16 Mar 2020 09:05:12 +0000 (19:35 +1030)
PR 25675
* elf.c (elf_sort_segments): Don't call bfd_octets_per_byte unless
we have a non-zero section count.  Do lma comparison in octets.

bfd/ChangeLog
bfd/elf.c

index cd421649cc824abc5b2e866a8d3f761e166c5fc9..76e2ba0fb88cd3c518cf58502aeb72251d9cbf98 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-16  Alan Modra  <amodra@gmail.com>
+
+       PR 25675
+       * elf.c (elf_sort_segments): Don't call bfd_octets_per_byte unless
+       we have a non-zero section count.  Do lma comparison in octets.
+
 2020-03-16  Alan Modra  <amodra@gmail.com>
 
        * vms-alpha.c (dst_restore_location): Validate index into
index c8241cc5799a35aa7e8ba3f3563607798a8aceb3..8ab7b3e2e816f5479b51da6a9789d800edeb8631 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -5312,19 +5312,25 @@ elf_sort_segments (const void *arg1, const void *arg2)
     return m1->no_sort_lma ? -1 : 1;
   if (m1->p_type == PT_LOAD && !m1->no_sort_lma)
     {
-      unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner,
-                                             m1->sections[0]);
-      bfd_vma lma1, lma2;  /* Bytes.  */
+      bfd_vma lma1, lma2;  /* Octets.  */
       lma1 = 0;
       if (m1->p_paddr_valid)
-       lma1 = m1->p_paddr / opb;
+       lma1 = m1->p_paddr;
       else if (m1->count != 0)
-       lma1 = m1->sections[0]->lma + m1->p_vaddr_offset;
+       {
+         unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner,
+                                                 m1->sections[0]);
+         lma1 = (m1->sections[0]->lma + m1->p_vaddr_offset) * opb;
+       }
       lma2 = 0;
       if (m2->p_paddr_valid)
-       lma2 = m2->p_paddr / opb;
+       lma2 = m2->p_paddr;
       else if (m2->count != 0)
-       lma2 = m2->sections[0]->lma + m2->p_vaddr_offset;
+       {
+         unsigned int opb = bfd_octets_per_byte (m2->sections[0]->owner,
+                                                 m2->sections[0]);
+         lma2 = (m2->sections[0]->lma + m2->p_vaddr_offset) * opb;
+       }
       if (lma1 != lma2)
        return lma1 < lma2 ? -1 : 1;
     }