30 #if !defined (__ARM_EABI__)
31 #warning Your compiler does not have EABI support.
32 #warning ARM unwind is known to compile only with EABI compilers.
33 #warning Change compiler or disable ARM_UNWIND option.
34 #elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
35 #warning Your compiler is too buggy; it is known to not compile ARM unwind support.
36 #warning Change compiler or disable ARM_UNWIND option.
40 #include <linux/kernel.h>
42 #include <linux/export.h>
43 #include <linux/sched.h>
44 #include <linux/slab.h>
46 #include <linux/list.h>
48 #include <asm/stacktrace.h>
49 #include <asm/traps.h>
50 #include <asm/unwind.h>
69 unsigned long vrs[16];
76 #ifdef CONFIG_THUMB2_KERNEL
87 static const struct unwind_idx *__origin_unwind_idx;
94 #define prel31_to_addr(ptr) \
97 long offset = (((long)*(ptr)) << 1) >> 1; \
98 (unsigned long)(ptr) + offset; \
114 unsigned long addr_prel31;
117 __func__, addr, start, origin, stop);
123 if (addr < (
unsigned long)start)
131 addr_prel31 = (addr - (
unsigned long)start) & 0x7fffffff;
133 while (start < stop - 1) {
140 if (addr_prel31 - ((
unsigned long)mid - (
unsigned long)start) <
145 addr_prel31 -= ((
unsigned long)mid -
146 (
unsigned long)
start);
151 if (
likely(start->addr_offset <= addr_prel31))
154 pr_warning(
"unwind: Unknown symbol address %08lx\n", addr);
159 static const struct unwind_idx *unwind_find_origin(
162 pr_debug(
"%s(%p, %p)\n", __func__, start, stop);
163 while (start < stop) {
166 if (
mid->addr_offset >= 0x40000000)
173 pr_debug(
"%s -> %p\n", __func__, stop);
177 static const struct unwind_idx *unwind_find_idx(
unsigned long addr)
182 pr_debug(
"%s(%08lx)\n", __func__, addr);
186 __origin_unwind_idx =
187 unwind_find_origin(__start_unwind_idx,
191 idx = search_index(addr, __start_unwind_idx,
202 idx = search_index(addr, table->
start,
206 list_move(&table->
list, &unwind_tables);
210 spin_unlock_irqrestore(&unwind_lock, flags);
213 pr_debug(
"%s: idx = %p\n", __func__, idx);
226 ret = (*ctrl->
insn >> (ctrl->
byte * 8)) & 0xff;
228 if (ctrl->
byte == 0) {
243 unsigned long insn = unwind_get_byte(ctrl);
245 pr_debug(
"%s: insn = %08lx\n", __func__, insn);
247 if ((insn & 0xc0) == 0x00)
248 ctrl->
vrs[
SP] += ((insn & 0x3f) << 2) + 4;
249 else if ((insn & 0xc0) == 0x40)
250 ctrl->
vrs[
SP] -= ((insn & 0x3f) << 2) + 4;
251 else if ((insn & 0xf0) == 0x80) {
253 unsigned long *vsp = (
unsigned long *)ctrl->
vrs[
SP];
254 int load_sp,
reg = 4;
256 insn = (insn << 8) | unwind_get_byte(ctrl);
257 mask = insn & 0x0fff;
259 pr_warning(
"unwind: 'Refuse to unwind' instruction %04lx\n",
265 load_sp = mask & (1 << (13 - 4));
274 }
else if ((insn & 0xf0) == 0x90 &&
275 (insn & 0x0d) != 0x0d)
276 ctrl->
vrs[
SP] = ctrl->
vrs[insn & 0x0f];
277 else if ((insn & 0xf0) == 0xa0) {
278 unsigned long *vsp = (
unsigned long *)ctrl->
vrs[
SP];
285 ctrl->
vrs[14] = *vsp++;
287 }
else if (insn == 0xb0) {
288 if (ctrl->
vrs[
PC] == 0)
292 }
else if (insn == 0xb1) {
293 unsigned long mask = unwind_get_byte(ctrl);
294 unsigned long *vsp = (
unsigned long *)ctrl->
vrs[
SP];
297 if (mask == 0 || mask & 0xf0) {
311 }
else if (insn == 0xb2) {
312 unsigned long uleb128 = unwind_get_byte(ctrl);
314 ctrl->
vrs[
SP] += 0x204 + (uleb128 << 2);
316 pr_warning(
"unwind: Unhandled instruction %02lx\n", insn);
320 pr_debug(
"%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
340 pr_debug(
"%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
341 frame->
pc, frame->
lr, frame->
sp);
346 idx = unwind_find_idx(frame->
pc);
348 pr_warning(
"unwind: Index not found %08lx\n", frame->
pc);
360 else if ((idx->
insn & 0x80000000) == 0)
363 else if ((idx->
insn & 0xff000000) == 0x80000000)
367 pr_warning(
"unwind: Unsupported personality routine %08lx in the index at %p\n",
373 if ((*ctrl.
insn & 0xff000000) == 0x80000000) {
376 }
else if ((*ctrl.
insn & 0xff000000) == 0x81000000) {
378 ctrl.
entries = 1 + ((*ctrl.
insn & 0x00ff0000) >> 16);
380 pr_warning(
"unwind: Unsupported personality routine %08lx at %p\n",
386 int urc = unwind_exec_insn(&ctrl);
393 if (ctrl.
vrs[
PC] == 0)
411 register unsigned long current_sp
asm (
"sp");
413 pr_debug(
"%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
419 frame.
fp = regs->ARM_fp;
420 frame.
sp = regs->ARM_sp;
421 frame.
lr = regs->ARM_lr;
424 ? regs->ARM_pc : regs->ARM_lr;
426 frame.
fp = (
unsigned long)__builtin_frame_address(0);
427 frame.
sp = current_sp;
428 frame.
lr = (
unsigned long)__builtin_return_address(0);
432 frame.
fp = thread_saved_fp(tsk);
433 frame.
sp = thread_saved_sp(tsk);
444 unsigned long where = frame.
pc;
454 unsigned long text_addr,
455 unsigned long text_size)
460 pr_debug(
"%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
461 text_addr, text_size);
470 tab->
end_addr = text_addr + text_size;
474 spin_unlock_irqrestore(&unwind_lock, flags);
488 spin_unlock_irqrestore(&unwind_lock, flags);