Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix linker file for RISCV-64 targets #236

Merged
merged 2 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions riscv-rt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

- `link.x.in`: remove references to `eh_frame`.
- Rename start/end section symbols to align with `cortex-m-rt`:
- `_stext`: it remains, as linker files can modify it.
- `__stext`: it coincides with `_stext`.
- `__etext`: new symbol. It points to the end of the text section.
- `__srodata`: new symbol. It points to the start of the read-only data section.
- `__erodata`: new symbol. It points to the end of the read-only data section.
- `__sdata`: substitutes `_sdata`. It points to the start of the on-flash data section.
- `__edata`: substitutes `_edata`. It points to the end of the on-flash data section.
- `__idata`: substitutes `_idata`. It points to the start of the on-RAM data section.
- `__sbss`: substitutes `_sbss`. It points to the start of the BSS section.
- `__ebss`: substitutes `_ebss`. It points to the end of the BSS section.
- `__sheap`: substitutes `_sheap`. It points to the start of the heap section.
- `__eheap`: substitutes `_eheap`. It points to the end of the heap section.
- `__estack`: substitutes `_estack`. It points to the end of the stack section.
- `__sstack`: substitutes `_sstack`. It points to the start of the stack section.
- `__edata` and `__ebss` are now defined outside of their respective sections.
In this way, users can inject custom sections and benefit from the copying and
zeroing routines, respectively.
- As `__sheap` is now private, `riscv-rt` now provides a `heap_start` function to
allow users get the initial address of the heap when initializing an allocator.
- Update documentation.
- Removed `.init.rust` section, as it is no longer required.

## [v0.13.0] - 2024-10-19

### Added
Expand Down
2 changes: 1 addition & 1 deletion riscv-rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ riscv-pac = { path = "../riscv-pac", version = "0.2.0" }
riscv-rt-macros = { path = "macros", version = "0.2.2" }

[dev-dependencies]
panic-halt = "0.2.0"
panic-halt = "1.0.0"

[features]
s-mode = ["riscv-rt-macros/s-mode"]
Expand Down
75 changes: 46 additions & 29 deletions riscv-rt/link.x.in
Original file line number Diff line number Diff line change
Expand Up @@ -100,65 +100,88 @@ SECTIONS

.text _stext :
{
__stext = .;

/* Put reset handler first in .text section so it ends up as the entry */
/* point of the program. */
KEEP(*(.init));
KEEP(*(.init.rust));
. = ALIGN(4);
KEEP(*(.init.trap));
. = ALIGN(4);
*(.trap);
*(.trap.rust);
*(.text.abort);
*(.text .text.*);

. = ALIGN(4);
__etext = .;
} > REGION_TEXT

.rodata : ALIGN(4)
{
. = ALIGN(4);
__srodata = .;

*(.srodata .srodata.*);
*(.rodata .rodata.*);

/* 4-byte align the end (VMA) of this section.
/* ${ARCH_WIDTH}-byte align the end (VMA) of this section.
This is required by LLD to ensure the LMA of the following .data
section will have the correct alignment. */
. = ALIGN(4);
. = ALIGN(${ARCH_WIDTH});
__erodata = .;
} > REGION_RODATA

.data : ALIGN(${ARCH_WIDTH})
{
_sidata = LOADADDR(.data);
_sdata = .;
. = ALIGN(${ARCH_WIDTH});
__sdata = .;

/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = . + 0x800);
*(.sdata .sdata.* .sdata2 .sdata2.*);
*(.data .data.*);
. = ALIGN(${ARCH_WIDTH});
_edata = .;

} > REGION_DATA AT > REGION_RODATA

/* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to
* use the .data loading mechanism by pushing __edata. Note: do not change
* output region or load region in those user sections! */
. = ALIGN(${ARCH_WIDTH});
__edata = .;

/* LMA of .data */
__sidata = LOADADDR(.data);

