mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
PR22758, FAIL: Run pr22393-2
We can't map different disk pages into the same memory page; The last page mapped will simply overwrite any previous pages. The executable/non-executable new_segment test ignored this fact, leading to a ld.so segfault on hppa when .dynamic is overwritten with zeros. This patch moves existing tests for demand paging with lma on the same memory page, to a new test performed before any case where we want a new segment due to protection or loadable conflicts. PR 22758 * elf.c (_bfd_elf_map_sections_to_segments): Don't start a new segment when demand paged with lma on the same page. Test this before load/non-load, executable/non-executable, writable/non-writable tests and simplify. Delete bogus relro condition in writable/non-writable test. Delete outdated comment. Formatting.
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
2018-01-30 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 22758
|
||||||
|
* elf.c (_bfd_elf_map_sections_to_segments): Don't start a new
|
||||||
|
segment when demand paged with lma on the same page. Test this
|
||||||
|
before load/non-load, executable/non-executable,
|
||||||
|
writable/non-writable tests and simplify. Delete bogus relro
|
||||||
|
condition in writable/non-writable test. Delete outdated
|
||||||
|
comment. Formatting.
|
||||||
|
|
||||||
2018-01-30 Alan Modra <amodra@gmail.com>
|
2018-01-30 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elflink.c (bfd_elf_define_start_stop): Make __start and __stop
|
* elflink.c (bfd_elf_define_start_stop): Make __start and __stop
|
||||||
|
40
bfd/elf.c
40
bfd/elf.c
@ -4727,33 +4727,35 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
|
|||||||
the previous section, then we need a new segment. */
|
the previous section, then we need a new segment. */
|
||||||
new_segment = TRUE;
|
new_segment = TRUE;
|
||||||
}
|
}
|
||||||
|
else if ((abfd->flags & D_PAGED) != 0
|
||||||
|
&& (((last_hdr->lma + last_size - 1) & -maxpagesize)
|
||||||
|
== (hdr->lma & -maxpagesize)))
|
||||||
|
{
|
||||||
|
/* If we are demand paged then we can't map two disk
|
||||||
|
pages onto the same memory page. */
|
||||||
|
new_segment = FALSE;
|
||||||
|
}
|
||||||
/* In the next test we have to be careful when last_hdr->lma is close
|
/* In the next test we have to be careful when last_hdr->lma is close
|
||||||
to the end of the address space. If the aligned address wraps
|
to the end of the address space. If the aligned address wraps
|
||||||
around to the start of the address space, then there are no more
|
around to the start of the address space, then there are no more
|
||||||
pages left in memory and it is OK to assume that the current
|
pages left in memory and it is OK to assume that the current
|
||||||
section can be included in the current segment. */
|
section can be included in the current segment. */
|
||||||
else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
|
else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
|
||||||
> last_hdr->lma)
|
+ maxpagesize > last_hdr->lma)
|
||||||
&& (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
|
&& (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
|
||||||
<= hdr->lma))
|
+ maxpagesize <= hdr->lma))
|
||||||
{
|
{
|
||||||
/* If putting this section in this segment would force us to
|
/* If putting this section in this segment would force us to
|
||||||
skip a page in the segment, then we need a new segment. */
|
skip a page in the segment, then we need a new segment. */
|
||||||
new_segment = TRUE;
|
new_segment = TRUE;
|
||||||
}
|
}
|
||||||
else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
|
else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
|
||||||
&& (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0
|
&& (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
|
||||||
&& ((abfd->flags & D_PAGED) == 0
|
|
||||||
|| (((last_hdr->lma + last_size - 1) & -maxpagesize)
|
|
||||||
!= (hdr->lma & -maxpagesize))))
|
|
||||||
{
|
{
|
||||||
/* We don't want to put a loaded section after a
|
/* We don't want to put a loaded section after a
|
||||||
nonloaded (ie. bss style) section in the same segment
|
nonloaded (ie. bss style) section in the same segment
|
||||||
as that will force the non-loaded section to be loaded.
|
as that will force the non-loaded section to be loaded.
|
||||||
Consider .tbss sections as loaded for this purpose.
|
Consider .tbss sections as loaded for this purpose. */
|
||||||
However, like the writable/non-writable case below,
|
|
||||||
if they are on the same page then they must be put
|
|
||||||
in the same segment. */
|
|
||||||
new_segment = TRUE;
|
new_segment = TRUE;
|
||||||
}
|
}
|
||||||
else if ((abfd->flags & D_PAGED) == 0)
|
else if ((abfd->flags & D_PAGED) == 0)
|
||||||
@ -4770,20 +4772,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
|
|||||||
new_segment = TRUE;
|
new_segment = TRUE;
|
||||||
}
|
}
|
||||||
else if (! writable
|
else if (! writable
|
||||||
&& (hdr->flags & SEC_READONLY) == 0
|
&& (hdr->flags & SEC_READONLY) == 0)
|
||||||
&& ((info != NULL
|
|
||||||
&& info->relro_end > info->relro_start)
|
|
||||||
|| (((last_hdr->lma + last_size - 1) & -maxpagesize)
|
|
||||||
!= (hdr->lma & -maxpagesize))))
|
|
||||||
{
|
{
|
||||||
/* We don't want to put a writable section in a read only
|
/* We don't want to put a writable section in a read only
|
||||||
segment, unless they are on the same page in memory
|
segment. */
|
||||||
anyhow and there is no RELRO segment. We already
|
|
||||||
know that the last section does not bring us past the
|
|
||||||
current section on the page, so the only case in which
|
|
||||||
the new section is not on the same page as the previous
|
|
||||||
section is when the previous section ends precisely on
|
|
||||||
a page boundary. */
|
|
||||||
new_segment = TRUE;
|
new_segment = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user