aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-03-16 19:34:00 +1030
committerAlan Modra <amodra@gmail.com>2020-03-16 19:35:12 +1030
commit4b3ecb3b91b1b6154a6444efdcbadb90854a6654 (patch)
tree9949842cb26ed8573ddb283fa8eff87be76058fd
parent28d1356774c2c61adc7d6e6723de2351cd9f4ddc (diff)
downloadbinutils-4b3ecb3b91b1b6154a6444efdcbadb90854a6654.zip
binutils-4b3ecb3b91b1b6154a6444efdcbadb90854a6654.tar.gz
binutils-4b3ecb3b91b1b6154a6444efdcbadb90854a6654.tar.bz2
PR25675: SIGSEGV in bfd_octets_per_byte
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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf.c20
2 files changed, 19 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cd42164..76e2ba0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
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
dst_ptr_offsets array before accessing. Return status.
(dst_retrieve_location): Similarly, making "loc" parameter a
diff --git a/bfd/elf.c b/bfd/elf.c
index c8241cc..8ab7b3e 100644
--- 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;
}