summaryrefslogblamecommitdiffstats
path: root/documentation/ovmf_with_gdb_16_5_2022.txt
blob: f2569d21fcf6549ed30b7e239788fb9cc99504f4 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                           
                    
                   



































































                                                                                                                                                                                                                                    
       













                                                                                          







                                               




                                                             














                                                                                                                                                            








                                                               
                          






                                                                                                                        
                                  




                                                                                                              
       
 

                                                          

                                                                               



















                                                                                                                                                                                                                                          
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
$ source edksetup.sh
$ make -C BaseTools
$ 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)