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]

Fix PR12763, .tbss mishandling


This patch fixes the primary complaint in PR12763, that ld reports
ld: pr12763: section `.tbss' can't be allocated in segment 1
by simply not checking .tbss.  The testcase is interesting for other
bugs it tickles too, most notably that a simple objcopy results in a
bogus PT_TLS header.  Also, I noticed that when you remove .tdata from
the testcase, ld creates a PT_LOAD header with zero p_filsiz and
p_memsz.

bfd/
	PR 12763
	* elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs
	from PT_TLS header.
	(_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD
	segment if just for .tbss.
	(assign_file_positions_for_load_sections): Don't report "can't
	allocate in segment" errors for .tbss.
	(assign_file_positions_for_non_load_sections): Don't set p_filesz
	from SHT_NOBITS section filepos.
ld/testsuite/
	PR 12763
	* ld-elf/tdata3.s: New test.
	* ld-elf/tbss3.s: New test.
	* ld-elf/binutils.exp: Consolidate tbss and tdata tests.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.536
diff -u -p -r1.536 elf.c
--- bfd/elf.c	12 May 2011 07:41:42 -0000	1.536
+++ bfd/elf.c	20 May 2011 15:18:32 -0000
@@ -976,7 +976,9 @@ _bfd_elf_make_section_from_shdr (bfd *ab
       phdr = elf_tdata (abfd)->phdr;
       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
 	{
-	  if (phdr->p_type == PT_LOAD
+	  if (((phdr->p_type == PT_LOAD
+		&& (hdr->sh_flags & SHF_TLS) == 0)
+	       || phdr->p_type == PT_TLS)
 	      && ELF_SECTION_IN_SEGMENT (hdr, phdr))
 	    {
 	      if ((flags & SEC_LOAD) == 0)
@@ -3987,8 +3989,12 @@ _bfd_elf_map_sections_to_segments (bfd *
 	  phdr_in_segment = FALSE;
 	}
 
-      /* Create a final PT_LOAD program segment.  */
-      if (last_hdr != NULL)
+      /* Create a final PT_LOAD program segment, but not if it's just
+	 for .tbss.  */
+      if (last_hdr != NULL
+	  && (i - phdr_index != 1
+	      || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
+		  != SEC_THREAD_LOCAL)))
 	{
 	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
 	  if (m == NULL)
@@ -4748,7 +4754,8 @@ assign_file_positions_for_load_sections 
 
 	      sec = m->sections[i];
 	      this_hdr = &(elf_section_data(sec)->this_hdr);
-	      if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0))
+	      if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
+		  && !ELF_TBSS_SPECIAL (this_hdr, p))
 		{
 		  (*_bfd_error_handler)
 		    (_("%B: section `%A' can't be allocated in segment %d"),
@@ -4919,17 +4926,21 @@ assign_file_positions_for_non_load_secti
 	      && (p->p_type != PT_NOTE
 		  || bfd_get_format (abfd) != bfd_core))
 	    {
-	      Elf_Internal_Shdr *hdr;
-	      asection *sect;
-
 	      BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
 
-	      sect = m->sections[m->count - 1];
-	      hdr = &elf_section_data (sect)->this_hdr;
-	      p->p_filesz = sect->filepos - m->sections[0]->filepos;
-	      if (hdr->sh_type != SHT_NOBITS)
-		p->p_filesz += hdr->sh_size;
+	      p->p_filesz = 0;
 	      p->p_offset = m->sections[0]->filepos;
+	      for (i = m->count; i-- != 0;)
+		{
+		  asection *sect = m->sections[i];
+		  Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
+		  if (hdr->sh_type != SHT_NOBITS)
+		    {
+		      p->p_filesz = (sect->filepos - m->sections[0]->filepos
+				     + hdr->sh_size);
+		      break;
+		    }
+		}
 	    }
 	}
       else if (m->includes_filehdr)
