llext: Fix off-by-one in RISC-V truncation check
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 <eric.ackermann@cispa.de>
This commit is contained in:
parent
5faf471ce0
commit
2d3390f866
1 changed files with 7 additions and 0 deletions
|
@ -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,
|
static inline int riscv_relocation_fits(long long jump_target, long long max_distance,
|
||||||
elf_word reloc_type)
|
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) {
|
if (llabs(jump_target) > max_distance) {
|
||||||
LOG_ERR("%lld byte relocation is not possible for type %" PRIu64 " (max %lld)!",
|
LOG_ERR("%lld byte relocation is not possible for type %" PRIu64 " (max %lld)!",
|
||||||
jump_target, (uint64_t)reloc_type, max_distance);
|
jump_target, (uint64_t)reloc_type, max_distance);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue