From 426294d6561391a5a403736bf2db20aaf9d5edf3 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Thu, 21 Aug 2025 16:54:30 +0100 Subject: [PATCH] [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) --- docs/gdb_debug_support_for_gbl.md | 180 ++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/gdb_debug_support_for_gbl.md diff --git a/docs/gdb_debug_support_for_gbl.md b/docs/gdb_debug_support_for_gbl.md new file mode 100644 index 00000000..7d67b26f --- /dev/null +++ b/docs/gdb_debug_support_for_gbl.md @@ -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