Skip to content

Commit f69f84a

Browse files
committed
_pre_init_trap defaults to _default_abort
1 parent 23be2d1 commit f69f84a

File tree

6 files changed

+55
-23
lines changed

6 files changed

+55
-23
lines changed

riscv-rt/CHANGELOG.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2424
`no-exceptions` and `no-interrupts` features are disabled, respectively.
2525
This is achieved by substituting `${INCLUDE_LINKER_FILES}` with the contents
2626
of `exceptions.x` and/or `interrupts.x`.
27+
- Add global `_default_abort` symbol, `PROVIDE(abort = _default_abort)` to avoid
28+
using weak symbols ([#247](https://github.com/rust-embedded/riscv/issues/247))
29+
- Replace weak definitions of `DefaultHandler` and `ExceptionHandler`
30+
with `PROVIDE(... = abort)`.
31+
- Replace weak definition of `_pre_init_trap` with `PROVIDE(_pre_init_trap = _default_abort)`.
32+
- Now, `_default_abort` is 4-byte aligned (required by `_pre_init_trap`)
33+
- Removed `.init.trap` section, as it is no longer required.
2734

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

@@ -62,8 +69,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6269
allow users get the initial address of the heap when initializing an allocator.
6370
- Update documentation.
6471
- Removed `.init.rust` section, as it is no longer required.
65-
- Add global `_abort` symbol, `PROVIDE(abort = _abort)`, and replace `DefaultHandler` and
66-
`ExceptionHandler` with `PROVIDE(... = abort)`.
6772

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

riscv-rt/link.x.in

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
2323
*/
2424

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

29+
/* Trap for exceptions triggered during initialization. If the execution reaches this point, it
30+
means that there is a bug in the boot code. If no _pre_init_trap symbol is provided, then
31+
_pre_init_trap defaults to _default_abort. Note that _pre_init_trap must be 4-byte aligned */
32+
PROVIDE(_pre_init_trap = _default_abort);
33+
2934
/* Default trap entry point. The riscv-rt crate provides a weak alias of this function,
3035
which saves caller saved registers, calls _start_trap_rust, restores caller saved registers
3136
and then returns. Users can override this alias by defining the symbol themselves */
@@ -70,11 +75,9 @@ SECTIONS
7075
/* point of the program. */
7176
KEEP(*(.init));
7277
. = ALIGN(4);
73-
KEEP(*(.init.trap));
74-
. = ALIGN(4);
7578
*(.trap);
7679
*(.trap.rust);
77-
*(.text.abort);
80+
*(.text.abort); /* close to .init section to support j abort */
7881
*(.text .text.*);
7982

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

195+
ASSERT(_pre_init_trap % 4 == 0, "
196+
BUG(riscv-rt): _pre_init_trap is not 4-byte aligned");
197+
192198
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
193199
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
194200
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");

riscv-rt/src/asm.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,6 @@ _setup_interrupts:",
251251
#[cfg(not(feature = "s-mode"))]
252252
"csrw mtvec, t0",
253253
"ret",
254-
// Default implementation of `_pre_init_trap` is an infinite loop.
255-
// Users can override this function by defining their own `_pre_init_trap`
256-
// If the execution reaches this point, it means that there is a bug in the boot code.
257-
".section .init.trap, \"ax\"
258-
.weak _pre_init_trap
259-
_pre_init_trap:
260-
j _pre_init_trap",
261254
);
262255

263256
riscv_rt_macros::weak_start_trap!();
@@ -268,6 +261,7 @@ riscv_rt_macros::vectored_interrupt_trap!();
268261
#[rustfmt::skip]
269262
global_asm!(
270263
".section .text.abort
264+
.align 4
271265
.global _default_abort
272266
_default_abort: // make sure there is an abort symbol when linking
273267
j _default_abort"

riscv-rt/src/lib.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,31 @@
289289
//! These functions are weakly defined in the `riscv-rt` crate, but they can be redefined
290290
//! in the user code. Next, we will describe these symbols and how to redefine them.
291291
//!
292+
//! ## `abort`
293+
//!
294+
//! This function is called when an unrecoverable error occurs. For example, if the
295+
//! current hart id is greater than `_max_hart_id`, the `abort` function is called.
296+
//! This function is also called when an exception or an interrupt occurs and there is no
297+
//! handler for it.
298+
//!
299+
//! If this function is not defined, the linker will use the `_default_abort` function
300+
//! defined in the `riscv-rt` crate. This function is a busy-loop that will never return.
301+
//!
302+
//! ### Note
303+
//!
304+
//! Recall that the `abort` function is called when an unrecoverable error occurs.
305+
//! This function should not be used to handle recoverable errors. Additionally, it may
306+
//! be triggered before the `.bss` and `.data` sections are initialized, so it is not safe
307+
//! to use any global variable in this function.
308+
//!
292309
//! ## `_pre_init_trap`
293310
//!
294311
//! This function is set as a provisional trap handler for the early trap handling.
295312
//! If either an exception or an interrupt occurs during the boot process, this
296-
//! function is triggered. The default implementation of this function is a busy-loop.
313+
//! function is triggered.
314+
//!
315+
//! If this function is not defined, the linker will use the `_default_abort` function
316+
//! defined in the `riscv-rt` crate. This function is a busy-loop that will never return.
297317
//!
298318
//! ### Note
299319
//!
@@ -302,6 +322,9 @@
302322
//! Recall that this trap is triggered before the `.bss` and `.data` sections are
303323
//! initialized, so it is not safe to use any global variables in this function.
304324
//!
325+
//! Furthermore, as this function is expected to behave like a trap handler, it is
326+
//! necessary to make it be 4-byte aligned.
327+
//!
305328
//! ## `_mp_hook`
306329
//!
307330
//! This function is called from all the harts and must return true only for one hart,
@@ -362,11 +385,10 @@
362385
//!
363386
//! If exception handler is not explicitly defined, `ExceptionHandler` is called.
364387
//!
365-
//! ### `ExceptionHandler`
388+
//! ## `ExceptionHandler`
366389
//!
367390
//! This function is called when exception without defined exception handler is occured.
368-
//! The exception reason can be decoded from the
369-
//! `mcause`/`scause` register.
391+
//! The exception reason can be decoded from the `mcause`/`scause` register.
370392
//!
371393
//! This function can be redefined in the following way:
372394
//!
@@ -384,7 +406,7 @@
384406
//! }
385407
//! ```
386408
//!
387-
//! Default implementation of this function stucks in a busy-loop.
409+
//! If `ExceptionHandler` is not defined, the linker will use the `abort` function instead.
388410
//!
389411
//! ## Core interrupt handlers
390412
//!
@@ -427,7 +449,7 @@
427449
//!
428450
//! If interrupt handler is not explicitly defined, `DefaultHandler` is called.
429451
//!
430-
//! ### `DefaultHandler`
452+
//! ## `DefaultHandler`
431453
//!
432454
//! This function is called when interrupt without defined interrupt handler is occured.
433455
//! The interrupt reason can be decoded from the `mcause`/`scause` register.
@@ -450,7 +472,7 @@
450472
//! }
451473
//! ```
452474
//!
453-
//! Default implementation of this function stucks in a busy-loop.
475+
//! If `DefaultHandler` is not defined, the linker will use the `abort` function instead.
454476
//!
455477
//! # Cargo Features
456478
//!

riscv-target-parser/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
### Fixed
9+
10+
- Fix links to URLs in docs
11+
812
## [v0.1.1] - 2025-03-18
13+
914
### Fixed
1015

1116
- Fix parsing of extensions starting with 's'/'x'/'z' from target features

riscv-target-parser/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ impl RiscvTarget {
189189
///
190190
/// # Related issues
191191
///
192-
/// - https://github.com/rust-embedded/riscv/issues/175
193-
/// - https://github.com/rust-lang/rust/issues/80608
194-
/// - https://github.com/llvm/llvm-project/issues/61991
192+
/// - <https://github.com/rust-embedded/riscv/issues/175>
193+
/// - <https://github.com/rust-lang/rust/issues/80608>
194+
/// - <https://github.com/llvm/llvm-project/issues/61991>
195195
pub fn llvm_arch_patch(&self) -> String {
196196
let mut patch = self.llvm_base_isa();
197197
if self.extensions.contains(&Extension::M) {

0 commit comments

Comments
 (0)