The problem with linkonce sections in ELF

H . J . Lu hjl@valinux.com
Tue Feb 1 13:19:00 GMT 2000


On Mon, Jan 31, 2000 at 11:27:19PM -0500, Ian Lance Taylor wrote:
> 
> Duplicate linkonce sections are removed before section addresses are
> assigned, so they should not leave any holes in the address space.
> 
> If they do leave holes in the address space, that is definitely a bug.
> Do you have any reason to think that that is happening?
> 

You are right. It is .rel.text and .rel.text which cause the problem.
When they are removed, they leave a hole in the address space. With
the modified ld/scripttempl/elf.sc, the hole is now at the end of the
text segment.

However, there is another bug. Under certain conditions,
_bfd_elf_set_section_contents will be called on the ".rel.init"
sections with the section offset == 0, which corrupts the ELF header
among others. I have no idea why _bfd_elf_set_section_contents is
called with section offset == 0. I will be happy to provide a binary
testcase on Linux/x86.

Thanks.

-- 
H.J. Lu (hjl@gnu.org)
---
Index: bfd/elf.c
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elf.c,v
retrieving revision 1.11
diff -u -p -r1.11 elf.c
--- bfd/elf.c	2000/01/13 19:43:43	1.11
+++ bfd/elf.c	2000/02/01 21:06:35
@@ -4777,6 +4777,10 @@ _bfd_elf_set_section_contents (abfd, sec
 
   hdr = &elf_section_data (section)->this_hdr;
 
+  /* FIXME: Why does section start at the offset 0? */
+  if (hdr->sh_offset == 0)
+    return true;
+
   if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1)
     return false;
   if (bfd_write (location, 1, count, abfd) != count)
Index: ld/scripttempl/elf.sc
===================================================================
RCS file: /work/cvs/gnu/binutils/ld/scripttempl/elf.sc,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 elf.sc
--- ld/scripttempl/elf.sc	2000/01/13 19:36:13	1.1.1.7
+++ ld/scripttempl/elf.sc	2000/02/01 21:16:54
@@ -123,18 +123,6 @@ SECTIONS
 
   .rel.init    ${RELOCATING-0} : { *(.rel.init)	}
   .rela.init   ${RELOCATING-0} : { *(.rela.init)	}
-  .rel.text    ${RELOCATING-0} :
-    {
-      *(.rel.text)
-      ${RELOCATING+*(.rel.text.*)}
-      ${RELOCATING+*(.rel.gnu.linkonce.t*)}
-    }
-  .rela.text   ${RELOCATING-0} :
-    {
-      *(.rela.text)
-      ${RELOCATING+*(.rela.text.*)}
-      ${RELOCATING+*(.rela.gnu.linkonce.t*)}
-    }
   .rel.fini    ${RELOCATING-0} : { *(.rel.fini)	}
   .rela.fini   ${RELOCATING-0} : { *(.rela.fini)	}
   .rel.rodata  ${RELOCATING-0} :
@@ -218,6 +206,22 @@ SECTIONS
   ${WRITABLE_RODATA-${RODATA}}
   .rodata1 ${RELOCATING-0} : { *(.rodata1) }
   ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+  /* .rel.text and .rela.text are moved to the end of the text segment
+     since they may be removed in DSO and executable which may lead to
+     hole in the address space. */
+  .rel.text    ${RELOCATING-0} :
+    {
+      *(.rel.text)
+      ${RELOCATING+*(.rel.text.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.t*)}
+    }
+  .rela.text   ${RELOCATING-0} :
+    {
+      *(.rela.text)
+      ${RELOCATING+*(.rela.text.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.t*)}
+    }
 
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */


More information about the Binutils mailing list