aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elf.c25
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/readelf.c4
-rw-r--r--include/elf/ChangeLog7
-rw-r--r--include/elf/internal.h54
-rw-r--r--ld/testsuite/ChangeLog7
-rw-r--r--ld/testsuite/ld-powerpc/tlsexe.r2
-rw-r--r--ld/testsuite/ld-powerpc/tlsexetoc.r2
-rw-r--r--ld/testsuite/ld-powerpc/tlsso.r2
-rw-r--r--ld/testsuite/ld-powerpc/tlstocso.r2
11 files changed, 81 insertions, 39 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a6dd0d8..aa36284 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2010-07-20 Alan Modra <amodra@gmail.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Check that
+ zero size sections are allocated in segments too.
+ (assign_file_positions_for_non_load_sections): Warn if zero
+ size alloc sections are found here.
+ (copy_elf_program_header): Don't drop zero size sections from
+ segment map.
+ (copy_private_bfd_data): Check for changes in zero size sections.
+
2010-07-17 Alan Modra <amodra@gmail.com>
* elf.c (_bfd_elf_map_sections_to_segments): Force new segment
diff --git a/bfd/elf.c b/bfd/elf.c
index 63f0260..e7651ba 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4589,8 +4589,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
sec = m->sections[i];
this_hdr = &(elf_section_data(sec)->this_hdr);
- if (this_hdr->sh_size != 0
- && !ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma))
+ if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0))
{
(*_bfd_error_handler)
(_("%B: section `%A' can't be allocated in segment %d"),
@@ -4640,13 +4639,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
else if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
- if (hdr->sh_size != 0)
- ((*_bfd_error_handler)
- (_("%B: warning: allocated section `%s' not in segment"),
- abfd,
- (hdr->bfd_section == NULL
- ? "*unknown*"
- : hdr->bfd_section->name)));
+ (*_bfd_error_handler)
+ (_("%B: warning: allocated section `%s' not in segment"),
+ abfd,
+ (hdr->bfd_section == NULL
+ ? "*unknown*"
+ : hdr->bfd_section->name));
/* We don't need to page align empty sections. */
if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
off += vma_page_aligned_bias (hdr->sh_addr, off,
@@ -5868,8 +5866,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
section = section->next)
{
this_hdr = &(elf_section_data(section)->this_hdr);
- if (this_hdr->sh_size != 0
- && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
if (!first_section)
first_section = lowest_section = section;
@@ -5948,8 +5945,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
section = section->next)
{
this_hdr = &(elf_section_data(section)->this_hdr);
- if (this_hdr->sh_size != 0
- && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
map->sections[isec++] = section->output_section;
if (isec == section_count)
@@ -6026,8 +6022,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
/* Check if this section is covered by the segment. */
this_hdr = &(elf_section_data(section)->this_hdr);
- if (this_hdr->sh_size != 0
- && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
/* FIXME: Check if its output section is changed or
removed. What else do we need to check? */
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 18c06c5..8e3ecb6 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2010-07-20 Alan Modra <amodra@gmail.com>
+
+ * readelf.c (process_program_headers): Don't ignore all zero size
+ sections.
+
2010-07-19 Andreas Schwab <schwab@redhat.com>
* readelf.c (process_section_headers): Update key to flags.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 883c482..447932c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3889,8 +3889,8 @@ process_program_headers (FILE * file)
for (j = 1; j < elf_header.e_shnum; j++, section++)
{
- if (ELF_SECTION_SIZE (section, segment) != 0
- && ELF_SECTION_IN_SEGMENT (section, segment))
+ if (!ELF_TBSS_SPECIAL (section, segment)
+ && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
printf ("%s ", SECTION_NAME (section));
}
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index 8a8e118..edd9b48 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,10 @@
+2010-07-20 Alan Modra <amodra@gmail.com>
+
+ * internal.h (ELF_TBSS_SPECIAL): New macro, extracted from..
+ (ELF_SECTION_SIZE): ..here.
+ (ELF_SECTION_IN_SEGMENT_1): Add "strict" arg.
+ (ELF_SECTION_IN_SEGMENT_STRICT): New macro.
+
2010-06-25 Alan Modra <amodra@gmail.com>
* ppc64.h (R_PPC64_LO_DS_OPT): Define.
diff --git a/include/elf/internal.h b/include/elf/internal.h
index 1dd336d..6998ae0 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -291,37 +291,55 @@ struct elf_segment_map
/* .tbss is special. It doesn't contribute memory space to normal
segments and it doesn't take file space in normal segments. */
+#define ELF_TBSS_SPECIAL(sec_hdr, segment) \
+ (((sec_hdr)->sh_flags & SHF_TLS) != 0 \
+ && (sec_hdr)->sh_type == SHT_NOBITS \
+ && (segment)->p_type != PT_TLS)
+
#define ELF_SECTION_SIZE(sec_hdr, segment) \
- ((!(((sec_hdr)->sh_flags & SHF_TLS) != 0 \
- && (sec_hdr)->sh_type == SHT_NOBITS) \
- || (segment)->p_type == PT_TLS) ? (sec_hdr)->sh_size : 0)
-
-/* Decide if the given sec_hdr is in the given segment. PT_TLS segment
- contains only SHF_TLS sections. Only PT_LOAD, PT_GNU_RELRO and
- and PT_TLS segments can contain SHF_TLS sections. */
-#define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma) \
- ((((((sec_hdr)->sh_flags & SHF_TLS) != 0) \
+ (ELF_TBSS_SPECIAL(sec_hdr, segment) ? 0 : (sec_hdr)->sh_size)
+
+/* Decide if the section SEC_HDR is in SEGMENT. If CHECK_VMA, then
+ VMAs are checked for alloc sections. If STRICT, then a zero size
+ section won't match at the end of a segment, unless the segment
+ is also zero size. */
+#define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma, strict) \
+ ((/* Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain \
+ SHF_TLS sections. */ \
+ ((((sec_hdr)->sh_flags & SHF_TLS) != 0) \
&& ((segment)->p_type == PT_TLS \
|| (segment)->p_type == PT_GNU_RELRO \
|| (segment)->p_type == PT_LOAD)) \
+ /* PT_TLS segment contains only SHF_TLS sections, PT_PHDR no \
+ sections at all. */ \
|| (((sec_hdr)->sh_flags & SHF_TLS) == 0 \
&& (segment)->p_type != PT_TLS \
&& (segment)->p_type != PT_PHDR)) \
- /* Any section besides one of type SHT_NOBITS must have a file \
- offset within the segment. */ \
+ /* Any section besides one of type SHT_NOBITS must have file \
+ offsets 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. Be \
- careful about segments right at the end of memory. */ \
+ && (!(strict) \
+ || ((sec_hdr)->sh_offset - (segment)->p_offset \
+ <= (segment)->p_filesz - 1)) \
+ && (((sec_hdr)->sh_offset - (segment)->p_offset \
+ + ELF_SECTION_SIZE(sec_hdr, segment)) \
+ <= (segment)->p_filesz))) \
+ /* SHF_ALLOC sections must have VMAs within the segment. */ \
&& (!(check_vma) \
|| ((sec_hdr)->sh_flags & SHF_ALLOC) == 0 \
|| ((sec_hdr)->sh_addr >= (segment)->p_vaddr \
- && ((sec_hdr)->sh_addr - (segment)->p_vaddr \
- + ELF_SECTION_SIZE(sec_hdr, segment) <= (segment)->p_memsz))))
+ && (!(strict) \
+ || ((sec_hdr)->sh_addr - (segment)->p_vaddr \
+ <= (segment)->p_memsz - 1)) \
+ && (((sec_hdr)->sh_addr - (segment)->p_vaddr \
+ + ELF_SECTION_SIZE(sec_hdr, segment)) \
+ <= (segment)->p_memsz))))
#define ELF_SECTION_IN_SEGMENT(sec_hdr, segment) \
- (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1))
+ (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 0))
+
+#define ELF_SECTION_IN_SEGMENT_STRICT(sec_hdr, segment) \
+ (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 1))
#endif /* _ELF_INTERNAL_H */
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 4691310..6ec6d55 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2010-07-20 Alan Modra <amodra@gmail.com>
+ * ld-powerpc/tlsexe.r: Update.
+ * ld-powerpc/tlsexetoc.r: Update.
+ * ld-powerpc/tlsso.r: Update.
+ * ld-powerpc/tlstocso.r: Update.
+
+2010-07-20 Alan Modra <amodra@gmail.com>
+
* ld-powerpc/vxworks-relax.s: Add branches to match expected output.
* ld-powerpc/vxworks-relax-2.s: Likewise.
* ld-powerpc/vxworks1-lib.rd: Reorder reloc sections.
diff --git a/ld/testsuite/ld-powerpc/tlsexe.r b/ld/testsuite/ld-powerpc/tlsexe.r
index db43d87..68b36bb 100644
--- a/ld/testsuite/ld-powerpc/tlsexe.r
+++ b/ld/testsuite/ld-powerpc/tlsexe.r
@@ -47,7 +47,7 @@ Program Headers:
+0+ +
+01 +\.interp
+02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +03 +\.tdata \.dynamic \.got \.plt
+ +03 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt
+04 +\.dynamic
+05 +\.tdata \.tbss
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.r b/ld/testsuite/ld-powerpc/tlsexetoc.r
index 82426ac..8ba8503 100644
--- a/ld/testsuite/ld-powerpc/tlsexetoc.r
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.r
@@ -47,7 +47,7 @@ Program Headers:
+0+ +
+01 +\.interp
+02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +03 +\.tdata \.dynamic \.got \.plt
+ +03 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt
+04 +\.dynamic
+05 +\.tdata \.tbss
diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r
index fa792f3..99c3659 100644
--- a/ld/testsuite/ld-powerpc/tlsso.r
+++ b/ld/testsuite/ld-powerpc/tlsso.r
@@ -40,7 +40,7 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
+0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +01 +\.tdata \.dynamic \.got \.plt
+ +01 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt
+02 +\.dynamic
+03 +\.tdata \.tbss
diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r
index 21ddeee..d04cf70 100644
--- a/ld/testsuite/ld-powerpc/tlstocso.r
+++ b/ld/testsuite/ld-powerpc/tlstocso.r
@@ -40,7 +40,7 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
+0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +01 +\.tdata \.dynamic \.got \.plt
+ +01 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt
+02 +\.dynamic
+03 +\.tdata \.tbss