目次: RISC-V
タイトルに反して実はRISC-Vはあまり関係ないですが……。GNU libcとmusl libcの実装を見ていたら、64bit環境でrebootシステムコールの引数magicに、
がいることに気づきました。
Cライブラリのrebootの関数宣言はint reboot(int cmd) となっています。musl libcの場合0xfee1deadをキャストせずlong型の引数に渡します。符号拡張は行われず0x00000000_fee1deadがシステムコールの引数に渡されます。
// musl/src/linux/reboot.c
int reboot(int type)
{
return syscall(SYS_reboot, 0xfee1dead, 672274793, type);
}
// musl/arch/riscv64/syscall_arch.h
static inline long __syscall3(long n, long a, long b, long c)
{
register long a7 __asm__("a7") = n;
register long a0 __asm__("a0") = a;
register long a1 __asm__("a1") = b;
register long a2 __asm__("a2") = c;
__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
}
一方のGNU libcの場合は、0xfee1deadをintにキャストしてからシステムコールに渡します。この値は負の数なので符号拡張が行われて0xffffffff_fee1deadがシステムコールの引数に渡されます。
// glibc/sysdeps/unix/sysv/linux/reboot.c
/* Call kernel with additional two arguments the syscall requires. */
int
reboot (int howto)
{
return INLINE_SYSCALL (reboot, 3, (int) 0xfee1dead, 672274793, howto);
}
// glibc/sysdeps/unix/sysv/linux/riscv/sysdep.h
# define internal_syscall3(number, arg0, arg1, arg2) \
({ \
long int _sys_result; \
long int _arg0 = (long int) (arg0); \
long int _arg1 = (long int) (arg1); \
long int _arg2 = (long int) (arg2); \
\
{ \
register long int __a7 asm ("a7") = number; \
register long int __a0 asm ("a0") = _arg0; \
register long int __a1 asm ("a1") = _arg1; \
register long int __a2 asm ("a2") = _arg2; \
__asm__ volatile ( \
"scall\n\t" \
: "+r" (__a0) \
: "r" (__a7), "r" (__a1), "r" (__a2) \
: __SYSCALL_CLOBBERS); \
_sys_result = __a0; \
} \
_sys_result; \
})
最初に気づいたときはどちらかがバグっている……?と勘違いしましたが、当たり前ですがどちらも正常に動きます。すなわちLinux側で何か対応しているはずです。続きはまた今度。
< | 2023 | > | ||||
<< | < | 02 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | - | - | - | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)