[docs] add debug support for GBL doc
Adding a document for how to debug GBL with UEFI debug support protocol. Signed-off-by: Ying-Chun Liu (PaulLiu) <paulliu@debian.org>
This commit is contained in:
committed by
Kelvin Zhang
parent
e38bf65034
commit
426294d656
180
docs/gdb_debug_support_for_gbl.md
Normal file
180
docs/gdb_debug_support_for_gbl.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# GDB debug support for GBL in LK
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes how to use GDB to debug GBL and using the UEFI
|
||||
debug support protocol.
|
||||
|
||||
## Build GBL
|
||||
|
||||
First, we need to build the GBL with the following steps.
|
||||
|
||||
### Download GBL
|
||||
|
||||
* GBL_MANIFEST_URL_DEFAULT="https://android.googlesource.com/kernel/manifest/"
|
||||
* GBL_MANIFEST_BRANCH_DEFAULT="uefi-gbl-mainline"
|
||||
* mkdir -p gbl
|
||||
* cd gbl
|
||||
* repo init -u ${GBL_MANIFEST_URL} -b ${GBL_MANIFEST_BRANCH}
|
||||
* repo sync
|
||||
|
||||
### Build GBL with Debug Target
|
||||
|
||||
* REPO_ROOT=$(readlink -f .)
|
||||
* BAZEL_TARGET="@gbl//efi:aarch64_debug_dev"
|
||||
* BAZEL_OUT_BASE="${REPO_ROOT}/out_aarch64_debug_dev"
|
||||
* # Build GBL
|
||||
* "${REPO_ROOT}/tools/bazel" "--output_base=${BAZEL_OUT_BASE}" build "${BAZEL_TARGET}" --sandbox_debug --verbose_failures --symlink_prefix=/
|
||||
* # Copy GBL out of the directory
|
||||
* BAZEL_OUT_BIN=$("${REPO_ROOT}/tools/bazel" cquery "${BAZEL_TARGET}" --output files 2>/dev/null)
|
||||
* BAZEL_OUT_BIN=$(readlink -f "${BAZEL_OUT_BASE}/execroot/_main/${BAZEL_OUT_BIN}")
|
||||
* GBL_DBG_BIN="${BAZEL_OUT_BASE}/gbl.efi"
|
||||
* cp "${BAZEL_OUT_BIN}" "${GBL_DBG_BIN}"
|
||||
* # pack debug symbols
|
||||
* DWO_OUT="${BAZEL_OUT_BASE}/dwo"
|
||||
* mkdir -p "${DWO_OUT}"
|
||||
* find "${BAZEL_OUT_BASE}" -name *.dwo -not -path "${DWO_OUT}*" -exec mv -f {} "${DWO_OUT}"/ \; 2>/dev/null || true
|
||||
* llvm-dwp -o "${GBL_DBG_BIN}.dwp" $(ls "${DWO_OUT}"/*.dwo)
|
||||
|
||||
## Run LK with QEmu and load GBL.
|
||||
|
||||
### Run qemu
|
||||
|
||||
* APP1=/path/to/gbl.efi
|
||||
* qemu-system-aarch64 -machine virt \
|
||||
-m 1024M \
|
||||
-cpu cortex-a57 \
|
||||
-nographic \
|
||||
-kernel build-qemu-virt-arm64-test/lk.elf \
|
||||
-drive if=none,file=${APP1},id=blk1,format=raw \
|
||||
-gdb tcp::13333
|
||||
|
||||
### Run GBL
|
||||
|
||||
In the LK prompt. Use the following commands.
|
||||
|
||||
* uefi_set_var gbl_debug 1
|
||||
* uefi_load virtio0
|
||||
|
||||
And we will see the following message.
|
||||
|
||||
```
|
||||
bio_read returns 4096, took 5 msecs (819200 bytes/sec)
|
||||
PE header machine type: aa64
|
||||
Valid UEFI application found.
|
||||
Failed to allocate physical memory size 7073792 at specified address 0x140000000 fallback to regular allocation
|
||||
Relocating image from 0x140000000 to 0x53600000
|
||||
Entry function located at 0x53604db0
|
||||
platform_setup_system_table is called
|
||||
Calling kernel with stack [0x54800000, 0x548fffff]
|
||||
locate_handle_buffer(0x2, (0x3152bca5 0xeade 0x433d 0x441f29dc1cc02e86), search_key=0)
|
||||
Required protocol not found: EfiRngProtocol
|
||||
SECURITY WARNING: Failed to generate stack canary, using static default: Unsupported
|
||||
open_protocol(LOADED_IMAGE_PROTOCOL_GUID, handle=0x53600000, agent_handle=0x53600000, controller_handle=0, attr=0x1)
|
||||
Image base: 0x53600000
|
||||
Please run load_gbl_debug_bin.py or set $x0=0 from gdb to continue.
|
||||
```
|
||||
|
||||
## Use GDB to debug.
|
||||
|
||||
### Use GDB to load debug symbols of GBL manually.
|
||||
|
||||
Since GBL prints its own address. We can load the debug symbols based on
|
||||
that address.
|
||||
|
||||
The above shows the Image base address is 0x53600000
|
||||
|
||||
We can use the command "readpe gbl.efi". Look at the "Virtual Address" field.
|
||||
And we can get the following offsets.
|
||||
|
||||
* .text: 0x1000
|
||||
* .data: 0x392000
|
||||
* .rdata: 0x315000
|
||||
|
||||
So the actual address is by adding the base address (0x53600000)
|
||||
to each of the address above. Then it becomes:
|
||||
|
||||
* .text: 0x53601000
|
||||
* .data: 0x53992000
|
||||
* .rdata: 0x53915000
|
||||
|
||||
Then we can run "gdb-multiarch". In the GDB prompt we use the following
|
||||
commands.
|
||||
|
||||
* target remote :13333
|
||||
* add-symbol-file /path/to/gbl.efi 0x53601000 -s .data 0x53992000 -s .rdata 0x53915000
|
||||
|
||||
And use "bt full" we can see the following output.
|
||||
|
||||
```
|
||||
#0 0x0000000053604d7c in app::wait_gdb (entry=0x548ffe30)
|
||||
at external/gbl/efi/app/main.rs:145
|
||||
buf = [49]
|
||||
image_base = 1398800384
|
||||
#1 0x0000000053604e80 in app::efi_main (image_handle=0x53600000,
|
||||
systab_ptr=0x5340f000) at external/gbl/efi/app/main.rs:184
|
||||
canary = 2812601071695653757
|
||||
entry = efi::EfiEntry {image_handle: 0x53600000, systab_ptr: 0x5340f000}
|
||||
#2 0xffff00000012dcfc in ?? ()
|
||||
No symbol table info available.
|
||||
#3 0xffff00000012ab10 in ?? ()
|
||||
No symbol table info available.
|
||||
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
|
||||
```
|
||||
|
||||
Then we can use "set $x0=0" in GDB to let the GBL continue to run.
|
||||
|
||||
### Use UEFI Debug support protocol.
|
||||
|
||||
By loading python extensions we made, we can make the above things easier.
|
||||
|
||||
In GDB, we load the python extension.
|
||||
|
||||
* target remote :13333
|
||||
* source gdb_efi_apps.py
|
||||
|
||||
And we will have several "efi" commands.
|
||||
* efi showvendor # show the vendor of the bootloader.
|
||||
* efi table # show the configuration tables of the UEFI
|
||||
* efi test list # list of the current loading UEFI apps
|
||||
* efi loadsymbols # load debug symbols
|
||||
|
||||
```
|
||||
(gdb) efi showvendor
|
||||
Firmware Vendor: Little Kernel
|
||||
Firmware Version: 0
|
||||
(gdb) efi table
|
||||
1CE1E5BC-7CEB-42F2-81E5-8AADF180F57B: VendorTable = 0x53411000
|
||||
B1B621D5-F19C-41A5-830B-D9152C69AAE0: VendorTable = 0x53412000
|
||||
gEfiDebugImageInfoTableGuid: VendorTable = 0xffff0000001767a8
|
||||
(gdb) efi test list
|
||||
\virtio0: addr: 0x53600000, size: 0x6bf000, path:None
|
||||
(gdb) efi loadsymbols -m virtio0 /path/to/gbl.efi /path/to/gbl.efi
|
||||
LoadedImage address: 0x53600000, size: 0x6bf000
|
||||
PE text offset: 0x1000
|
||||
PE data offset: 0x392000
|
||||
PE rdata offset: 0x315000
|
||||
(gdb) bt full
|
||||
#0 0x0000000053604d7c in app::wait_gdb (entry=0x548ffe30)
|
||||
at external/gbl/efi/app/main.rs:145
|
||||
buf = [49]
|
||||
image_base = 1398800384
|
||||
#1 0x0000000053604e80 in app::efi_main (image_handle=0x53600000,
|
||||
systab_ptr=0x5340f000) at external/gbl/efi/app/main.rs:184
|
||||
canary = 2812601071695653757
|
||||
entry = efi::EfiEntry {image_handle: 0x53600000, systab_ptr: 0x5340f000}
|
||||
#2 0xffff00000012dcfc in ?? ()
|
||||
No symbol table info available.
|
||||
#3 0xffff00000012ab10 in ?? ()
|
||||
No symbol table info available.
|
||||
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
|
||||
```
|
||||
|
||||
The GDB python extension is currently put here.
|
||||
|
||||
* https://git.codelinaro.org/paul_liu/test-e5e925b80fd7/-/blob/clo/main/verify_gbl_on_qemu/gdb_efi_apps.py?ref_type=heads
|
||||
|
||||
It needs EDK2's python extension scritps. And we are currently trying
|
||||
to upstream this extension to EDK2.
|
||||
|
||||
* https://github.com/tianocore/edk2/pull/11285
|
||||
Reference in New Issue
Block a user