diff --git a/docs/grub.texi b/docs/grub.texi index 058b0eaaf..9b58886a9 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4324,6 +4324,7 @@ you forget a command, you can run the command @command{help} * export:: Export an environment variable * false:: Do nothing, unsuccessfully * fwsetup:: Reboot into the firmware setup menu +* gdbinfo:: Provide info for debugging with GDB * gettext:: Translate a string * gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer @@ -4856,6 +4857,18 @@ exit successfully if so. @end deffn +@node gdbinfo +@subsection gdbinfo + +@deffn Command gdbinfo +Output text to be used as a GDB command for a GDB session using the gdb_grub +script and attached to a running GRUB instance. The GDB command that is +output will tell GDB how to load debugging symbols to their proper runtime +address. Currently this is only available for EFI platforms. See the Debugging +in the developer documentation for more information. +@end deffn + + @node gettext @subsection gettext diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index a8c0c4a52..e458aa665 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -211,6 +211,7 @@ kernel = { efi = disk/efi/efidisk.c; efi = kern/efi/efi.c; + efi = kern/efi/debug.c; efi = kern/efi/init.c; efi = kern/efi/mm.c; efi = term/efi/console.c; diff --git a/grub-core/kern/efi/debug.c b/grub-core/kern/efi/debug.c new file mode 100644 index 000000000..5d2ab1a36 --- /dev/null +++ b/grub-core/kern/efi/debug.c @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 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 . + */ +/* debug.c - aides for debugging the EFI application */ + +#include +#include +#include + +static grub_err_t +grub_cmd_gdbinfo (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_efi_print_gdb_info (); + return 0; +} + +void +grub_efi_register_debug_commands (void) +{ + grub_register_command ("gdbinfo", grub_cmd_gdbinfo, 0, + N_("Print infomation useful for GDB debugging")); +} diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index f54fdcacd..a2afd8de9 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -320,7 +320,7 @@ grub_efi_get_variable (const char *var, const grub_guid_t *guid, /* Search the mods section from the PE32/PE32+ image. This code uses a PE32 header, but should work with PE32+ as well. */ grub_addr_t -grub_efi_modules_addr (void) +grub_efi_section_addr (const char *section_name) { grub_efi_loaded_image_t *image; struct grub_msdos_image_header *header; @@ -349,7 +349,7 @@ grub_efi_modules_addr (void) i < coff_header->num_sections; i++, section++) { - if (grub_strcmp (section->name, "mods") == 0) + if (grub_strcmp (section->name, section_name) == 0) break; } diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 8a9c838c0..6fe1ff8c8 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -104,7 +105,7 @@ grub_addr_t grub_modbase; void grub_efi_init (void) { - grub_modbase = grub_efi_modules_addr (); + grub_modbase = grub_efi_section_addr ("mods"); /* First of all, initialize the console so that GRUB can display messages. */ grub_console_init (); @@ -127,6 +128,8 @@ grub_efi_init (void) grub_efi_system_table->boot_services->set_watchdog_timer (0, 0, 0, NULL); grub_efidisk_init (); + + grub_efi_register_debug_commands (); } void (*grub_efi_net_config) (grub_efi_handle_t hnd, diff --git a/include/grub/efi/debug.h b/include/grub/efi/debug.h new file mode 100644 index 000000000..c2d2a03b0 --- /dev/null +++ b/include/grub/efi/debug.h @@ -0,0 +1,41 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 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 . + */ +/* debug.h - declare variables and functions for EFI debugging support */ + +#ifndef GRUB_EFI_DEBUG_HEADER +#define GRUB_EFI_DEBUG_HEADER 1 + +#include +#include + + +void grub_efi_register_debug_commands (void); + +static inline void +grub_efi_print_gdb_info (void) +{ + grub_addr_t text; + + text = grub_efi_section_addr (".text"); + if (!text) + return; + + grub_printf ("dynamic_load_symbols %p\n", (void *)text); +} + +#endif /* ! GRUB_EFI_DEBUG_HEADER */ diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index cd977cbbc..572f7135f 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -129,7 +129,7 @@ grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file, grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, char *args); -grub_addr_t grub_efi_modules_addr (void); +grub_addr_t grub_efi_section_addr (const char *section); void grub_efi_mm_init (void); void grub_efi_mm_fini (void);