This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: VMA section overlap warnings for overlays


This removes all the special treatment for zero size sections when
using ELF_SECTION_IN_SEGMENT in elf.c, and makes readelf display
section to segment mapping for zero size sections.  I chose to not
include a zero size section in readelf's mapping if the section was at
the end of a segment.  eg. if the segment covers 0x1000 to 0x1fff,
then a zero sized section located at 0x2000 is not shown as part of
the segment.  That seems reasonable to me, but I'm open to
suggestions.  I'll note that omitting sections like this in elf.c, ie.
using ELF_SECTION_IN_SEGMENT_STRICT there, causes testsuite failures
on x86.  A zero length .got.plt sometimes ends up as the last section
mapped to a load segment.

include/elf/
	* 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.
bfd/
	* 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.
binutils/
	* readelf.c (process_program_headers): Don't ignore all zero size
	sections.
ld/testsuite/
	* ld-powerpc/tlsexe.r: Update.
	* ld-powerpc/tlsexetoc.r: Update.
	* ld-powerpc/tlsso.r: Update.
	* ld-powerpc/tlstocso.r: Update.

Index: include/elf/internal.h
===================================================================
RCS file: /cvs/src/src/include/elf/internal.h,v
retrieving revision 1.25
diff -u -p -r1.25 internal.h
--- include/elf/internal.h	24 Apr 2010 01:05:22 -0000	1.25
+++ include/elf/internal.h	20 Jul 2010 13:53:26 -0000
@@ -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)
+  (ELF_TBSS_SPECIAL(sec_hdr, segment) ? 0 : (sec_hdr)->sh_size)
 
-/* 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)				\
+/* 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 */
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.512
diff -u -p -r1.512 elf.c
--- bfd/elf.c	17 Jul 2010 03:10:50 -0000	1.512
+++ bfd/elf.c	20 Jul 2010 13:53:29 -0000
@@ -4589,8 +4589,7 @@ assign_file_positions_for_load_sections 
 
 	      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_secti
 	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 
 	   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 
 	       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 *o
 
 	      /* 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?  */
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.506
diff -u -p -r1.506 readelf.c
--- binutils/readelf.c	19 Jul 2010 12:46:01 -0000	1.506
+++ binutils/readelf.c	20 Jul 2010 13:53:33 -0000
@@ -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));
 	    }
 
Index: ld/testsuite/ld-powerpc/tlsexe.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.r,v
retrieving revision 1.25
diff -u -p -r1.25 tlsexe.r
--- ld/testsuite/ld-powerpc/tlsexe.r	2 Oct 2009 15:00:30 -0000	1.25
+++ ld/testsuite/ld-powerpc/tlsexe.r	20 Jul 2010 07:05:25 -0000
@@ -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 
 
Index: ld/testsuite/ld-powerpc/tlsexetoc.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.r,v
retrieving revision 1.26
diff -u -p -r1.26 tlsexetoc.r
--- ld/testsuite/ld-powerpc/tlsexetoc.r	2 Oct 2009 15:00:30 -0000	1.26
+++ ld/testsuite/ld-powerpc/tlsexetoc.r	20 Jul 2010 07:05:25 -0000
@@ -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 
 
Index: ld/testsuite/ld-powerpc/tlsso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.r,v
retrieving revision 1.26
diff -u -p -r1.26 tlsso.r
--- ld/testsuite/ld-powerpc/tlsso.r	2 Oct 2009 15:00:30 -0000	1.26
+++ ld/testsuite/ld-powerpc/tlsso.r	20 Jul 2010 07:05:25 -0000
@@ -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 
 
Index: ld/testsuite/ld-powerpc/tlstocso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.r,v
retrieving revision 1.24
diff -u -p -r1.24 tlstocso.r
--- ld/testsuite/ld-powerpc/tlstocso.r	2 Oct 2009 15:00:30 -0000	1.24
+++ ld/testsuite/ld-powerpc/tlstocso.r	20 Jul 2010 07:05:25 -0000
@@ -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 
 

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]