summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2007-05-30 13:38:50 +0000
committerAlan Modra <amodra@bigpond.net.au>2007-05-30 13:38:50 +0000
commitbfb22d3471b61eb3e20e2dd09f7bb712a9dae3ee (patch)
tree7d06b83acfb02e9b888b8b4a5da80b1f4534f68c
parent81c8a7e2931af2cb670d9bc91084590dc864f99b (diff)
downloadbinutils-redhat-bfb22d3471b61eb3e20e2dd09f7bb712a9dae3ee.tar.gz
* elf.c (assign_file_positions_for_load_sections): Correct sh_type
to SHT_NOBITS earlier. Base actions in rest of function on sh_type and sh_flags instead of bfd section flags. Delete voff and code keeping nobits segments aligned.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf.c99
2 files changed, 45 insertions, 61 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 37c21ddd6e..01d0436fab 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2007-05-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): Correct sh_type
+ to SHT_NOBITS earlier. Base actions in rest of function on sh_type
+ and sh_flags instead of bfd section flags. Delete voff and code
+ keeping nobits segments aligned.
+
2007-05-25 Eric Christopher <echristo@apple.com>
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame):
diff --git a/bfd/elf.c b/bfd/elf.c
index f39fdfab5a..25266eaae8 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4282,7 +4282,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
struct elf_segment_map *m;
Elf_Internal_Phdr *phdrs;
Elf_Internal_Phdr *p;
- file_ptr off, voff;
+ file_ptr off;
bfd_size_type maxpagesize;
unsigned int alloc;
unsigned int i, j;
@@ -4344,10 +4344,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
number of sections with contents contributing to both p_filesz
and p_memsz, followed by a number of sections with no contents
that just contribute to p_memsz. In this loop, OFF tracks next
- available file offset for PT_LOAD and PT_NOTE segments. VOFF is
- an adjustment we use for segments that have no file contents
- but need zero filled memory allocation. */
- voff = 0;
+ available file offset for PT_LOAD and PT_NOTE segments. */
p->p_type = m->p_type;
p->p_flags = m->p_flags;
@@ -4410,31 +4407,34 @@ assign_file_positions_for_load_sections (bfd *abfd,
align = maxpagesize;
}
+ for (i = 0; i < m->count; i++)
+ if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ /* If we aren't making room for this section, then
+ it must be SHT_NOBITS regardless of what we've
+ set via struct bfd_elf_special_section. */
+ elf_section_type (m->sections[i]) = SHT_NOBITS;
+
adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
- off += adjust;
- if (adjust != 0
- && !m->includes_filehdr
- && !m->includes_phdrs
- && (ufile_ptr) off >= align)
+ if (adjust != 0)
{
- /* If the first section isn't loadable, the same holds for
- any other sections. Since the segment won't need file
- space, we can make p_offset overlap some prior segment.
- However, .tbss is special. If a segment starts with
- .tbss, we need to look at the next section to decide
- whether the segment has any loadable sections. */
+ /* If the first section isn't loadable, the same holds
+ for any other sections. We don't need to align the
+ segment on disk since the segment doesn't need file
+ space. */
i = 0;
- while ((m->sections[i]->flags & SEC_LOAD) == 0
- && (m->sections[i]->flags & SEC_HAS_CONTENTS) == 0)
+ while (elf_section_type (m->sections[i]) == SHT_NOBITS)
{
- if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
+ /* If a segment starts with .tbss, we need to look
+ at the next section to decide whether the segment
+ has any loadable sections. */
+ if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0
|| ++i >= m->count)
{
- off -= adjust;
- voff = adjust - align;
+ adjust = 0;
break;
}
}
+ off += adjust;
}
}
/* Make sure the .dynamic section is the first section in the
@@ -4505,7 +4505,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
|| (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
{
if (! m->includes_filehdr && ! m->includes_phdrs)
- p->p_offset = off + voff;
+ p->p_offset = off;
else
{
file_ptr adjust;
@@ -4524,12 +4524,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
{
asection *sec;
- flagword flags;
bfd_size_type align;
Elf_Internal_Shdr *this_hdr;
sec = *secpp;
- flags = sec->flags;
+ this_hdr = &elf_section_data (sec)->this_hdr;
align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
if (p->p_type == PT_LOAD
@@ -4537,9 +4536,9 @@ assign_file_positions_for_load_sections (bfd *abfd,
{
bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
- if ((flags & SEC_LOAD) != 0
- || ((flags & SEC_ALLOC) != 0
- && ((flags & SEC_THREAD_LOCAL) == 0
+ if (this_hdr->sh_type != SHT_NOBITS
+ || ((this_hdr->sh_flags & SHF_ALLOC) != 0
+ && ((this_hdr->sh_flags & SHF_TLS) == 0
|| p->p_type == PT_TLS)))
{
if (adjust < 0)
@@ -4551,7 +4550,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
}
p->p_memsz += adjust;
- if ((flags & SEC_LOAD) != 0)
+ if (this_hdr->sh_type != SHT_NOBITS)
{
off += adjust;
p->p_filesz += adjust;
@@ -4559,7 +4558,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
}
}
- this_hdr = &elf_section_data (sec)->this_hdr;
if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
{
/* The section at i == 0 is the one that actually contains
@@ -4585,46 +4583,25 @@ assign_file_positions_for_load_sections (bfd *abfd,
{
if (p->p_type == PT_LOAD)
{
- this_hdr->sh_offset = sec->filepos = off + voff;
- /* FIXME: The SEC_HAS_CONTENTS test here dates back to
- 1997, and the exact reason for it isn't clear. One
- plausible explanation is that it is to work around
- a problem we have with linker scripts using data
- statements in NOLOAD sections. I don't think it
- makes a great deal of sense to have such a section
- assigned to a PT_LOAD segment, but apparently
- people do this. The data statement results in a
- bfd_data_link_order being built, and these need
- section contents to write into. Eventually, we get
- to _bfd_elf_write_object_contents which writes any
- section with contents to the output. Make room
- here for the write, so that following segments are
- not trashed. */
- if ((flags & SEC_LOAD) != 0
- || (flags & SEC_HAS_CONTENTS) != 0)
+ this_hdr->sh_offset = sec->filepos = off;
+ if (this_hdr->sh_type != SHT_NOBITS)
off += sec->size;
- else
- /* If we aren't making room for this section, then
- it must be SHT_NOBITS regardless of what we've
- set via struct bfd_elf_special_section. */
- this_hdr->sh_type = SHT_NOBITS;
}
- if ((flags & SEC_LOAD) != 0)
+ if (this_hdr->sh_type != SHT_NOBITS)
{
p->p_filesz += sec->size;
- /* SEC_LOAD without SEC_ALLOC is a weird combination
- used by note sections to signify that a PT_NOTE
- segment should be created. These take file space
- but are not actually loaded into memory. */
- if ((flags & SEC_ALLOC) != 0)
+ /* A load section without SHF_ALLOC is something like
+ a note section in a PT_NOTE segment. These take
+ file space but are not loaded into memory. */
+ if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
p->p_memsz += sec->size;
}
/* .tbss is special. It doesn't contribute to p_memsz of
normal segments. */
- else if ((flags & SEC_ALLOC) != 0
- && ((flags & SEC_THREAD_LOCAL) == 0
+ else if ((this_hdr->sh_flags & SHF_ALLOC) != 0
+ && ((this_hdr->sh_flags & SHF_TLS) == 0
|| p->p_type == PT_TLS))
p->p_memsz += sec->size;
@@ -4649,9 +4626,9 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (! m->p_flags_valid)
{
p->p_flags |= PF_R;
- if ((flags & SEC_CODE) != 0)
+ if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
p->p_flags |= PF_X;
- if ((flags & SEC_READONLY) == 0)
+ if ((this_hdr->sh_flags & SHF_WRITE) != 0)
p->p_flags |= PF_W;
}
}