Index: ld/testsuite/ld-elf/binutils.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elf/binutils.exp,v
retrieving revision 1.13
diff -u -p -r1.13 binutils.exp
--- ld/testsuite/ld-elf/binutils.exp	18 Nov 2010 06:57:56 -0000	1.13
+++ ld/testsuite/ld-elf/binutils.exp	20 May 2011 15:20:11 -0000
@@ -121,35 +121,22 @@ if { ([istarget "i?86-*-elf*"]		
 
 binutils_test strip "-T ${srcdir}/${subdir}/lma.lnk" lma
 
+set tls_tests { "tdata1" "tdata2" "tdata3" }
 # hppa64 has its own .tbss section, with different flags.
 if { ![istarget "hppa64-*-*"] } {
-    binutils_test objcopy "" tbss1
-    binutils_test objcopy "-z relro" tbss1
-    binutils_test objcopy "-shared" tbss1
-    binutils_test objcopy "-shared -z relro" tbss1
-    binutils_test objcopy "-z max-page-size=0x100000" tbss1
-    binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tbss1
+    lappend tls_tests "tbss1" "tbss2" "tbss3"
 }
-
-binutils_test objcopy "" tdata1
-binutils_test objcopy "-z relro" tdata1
-binutils_test objcopy "-shared" tdata1
-binutils_test objcopy "-shared -z relro" tdata1
-binutils_test objcopy "-z max-page-size=0x100000" tdata1
-binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tdata1
-
-if { ![istarget "hppa64-*-*"] } {
-    binutils_test objcopy "" tbss2
-    binutils_test objcopy "-z relro" tbss2
-    binutils_test objcopy "-shared" tbss2
-    binutils_test objcopy "-shared -z relro" tbss2
-    binutils_test objcopy "-z max-page-size=0x100000" tbss2
-    binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tbss2
+set tls_opts {
+    ""
+    "-z relro"
+    "-shared"
+    "-shared -z relro"
+    "-z max-page-size=0x100000"
+    "-z max-page-size=0x100000 -z common-page-size=0x1000"
 }
 
-binutils_test objcopy "" tdata2
-binutils_test objcopy "-z relro" tdata2
-binutils_test objcopy "-shared" tdata2
-binutils_test objcopy "-shared -z relro" tdata2
-binutils_test objcopy "-z max-page-size=0x100000" tdata2
-binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tdata2
+foreach testitem $tls_tests {
+    foreach testopt $tls_opts {
+	binutils_test objcopy $testopt $testitem
+    }
+}
Index: ld/testsuite/ld-elf/tbss3.s
===================================================================
RCS file: ld/testsuite/ld-elf/tbss3.s
diff -N ld/testsuite/ld-elf/tbss3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/tbss3.s	20 May 2011 15:20:11 -0000
@@ -0,0 +1,17 @@
+	.globl main
+	.globl start
+	.globl _start
+	.globl __start
+	.text
+main:
+start:
+_start:
+__start:
+	.byte 0
+
+	.section .tbss,"awT",%nobits
+	.p2align 10
+	.type	tbss, %object
+	.size	tbss, 1024
+tbss:
+	.zero	1024
Index: ld/testsuite/ld-elf/tdata3.s
===================================================================
RCS file: ld/testsuite/ld-elf/tdata3.s
diff -N ld/testsuite/ld-elf/tdata3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/tdata3.s	20 May 2011 15:20:11 -0000
@@ -0,0 +1,23 @@
+	.globl main
+	.globl start
+	.globl _start
+	.globl __start
+	.text
+main:
+start:
+_start:
+__start:
+	.byte 0
+
+	.section .tdata,"awT",%progbits
+	.type	tdata,%object
+	.size	tdata,1
+tdata:
+	.byte 17
+
+	.section .tbss,"awT",%nobits
+	.p2align 10
+	.type	tbss, %object
+	.size	tbss, 1024
+tbss:
+	.zero	1024

-- 
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]