1 .. SPDX-License-Identifier: GPL-2.0+
2 .. Copyright (c) 2020 Heinrich Schuchardt
7 When the CPU detects an instruction that it cannot execute it raises an
8 interrupt. U-Boot then writes a crash dump. This chapter describes how such
11 Creating a crash dump voluntarily
12 ---------------------------------
14 For describing the analysis of a crash dump we need an example. U-Boot comes
15 with a command :doc:`exception <../usage/cmd/exception>` that comes in handy
16 here. The command is enabled by::
18 CONFIG_CMD_EXCEPTION=y
20 The example output below was recorded when running qemu\_arm64\_defconfig on
23 => exception undefined
24 "Synchronous Abort" handler, esr 0x02000000
25 elr: 00000000000101fc lr : 00000000000214ec (reloc)
26 elr: 000000007ff291fc lr : 000000007ff3a4ec
27 x0 : 000000007ffbd7f8 x1 : 0000000000000000
28 x2 : 0000000000000001 x3 : 000000007eedce18
29 x4 : 000000007ff291fc x5 : 000000007eedce50
30 x6 : 0000000000000064 x7 : 000000007eedce10
31 x8 : 0000000000000000 x9 : 0000000000000004
32 x10: 6db6db6db6db6db7 x11: 000000000000000d
33 x12: 0000000000000006 x13: 000000000001869f
34 x14: 000000007edd7dc0 x15: 0000000000000002
35 x16: 000000007ff291fc x17: 0000000000000000
36 x18: 000000007eed8dc0 x19: 0000000000000000
37 x20: 000000007ffbd7f8 x21: 0000000000000000
38 x22: 000000007eedce10 x23: 0000000000000002
39 x24: 000000007ffd4c80 x25: 0000000000000000
40 x26: 0000000000000000 x27: 0000000000000000
41 x28: 000000007eedce70 x29: 000000007edd7b40
43 Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)
48 The first line provides us with the type of interrupt that occurred.
49 On ARMv8 a synchronous abort is an exception thrown when hitting an unallocated
50 instruction. The exception syndrome register ESR register contains information
51 describing the reason for the exception. Bit 25 set here indicates that a 32 bit
52 instruction led to the exception.
54 The second line provides the contents of the elr and the lr register after
55 subtracting the relocation offset. - U-Boot relocates itself after being
56 loaded. - The relocation offset can also be displayed using the bdinfo command.
58 After the contents of the registers we get a line indicating the machine
59 code of the instructions preceding the crash and in parentheses the instruction
62 Analyzing the code location
63 ---------------------------
65 We can convert the instructions in the line starting with 'Code:' into mnemonics
66 using the objdump command. To make things easier scripts/decodecode is
69 $echo 'Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)' | \
70 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 scripts/decodecode
71 Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)
74 0: b00003c0 adrp x0, 0x79000
75 4: 912ad000 add x0, x0, #0xab4
77 c: 17ffff52 b 0xfffffffffffffd54
78 10:* e7f7defb .inst 0xe7f7defb ; undefined <-- trapping instruction
80 Code starting with the faulting instruction
81 ===========================================
82 0: e7f7defb .inst 0xe7f7defb ; undefined
84 Now lets use the locations provided by the elr and lr registers after
85 subtracting the relocation offset to find out where in the code the crash
86 occurred and from where it was invoked.
88 File u-boot.map contains the memory layout of the U-Boot binary. Here we find
92 0x00000000000101fc 0xc cmd/built-in.o
93 .text.exception_complete
94 0x0000000000010208 0x90 cmd/built-in.o
97 0x00000000000213b8 0x164 common/built-in.o
98 0x00000000000213b8 cmd_process
99 .text.cmd_process_error
100 0x000000000002151c 0x40 common/built-in.o
101 0x000000000002151c cmd_process_error
103 So the error occurred at the start of function do\_undefined() and this
104 function was invoked from somewhere inside function cmd\_process().
106 If we want to dive deeper, we can disassemble the U-Boot binary::
108 $ aarch64-linux-gnu-objdump -S -D u-boot | less
110 00000000000101fc <do_undefined>:
113 * 0xe7f...f. is undefined in ARM mode
114 * 0xde.. is undefined in Thumb mode
116 asm volatile (".word 0xe7f7defb\n");
117 101fc: e7f7defb .inst 0xe7f7defb ; undefined
118 return CMD_RET_FAILURE;
120 10200: 52800020 mov w0, #0x1 // #1
123 This example is based on the ARMv8 architecture but the same procedures can be
124 used on other architectures as well.
126 Crashs in UEFI binaries
127 -----------------------
129 If UEFI images are loaded when a crash occurs, their load addresses are
130 displayed. If the process counter points to an address in a loaded UEFI
131 binary, the relative process counter position is indicated. Here is an
132 example executed on the U-Boot sandbox::
134 => load host 0:1 $kernel_addr_r buggy.efi
135 5632 bytes read in 0 ms
136 => bootefi $kernel_addr_r
140 Segmentation violation
141 pc = 0x19fc264c, pc_reloc = 0xffffaa4688b1664c
143 UEFI image [0x0000000019fc0000:0x0000000019fc6137] pc=0x264c '/buggy.efi'
145 The crash occured in UEFI binary buggy.efi at relative position 0x264c.
146 Disassembly may be used to find the actual source code location::
148 $ x86_64-linux-gnu-objdump -S -D buggy_efi.so
150 0000000000002640 <memset>:
151 2640: f3 0f 1e fa endbr64
152 2644: 48 89 f8 mov %rdi,%rax
153 2647: 48 89 f9 mov %rdi,%rcx
154 264a: eb 0b jmp 2657 <memset+0x17>
155 264c: 40 88 31 mov %sil,(%rcx)
157 Architecture specific details
158 -----------------------------
163 On the ARM 64-bit architecture CONFIG_ARMV8_SPL_EXCEPTION_VECTORS controls
164 if the exception vector tables are set up in the Secondary Program Loader (SPL).
165 Without initialization of the tables crash dumps cannot be shown. The feature is
166 disabled by default on most boards to reduce the size of the SPL.
171 On the RISC-V architecture CONFIG_SHOW_REGS=y has to be specified to show
172 all registers in crash dumps.
177 The sandbox U-Boot binary must be invoked with parameter *-S* to display crash
184 Only with CONFIG_SANDBOX_CRASH_RESET=y the sandbox reboots after a crash.