From bf988460f1ac19b0e7add220132af27241bd9cef Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 29 Jun 2007 01:12:52 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 11 +++++++-- bfd/elf.c | 67 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cdb4784efe4..37782207b47 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2007-06-29 Alan Modra + + * 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. + 2007-06-27 Alan Modra * bfd.c (struct bfd): Rename "next" to "archive_next". @@ -90,7 +97,7 @@ 2007-06-11 Sterling Augustine Bob Wilson - + * elf32-xtensa.c (extend_ebb_bounds_forward): Use renamed XTENSA_PROP_NO_TRANSFORM flag instead of XTENSA_PROP_INSN_NO_TRANSFORM. (extend_ebb_bounds_backward, compute_text_actions): Likewise. @@ -99,7 +106,7 @@ (compute_removed_literals): Pass new arguments to is_removable_literal. (is_removable_literal): Add sec, prop_table and ptblsize arguments. Do not remove literal if the NO_TRANSFORM property flag is set. - + 2007-05-31 Richard Sandiford * elfxx-mips.c (mips_elf_initialize_tls_index): When processing a diff --git a/bfd/elf.c b/bfd/elf.c index 532e6b57492..a269f329ff0 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. */ -- 2.30.2