+2007-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): Set sh_offset
+ here. Set sh_type to SHT_NOBITS if we won't be allocating
+ file space. Don't bump p_memsz for non-alloc sections. Adjust
+ section-in-segment check.
+ (assign_file_positions_for_non_load_sections): Don't set sh_offset
+ here for sections that have already been handled above.
+
2007-04-30 Alan Modra <amodra@bigpond.net.au>
* elf32-spu.c (struct spu_link_hash_table): Add stack_analysis
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;
if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
{
/* The section at i == 0 is the one that actually contains
everything. */
if (i == 0)
{
- sec->filepos = off;
+ this_hdr->sh_offset = sec->filepos = off;
off += sec->size;
p->p_filesz = sec->size;
p->p_memsz = 0;
{
if (p->p_type == PT_LOAD)
{
- sec->filepos = off + voff;
+ 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
if ((flags & SEC_LOAD) != 0
|| (flags & SEC_HAS_CONTENTS) != 0)
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)
{
p->p_filesz += sec->size;
- p->p_memsz += 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)
+ p->p_memsz += sec->size;
}
/* .tbss is special. It doesn't contribute to p_memsz of
}
}
- /* Check if all sections are in the segment. Skip PT_GNU_RELRO
- and PT_NOTE segments since they will be processed by
- assign_file_positions_for_non_load_sections later. */
- if (p->p_type != PT_GNU_RELRO
- && p->p_type != PT_NOTE)
+ /* Check that all sections are in the segment. */
+ if (p->p_type == PT_LOAD
+ || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
{
Elf_Internal_Shdr *this_hdr;
&& (hdr->bfd_section->filepos != 0
|| (hdr->sh_type == SHT_NOBITS
&& hdr->contents == NULL)))
- hdr->sh_offset = hdr->bfd_section->filepos;
+ BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
else if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
if (hdr->sh_size != 0)
+2007-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
+ and vma for appropriate sections.
+
2007-04-26 Jan Beulich <jbeulich@novell.com>
* common.h (DT_ENCODING): Correct value (back to spec mandated
/* ELF support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
- 2003, 2006 Free Software Foundation, Inc.
+ 2003, 2006, 2007 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
/* Decide if the given sec_hdr is in the given segment. PT_TLS segment
contains only SHF_TLS sections. Only PT_LOAD and PT_TLS segments
can contain SHF_TLS sections. */
-#define ELF_IS_SECTION_IN_SEGMENT(sec_hdr, segment) \
- (((((sec_hdr->sh_flags & SHF_TLS) != 0) \
- && (segment->p_type == PT_TLS \
- || segment->p_type == PT_LOAD)) \
- || ((sec_hdr->sh_flags & SHF_TLS) == 0 \
- && segment->p_type != PT_TLS)) \
- /* Compare allocated sec_hdrs by VMA, unallocated sec_hdrs \
- by file offset. */ \
- && (sec_hdr->sh_flags & SHF_ALLOC \
- ? (sec_hdr->sh_addr >= segment->p_vaddr \
- && (sec_hdr->sh_addr \
- + ELF_SECTION_SIZE(sec_hdr, segment) \
- <= segment->p_vaddr + segment->p_memsz)) \
- : ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset \
- && (sec_hdr->sh_offset \
- + ELF_SECTION_SIZE(sec_hdr, segment) \
- <= segment->p_offset + segment->p_filesz))))
+#define ELF_IS_SECTION_IN_SEGMENT(sec_hdr, segment) \
+ (((((sec_hdr->sh_flags & SHF_TLS) != 0) \
+ && (segment->p_type == PT_TLS \
+ || segment->p_type == PT_LOAD)) \
+ || ((sec_hdr->sh_flags & SHF_TLS) == 0 \
+ && segment->p_type != PT_TLS)) \
+ /* Any section besides one of type SHT_NOBITS must have a file \
+ offset within the segment. */ \
+ && (sec_hdr->sh_type == SHT_NOBITS \
+ || ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset \
+ && (sec_hdr->sh_offset + ELF_SECTION_SIZE(sec_hdr, segment) \
+ <= segment->p_offset + segment->p_filesz))) \
+ /* SHF_ALLOC sections must have VMAs within the segment. */ \
+ && ((sec_hdr->sh_flags & SHF_ALLOC) == 0 \
+ || (sec_hdr->sh_addr >= segment->p_vaddr \
+ && (sec_hdr->sh_addr + ELF_SECTION_SIZE(sec_hdr, segment) \
+ <= segment->p_vaddr + segment->p_memsz))))
/* Decide if the given sec_hdr is in the given segment in file. */
#define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment) \