【发布时间】:2013-12-12 19:13:42
【问题描述】:
我正在尝试从以下代码中删除堆栈依赖项。
void myfunction(struct kprobe *p, struct pt_regs *regs)
{
register void *rregs asm("r1") = regs;
register void *rfn asm("lr") = p->ainsn.insn_fn;
__asm__ __volatile__ (
"stmdb sp!, {%[regs], r11} \n\t"
"ldmia %[regs], {r0-r12} \n\t"
"blx %[fn] \n\t"
"ldr lr, [sp], #4 \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
"ldr r11, [sp], #4 \n\t"
: [regs] "=r" (rregs), [fn] "=r" (rfn)
: "" (rregs), "1" (rfn)
: "r0", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r12", "memory", "cc"
);
}
在上述函数中,stmdb sp!, {%[regs], r11} 将 r1 和 r11 压入堆栈,然后再返回。
就我而言,我应该避免在这里使用堆栈。所以我重写了
void myfunction(struct kprobe *p, struct pt_regs *regs)
{
int r1_bk = 0, r11_bk = 0;
register void *rregs asm("r1") = regs;
register void *rfn asm("lr") = p->ainsn.insn_fn;
register void *r1b_c asm("r1") = &r1_bk;
register void *r11b_c asm("r11") = &r11_bk;
__asm__ __volatile__ (
"ldr %[r1b], r1 \n\t"
"ldr %[r11b], r11 \n\t"
"ldmia %[regs], {r0-r12} \n\t"
"blx %[fn] \n\t"
"ldr lr, %[r1b] \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
"ldr r11, %[r11b] \n\t"
: [regs] "=r" (rregs), [fn] "=r" (rfn), [r1b] "=r" (r1b_c), [r11b] "=r" (r11b_c)
: "0" (rregs), "1" (rfn)
: "r0", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r12", "memory", "cc"
);
}
当我编译时,出现以下错误。
/tmp/ccJMefdC.s: Assembler messages:
/tmp/ccJMefdC.s:579: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:580: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:583: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:585: Error: internal_relocation (type: OFFSET_IMM) not fixed up
我在这里提到了internal relocation not fixed up。但它没有给出明确的想法。请分享您对此的了解。
【问题讨论】:
-
我没有看到您正在恢复 r1,而我看到您正在加载 r14 中的 r1b(即 LR)。这是想要的吗?
-
r1b 的内容包含 r1 值。见
"ldr %[r1b], r1" -
我看到了,我没有看到 "ldr r1, %[r1b]" 恢复原始值,但是在仅恢复 r11 的原始代码中甚至没有这样做.所以我认为它不会改变任何东西,对不起
-
看起来很狂野。你声明了一些本地人,你希望他们去哪里?如果您能够设法编译该 sn-p,并且如果您之后反汇编它,您可能会注意到它无论如何都使用堆栈。这看起来不像一个叶子函数,所以你不能轻易地依赖临时寄存器。并且您对 r1 的使用也可能是错误的。
标签: c assembly arm inline-assembly kprobe