summaryrefslogtreecommitdiffstats
path: root/test_code/ovmf_with_gdb_16_5_2022.txt
blob: c5b8b7a564db222c42dfae4ecd8adac905eb6330 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
https://retrage.github.io/2019/12/05/debugging-ovmf-en.html


Building EDK2
Build EDK2 using gcc as usual.

$ git clone git@github.com:tianocore/edk2.git
$ cd edk2
$ git submodule update --init --recursive
$ make -C BaseTools
$ source ./edksetup.sh
$ build -p OvmfPkg/OvmfPkgX64.dsc -b DEBUG -a X64 -t GCC5
To make debugging easy, create a Makefile as follow. Note that we have to connect debugcon at 0x402 to dump debug information (debug.log) from OVMF[4].

#!/usr/bin/env make

SHELL=/bin/bash

LOG=debug.log
OVMFBASE=edk2/Build/OvmfX64/DEBUG_GCC5/
OVMFCODE=$(OVMFBASE)/FV/OVMF_CODE.fd
OVMFVARS=$(OVMFBASE)/FV/OVMF_VARS.fd
QEMU=qemu-system-x86_64
QEMUFLAGS=-drive format=raw,file=fat:rw:image \
          -drive if=pflash,format=raw,readonly,file=$(OVMFCODE) \
          -drive if=pflash,format=raw,file=$(OVMFVARS) \
          -debugcon file:$(LOG) -global isa-debugcon.iobase=0x402 \
          -serial stdio \
          -nographic \
          -nodefaults

run:
    $(QEMU) $(QEMUFLAGS)

debug:
    $(QEMU) $(QEMUFLAGS) -s -S

.PHONY: run debug
Before debugging, run the firmware to get debug.log. It may be better to provide startup.nsh script.

$ make run
Now, we have debug.log. It includes the addresses of loaded UEFI images like this:

Loading PEIM at 0x00007EA8000 EntryPoint=0x00007EAB0BC DxeCore.efi
Next, extract text section (.text) RVA from *.efi PE binaries. This can be done by readelf if it is ELF, but the images are PE format. Here we use retrage/peinfo[3].

$ git clone git@github.com:retrage/peinfo.git
$ cd peinfo
$ make
peinfo extracts section information from a binary. This time we want to know VirtualAddress in RVA.

Name: .text
VirtualSize: 0x000204c0
VirtualAddress: 0x00000240
SizeOfRawData: 0x000204c0
PointerToRawData: 0x00000240
PointerToRelocations: 0x00000000
PointerToLinenumbers: 0x00000000
NumberOfRelocations: 0x0000
NumberOfLinenumbers: 0x0000
Characteristics: 0x60000020
Run following bash script with debug.log and peinfo. This outputs a snippet of GDB script that adds symbol information (add-symbol-file). It calculates the address of UEFI image text section from base address and VirtualAddress.

#!/bin/bash

LOG="debug.log"
BUILD="edk2/Build/OvmfX64/DEBUG_GCC5/X64"
PEINFO="peinfo/peinfo"

cat ${LOG} | grep Loading | grep -i efi | while read LINE; do
  BASE="`echo ${LINE} | cut -d " " -f4`"
  NAME="`echo ${LINE} | cut -d " " -f6 | tr -d "[:cntrl:]"`"
  ADDR="`${PEINFO} ${BUILD}/${NAME} \
        | grep -A 5 text | grep VirtualAddress | cut -d " " -f2`"
  TEXT="`python -c "print(hex(${BASE} + ${ADDR}))"`"
  SYMS="`echo ${NAME} | sed -e "s/\.efi/\.debug/g"`"
  echo "add-symbol-file ${BUILD}/${SYMS} ${TEXT}"
done
$ bash gen_symbol_offsets.sh > gdbscript
cat gdb
The generated GDB script is like this:

add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/PcdPeim.debug 0x82c380
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/ReportStatusCodeRouterPei.debug 0x831080
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/StatusCodeHandlerPei.debug 0x833100
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/PlatformPei.debug 0x835100
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug 0x7ee8240
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug 0x7ee3240
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/S3Resume2Pei.debug 0x7edf240
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/CpuMpPei.debug 0x7ed6240
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/DxeCore.debug 0x7ea8240
add-symbol-file edk2/Build/OvmfX64/DEBUG_GCC5/X64/DevicePathDxe.debug 0x7b8f240
Now we are ready.

$ less debug.log
...
The 0th FV start address is 0x0000082000
...
Loading PEIM at 0x0000082BFC0
	Entry Point = 0x0000082F40A PcdPeim.efi
...

$ make debug

Let’s place a breakpoint at BootServices->HandleProtocol().

(gdb) source gdbscript
.
.
.
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/UsbBusDxe.debug" at
        .text_addr = 0x6c85240
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/UsbKbDxe.debug" at
        .text_addr = 0x6cb3240
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/UsbMassStorageDxe.debug" at                                         
        .text_addr = 0x6c6d240                                          
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/QemuVideoDxe.debug" at                                         
        .text_addr = 0x6c66240      
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/VirtioGpuDxe.debug" at                                       
        .text_addr = 0x6c60240                                           
add symbol table from file "/home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/Shell.debug" at                                         
        .text_addr = 0x64f5240   

(gdb) info functions CoreHandleProtocol
All functions matching regular expression "CoreHandleProtocol":
File /.../edk2/MdeModulePkg/Core/Dxe/Hand/Handle.c:
EFI_STATUS CoreHandleProtocol(EFI_HANDLE, EFI_GUID *, void **);

(gdb) info address CoreHandleProtocol
Symbol "CoreHandleProtocol" is a function at address 0x7ea4aa9.

(gdb) b CoreHandleProtocol

(gdb) info symbol 0x82F40A            
_ModuleEntryPoint in section .text of /home/koenigr/Memtest/git/edk2/Build/OvmfX64/DEBUG_GCC5/X64/PcdPeim.debug 

(gdb) b *0x82F40A                                     
Breakpoint 2 at 0x82f40a: file /home/koenigr/Memtest/git/edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c, line 33.  

(gdb) target remote localhost:1234
Remote debugging using localhost:1234                                         
warning: No executable has been specified and target does not support      
determining executable automatically.  Try using the "file" command.                                          
0x000000000000fff0 in ?? ()  

(gdb) c

The debugger stops, and we can do source code level debug.

!!!!!!!!!!!!!!!!!!!!!!!!!!! DOES NOT WORK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   ┌──/home/akira/src/ovmf-debug/edk2/MdeModulePkg/Core/Dxe/Hand/Handle.c──────┐
   │933     CoreHandleProtocol (                                               │
   │934       IN EFI_HANDLE       UserHandle,                                  │
   │935       IN EFI_GUID         *Protocol,                                   │
   │936       OUT VOID            **Interface                                  │
   │937       )                                                                │
B+>│938     {                                                                  │
   │939       return CoreOpenProtocol (                                        │
   │940               UserHandle,                                              │
   │941               Protocol,                                                │
   │942               Interface,                                               │
   │943               gDxeCoreImageHandle,                                     │
   │944               NULL,                                                    │
   │945               EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL                     │
   └───────────────────────────────────────────────────────────────────────────┘
remote Thread 1 In: CoreHandleProtocol                      L938  PC: 0x7eb6ad4 



(gdb)