内核版本:
4.14.199
crash中的spin_lock汇编指令是
crash_arm64> dis _raw_spin_lock -x
0xffffff8008c41e90 <_raw_spin_lock>: stp x29, x30, [sp,#-32]!
0xffffff8008c41e94 <_raw_spin_lock+0x4>: str x19, [sp,#16]
0xffffff8008c41e98 <_raw_spin_lock+0x8>: mov x29, sp
0xffffff8008c41e9c <_raw_spin_lock+0xc>: mov x19, x0
0xffffff8008c41ea0 <_raw_spin_lock+0x10>: nop
0xffffff8008c41ea4 <_raw_spin_lock+0x14>: mov w0, #0x1 // #1
0xffffff8008c41ea8 <_raw_spin_lock+0x18>: bl 0xffffff80080f399c <preempt_count_add>
0xffffff8008c41eac <_raw_spin_lock+0x1c>: mov w10, #0x10000 // #65536
0xffffff8008c41eb0 <_raw_spin_lock+0x20>: .inst 0xb8aa0268 ; undefined
0xffffff8008c41eb4 <_raw_spin_lock+0x24>: nop
0xffffff8008c41eb8 <_raw_spin_lock+0x28>: nop
0xffffff8008c41ebc <_raw_spin_lock+0x2c>: nop
0xffffff8008c41ec0 <_raw_spin_lock+0x30>: eor w9, w8, w8, ror #16
0xffffff8008c41ec4 <_raw_spin_lock+0x34>: cbz w9, 0xffffff8008c41edc <_raw_spin_lock+0x4c>
0xffffff8008c41ec8 <_raw_spin_lock+0x38>: sevl
0xffffff8008c41ecc <_raw_spin_lock+0x3c>: wfe
0xffffff8008c41ed0 <_raw_spin_lock+0x40>: ldaxrh w10, [x19]
0xffffff8008c41ed4 <_raw_spin_lock+0x44>: eor w9, w10, w8, lsr #16
0xffffff8008c41ed8 <_raw_spin_lock+0x48>: cbnz w9, 0xffffff8008c41ecc <_raw_spin_lock+0x3c>
0xffffff8008c41edc <_raw_spin_lock+0x4c>: ldr x19, [sp,#16]
0xffffff8008c41ee0 <_raw_spin_lock+0x50>: ldp x29, x30, [sp],#32
0xffffff8008c41ee4 <_raw_spin_lock+0x54>: ret
.inst
指令是什么意思?
0xffffff8008c41eb0 <_raw_spin_lock+0x20>: .inst 0xb8aa0268 ; undefined
我在
arch/arm64/include/asm/spinlock.h
中找到了函数定义。
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned int tmp;
arch_spinlock_t lockval, newval;
asm volatile(
/* Atomically increment the next ticket. */
ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
" prfm pstl1strm, %3\n"
"1: ldaxr %w0, %3\n"
" add %w1, %w0, %w5\n"
" stxr %w2, %w1, %3\n"
" cbnz %w2, 1b\n",
/* LSE atomics */
" mov %w2, %w5\n"
" ldadda %w2, %w0, %3\n"
__nops(3)
)
/* Did we get the lock? */
" eor %w1, %w0, %w0, ror #16\n"
" cbz %w1, 3f\n"
/*
* No: spin on the owner. Send a local event to avoid missing an
* unlock before the exclusive load.
*/
" sevl\n"
"2: wfe\n"
" ldaxrh %w2, %4\n"
" eor %w1, %w2, %w0, lsr #16\n"
" cbnz %w1, 2b\n"
/* We got the lock. Critical section starts here. */
"3:"
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock)
: "Q" (lock->owner), "I" (1 << TICKET_SHIFT)
: "memory");
}
在我看来,
.inst 0xb8aa0268
应该对应于ldadda %w2, %w0, %3\n"
。
为什么显示的崩溃与源代码不同?
我想我在这里找到了这个 ARM 指令的定义:
.inst
在代码中分配一块内存,并指定操作码。在 A32 代码中,这是一个四字节块。在 T32 代码中,这可以是两字节或四字节块。 .inst.n 分配一个两字节块,.inst.w 分配一个四字节块。