[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:
@@ -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 = .;
|
||||
|
||||
Reference in New Issue
Block a user