Hi All, I was debugging some problem lately and felt that I need to use debugger. As I like how JTAG debugging works I wanted to have similar feeling :). Obivious choice is to use QEMU.
QEMU provides a GDB stub that can be used to debug code running on its virtual session. I also found out that VMware also features this same feature, though it needs a bit configuration changes. Anyway... In order for GDB session to be a bit fancier you are going to need debug symbols. In order to do that we need Lubomir Rintel's patch to support debug symbol generation. (Adapted version is attached to this email). After this everything is ready in GRUB 2 building. Next steps is to improve GDB handling to support our dynamic module loader. For this Lubomir's scripts for GDB comes in to play. I adapted them a bit for new naming and after this I could nicely add breakpoint to code that gets loaded later on by GRUB module loader and it stopped nicely there on correct spot. Based on this finding I would say that we integrate following bits of code. Lubomir also create GDB stub that allows debugging on real hardware over serial cable. This is fine for me, but at this time I only need to have QEMU debugging working. And as this step is shared between those two I propose that this work is sliced to two pieces. Thanks, Vesa Jääskeläinen
Index: ChangeLog =================================================================== --- ChangeLog (revision 1999) +++ ChangeLog (working copy) @@ -1,3 +1,11 @@ +2009-02-22 Vesa Jääskeläinen <ch...@nic.fi> + + Based on patch by Lubomir Rintel <lkund...@fedoraproject.org>. + + * genmk.rb: Add new stage to compile first debug symbol version of + module and then use objcopy to generate final image to allow easier + debugging. + 2009-02-22 Robert Millan <r...@aybabtu.com> * include/multiboot.h (MULTIBOOT_INFO_ALIGN): New macro. Index: genmk.rb =================================================================== --- genmk.rb (revision 1996) +++ genmk.rb (working copy) @@ -101,10 +101,11 @@ mod_obj = mod_src.suffix('o') defsym = 'def-' + @name.suffix('lst') undsym = 'und-' + @name.suffix('lst') + exec = @name.suffix('mod.exec') mod_name = File.basename(@name, '.mod') symbolic_name = mod_name.sub(/\.[^\.]*$/, '') - "CLEANFILES += #...@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym} + "CLEANFILES += #...@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym} #{exec} ifneq ($(#{prefix}_EXPORTS),no) CLEANFILES += #{defsym} DEFSYMFILES += #{defsym} @@ -112,11 +113,14 @@ MOSTLYCLEANFILES += #{deps_str} UNDSYMFILES += #{undsym} -...@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) +...@name}: #{exec} + -rm -f $@ + $(OBJCOPY) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $^ $@ + +#{exec}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) -rm -f $@ $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj} if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi - $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str} -rm -f $@
# gmodule.pl - Generate GDB commands to load symbols to right addresses # GRUB -- GRand Unified Bootloader # Copyright (C) 2009 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GRUB is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see <http://www.gnu.org/licenses/>. use strict; use warnings; while (<>) { # Line we get contains section number - load address pairs # prepended by module name my ($file, %load_addr) = split; my $text = ''; # This one needs not be prepended by -s my $sections = ''; # All but .text print "add-symbol-file $file"; open (READELF, "readelf -S $file |") or die $!; while (<READELF>) { /\[\s*(\d+)\]\s+(\.\S+)/ or next; my $sec_num = $1; my $sec_name = $2; # .text section doesn't have to be prepended by -s .text if ($sec_name eq '.text') { $text = $load_addr{$sec_num}; next; } $sections .= " -s $sec_name $load_addr{$sec_num}" if ($load_addr{$sec_num} and $load_addr{$sec_num} ne '0x0'); }; close (READELF); print " $text $sections\n"; }
# grub.gdb - Macros to ease debugging of GRUB and its modules with GDB # GRUB -- GRand Unified Bootloader # Copyright (C) 2009 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GRUB is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see <http://www.gnu.org/licenses/>. # # Load debuging information about GNU GRUB 2 modules into GDB # automatically. Needs readelf, Perl and gmodule.pl script # # Note: break_load command won't work with GDB up to 6.6 due to # bug in processing breakpoint command hooks. GDB 6.8 works fine. # # This is needed especially on Linux, so that the debugger doesn't # request special register values which we do not know about set osabi none define _cleanup shell rm -f .segments.tmp .loadsym.gdb end # Add section numbers and addresses to .segments.tmp define _dump_module_sections set $mod = $arg0 # FIXME: save logging status set logging file .segments.tmp set logging redirect on set logging overwrite off set logging on printf "%s.mod.exec", $mod->name set $segment = $mod->segment while ($segment) printf " %i 0x%x", $segment->section, $segment->addr set $segment = $segment->next end printf "\n" set logging off # FIXME: restore logging status end document _dump_module_sections Gather information about module whose mod structure was given for use with match_and_load_symbols end # Generate and execute GDB commands and delete temporary files # afterwards define _match_and_load_symbols shell perl gmodule.pl <.segments.tmp >.loadsym.gdb source .loadsym.gdb _cleanup end document _match_and_load_symbols Launch script, that matches section names with information generated by dump_module_sections and load debugging info apropriately end define load_module _cleanup _dump_module_sections $arg0 _match_and_load_symbols end document load_module Load debugging information for module given as argument. end define load_modules _cleanup set $this = grub_dl_head while ($this != 0) _dump_module_sections $this->mod set $this = $this->next end _match_and_load_symbols end document load_modules Load debugging information for all loaded modules. end define load_kernel file kernel.exec end document load_kernel Load debugging information for kernel. end define break_load # Load debugging symbols for module when it's loaded break grub_dl_ref commands load_module mod cont end end document break_load Make modules load automatically. end
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel