-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: llext: Add RISC-V CB-Type edge case test
All immediates in RISC-V are encoded as two's complement. This commit adds a test for relocating jumps that utilize the full range of the immediate, in both positive and negative direction. To this end, the test uses the compressed b-type (CB) instruction to branch to its maximum negative (-256) and maximum positive (+254) targets. In case of test failure, expect relocating the corresponding llext to fail. Signed-off-by: Eric Ackermann <eric.ackermann@cispa.de>
- Loading branch information
1 parent
7e1f7fa
commit 9381ec2
Showing
4 changed files
with
117 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (c) 2024 CISPA Helmholtz Center for Information Security | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/* | ||
* This extension tests a relocation edge case in RISC-V: | ||
* Immediates in branch/jump-type instructions are signed-extended. | ||
* Thus, a jump with a negative offset can have a greater jump target than | ||
* a jump with a positive offset. | ||
* A compressed branch (cb-type) instruction is used to trigger the edge case. | ||
* It has a 9-bit immediate (with an implicit LSB of 0), allowing it to jump | ||
* 256 bytes backward and 254 bytes forward. | ||
*/ | ||
|
||
#include <stdbool.h> | ||
#include <zephyr/llext/symbol.h> | ||
#include <zephyr/ztest_assert.h> | ||
|
||
extern int _riscv_edge_case_cb_trigger_forward(void); | ||
extern int _riscv_edge_case_cb_trigger_backward(void); | ||
|
||
void test_entry(void) | ||
{ | ||
int test_ok; | ||
|
||
test_ok = _riscv_edge_case_cb_trigger_forward(); | ||
zassert_equal(test_ok, 0x1); | ||
|
||
test_ok = _riscv_edge_case_cb_trigger_backward(); | ||
zassert_equal(test_ok, 0x1); | ||
} | ||
EXPORT_SYMBOL(test_entry); |
64 changes: 64 additions & 0 deletions
64
tests/subsys/llext/simple/src/riscv_edge_case_cb_type_trigger.S
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright (c) 2024 CISPA Helmholtz Center for Information Security | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/toolchain.h> | ||
|
||
GTEXT(_riscv_edge_case_cb_trigger_backward) | ||
|
||
/* | ||
* Tests that jumping 256 bytes (the maximum) backwards | ||
* using CB-type instruction is feasible | ||
*/ | ||
SECTION_FUNC(TEXT, _riscv_edge_case_cb_trigger_backward) | ||
/* | ||
* tentative fail | ||
* this needs precise alignment - need explicit compressed instructions | ||
*/ | ||
addi a0, zero, 0 | ||
c.j _do_jump | ||
|
||
_backward_jump_target: | ||
/* we made it to the correct target - success, return true */ | ||
c.addi a0, 0x1 | ||
/* explicit ret */ | ||
ret | ||
|
||
|
||
/* | ||
* 2+4 bytes for _backward_jump_target itself | ||
* need to insert 122 padding bytes | ||
*/ | ||
.fill 126, 2, 0x2 | ||
|
||
_do_jump: | ||
/* jump precisely 256 bytes, the maximum distance, backwards */ | ||
c.beqz a0, _backward_jump_target | ||
/* should not be reached - causes return false */ | ||
ret | ||
|
||
GTEXT(_riscv_edge_case_cb_trigger_forward) | ||
|
||
/* | ||
* Tests that jumping 256 bytes (the maximum) forwards | ||
* using CB-type instruction is feasible | ||
*/ | ||
SECTION_FUNC(TEXT, _riscv_edge_case_cb_trigger_forward) | ||
/* | ||
* tentative fail | ||
* this needs precise alignment - need explicit compressed instructions | ||
*/ | ||
addi a0, zero, 0 | ||
/* jump precisely 254 bytes, the maximum distance, forwards */ | ||
c.beqz a0, _forward_jump_target | ||
|
||
/* need to insert 252 padding bytes to pad to 254 byte jump */ | ||
.fill 126, 2, 0x0 | ||
|
||
_forward_jump_target: | ||
/* we made it to the correct target - success, return true */ | ||
li a0, 1 | ||
/* should not be reached - causes return false */ | ||
ret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters