2000-01-11 15:35:16 +00:00
|
|
|
/* $FreeBSD$ */
|
2002-10-11 19:38:04 +00:00
|
|
|
OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
|
1998-09-30 12:14:39 +00:00
|
|
|
OUTPUT_ARCH(i386)
|
|
|
|
ENTRY(btext)
|
1999-06-03 22:07:41 +00:00
|
|
|
SEARCH_DIR(/usr/lib);
|
1998-09-30 12:14:39 +00:00
|
|
|
SECTIONS
|
|
|
|
{
|
|
|
|
/* Read-only sections, merged into text segment: */
|
i386 4/4G split.
The change makes the user and kernel address spaces on i386
independent, giving each almost the full 4G of usable virtual addresses
except for one PDE at top used for trampoline and per-CPU trampoline
stacks, and system structures that must be always mapped, namely IDT,
GDT, common TSS and LDT, and process-private TSS and LDT if allocated.
By using 1:1 mapping for the kernel text and data, it appeared
possible to eliminate assembler part of the locore.S which bootstraps
initial page table and KPTmap. The code is rewritten in C and moved
into the pmap_cold(). The comment in vmparam.h explains the KVA
layout.
There is no PCID mechanism available in protected mode, so each
kernel/user switch forth and back completely flushes the TLB, except
for the trampoline PTD region. The TLB invalidations for userspace
becomes trivial, because IPI handlers switch page tables. On the other
hand, context switches no longer need to reload %cr3.
copyout(9) was rewritten to use vm_fault_quick_hold(). An issue for
new copyout(9) is compatibility with wiring user buffers around sysctl
handlers. This explains two kind of locks for copyout ptes and
accounting of the vslock() calls. The vm_fault_quick_hold() AKA slow
path, is only tried after the 'fast path' failed, which temporary
changes mapping to the userspace and copies the data to/from small
per-cpu buffer in the trampoline. If a page fault occurs during the
copy, it is short-circuit by exception.s to not even reach C code.
The change was motivated by the need to implement the Meltdown
mitigation, but instead of KPTI the full split is done. The i386
architecture already shows the sizing problems, in particular, it is
impossible to link clang and lld with debugging. I expect that the
issues due to the virtual address space limits would only exaggerate
and the split gives more liveness to the platform.
Tested by: pho
Discussed with: bde
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D14633
2018-04-13 20:30:49 +00:00
|
|
|
. = kernbase + SIZEOF_HEADERS;
|
2010-11-05 19:30:30 +00:00
|
|
|
.interp : { *(.interp) }
|
|
|
|
.hash : { *(.hash) }
|
2010-11-05 19:40:27 +00:00
|
|
|
.gnu.hash : { *(.gnu.hash) }
|
2010-11-05 19:30:30 +00:00
|
|
|
.dynsym : { *(.dynsym) }
|
|
|
|
.dynstr : { *(.dynstr) }
|
|
|
|
.gnu.version : { *(.gnu.version) }
|
|
|
|
.gnu.version_d : { *(.gnu.version_d) }
|
|
|
|
.gnu.version_r : { *(.gnu.version_r) }
|
|
|
|
.rel.init : { *(.rel.init) }
|
|
|
|
.rela.init : { *(.rela.init) }
|
|
|
|
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
|
|
|
|
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
|
|
|
|
.rel.fini : { *(.rel.fini) }
|
|
|
|
.rela.fini : { *(.rela.fini) }
|
|
|
|
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
|
|
|
|
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
|
2010-11-05 19:40:27 +00:00
|
|
|
.rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) }
|
|
|
|
.rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
|
2010-11-05 19:30:30 +00:00
|
|
|
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
|
|
|
|
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
|
|
|
|
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
|
|
|
|
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
|
|
|
|
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
|
|
|
|
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
|
|
|
|
.rel.ctors : { *(.rel.ctors) }
|
|
|
|
.rela.ctors : { *(.rela.ctors) }
|
|
|
|
.rel.dtors : { *(.rel.dtors) }
|
|
|
|
.rela.dtors : { *(.rela.dtors) }
|
|
|
|
.rel.got : { *(.rel.got) }
|
|
|
|
.rela.got : { *(.rela.got) }
|
|
|
|
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
|
|
|
|
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
|
|
|
.rel.plt : { *(.rel.plt) }
|
|
|
|
.rela.plt : { *(.rela.plt) }
|
|
|
|
.init :
|
1998-09-30 12:14:39 +00:00
|
|
|
{
|
2010-11-05 19:30:30 +00:00
|
|
|
KEEP (*(.init))
|
2017-03-19 00:22:13 +00:00
|
|
|
} =0xCCCCCCCC
|
2010-11-05 19:30:30 +00:00
|
|
|
.plt : { *(.plt) }
|
|
|
|
.text :
|
|
|
|
{
|
|
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)
|
2010-11-05 19:40:27 +00:00
|
|
|
KEEP (*(.text.*personality*))
|
1998-09-30 12:14:39 +00:00
|
|
|
/* .gnu.warning sections are handled specially by elf32.em. */
|
|
|
|
*(.gnu.warning)
|
2017-03-19 00:22:13 +00:00
|
|
|
} =0xCCCCCCCC
|
2010-11-05 19:30:30 +00:00
|
|
|
.fini :
|
|
|
|
{
|
|
|
|
KEEP (*(.fini))
|
2017-03-19 00:22:13 +00:00
|
|
|
} =0xCCCCCCCC
|
2010-11-05 19:30:30 +00:00
|
|
|
PROVIDE (__etext = .);
|
|
|
|
PROVIDE (_etext = .);
|
1998-09-30 12:14:39 +00:00
|
|
|
PROVIDE (etext = .);
|
2010-11-05 19:30:30 +00:00
|
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
|
|
|
.rodata1 : { *(.rodata1) }
|
|
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
2010-11-05 19:40:27 +00:00
|
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
|
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
1998-09-30 12:14:39 +00:00
|
|
|
/* Adjust the address for the data segment. We want to adjust up to
|
|
|
|
the same address within the page on the next page up. */
|
2010-11-05 19:40:27 +00:00
|
|
|
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
|
|
|
/* Exception handling */
|
|
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
|
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
|
|
|
/* Thread Local Storage sections */
|
2010-11-05 19:30:30 +00:00
|
|
|
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
|
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
2010-11-05 19:40:27 +00:00
|
|
|
.preinit_array :
|
|
|
|
{
|
|
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
|
|
|
KEEP (*(.preinit_array))
|
|
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
|
|
|
}
|
|
|
|
.init_array :
|
|
|
|
{
|
|
|
|
PROVIDE_HIDDEN (__init_array_start = .);
|
|
|
|
KEEP (*(SORT(.init_array.*)))
|
|
|
|
KEEP (*(.init_array))
|
|
|
|
PROVIDE_HIDDEN (__init_array_end = .);
|
|
|
|
}
|
|
|
|
.fini_array :
|
|
|
|
{
|
|
|
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
|
|
|
KEEP (*(.fini_array))
|
|
|
|
KEEP (*(SORT(.fini_array.*)))
|
|
|
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
|
|
|
}
|
2003-01-06 07:37:15 +00:00
|
|
|
_start_ctors = .;
|
|
|
|
PROVIDE (start_ctors = .);
|
2010-11-05 19:30:30 +00:00
|
|
|
.ctors :
|
1998-09-30 12:14:39 +00:00
|
|
|
{
|
2010-11-05 19:30:30 +00:00
|
|
|
/* gcc uses crtbegin.o to find the start of
|
|
|
|
the constructors, so we make sure it is
|
|
|
|
first. Because this is a wildcard, it
|
|
|
|
doesn't matter if the user does not
|
|
|
|
actually link against crtbegin.o; the
|
|
|
|
linker won't look for a file to match a
|
|
|
|
wildcard. The wildcard also means that it
|
|
|
|
doesn't matter which directory crtbegin.o
|
|
|
|
is in. */
|
2010-11-05 19:40:27 +00:00
|
|
|
KEEP (*crtbegin.o(.ctors))
|
|
|
|
KEEP (*crtbegin?.o(.ctors))
|
2010-11-05 19:30:30 +00:00
|
|
|
/* We don't want to include the .ctor section from
|
2010-11-05 19:40:27 +00:00
|
|
|
the crtend.o file until after the sorted ctors.
|
2010-11-05 19:30:30 +00:00
|
|
|
The .ctor section from the crtend file contains the
|
|
|
|
end of ctors marker and it must be last */
|
2010-11-05 19:40:27 +00:00
|
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
2010-11-05 19:30:30 +00:00
|
|
|
KEEP (*(SORT(.ctors.*)))
|
|
|
|
KEEP (*(.ctors))
|
1998-09-30 12:14:39 +00:00
|
|
|
}
|
2003-01-06 07:37:15 +00:00
|
|
|
_stop_ctors = .;
|
|
|
|
PROVIDE (stop_ctors = .);
|
2010-11-05 19:30:30 +00:00
|
|
|
.dtors :
|
1998-09-30 12:14:39 +00:00
|
|
|
{
|
2010-11-05 19:40:27 +00:00
|
|
|
KEEP (*crtbegin.o(.dtors))
|
|
|
|
KEEP (*crtbegin?.o(.dtors))
|
|
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
2010-11-05 19:30:30 +00:00
|
|
|
KEEP (*(SORT(.dtors.*)))
|
|
|
|
KEEP (*(.dtors))
|
1998-09-30 12:14:39 +00:00
|
|
|
}
|
2010-11-05 19:30:30 +00:00
|
|
|
.jcr : { KEEP (*(.jcr)) }
|
2010-11-05 19:40:27 +00:00
|
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
|
|
|
|
.dynamic : { *(.dynamic) }
|
|
|
|
.got : { *(.got) }
|
|
|
|
. = DATA_SEGMENT_RELRO_END (12, .);
|
|
|
|
.got.plt : { *(.got.plt) }
|
|
|
|
.data :
|
|
|
|
{
|
|
|
|
*(.data .data.* .gnu.linkonce.d.*)
|
|
|
|
KEEP (*(.gnu.linkonce.d.*personality*))
|
|
|
|
}
|
|
|
|
.data1 : { *(.data1) }
|
|
|
|
_edata = .; PROVIDE (edata = .);
|
2010-11-05 19:30:30 +00:00
|
|
|
.bss :
|
1998-09-30 12:14:39 +00:00
|
|
|
{
|
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.
2018-10-11 20:44:25 +00:00
|
|
|
__bss_start = .;
|
1998-09-30 12:14:39 +00:00
|
|
|
*(.dynbss)
|
2010-11-05 19:30:30 +00:00
|
|
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
1998-09-30 12:14:39 +00:00
|
|
|
*(COMMON)
|
2010-11-05 19:30:30 +00:00
|
|
|
/* Align here to ensure that the .bss section occupies space up to
|
|
|
|
_end. Align after .bss to ensure correct alignment even if the
|
2010-11-05 19:40:27 +00:00
|
|
|
.bss section disappears because there are no input 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);
|
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.
2018-10-11 20:44:25 +00:00
|
|
|
__bss_end = .;
|
1998-09-30 12:14:39 +00:00
|
|
|
}
|
|
|
|
. = ALIGN(32 / 8);
|
2010-11-05 19:40:27 +00:00
|
|
|
. = ALIGN(32 / 8);
|
|
|
|
_end = .; PROVIDE (end = .);
|
2010-11-05 19:30:30 +00:00
|
|
|
. = DATA_SEGMENT_END (.);
|
1998-09-30 12:14:39 +00:00
|
|
|
/* Stabs debugging sections. */
|
2010-11-05 19:30:30 +00:00
|
|
|
.stab 0 : { *(.stab) }
|
|
|
|
.stabstr 0 : { *(.stabstr) }
|
|
|
|
.stab.excl 0 : { *(.stab.excl) }
|
|
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
|
|
.stab.index 0 : { *(.stab.index) }
|
1998-09-30 12:14:39 +00:00
|
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
2010-11-05 19:30:30 +00:00
|
|
|
.comment 0 : { *(.comment) }
|
1998-09-30 12:14:39 +00:00
|
|
|
/* DWARF debug sections.
|
|
|
|
Symbols in the DWARF debugging sections are relative to the beginning
|
|
|
|
of the section so we begin them at 0. */
|
|
|
|
/* DWARF 1 */
|
|
|
|
.debug 0 : { *(.debug) }
|
|
|
|
.line 0 : { *(.line) }
|
|
|
|
/* GNU DWARF 1 extensions */
|
|
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
|
|
/* DWARF 1.1 and DWARF 2 */
|
|
|
|
.debug_aranges 0 : { *(.debug_aranges) }
|
|
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
|
|
/* DWARF 2 */
|
2010-11-05 19:30:30 +00:00
|
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
1998-09-30 12:14:39 +00:00
|
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
|
|
.debug_line 0 : { *(.debug_line) }
|
|
|
|
.debug_frame 0 : { *(.debug_frame) }
|
|
|
|
.debug_str 0 : { *(.debug_str) }
|
|
|
|
.debug_loc 0 : { *(.debug_loc) }
|
|
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
|
|
/* SGI/MIPS DWARF 2 extensions */
|
|
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
|
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
|
|
|
.debug_typenames 0 : { *(.debug_typenames) }
|
|
|
|
.debug_varnames 0 : { *(.debug_varnames) }
|
2010-11-05 19:40:27 +00:00
|
|
|
/* DWARF 3 */
|
|
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
|
|
|
.debug_ranges 0 : { *(.debug_ranges) }
|
|
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
2010-11-05 19:30:30 +00:00
|
|
|
/DISCARD/ : { *(.note.GNU-stack) }
|
1998-09-30 12:14:39 +00:00
|
|
|
}
|