diff options
author | Alan Modra <amodra@gmail.com> | 2007-06-29 01:12:52 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-06-29 01:12:52 +0000 |
commit | bf988460f1ac19b0e7add220132af27241bd9cef (patch) | |
tree | da76b55f1d44b96a3a996300ca7225d03cb03757 /bfd/elf.c | |
parent | f08312c2d4e86b40fed18f1a9c4e38192e272cea (diff) | |
download | gdb-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.c | 67 |
1 files changed, 41 insertions, 26 deletions
@@ -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. */ |