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]

PATCH: PR ld/4007: Linker failed to issue an error on bad section in segment


When a linker script puts a section into a segment, linker doesn't
check if the section can be placed in the segment. This patch adds
the sanity check.


H.J.
----
bfd/

2007-02-27  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/4007
	* elf.c (assign_file_positions_for_load_sections): Check if
	all all sections are in the segment.

ld/testsuite/

2007-02-27  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/4007
	* ld-i386/alloc.d: New file.
	* ld-i386/alloc.s: Likewise.
	* ld-i386/alloc.t: Likewise.

	* ld-i386/i386.exp: Run "alloc".

--- binutils/bfd/elf.c.phdr	2007-02-26 14:58:31.000000000 -0800
+++ binutils/bfd/elf.c	2007-02-26 17:09:22.000000000 -0800
@@ -4348,7 +4348,7 @@ assign_file_positions_for_load_sections 
   file_ptr off, voff;
   bfd_size_type maxpagesize;
   unsigned int alloc;
-  unsigned int i;
+  unsigned int i, j;
 
   if (link_info == NULL
       && !elf_modify_segment_map (abfd, link_info))
@@ -4386,9 +4386,9 @@ assign_file_positions_for_load_sections 
   off = bed->s->sizeof_ehdr;
   off += alloc * bed->s->sizeof_phdr;
 
-  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
+  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
        m != NULL;
-       m = m->next, p++)
+       m = m->next, p++, j++)
     {
       asection **secpp;
 
@@ -4715,6 +4715,28 @@ assign_file_positions_for_load_sections 
 		p->p_flags |= PF_W;
 	    }
 	}
+
+      /* Check if all sections are in the segment.  Skip PT_GNU_RELRO
+	 segment since it will be extracted from PT_LOAD segment
+	 later.  */
+      if (p->p_type != PT_GNU_RELRO)
+	for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+	  {
+	    Elf_Internal_Shdr *this_hdr;
+	    asection *sec;
+
+	    sec = *secpp;
+	    this_hdr = &(elf_section_data(sec)->this_hdr);
+	    if (this_hdr->sh_size != 0
+		&& !ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, p))
+	      {
+		(*_bfd_error_handler)
+		  (_("%B: section `%A' can't be allocated in segement %d"),
+		   abfd, sec, j);
+		bfd_set_error (bfd_error_bad_value);
+		return FALSE;
+	      }
+	  }
     }
 
   elf_tdata (abfd)->next_file_pos = off;
--- binutils/ld/testsuite/ld-i386/alloc.d.phdr	2007-02-26 17:18:45.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/alloc.d	2007-02-26 17:16:39.000000000 -0800
@@ -0,0 +1,4 @@
+#name: Invalid allocated section
+#as: --32
+#ld: -melf_i386 -T alloc.t
+#error: .*section `.foo' can't be allocated in segement 0.*
--- binutils/ld/testsuite/ld-i386/alloc.s.phdr	2007-02-26 17:18:34.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/alloc.s	2007-02-26 17:10:06.000000000 -0800
@@ -0,0 +1,6 @@
+	.section .bar,"ax","progbits"
+	.byte 0
+	.section .foo,"aw","progbits"
+	.byte 0
+	.bss
+	.long 0
--- binutils/ld/testsuite/ld-i386/alloc.t.phdr	2007-02-26 17:18:38.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/alloc.t	2007-02-26 17:10:15.000000000 -0800
@@ -0,0 +1,13 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+PHDRS {
+ text PT_LOAD FLAGS(5); /* R_E */
+}
+SECTIONS
+{
+  . = 0xC0000000 + ((0x100000 + (0x100000 - 1)) & ~(0x100000 - 1));
+  .bar : AT(ADDR(.bar) - 0xC0000000) { *(.bar) } :text
+  .bss : AT(ADDR(.bss) - 0xC0000000) { *(.bss) }
+  .foo 0 : AT(ADDR(.bss) + SIZEOF(.bss) - 0xC0000000) { *(.foo) } :text
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-i386/i386.exp.phdr	2007-02-26 14:58:31.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/i386.exp	2007-02-26 17:13:04.000000000 -0800
@@ -114,3 +114,4 @@ run_dump_test "abs"
 run_dump_test "pcrel8"
 run_dump_test "pcrel16"
 run_dump_test "pcrel16abs"
+run_dump_test "alloc"


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