[arch][riscv] tweak the linker scripts to better place .sdata and .sbss

Refactor the two linker scripts to put .sdata at the end of the data segment
and .sbss at the start of the bss segment to try to maximize the reach of
the global pointer.

Also generally tries to clean up and align the two linker scripts as a new
golden standard for other architectures.
This commit is contained in:
Travis Geiselbrecht
2020-07-11 15:33:14 -07:00
parent 213895c69a
commit 4ca59c9237
2 changed files with 75 additions and 65 deletions

View File

@@ -1,9 +1,5 @@
/*
* LK linker script for multi segment binaries.
* In this case the read only portion of the binary lives in read only
* memory, usually in ROM at a lower address.
* Data and BSS live in a higher memory address and initial data is
* copied from rom during initialization.
* LK linker script for single segment binaries.
*/
PHDRS
{
@@ -18,6 +14,7 @@ SECTIONS
. = %KERNEL_BASE% + %KERNEL_LOAD_OFFSET%;
_start = .;
__rom_start = .;
/* text/read-only data */
/* set the load address to physical MEMBASE */
@@ -27,28 +24,22 @@ SECTIONS
*(.gnu.linkonce.t.*)
} :code
.rodata : ALIGN(CONSTANT(MAXPAGESIZE)) {
. = ALIGN(CONSTANT(MAXPAGESIZE));
.rodata : {
__rodata_start = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.srodata*)
} :rodata
/*
* extra linker scripts tend to insert sections just after .rodata,
* so we want to make sure this symbol comes after anything inserted above,
* but not aligned to the next section necessarily.
*/
.dummy_post_rodata : {
__rodata_end = .;
}
. = .;
__rodata_end = .;
__rom_end = . ;
. = ALIGN(CONSTANT(MAXPAGESIZE));
__data_start_rom = .;
.data : ALIGN(CONSTANT(MAXPAGESIZE)) {
__data_start_rom = .;
/* in one segment binaries, the rom data address is on top of the ram data address */
.data : {
__data_start = .;
*(.data .data.* .gnu.linkonce.d.*)
PROVIDE( __global_pointer$ = . + (4K / 2) );
*(.sdata .sdata.*)
__ctor_list = .;
KEEP(*(.ctors .init_array))
__ctor_end = .;
@@ -59,28 +50,35 @@ SECTIONS
*(.dynamic)
} :data
/*
* extra linker scripts tend to insert sections just after .data,
* so we want to make sure this symbol comes after anything inserted above,
* but not aligned to the next section necessarily.
*/
.dummy_post_data : {
. = ALIGN(%BITS% / 8);
__data_end = .;
/* Try to put sdata and sbss near each other by putting sdata at the end of the data segment
* and sbss at the start of the bss segment. This maximizes reach of things referenced off of
* the global pointer. */
.sdata : {
__global_pointer$ = . + (4K / 2);
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
}
. = ALIGN(%BITS% / 8);
__data_end = .;
__bss_start = .;
.sbss : {
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
/* uninitialized data (in same segment as writable data) */
.bss : ALIGN(%BITS% / 8) {
__bss_start = .;
.bss : {
/* regular bss */
*(.bss .bss.*)
*(.sbss .sbss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(%BITS% / 8);
__bss_end = .;
}
. = ALIGN(%BITS% / 8);
__bss_end = .;
/* Align the end to ensure anything after the kernel ends up on its own pages */
. = ALIGN(CONSTANT(MAXPAGESIZE));
_end = .;