This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] *-nacl: fix layout magic for explicit section placement case
- From: Roland McGrath <mcgrathr at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 20 Nov 2012 11:14:37 -0800
- Subject: [PATCH] *-nacl: fix layout magic for explicit section placement case
This fixes the special layout logic for *-nacl targets in the case
where --section-start or similar is used to place .rodata without
leaving space before it for the headers. In that case, the special
layout cannot apply and so we just fall back to the default behavior,
where the headers will not appear in any segment.
As this change is isolated to target-specific code for which I am the sole
contributor, I'll commit it in the next day or so if I don't get any
objections. But I'm interested in any feedback that the BFD savants may
have about the method for detecting this case.
Thanks,
Roland
bfd/
2012-11-20 Roland McGrath <mcgrathr@google.com>
* elf-nacl.c (segment_nonexecutable_and_has_contents): Renamed to ...
(segment_eligible_for_headers): ... this. Take new arguments
MAXPAGESIZE and SIZEOF_HEADERS. Return false if the first section's
start address doesn't leave space for the headers.
(nacl_modify_segment_map): Update caller.
--- a/bfd/elf-nacl.c
+++ b/bfd/elf-nacl.c
@@ -42,11 +42,18 @@ segment_executable (struct elf_segment_map *seg)
return FALSE;
}
+/* Determine if this segment is eligible to receive the file and program
+ headers. It must be non-executable and have contents. Its first
+ section must start far enough past the page boundary to allow space
+ for the headers. */
static bfd_boolean
-segment_nonexecutable_and_has_contents (struct elf_segment_map *seg)
+segment_eligible_for_headers (struct elf_segment_map *seg,
+ bfd_vma maxpagesize, bfd_vma sizeof_headers)
{
bfd_boolean any_contents = FALSE;
unsigned int i;
+ if (seg->count == 0 || seg->sections[0]->lma % maxpagesize < sizeof_headers)
+ return FALSE;
for (i = 0; i < seg->count; ++i)
{
if (seg->sections[i]->flags & SEC_CODE)
@@ -68,6 +75,8 @@ nacl_modify_segment_map (bfd *abfd, struct
bfd_link_info *info)
struct elf_segment_map **first_load = NULL;
struct elf_segment_map **last_load = NULL;
bfd_boolean moved_headers = FALSE;
+ int sizeof_headers = bfd_sizeof_headers (abfd, info);
+ bfd_vma maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
if (info != NULL && info->user_phdrs)
/* The linker script used PHDRS explicitly, so don't change what the
@@ -93,7 +102,8 @@ nacl_modify_segment_map (bfd *abfd, struct
bfd_link_info *info)
/* Now that we've noted the first PT_LOAD, we're looking for
the first non-executable PT_LOAD with a nonempty p_filesz. */
else if (!moved_headers
- && segment_nonexecutable_and_has_contents (seg))
+ && segment_eligible_for_headers (seg, maxpagesize,
+ sizeof_headers))
{
/* This is the one we were looking for!