log
the nix shell:
{ pkgs ? import <nixpkgs> {} }:
let
linux = (pkgs.linux.override { stdenv = pkgs.llvmPackages_latest.stdenv; }).overrideAttrs (prev: { nativeBuildInputs = prev.nativeBuildInputs or [] ++ [pkgs.ncurses]; });
in linux(nixpkgs/917fec990948658ef1ccd07cef2a1ef060786846)
i got the source by running unpackPhase.
then make LLVM=1 defconfig
and make with the makeflags which the nix buildPhase prints (Pasted image 20260710224909.png). (removed the last bit to have only bzImage and vmlinux as the target, not modules)
YESSS. after python ./scripts/clang-tools/gen_compile_commands.py and
{
"load_direnv":"direct",
"lsp": {
"clangd": {
"binary": {
"arguments": [
"--compile-commands-dir=.",
"--background-index",
"--clang-tidy",
"--completion-style=detailed",
"--header-insertion=never"
]
}
}
}
}
in zed (editor)‘s project settings… we have working Intellisence
enabled the 3 debug config options CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y CONFIG_GDB_SCRIPTS=y and smth about automatic dwarf version. with make menuconfig
-
./vmlinux: the full kernel as an ELF with debug symbols. however not bootable. as compressed data inside the bzImage- does not contain the efi_stub_entry symbol (that is before decompression, it then calls decompress_kernel)
-
./arch/x86/boot/setup.elf: the setup code. but also no efi_stub_entry as this is only the Real Mode part of the setup code… which is completely not in use when using efi… -
./arch/x86/boot/compressed/vmlinux: the whole decompressor stuff (runs in Protected Mode i think, where we are when we get run by the efi)- has efi_stub_entry … yay
-
next problem: the efi does ASLR = Address Space Layout Randomisation. meaning our binary will be placed ANYWHERE in the address space. (so any breakpoints/source mappings just won’t work where stuff is.)
- also bzImage is completely stripped…
-
so i added a spinlock: Pasted image 20260710231214.png (so we are stuck there before any uncompressing and start_kernel())
- you can then do
process interruptinside lldb to “break” there. set thewait_for_lldb to 0 manually (after breakpoints and stuff works) . after which you will continue like normal
- you can then do
(qemu cmdline in makefile at the bottom, does gdb debug listener on localhost:1234)
(and (lldb) gdb-remote localhost:1234 of course)
-
with
(lldb) dis -s $rip-34 -c 20i was able to see that pause instruction. -
no debug symbols/source maps are working. we need to somehow tell the debugger that
./arch/x86/boot/compressed/vmlinuxis the executable we “are running” and at what offset it got loaded by efi’s aslr -
the addr from that pause instruction in the running system is eg 0x780fb15e (from the dis command)
-
with
objdump -d arch/x86/boot/compressed/vmlinux | lessand then searching for efi_stub_entry i could find the same pause instruction at 0x3a1715e in the file. -
rech 0x780fb15e - 0x3a1715egives eg: 1953382400
~ ❯❯❯ command -V rech
rech is a function
rech ()
{
python3 -c "print($@)"
}
~ ❯❯❯
(“rechnen” is german for calculate)
with
-
(lldb) target create arch/x86/boot/compressed/vmlinux -
(lldb) target modules load --file /arch/x86/boot/compressed/vmlinux -s 0x1953382400we should have correctly aligned the debug symbols. BUT IT JUST NOT WORK -
rech 'hex(0x780fb15e - 0x3a1715e)'…- yup. big big F.
- took me i think 2h to realize
- (did think before) how lucky we got… that there are just no letters in our address… xD
-
now we do se the right symbols in the dissasembly: Pasted image 20260710233644.png
- but still just no sources via
sources info,l
- but still just no sources via
there should be a CompileUnit… but there just is not…
(lldb) image lookup -n efi_stub_entry
1 match found in /root/work/c2vi/acern-fixing/nix-linux/arch/x86/boot/compressed/vmlinux:
Address: vmlinux[0x0000000003a17109] (vmlinux.PT_LOAD[0]..text + 35801)
Summary: vmlinux`efi_stub_entry
-
so we mapped the symbols of arch/x86/boot/compressed/vmlinux correctly into our proccess… but just seem to have no debug info????
- but how can that be… the file command clearly shows “with debug_info”
-
a peak into the .debug_line section using
readelf --debug-dump=decodedline arch/x86/boot/compressed/vmlinux | lessshows that all entries there are for one filearch/x86/boot/startup/efi-mixed.S- so file says “with debug_info” as that section exists… but it just has no useful data.
-
the efi_stub and decompression code needs to be PIC. there is a check in drivers/firmware/efi/libstub/Makefile to make sure there are no absolute adresses in any objfiles in question.
- as debug_info would have absolute addresses (which are not actually uses for running…) that check would not work… so debug info is stripped. (also to safe space in bzImage)
- there is a patch on the LKML = Linux Kernel Mailing List about keeping the debug symbols (https://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/462131.html)
- i think however this patch is applied. SO WHY STILL NO SYMBOLS.
- well the patch talks about arm64 and the top of said Makefile
# non-x86 reuses KBUILD_CFLAGS, x86 does not- so for x86 we use special KBUILD_CFLAGS for the efi_stub defined in this Makefile. these flags don’t handle
CONFIG_DEBUG_INFOand never add a -g. so there were never any debug symbols emitted for any efi_stub things.
- so for x86 we use special KBUILD_CFLAGS for the efi_stub defined in this Makefile. these flags don’t handle
-
YESSSS … after adding that -g… it all works … Pasted image 20260710223729.png
(lldb) image lookup -v -n efi_stub_entry… Pasted image 20260711000124.png- i needed to
(lldb) step instructiononce for(lldb) lto work
the makefile:
.PHONY: run
#KERNEL=/boot/vmlinuz-6.12.88+deb13-amd64
#KERNEL=./linux/arch/x86/boot/bzImage
KERNEL=./nix-linux/arch/x86/boot/bzImage
default: clean build
clean:
rm -rf ./initrd
build:
# initrd
mkdir -p ./initrd
cp -r ./nix-busybox/* ./initrd
ln -fs ./bin/sh ./initrd/init
find ./initrd | cpio -o -H newc | gzip -9 > ../initrd.img
# efi file
# useless as i found out bzImage is already an efi file
# ukify build --linux=${KERNEL} --initrd=./initrd.img --cmdline="debug log_buf_len=10M console=ttyS0,115200 earlyprintk=serial,ttyS0,115200 earlycon=uart8250,io,0x3f8,115200" --output=./linux.efi --uname="6.18.16"
# copy to VM dir
cp ${KERNEL} ./boot/EFI/BOOT/BOOTX64.EFI
run: build
qemu-system-x86_64 -nographic \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \
-drive file=fat:rw:./boot,format=raw \
-net none \
-serial mon:stdio \
-m 2G -s
#-kernel ./linux/linux-6.18.16/build/vmlinux \
#-initrd ./initrd.img \
#-append "debug log_buf_len=10M console=ttyS0,115200 earlyprintk=serial,ttyS0,115200 earlycon=uart8250,io,0x3f8,115200" \