Skip to content

_pre_init_trap defaults to _default_abort #278

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

Merged
merged 1 commit into from
Apr 23, 2025
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
9 changes: 7 additions & 2 deletions riscv-rt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
`no-exceptions` and `no-interrupts` features are disabled, respectively.
This is achieved by substituting `${INCLUDE_LINKER_FILES}` with the contents
of `exceptions.x` and/or `interrupts.x`.
- Add global `_default_abort` symbol, `PROVIDE(abort = _default_abort)` to avoid
using weak symbols ([#247](https://github.com/rust-embedded/riscv/issues/247))
- Replace weak definitions of `DefaultHandler` and `ExceptionHandler`
with `PROVIDE(... = abort)`.
- Replace weak definition of `_pre_init_trap` with `PROVIDE(_pre_init_trap = _default_abort)`.
- Now, `_default_abort` is 4-byte aligned (required by `_pre_init_trap`)
- Removed `.init.trap` section, as it is no longer required.

## [v0.14.0] - 2025-02-18

Expand Down Expand Up @@ -62,8 +69,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
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.
- Add global `_abort` symbol, `PROVIDE(abort = _abort)`, and replace `DefaultHandler` and
`ExceptionHandler` with `PROVIDE(... = abort)`.

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

Expand Down
14 changes: 10 additions & 4 deletions riscv-rt/link.x.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
*/

/* Default abort entry point. If no abort symbol is provided, then abort maps to _abort. */
/* Default abort entry point. If no abort symbol is provided, then abort maps to _default_abort. */
EXTERN(_default_abort);
PROVIDE(abort = _default_abort);

/* Trap for exceptions triggered during initialization. If the execution reaches this point, it
means that there is a bug in the boot code. If no _pre_init_trap symbol is provided, then
_pre_init_trap defaults to _default_abort. Note that _pre_init_trap must be 4-byte aligned */
PROVIDE(_pre_init_trap = _default_abort);

/* Default trap entry point. The riscv-rt crate provides a weak alias of this function,
which saves caller saved registers, calls _start_trap_rust, restores caller saved registers
and then returns. Users can override this alias by defining the symbol themselves */
Expand Down Expand Up @@ -70,11 +75,9 @@ SECTIONS
/* point of the program. */
KEEP(*(.init));
. = ALIGN(4);
KEEP(*(.init.trap));
. = ALIGN(4);
*(.trap);
*(.trap.rust);
*(.text.abort);
*(.text.abort); /* close to .init section to support j abort */
*(.text .text.*);

. = ALIGN(4);
Expand Down Expand Up @@ -189,6 +192,9 @@ BUG(riscv-rt): .bss is not ${ARCH_WIDTH}-byte aligned");
ASSERT(__sheap % 4 == 0, "
BUG(riscv-rt): start of .heap is not 4-byte aligned");

ASSERT(_pre_init_trap % 4 == 0, "
BUG(riscv-rt): _pre_init_trap is not 4-byte aligned");

ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
Expand Down
8 changes: 1 addition & 7 deletions riscv-rt/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,6 @@ _setup_interrupts:",
#[cfg(not(feature = "s-mode"))]
"csrw mtvec, t0",
"ret",
// Default implementation of `_pre_init_trap` is an infinite loop.
// Users can override this function by defining their own `_pre_init_trap`
// If the execution reaches this point, it means that there is a bug in the boot code.
".section .init.trap, \"ax\"
.weak _pre_init_trap
_pre_init_trap:
j _pre_init_trap",
);

riscv_rt_macros::weak_start_trap!();
Expand All @@ -268,6 +261,7 @@ riscv_rt_macros::vectored_interrupt_trap!();
#[rustfmt::skip]
global_asm!(
".section .text.abort
.align 4
.global _default_abort
_default_abort: // make sure there is an abort symbol when linking
j _default_abort"
Expand Down
36 changes: 29 additions & 7 deletions riscv-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,31 @@
//! These functions are weakly defined in the `riscv-rt` crate, but they can be redefined
//! in the user code. Next, we will describe these symbols and how to redefine them.
//!
//! ## `abort`
//!
//! This function is called when an unrecoverable error occurs. For example, if the
//! current hart id is greater than `_max_hart_id`, the `abort` function is called.
//! This function is also called when an exception or an interrupt occurs and there is no
//! handler for it.
//!
//! If this function is not defined, the linker will use the `_default_abort` function
//! defined in the `riscv-rt` crate. This function is a busy-loop that will never return.
//!
//! ### Note
//!
//! Recall that the `abort` function is called when an unrecoverable error occurs.
//! This function should not be used to handle recoverable errors. Additionally, it may
//! be triggered before the `.bss` and `.data` sections are initialized, so it is not safe
//! to use any global variable in this function.
//!
//! ## `_pre_init_trap`
//!
//! This function is set as a provisional trap handler for the early trap handling.
//! If either an exception or an interrupt occurs during the boot process, this
//! function is triggered. The default implementation of this function is a busy-loop.
//! function is triggered.
//!
//! If this function is not defined, the linker will use the `_default_abort` function
//! defined in the `riscv-rt` crate. This function is a busy-loop that will never return.
//!
//! ### Note
//!
Expand All @@ -302,6 +322,9 @@
//! Recall that this trap is triggered before the `.bss` and `.data` sections are
//! initialized, so it is not safe to use any global variables in this function.
//!
//! Furthermore, as this function is expected to behave like a trap handler, it is
//! necessary to make it be 4-byte aligned.
//!
//! ## `_mp_hook`
//!
//! This function is called from all the harts and must return true only for one hart,
Expand Down Expand Up @@ -362,11 +385,10 @@
//!
//! If exception handler is not explicitly defined, `ExceptionHandler` is called.
//!
//! ### `ExceptionHandler`
//! ## `ExceptionHandler`
//!
//! This function is called when exception without defined exception handler is occured.
//! The exception reason can be decoded from the
//! `mcause`/`scause` register.
//! The exception reason can be decoded from the `mcause`/`scause` register.
//!
//! This function can be redefined in the following way:
//!
Expand All @@ -384,7 +406,7 @@
//! }
//! ```
//!
//! Default implementation of this function stucks in a busy-loop.
//! If `ExceptionHandler` is not defined, the linker will use the `abort` function instead.
//!
//! ## Core interrupt handlers
//!
Expand Down Expand Up @@ -427,7 +449,7 @@
//!
//! If interrupt handler is not explicitly defined, `DefaultHandler` is called.
//!
//! ### `DefaultHandler`
//! ## `DefaultHandler`
//!
//! This function is called when interrupt without defined interrupt handler is occured.
//! The interrupt reason can be decoded from the `mcause`/`scause` register.
Expand All @@ -450,7 +472,7 @@
//! }
//! ```
//!
//! Default implementation of this function stucks in a busy-loop.
//! If `DefaultHandler` is not defined, the linker will use the `abort` function instead.
//!
//! # Cargo Features
//!
Expand Down
5 changes: 5 additions & 0 deletions riscv-target-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed

- Fix links to URLs in docs

## [v0.1.1] - 2025-03-18

### Fixed

- Fix parsing of extensions starting with 's'/'x'/'z' from target features
Expand Down
6 changes: 3 additions & 3 deletions riscv-target-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ impl RiscvTarget {
///
/// # Related issues
///
/// - https://github.com/rust-embedded/riscv/issues/175
/// - https://github.com/rust-lang/rust/issues/80608
/// - https://github.com/llvm/llvm-project/issues/61991
/// - <https://github.com/rust-embedded/riscv/issues/175>
/// - <https://github.com/rust-lang/rust/issues/80608>
/// - <https://github.com/llvm/llvm-project/issues/61991>
pub fn llvm_arch_patch(&self) -> String {
let mut patch = self.llvm_base_isa();
if self.extensions.contains(&Extension::M) {
Expand Down