Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Oct 2018 20:44:25 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r339317 - in projects/clang700-import/sys: conf i386/i386
Message-ID:  <201810112044.w9BKiPBD017697@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu Oct 11 20:44:25 2018
New Revision: 339317
URL: https://svnweb.freebsd.org/changeset/base/339317

Log:
  Fix placement of __bss_start in i386 kernel linker script
  
  With lld 7.0.0, a rather nasty problem in our kernel linker script came
  to light.  We use quite a lot of so-called "orphan" sections, e.g.
  sections which are not explicitly named in the linker script.  Mainly,
  these are the linker sets (such as set_sysinit_set).
  
  Note that the placement of these orphan sections is not very well
  defined.  Usually, any read-only orphan sections get placed after the
  last read-only section from the linker script, and similarly for the
  read/write variants.
  
  In our linker scripts, there are also symbol assignments like _etext,
  _edata, and __bss_start, which are used in various places to refer to
  the start or end addresses of sections.
  
  However, some of these symbol assignments are interspersed with output
  section descriptions.  While the linker will guarantee that a symbol
  assignment after some section will stay after that section, there is no
  guarantee that an orphan section cannot be inserted just before it.
  
  Take for example the following script:
  
  SECTIONS
  {
    .data : { *(.data) }
    __bss_start = .;
    .bss : { *(.bss) }
  }
  
  If an orphan section (like set_sysinit_set) is now inserted just after
  the __bss_start assignment, __bss_start will actually point to the start
  of that orphan section, *not* to the start of the .bss section.
  
  Unfortunately, something like this happened with our i386 kernel linker
  script, and since sys/i386/i386/locore.s tries to zero .bss, it ended up
  zeroing all the linker sets too, leading to a crash very soon after the
  <--BOOT--> message.
  
  To fix this, move the __bss_start symbol assignment *into* the .bss
  section description, so there is no way a linker can then insert orphan
  sections at that point.  Also add a corresponding __bss_end symbol.
  
  In addition, change sys/i386/i386/locore.s, so it clears from
  __bss_start to __bss_end, instead of assuming that _edata is just
  before .bss (which may not be true), and that _end is just after _bss
  (which also may not be true).
  
  This allows an i386 kernel linked with lld 7.0.0 to boot successfully.

Modified:
  projects/clang700-import/sys/conf/ldscript.i386
  projects/clang700-import/sys/i386/i386/locore.s

Modified: projects/clang700-import/sys/conf/ldscript.i386
==============================================================================
--- projects/clang700-import/sys/conf/ldscript.i386	Thu Oct 11 19:18:06 2018	(r339316)
+++ projects/clang700-import/sys/conf/ldscript.i386	Thu Oct 11 20:44:25 2018	(r339317)
@@ -140,9 +140,9 @@ SECTIONS
   }
   .data1          : { *(.data1) }
   _edata = .; PROVIDE (edata = .);
-  __bss_start = .;
   .bss            :
   {
+   __bss_start = .;
    *(.dynbss)
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
@@ -152,6 +152,7 @@ SECTIONS
       FIXME: Why do we need it? When there is no .bss section, we don't
       pad the .data section.  */
    . = ALIGN(. != 0 ? 32 / 8 : 1);
+   __bss_end = .;
   }
   . = ALIGN(32 / 8);
   . = ALIGN(32 / 8);

Modified: projects/clang700-import/sys/i386/i386/locore.s
==============================================================================
--- projects/clang700-import/sys/i386/i386/locore.s	Thu Oct 11 19:18:06 2018	(r339316)
+++ projects/clang700-import/sys/i386/i386/locore.s	Thu Oct 11 20:44:25 2018	(r339317)
@@ -120,8 +120,8 @@ NON_GPROF_ENTRY(btext)
  * inactive from now until we switch to new ones, since we don't load any
  * more segment registers or permit interrupts until after the switch.
  */
-	movl	$end,%ecx
-	movl	$edata,%edi
+	movl	$__bss_end,%ecx
+	movl	$__bss_start,%edi
 	subl	%edi,%ecx
 	xorl	%eax,%eax
 	cld



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810112044.w9BKiPBD017697>