implements proper linker script to support TLS
This change updates the linker script and dependend wile so that thread local storage sections are properly supported and initailaized
This commit is contained in:
@@ -4,9 +4,9 @@ ENTRY( _start )
|
||||
|
||||
INCLUDE memory_map.ld
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", flash);
|
||||
REGION_ALIAS("REGION_RODATA", flash);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("LOCATION_TEXT", flash);
|
||||
REGION_ALIAS("LOCATION_RODATA", flash);
|
||||
REGION_ALIAS("LOCATION_DATA", ram);
|
||||
REGION_ALIAS("LOCATION_STACK", ram);
|
||||
|
||||
INCLUDE sections.ld
|
||||
12
src/ram.lds
12
src/ram.lds
@@ -1,12 +1,12 @@
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
OUTPUT_ARCH(riscv)
|
||||
|
||||
ENTRY( _start )
|
||||
ENTRY(_start)
|
||||
|
||||
INCLUDE memory_map.ld
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", ram);
|
||||
REGION_ALIAS("REGION_RODATA", ram);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("LOCATION_TEXT", ram);
|
||||
REGION_ALIAS("LOCATION_RODATA", ram);
|
||||
REGION_ALIAS("LOCATION_DATA", ram);
|
||||
REGION_ALIAS("LOCATION_STACK", ram);
|
||||
|
||||
INCLUDE sections.ld
|
||||
12
src/ram_dram.lds
Normal file
12
src/ram_dram.lds
Normal file
@@ -0,0 +1,12 @@
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
ENTRY( _start )
|
||||
|
||||
INCLUDE memory_map.ld
|
||||
|
||||
REGION_ALIAS("LOCATION_TEXT", ram);
|
||||
REGION_ALIAS("LOCATION_RODATA", ram);
|
||||
REGION_ALIAS("LOCATION_DATA", dram);
|
||||
REGION_ALIAS("LOCATION_STACK", dram);
|
||||
|
||||
INCLUDE sections.ld
|
||||
@@ -4,9 +4,9 @@ ENTRY( _start )
|
||||
|
||||
INCLUDE memory_map.ld
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("LOCATION_TEXT", rom);
|
||||
REGION_ALIAS("LOCATION_RODATA", rom);
|
||||
REGION_ALIAS("LOCATION_DATA", ram);
|
||||
REGION_ALIAS("LOCATION_STACK", ram);
|
||||
|
||||
INCLUDE sections.ld
|
||||
226
src/sections.ld
226
src/sections.ld
@@ -1,184 +1,108 @@
|
||||
PHDRS
|
||||
{
|
||||
flash PT_LOAD;
|
||||
ram_init PT_LOAD;
|
||||
tls PT_TLS;
|
||||
ram PT_NULL;
|
||||
dram PT_NULL;
|
||||
text PT_LOAD;
|
||||
data PT_LOAD;
|
||||
tls PT_TLS;
|
||||
stack PT_NULL;
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||
__stack_segment_size = DEFINED(__stack_segment_size) ? __stack_segment_size : __stack_size;
|
||||
.init ORIGIN(REGION_TEXT) :
|
||||
|
||||
/* Code/Const in LOCATION_TEXT */
|
||||
. = ORIGIN(LOCATION_TEXT);
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
KEEP (*(.text.init.enter))
|
||||
KEEP (*(.text.init.*))
|
||||
KEEP (*(.text.init))
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
KEEP (*(.text.libgloss.start))
|
||||
} >REGION_TEXT AT>REGION_TEXT :flash
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.unlikely.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
KEEP(*(.text.boot))
|
||||
*(.text .text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} >REGION_TEXT AT>REGION_TEXT :flash
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} >REGION_TEXT AT>REGION_TEXT :flash
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rdata)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
.srodata :
|
||||
{
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.preinit_array :
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
} > LOCATION_TEXT :text
|
||||
|
||||
/* trap/interrupt vectors */
|
||||
.vectors : ALIGN(256)
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
.init_array :
|
||||
KEEP(*(.vectors .vectors.*))
|
||||
} > LOCATION_TEXT
|
||||
|
||||
/* C++ ctors/dtors */
|
||||
.init_array : ALIGN(4)
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
} > LOCATION_TEXT :text
|
||||
|
||||
.fini_array :
|
||||
.fini_array : ALIGN(4)
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
} > LOCATION_TEXT :text
|
||||
|
||||
.ctors :
|
||||
/* .data in LOCATION_DATA, Load-Image in LOCATION_TEXT, PHDR is data */
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
/* 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. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
.lalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _data_lma = . );
|
||||
} >REGION_RODATA AT>REGION_RODATA :flash
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
__DATA_BEGIN__ = .;
|
||||
__data_start = .;
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__SDATA_BEGIN__ = .;
|
||||
*(.sdata .sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
} >REGION_DATA AT>REGION_RODATA :ram_init
|
||||
__data_end = .;
|
||||
} > LOCATION_DATA AT> LOCATION_TEXT :data
|
||||
__data_source = LOADADDR(.data);
|
||||
|
||||
.tdata : ALIGN(8) {
|
||||
PROVIDE( __tls_base = . );
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
} >REGION_DATA AT>REGION_RODATA :tls :ram_init
|
||||
|
||||
PROVIDE( __data_source = LOADADDR(.data) );
|
||||
PROVIDE( __data_start = ADDR(.data) );
|
||||
PROVIDE( __data_end = ADDR(.tdata) + SIZEOF(.tdata) );
|
||||
|
||||
PROVIDE( __tdata_source = LOADADDR(.tdata) );
|
||||
PROVIDE( __tdata_size = SIZEOF(.tdata) );
|
||||
|
||||
.tbss : ALIGN(8) {
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
PROVIDE( __tls_end = . );
|
||||
} >REGION_DATA AT>REGION_DATA :tls :ram
|
||||
|
||||
PROVIDE( __tbss_size = SIZEOF(.tbss) );
|
||||
PROVIDE( __tls_size = __tls_end - __tls_base );
|
||||
|
||||
.tbss_space : ALIGN(8) {
|
||||
. = . + __tbss_size;
|
||||
} >REGION_DATA :ram
|
||||
|
||||
.bss :
|
||||
/* TLS: in LOCATION_DATA, initial values are in LOCATION_TEXT, PHDR is tls */
|
||||
.tls : ALIGN(16)
|
||||
{
|
||||
__BSS_BEGIN__ = .;
|
||||
*(.sbss*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
/* TLS init data (.tdata) */
|
||||
__tls_base = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
__tdata_size = __tdata_end - __tls_base;
|
||||
|
||||
/* TLS bss (.tbss) */
|
||||
__tbss_start = .;
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
__tbss_size = __tbss_end - __tbss_start;
|
||||
|
||||
__tls_size = __tbss_end - __tls_base;
|
||||
} > LOCATION_DATA AT> LOCATION_TEXT :tls
|
||||
__tdata_source = LOADADDR(.tls);
|
||||
|
||||
/* normales BSS (inkl. sbss), PHDR is data */
|
||||
.bss (NOLOAD) : ALIGN(16)
|
||||
{
|
||||
__bss_start = .;
|
||||
*(.sbss .sbss.*)
|
||||
*(.bss .bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__BSS_END__ = .;
|
||||
__bss_end = .;
|
||||
} > LOCATION_DATA :data
|
||||
|
||||
} >REGION_BSS AT>REGION_BSS :ram
|
||||
__global_pointer$ = .;
|
||||
|
||||
/* Heap/Stack Grenzen */
|
||||
. = ALIGN(16);
|
||||
__heap_start = .;
|
||||
|
||||
PROVIDE( __bss_start = ADDR(.tbss) );
|
||||
PROVIDE( __bss_end = ADDR(.bss) + SIZEOF(.bss) );
|
||||
|
||||
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
|
||||
PROVIDE( _end = . );
|
||||
PROVIDE( end = . );
|
||||
|
||||
.stack ORIGIN(ram) + LENGTH(ram) - __stack_segment_size :
|
||||
/* __stack_top = ORIGIN(LOCATION_BSS) + LENGTH(LOCATION_BSS); */
|
||||
/* PROVIDE(_sp = __stack_top); */
|
||||
/* stack segement, PHDR is stack */
|
||||
.stack ORIGIN(LOCATION_STACK) + LENGTH(LOCATION_STACK) - __stack_segment_size :
|
||||
{
|
||||
PROVIDE( _heap_end = . );
|
||||
. = __stack_segment_size;
|
||||
PROVIDE( _sp = . );
|
||||
} >REGION_BSS AT>REGION_BSS :ram
|
||||
} >LOCATION_STACK AT>LOCATION_STACK :stack
|
||||
|
||||
|
||||
|
||||
PROVIDE( tohost = . );
|
||||
PROVIDE( fromhost = . + 8 );
|
||||
|
||||
/DISCARD/ : { *(.eh_frame*) *(.comment) *(.note .note.*) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user