Skip to content

Commit

Permalink
llext: Fix off-by-one in RISC-V truncation check
Browse files Browse the repository at this point in the history
The RISC-V architecture-specific relocations need to check whether
each required relocation can fit into the modified instruction's
immediate. All immediates in RISC-V are encoded as two's complement.
The current truncation check has an off-by-one error for checking
the maximum negative distance, as two's complement encoding can
represent a negative value that is the maximum positive value plus
one, causing LLEXT to refuse loading valid code.
This commit adds an additional condition to the check that fixes
the aforementioned issue.

Signed-off-by: Eric Ackermann <[email protected]>
  • Loading branch information
WorldofJARcraft committed Jan 6, 2025
1 parent 1a578eb commit aaa256a
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions arch/riscv/core/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL);
static inline int riscv_relocation_fits(long long jump_target, long long max_distance,
elf_word reloc_type)
{
/*
* two's complement encoding
* e.g., [-128=0b10000000, 127=0b01111111] encodable with 8 bits
*/
if (jump_target < 0) {
max_distance++;
}
if (llabs(jump_target) > max_distance) {
LOG_ERR("%lld byte relocation is not possible for type %" PRIu64 " (max %lld)!",
jump_target, (uint64_t)reloc_type, max_distance);
Expand Down

0 comments on commit aaa256a

Please sign in to comment.