1.. SPDX-License-Identifier: GPL-2.0+
2.. Copyright (c) 2020 Heinrich Schuchardt
3
4Analyzing crash dumps
5=====================
6
7When the CPU detects an instruction that it cannot execute it raises an
8interrupt. U-Boot then writes a crash dump. This chapter describes how such
9dump can be analyzed.
10
11Creating a crash dump voluntarily
12---------------------------------
13
14For describing the analysis of a crash dump we need an example. U-Boot comes
15with a command :doc:`exception <../usage/cmd/exception>` that comes in handy
16here. The command is enabled by::
17
18    CONFIG_CMD_EXCEPTION=y
19
20The example output below was recorded when running qemu\_arm64\_defconfig on
21QEMU::
22
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
42
43    Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)
44    Resetting CPU ...
45
46    resetting ...
47
48The first line provides us with the type of interrupt that occurred.
49On ARMv8 a synchronous abort is an exception thrown when hitting an unallocated
50instruction. The exception syndrome register ESR register contains information
51describing the reason for the exception. Bit 25 set here indicates that a 32 bit
52instruction led to the exception.
53
54The second line provides the contents of the elr and the lr register after
55subtracting the relocation offset. - U-Boot relocates itself after being
56loaded. - The relocation offset can also be displayed using the bdinfo command.
57
58After the contents of the registers we get a line indicating the machine
59code of the instructions preceding the crash and in parentheses the instruction
60leading to the dump.
61
62Analyzing the code location
63---------------------------
64
65We can convert the instructions in the line starting with 'Code:' into mnemonics
66using the objdump command. To make things easier scripts/decodecode is
67supplied::
68
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)
72    All code
73    ========
74       0:   b00003c0     adrp   x0, 0x79000
75       4:   912ad000     add    x0, x0, #0xab4
76       8:   940029d6     bl     0xa760
77       c:   17ffff52     b      0xfffffffffffffd54
78      10:*  e7f7defb     .inst  0xe7f7defb ; undefined <-- trapping instruction
79
80    Code starting with the faulting instruction
81    ===========================================
82       0:   e7f7defb     .inst  0xe7f7defb ; undefined
83
84Now lets use the locations provided by the elr and lr registers after
85subtracting the relocation offset to find out where in the code the crash
86occurred and from where it was invoked.
87
88File u-boot.map contains the memory layout of the U-Boot binary. Here we find
89these lines::
90
91   .text.do_undefined
92                  0x00000000000101fc        0xc cmd/built-in.o
93   .text.exception_complete
94                  0x0000000000010208       0x90 cmd/built-in.o
95   ...
96   .text.cmd_process
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
102
103So the error occurred at the start of function do\_undefined() and this
104function was invoked from somewhere inside function cmd\_process().
105
106If we want to dive deeper, we can disassemble the U-Boot binary::
107
108    $ aarch64-linux-gnu-objdump -S -D u-boot | less
109
110    00000000000101fc <do_undefined>:
111    {
112            /*
113             * 0xe7f...f.   is undefined in ARM mode
114             * 0xde..       is undefined in Thumb mode
115            */
116            asm volatile (".word 0xe7f7defb\n");
117       101fc:       e7f7defb        .inst   0xe7f7defb ; undefined
118            return CMD_RET_FAILURE;
119    }
120    10200:       52800020        mov     w0, #0x1        // #1
121    10204:       d65f03c0        ret
122
123This example is based on the ARMv8 architecture but the same procedures can be
124used on other architectures as well.
125
126Crashs in UEFI binaries
127-----------------------
128
129If UEFI images are loaded when a crash occurs, their load addresses are
130displayed. If the process counter points to an address in a loaded UEFI
131binary, the relative process counter position is indicated. Here is an
132example executed on the U-Boot sandbox::
133
134    => load host 0:1 $kernel_addr_r buggy.efi
135    5632 bytes read in 0 ms
136    => bootefi $kernel_addr_r
137    Booting /buggy.efi
138    Buggy world!
139
140    Segmentation violation
141    pc = 0x19fc264c, pc_reloc = 0xffffaa4688b1664c
142
143    UEFI image [0x0000000019fc0000:0x0000000019fc6137] pc=0x264c '/buggy.efi'
144
145The crash occured in UEFI binary buggy.efi at relative position 0x264c.
146Disassembly may be used to find the actual source code location::
147
148    $ x86_64-linux-gnu-objdump -S -D buggy_efi.so
149
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)
156
157Architecture specific details
158-----------------------------
159
160ARMv8
161~~~~~
162
163On the ARM 64-bit architecture CONFIG_ARMV8_SPL_EXCEPTION_VECTORS controls
164if the exception vector tables are set up in the Secondary Program Loader (SPL).
165Without initialization of the tables crash dumps cannot be shown. The feature is
166disabled by default on most boards to reduce the size of the SPL.
167
168RISC-V
169~~~~~~
170
171On the RISC-V architecture CONFIG_SHOW_REGS=y has to be specified to show
172all registers in crash dumps.
173
174Sandbox
175~~~~~~~
176
177The sandbox U-Boot binary must be invoked with parameter *-S* to display crash
178dumps:
179
180.. code-block:: bash
181
182    ./u-boot -S -T
183
184Only with CONFIG_SANDBOX_CRASH_RESET=y the sandbox reboots after a crash.
185