aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2007-06-29 01:12:52 +0000
committerAlan Modra <amodra@gmail.com>2007-06-29 01:12:52 +0000
commitbf988460f1ac19b0e7add220132af27241bd9cef (patch)
treeda76b55f1d44b96a3a996300ca7225d03cb03757 /bfd/elf.c
parentf08312c2d4e86b40fed18f1a9c4e38192e272cea (diff)
downloadgdb-bf988460f1ac19b0e7add220132af27241bd9cef.zip
gdb-bf988460f1ac19b0e7add220132af27241bd9cef.tar.gz
gdb-bf988460f1ac19b0e7add220132af27241bd9cef.tar.bz2
* elf.c (assign_file_positions_for_load_sections): Ensure bss
segments meet gABI alignment requirements. Don't allocate file space for bss sections in a segment also containing file or program headers.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 532e6b5..a269f32 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4327,6 +4327,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
m = m->next, p++, j++)
{
asection **secpp;
+ bfd_vma off_adjust;
+ bfd_boolean no_contents;
/* If elf_segment_map is not from map_sections_to_segments, the
sections may not be correctly ordered. NOTE: sorting should
@@ -4382,11 +4384,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
else
p->p_align = 0;
+ no_contents = FALSE;
+ off_adjust = 0;
if (p->p_type == PT_LOAD
&& m->count > 0)
{
bfd_size_type align;
- bfd_vma adjust;
unsigned int align_power = 0;
if (m->p_align_valid)
@@ -4413,28 +4416,38 @@ assign_file_positions_for_load_sections (bfd *abfd,
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);
- if (adjust != 0)
+ /* Find out whether this segment contains any loadable
+ sections. If the first section isn't loadable, the same
+ holds for any other sections. */
+ i = 0;
+ while (elf_section_type (m->sections[i]) == SHT_NOBITS)
{
- /* 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 (elf_section_type (m->sections[i]) == SHT_NOBITS)
+ /* 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)
{
- /* 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)
- {
- adjust = 0;
- break;
- }
+ no_contents = TRUE;
+ break;
}
- off += adjust;
}
+
+ off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
+ off += off_adjust;
+ if (no_contents)
+ {
+ /* We shouldn't need to align the segment on disk since
+ the segment doesn't need file space, but the gABI
+ arguably requires the alignment and glibc ld.so
+ checks it. So to comply with the alignment
+ requirement but not waste file space, we adjust
+ p_offset for just this segment. (OFF_ADJUST is
+ subtracted from OFF later.) This may put p_offset
+ past the end of file, but that shouldn't matter. */
+ }
+ else
+ off_adjust = 0;
}
/* Make sure the .dynamic section is the first section in the
PT_DYNAMIC segment. */
@@ -4455,7 +4468,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (m->includes_filehdr)
{
- if (! m->p_flags_valid)
+ if (!m->p_flags_valid)
p->p_flags |= PF_R;
p->p_filesz = bed->s->sizeof_ehdr;
p->p_memsz = bed->s->sizeof_ehdr;
@@ -4473,14 +4486,14 @@ assign_file_positions_for_load_sections (bfd *abfd,
}
p->p_vaddr -= off;
- if (! m->p_paddr_valid)
+ if (!m->p_paddr_valid)
p->p_paddr -= off;
}
}
if (m->includes_phdrs)
{
- if (! m->p_flags_valid)
+ if (!m->p_flags_valid)
p->p_flags |= PF_R;
if (!m->includes_filehdr)
@@ -4491,7 +4504,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
{
BFD_ASSERT (p->p_type == PT_LOAD);
p->p_vaddr -= off - p->p_offset;
- if (! m->p_paddr_valid)
+ if (!m->p_paddr_valid)
p->p_paddr -= off - p->p_offset;
}
}
@@ -4503,14 +4516,15 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (p->p_type == PT_LOAD
|| (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
{
- if (! m->includes_filehdr && ! m->includes_phdrs)
+ if (!m->includes_filehdr && !m->includes_phdrs)
p->p_offset = off;
else
{
file_ptr adjust;
adjust = off - (p->p_offset + p->p_filesz);
- p->p_filesz += adjust;
+ if (!no_contents)
+ p->p_filesz += adjust;
p->p_memsz += adjust;
}
}
@@ -4622,7 +4636,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
p->p_align = align;
}
- if (! m->p_flags_valid)
+ if (!m->p_flags_valid)
{
p->p_flags |= PF_R;
if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
@@ -4631,6 +4645,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
p->p_flags |= PF_W;
}
}
+ off -= off_adjust;
/* Check that all sections are in a PT_LOAD segment.
Don't check funky gdb generated core files. */