###
### Load debuging information about GNU GRUB 2 modules into GDB
### automatically. Needs readelf, objdump, Python and gdb_helper.py script
###
### Has to be launched from the writable and trusted
### directory containing *.image and *.module
###
### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
### Lubomir Kundrak <lkudrak@skosi.org>
###

source gdb_helper.py


define dynamic_load_symbols
	dynamic_load_kernel_exec_symbols $arg0

	run_on_start

	# We may have been very late to loading the kernel.exec symbols and
	# and modules may already be loaded. So load symbols for any already
	# loaded.
	load_all_modules

	if $is_grub_loaded()
		runtime_load_module
	end
end
document dynamic_load_symbols
	Load debugging symbols from kernel.exec and any loaded modules given
	the address of the .text segment of the UEFI binary in memory. Also
	setup session to automatically load module symbols for modules loaded
	in the future.
end

define load_all_modules
	set $this = grub_dl_head
	while ($this != 0)
		load_module $this
		set $this = $this->next
	end
end
document load_all_modules
	Load debugging information for all loaded modules.
end

define runtime_load_module
	break grub_dl_add
	commands
		silent
		load_module mod
		cont
	end
end
document runtime_load_module
	Load module symbols at runtime as they are loaded.
end

define run_on_start
	# TODO: Add check to see if _start symbol is defined, if not, then
	# the symbols have not yet been loaded and this command will not work.
	watch *_start
	set $break_efi_start_bpnum = $bpnum
	commands
		silent
		delete $break_efi_start_bpnum

		# Save the breakpoints here before the GRUB image is loaded
		# into memory, then delete them. Later they will be reloaded
		# once the GRUB image has been loaded. This avoids the issue
		# where the loading of the GRUB image overwrites the software
		# breakpoints, thus confusing GDB and effectively clearing
		# those breakpoints.
		save breakpoints .early-breakpoints.gdb
		delete breakpoints

		tbreak _start
		commands
			silent

			# Reload the breakpoints now that the GRUB image has
			# finished being loaded into memory.
			source .early-breakpoints.gdb

			runtime_load_module

			if $is_user_command("onstart")
				onstart
			end
			continue
		end
		continue
	end
end
document run_on_start
	On some targets, such as x86_64-efi, even if you know where the
	firmware will load the GRUB image, you can not simply set a break
	point before the image is loaded because loading the image
	overwrites the break point in memory. So setup a hardware watch
	point, which does not have that problem, and if that gets triggered,
	then reset the break point. If a user-defined command named
	"onstart" exists it will be run after the start is hit.
	NOTE: This assumes symbols have already been correctly loaded for
	the EFI application.
end

###

set confirm off

# Note: On EFI and other platforms that load GRUB to an address that is
# determined at runtime, the symbols in kernel.exec will be wrong.
# However, we must start by loading some executable file or GDB will
# fail.

set $platform_efi = $_streq("@platform@", "efi")
set $target = "@target_cpu@-@platform@"

if ! $runonce
	if $platform_efi
		# Only load the executable file, not the symbols
		exec-file kernel.exec
	else
		if $_streq($target, "i386-pc")
			add-symbol-file boot.image
			add-symbol-file diskboot.image
			add-symbol-file lzma_decompress.image
		end
		file kernel.exec
		run_on_start
		runtime_load_module
	end

	target remote :1234
	set $runonce = 1
end
