hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/arch/arm/kernel/unwind.c
....@@ -1,21 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * arch/arm/kernel/unwind.c
34 *
45 * Copyright (C) 2008 ARM Limited
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
- *
196 *
207 * Stack unwinding support for ARM
218 *
....@@ -313,6 +300,29 @@
313300 return URC_OK;
314301 }
315302
303
+static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl)
304
+{
305
+ unsigned long bytes = 0;
306
+ unsigned long insn;
307
+ unsigned long result = 0;
308
+
309
+ /*
310
+ * unwind_get_byte() will advance `ctrl` one instruction at a time, so
311
+ * loop until we get an instruction byte where bit 7 is not set.
312
+ *
313
+ * Note: This decodes a maximum of 4 bytes to output 28 bits data where
314
+ * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence
315
+ * it is sufficient for unwinding the stack.
316
+ */
317
+ do {
318
+ insn = unwind_get_byte(ctrl);
319
+ result |= (insn & 0x7f) << (bytes * 7);
320
+ bytes++;
321
+ } while (!!(insn & 0x80) && (bytes != sizeof(result)));
322
+
323
+ return result;
324
+}
325
+
316326 /*
317327 * Execute the current unwind instruction.
318328 */
....@@ -366,7 +376,7 @@
366376 if (ret)
367377 goto error;
368378 } else if (insn == 0xb2) {
369
- unsigned long uleb128 = unwind_get_byte(ctrl);
379
+ unsigned long uleb128 = unwind_decode_uleb128(ctrl);
370380
371381 ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
372382 } else {
....@@ -457,7 +467,7 @@
457467 ctrl.vrs[PC] = ctrl.vrs[LR];
458468
459469 /* check for infinite loop */
460
- if (frame->pc == ctrl.vrs[PC])
470
+ if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP])
461471 return -URC_FAILURE;
462472
463473 frame->fp = ctrl.vrs[FP];
....@@ -468,7 +478,8 @@
468478 return URC_OK;
469479 }
470480
471
-void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
481
+void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk,
482
+ const char *loglvl)
472483 {
473484 struct stackframe frame;
474485
....@@ -506,7 +517,7 @@
506517 urc = unwind_frame(&frame);
507518 if (urc < 0)
508519 break;
509
- dump_backtrace_entry(where, frame.pc, frame.sp - 4);
520
+ dump_backtrace_entry(where, frame.pc, frame.sp - 4, loglvl);
510521 }
511522 }
512523