QEMU

复现问题

1
2
3
4
5
6
7
(qemu) xp 0x09000010
PL011State::read: Bad offset 09000010: 0x00000000
(qemu)
$ grep "Bad offset" rust/hw/char/pl011/src/device.rs
log_mask_ln!(Log::GuestError, "PL011State::read: Bad offset {offset}");
"PL011State::write: Bad offset {offset} value {value}"
$

image-20260818223208780

image-20260818223458325

找到Rust FFI键绑定

image-20260818223545526

1
2
$ grep -rn "rust_fwrite" --include="*.c"
util/log.c:589:ssize_t rust_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

image-20260818223724367

这里出现了一个明显的错误,fwrite的返回值没有被使用。

修复:

1
return ret < 0 ? -errno : (ssize_t)(ret * size);

验证修复

1
2
3
4
(qemu) xp 0x09000010
PL011State::read: Bad offset 16
09000010: 0x00000000
(qemu)

附录

启动gdb对rust_fwrite进行调试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[*#0] 0x5555568e209c <rust_fwrite+0x2f>
[...]
-------------------------------------------------------------------------------
gef> p ret
$1 = 0x0
gef> p size # 每个元素字节大小
$2 = 0x1
gef> p nmemb # 要写入的元素个数
$3 = 0x1d
gef> p stream # 文件流指针
$4 = (FILE *) 0x7ffff7e1b6a0 <_IO_2_1_stderr_>
gef> list
590 {
591 /*
592 * Same as fwrite, but return -errno because Rust libc does not provide
593 * portable access to errno. :(
594 */
595 int ret = fwrite(ptr, size, nmemb, stream);
596 printf("ret=%d, size=%zu, returning=%ld\n", ret, size, ret * size);
597
598 return ret < 0 ? -errno : (ssize_t)(ret * size);
599 }
gef>

QEMU
https://47.108.189.123/2026/08/19/课外练习/QEMU/
Author
Dong
Posted on
August 19, 2026
Licensed under