Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
50 changes: 50 additions & 0 deletions apps/starry/llama-cpp/riscv64-static-pie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# riscv64 static-pie segfault

## Reproduction

- Minimal C program (printf only)
- Built with `riscv64-linux-musl-gcc -static-pie`
- ELF Type: DYN (Position-Independent Executable)
- QEMU on StarryOS riscv64
- Result: segfault, RC=139

```c
#include <stdio.h>
int main(void) {
printf("static-pie test OK\n");
return 0;
}
```

## Crash

```
pc(sepc)=0x00000000000003b0
Segmentation fault (core dumped)
```

## Root cause

PC=0x3b0 is the start of `.plt` section, NOT `.text` (0x3f0).

The binary has unresolved PLT relocations (from `readelf -r`):

- `.rela.plt`: `R_RISCV_JUMP_SLOT` for `puts` and `__libc_start_main`
- `.rela.dyn`: `R_RISCV_RELATIVE` entries for data pointers

The StarryOS ELF loader (`os/StarryOS/kernel/src/mm/loader.rs`) maps segments
and jumps to entry, but does NOT process `.rela.dyn` or `.rela.plt` relocations.
The unresolved PLT entries cause a jump to 0x3b0 (PLT stub) which segfaults.

aarch64/x86_64 static-pie works because their musl CRT handles relocations
differently, or their PLT stubs happen to work without relocation processing.

## Conclusion

Not a llama.cpp issue. The ELF loader needs relocation processing for
static-PIE (Type=DYN) binaries. The fix requires:
1. Parsing `.rela.dyn` and `.rela.plt` sections
2. Applying R_RISCV_RELATIVE and R_RISCV_JUMP_SLOT relocations
3. Then jumping to the entry point

This is a kernel loader enhancement, tracked separately.
13 changes: 13 additions & 0 deletions apps/starry/static-pie-test/build-riscv64gc-unknown-none-elf.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
env = {AX_IP = "10.0.2.15", AX_GW = "10.0.2.2"}
features = [
"ax-hal/riscv64-qemu-virt",
"qemu",
"ax-driver/virtio-blk",
"ax-driver/virtio-net",
"ax-driver/virtio-gpu",
"ax-driver/virtio-input",
"ax-driver/virtio-socket",
]
log = "Warn"
plat_dyn = false
target = "riscv64gc-unknown-none-elf"
34 changes: 34 additions & 0 deletions apps/starry/static-pie-test/prebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -euo pipefail

app_dir="${STARRY_APP_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
overlay_dir="${STARRY_OVERLAY_DIR:-}"

if [[ -z "$overlay_dir" ]]; then
echo "error: STARRY_OVERLAY_DIR is required" >&2
exit 1
fi

install -Dm0755 "$app_dir/static-pie-test.sh" "$overlay_dir/usr/bin/static-pie-test.sh"

# Compile and copy static-pie test binary
TOOLCHAIN="/root/project/toolchains/riscv64-linux-musl-cross/bin/riscv64-linux-musl-gcc"
TEST_SRC="/tmp/opencode/static-pie-test.c"
TEST_BIN="/tmp/opencode/static-pie-test"

mkdir -p /tmp/opencode
cat > "$TEST_SRC" << "CEOF"
#include <stdio.h>
int main(void) {
printf("static-pie test OK\n");
return 0;
}
CEOF

if [[ -f "$TOOLCHAIN" ]]; then
"$TOOLCHAIN" -static -o "$TEST_BIN" "$TEST_SRC"
install -Dm0755 "$TEST_BIN" "$overlay_dir/usr/bin/static-pie-test"
echo "Static-pie binary compiled and installed to /usr/bin/static-pie-test"
else
echo "Warning: riscv64 toolchain not found, skipping binary"
Comment thread
SongShiQ marked this conversation as resolved.
Outdated
Comment thread
SongShiQ marked this conversation as resolved.
Outdated
fi
22 changes: 22 additions & 0 deletions apps/starry/static-pie-test/qemu-riscv64.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
args = [
"-nographic",
"-m",
"512M",
"-cpu",
"rv64",
"-device",
"virtio-blk-pci,drive=disk0",
"-drive",
"id=disk0,if=none,format=raw,file=${workspace}/tmp/axbuild/rootfs/rootfs-riscv64-static-pie-test.img",
"-device",
"virtio-net-pci,netdev=net0",
"-netdev",
"user,id=net0",
]
uefi = false
to_bin = true
shell_prefix = "root@starry:"
shell_init_cmd = "/usr/bin/static-pie-test.sh"
success_regex = ["(?m)^STATIC_PIE_TEST_PASSED"]
fail_regex = ["(?i)panic", "(?i)segmentation fault", "(?i)SIGSEGV"]
timeout = 30
10 changes: 10 additions & 0 deletions apps/starry/static-pie-test/static-pie-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
echo "BEFORE_BINARY"
/usr/bin/static-pie-test
RC=$?
echo "AFTER_BINARY RC=$RC"
if [ $RC -eq 0 ]; then
echo "STATIC_PIE_TEST_PASSED"
else
echo "STATIC_PIE_TEST_FAILED: RC=$RC"
fi
Loading
Loading