.bss (NOLOAD) : ALIGN(${ARCH_WIDTH})
{
_sbss = .;
*(.sbss .sbss.* .bss .bss.*);
. = ALIGN(${ARCH_WIDTH});
_ebss = .;
__sbss = .;

*(.sbss .sbss.* .bss .bss.*);
} > REGION_BSS

/* Allow sections from user `memory.x` injected using `INSERT AFTER .bss` to
* use the .bss zeroing mechanism by pushing __ebss. Note: do not change
* output region or load region in those user sections! */
. = ALIGN(${ARCH_WIDTH});
__ebss = .;

/* fictitious region that represents the memory available for the heap */
.heap (NOLOAD) :
{
_sheap = .;
__sheap = .;
. += _heap_size;
. = ALIGN(4);
_eheap = .;
__eheap = .;
} > REGION_HEAP

/* fictitious region that represents the memory available for the stack */
.stack (NOLOAD) :
{
_estack = .;
__estack = .;
. = ABSOLUTE(_stack_start);
_sstack = .;
__sstack = .;
} > REGION_STACK

/* fake output .got section */
Expand All @@ -169,9 +192,6 @@ SECTIONS
{
KEEP(*(.got .got.*));
}

.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
}

/* Do not exceed this mark in the error messages above | */
Expand All @@ -187,25 +207,22 @@ ERROR(riscv-rt): the start of the REGION_DATA must be ${ARCH_WIDTH}-byte aligned
ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");

ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");

ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");

ASSERT(_stext % 4 == 0, "
ERROR(riscv-rt): `_stext` must be 4-byte aligned");

ASSERT(_sdata % ${ARCH_WIDTH} == 0 && _edata % ${ARCH_WIDTH} == 0, "
ASSERT(__sdata % ${ARCH_WIDTH} == 0 && __edata % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): .data is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sidata % ${ARCH_WIDTH} == 0, "
ASSERT(__sidata % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): the LMA of .data is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sbss % ${ARCH_WIDTH} == 0 && _ebss % ${ARCH_WIDTH} == 0, "
ASSERT(__sbss % ${ARCH_WIDTH} == 0 && __ebss % ${ARCH_WIDTH} == 0, "
BUG(riscv-rt): .bss is not ${ARCH_WIDTH}-byte aligned");

ASSERT(_sheap % 4 == 0, "
ASSERT(__sheap % 4 == 0, "
BUG(riscv-rt): start of .heap is not 4-byte aligned");

ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
Expand All @@ -216,11 +233,11 @@ ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
Consider changing `_max_hart_id` or `_hart_stack_size`.");

/* # Other checks */
ASSERT(SIZEOF(.got) == 0, "
.got section detected in the input files. Dynamic relocations are not
supported. If you are linking to C code compiled using the `gcc` crate
then modify your build script to compile the C code _without_ the
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
details.");
ERROR(riscv-rt): .got section detected in the input files. Dynamic relocations are not
supported. If you are linking to C code compiled using the `cc` crate then modify your
build script to compile the C code _without_ the -fPIC flag. See the documentation of
the `cc::Build.pic` method for details.");
Comment on lines +238 to +241
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to support PIC relocation in the future? If it is, this is something I would be interested in working on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an interesting research line. Especially for RISC-V 64 targets which currently face issues with static linking (see #153). However, it would need specific code to deal with dynamic linking etc.


/* Do not exceed this mark in the error messages above | */
10 changes: 5 additions & 5 deletions riscv-rt/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ cfg_global_asm!(
cfg_global_asm!(
"call __pre_init
// Copy .data from flash to RAM
la t0, _sdata
la t2, _edata
la t1, _sidata
la t0, __sdata
la t2, __edata
la t1, __sidata
bgeu t0, t2, 2f
1: ",
#[cfg(target_arch = "riscv32")]
Expand All @@ -171,8 +171,8 @@ cfg_global_asm!(
bltu t0, t2, 1b",
"
2: // Zero out .bss
la t0, _sbss
la t2, _ebss
la t0, __sbss
la t2, __ebss
bgeu t0, t2, 4f
3: ",
#[cfg(target_arch = "riscv32")]
Expand Down
Loading
Loading