From d16e3d2e5b717cf83c1fe47a70e0a9f2c2024a44 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 24 Mar 2020 10:42:45 +1030 Subject: [PATCH] PR25662, invalid sh_offset for first section in segment with phdrs PR 25662 * elf.c (assign_file_positions_for_load_sections): Adjust offset for SHT_NOBITS section if first in segment. --- bfd/ChangeLog | 6 ++++++ bfd/elf.c | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f273ea54e9..b4160c943a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2020-03-25 Alan Modra + + PR 25662 + * elf.c (assign_file_positions_for_load_sections): Adjust offset + for SHT_NOBITS section if first in segment. + 2020-03-24 H.J. Lu PR binutils/25708 diff --git a/bfd/elf.c b/bfd/elf.c index 2512b6543b..86dadea05c 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -5833,10 +5833,11 @@ assign_file_positions_for_load_sections (bfd *abfd, } p->p_memsz += adjust; - if (this_hdr->sh_type != SHT_NOBITS) + if (p->p_type == PT_LOAD) { - if (p->p_type == PT_LOAD) + if (this_hdr->sh_type != SHT_NOBITS) { + off_adjust = 0; if (p->p_filesz + adjust < p->p_memsz) { /* We have a PROGBITS section following NOBITS ones. @@ -5846,10 +5847,25 @@ assign_file_positions_for_load_sections (bfd *abfd, if (!write_zeros (abfd, off, adjust)) return FALSE; } - off += adjust; } - p->p_filesz += adjust; + /* We only adjust sh_offset in SHT_NOBITS sections + as would seem proper for their address when the + section is first in the segment. sh_offset + doesn't really have any significance for + SHT_NOBITS anyway, apart from a notional position + relative to other sections. Historically we + didn't bother with adjusting sh_offset and some + programs depend on it not being adjusted. See + pr12921 and pr25662. */ + if (this_hdr->sh_type != SHT_NOBITS || i == 0) + { + off += adjust; + if (this_hdr->sh_type == SHT_NOBITS) + off_adjust += adjust; + } } + if (this_hdr->sh_type != SHT_NOBITS) + p->p_filesz += adjust; } if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)