From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1q4Zti-0002Sb-K8 for mharc-grub-devel@gnu.org; Thu, 01 Jun 2023 00:26:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4Zth-0002SS-QI for grub-devel@gnu.org; Thu, 01 Jun 2023 00:26:49 -0400 Received: from mail-qt1-x836.google.com ([2607:f8b0:4864:20::836]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q4Zte-00084O-PG for grub-devel@gnu.org; Thu, 01 Jun 2023 00:26:49 -0400 Received: by mail-qt1-x836.google.com with SMTP id d75a77b69052e-3f8008cb772so2898411cf.3 for ; Wed, 31 May 2023 21:26:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficientek-com.20221208.gappssmtp.com; s=20221208; t=1685593605; x=1688185605; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=iBc1u6XlixesG4tR45aElXzFlukFmSewETv1suQO5Yg=; b=DbMWB1oX8fZnb59VGnkVKQBQUWTj7xulCsiN3UELPkTkCdQoQmI7DpukutM0KvwOQ7 QVzibPBAtPlq3QSvtmFn4N6jPHCd4qGl6O5uQoIpkBt/jHJA+TfZkKMdRLdG80447qpY s9T55BXCsAOGZ5jpfA+57FWNFLAvna6r68BUvP4L6nYVfujaR4wQHr6fEwEnMgdovhJe optMGSgA5LN737YDw3+/V1CrJH2o+UO5M8E+RLCzPYTh9vwfWaa63ML+9lzzvGRezrsc N837HB0HFO8cv31K2PYIk0S9wi13Q85AzqhM9BEdNa3e06zAqP8ci11jfSOrbKeYeTgv K07g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685593605; x=1688185605; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=iBc1u6XlixesG4tR45aElXzFlukFmSewETv1suQO5Yg=; b=On3KQPfW5Vo7CclxR1sL9A9+sKsHYRy0JvccqcRGr/Hr46Ccw/p0ridINHOypRbJwX 1mFD701H5bHDlSMFyKNinFgSE2zsIC9IKrba8F4Af+638eOYN6ZOcud3GkomZz+DT8os PnUL8L0XA162q8AeN/MSbMeerTDuUBvsmokNV+eTjMs7PaFmsYX7wZ9lJVDnCYMBnSIw Hw7LhpA60MBR1Bcin4qBpiwfiku+BSDv2oldEGelGtNmNlSA3nmSYlKkje0HQIMjnkKW R/alCA4iA8mkiB4II6NtFy4XWM6Xsnzy6/98VZJqLYJTTWjuQ3u+2XgkQ9O8kJw00ecc a9Xg== X-Gm-Message-State: AC+VfDzwZxKn5pA2pUyguQtSZ4Yi8ZLiFqycYup2qiVqhPj2E/JUnMFv Xi0kuXH7Y4WGjL0YvxdR8fA0kXE/mPpD7DaAFrM= X-Google-Smtp-Source: ACHHUZ7Ql/99yi54MbEji0aL7bfgWYQSNGNo5L2p+DHHrlewgdVwCxPTx7B5BA85nm0iideNqyhXJA== X-Received: by 2002:ac8:4e42:0:b0:3ef:62f7:899b with SMTP id e2-20020ac84e42000000b003ef62f7899bmr8291416qtw.57.1685593604741; Wed, 31 May 2023 21:26:44 -0700 (PDT) Received: from localhost.localdomain ([199.58.83.12]) by smtp.gmail.com with ESMTPSA id j21-20020ac85f95000000b003f6b8a6fd18sm7077971qta.96.2023.05.31.21.26.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 May 2023 21:26:43 -0700 (PDT) From: Glenn Washburn To: grub-devel@gnu.org, Daniel Kiper Cc: Peter Jones , Glenn Washburn Subject: [PATCH v3] gdb: Add gdbinfo command for printing the load address of the EFI application Date: Wed, 31 May 2023 23:25:55 -0500 Message-Id: <20230601042555.123968-1-development@efficientek.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::836; envelope-from=development@efficientek.com; helo=mail-qt1-x836.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Jun 2023 04:26:50 -0000 EFI firmware determines where to load the GRUB EFI at runtime, and so the addresses of debug symbols are not known ahead of time. There is a command defined in the gdb_grub script which will load the debug symbols at the appropriate addresses, if given the application load address for GRUB. So add a command named "gdbinfo" to allow the user to print this GDB command string with the application load address on-demand. For the outputted GDB command to have any effect when entered into a GDB session, GDB should have been started with the script as an argument to the -x option or sourced into an active GDB session before running the outputted command. Documentation for the gdbinfo command is also added. Co-developed-by: Peter Jones Signed-off-by: Peter Jones Signed-off-by: Glenn Washburn --- Changes since v3: * Remove duplicate "given" in commit message * Allow command even in lockdown mode Changes since v2: * rebase onto master Glenn --- Range-diff against v2: 1: 1d438175061f ! 1: a609424466cd gdb: Add gdbinfo command for printing the load address of the EFI application @@ Commit message EFI firmware determines where to load the GRUB EFI at runtime, and so the addresses of debug symbols are not known ahead of time. There is a command defined in the gdb_grub script which will load the debug symbols at the - appropriate addresses, if given given the application load address for GRUB. + appropriate addresses, if given the application load address for GRUB. So add a command named "gdbinfo" to allow the user to print this GDB command string with the application load address on-demand. For the outputted GDB command to have any effect when entered into a GDB session, GDB should have @@ grub-core/kern/efi/debug.c (new) +void +grub_efi_register_debug_commands (void) +{ -+ grub_register_command_lockdown ("gdbinfo", grub_cmd_gdbinfo, 0, -+ N_("Print infomation useful for GDB debugging")); ++ grub_register_command ("gdbinfo", grub_cmd_gdbinfo, 0, ++ N_("Print infomation useful for GDB debugging")); +} ## grub-core/kern/efi/efi.c ## @@ grub-core/kern/efi/init.c: grub_addr_t grub_modbase; messages. */ grub_console_init (); @@ grub-core/kern/efi/init.c: grub_efi_init (void) - 0, 0, 0, NULL); + grub_efi_system_table->boot_services->set_watchdog_timer (0, 0, 0, NULL); grub_efidisk_init (); + @@ include/grub/efi/debug.h (new) +#endif /* ! GRUB_EFI_DEBUG_HEADER */ ## include/grub/efi/efi.h ## -@@ include/grub/efi/efi.h: grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, +@@ include/grub/efi/efi.h: 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); - #endif -grub_addr_t grub_efi_modules_addr (void); +grub_addr_t grub_efi_section_addr (const char *section); docs/grub.texi | 13 ++++++++++++ grub-core/Makefile.core.def | 1 + grub-core/kern/efi/debug.c | 38 ++++++++++++++++++++++++++++++++++ grub-core/kern/efi/efi.c | 4 ++-- grub-core/kern/efi/init.c | 5 ++++- include/grub/efi/debug.h | 41 +++++++++++++++++++++++++++++++++++++ include/grub/efi/efi.h | 2 +- 7 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 grub-core/kern/efi/debug.c create mode 100644 include/grub/efi/debug.h diff --git a/docs/grub.texi b/docs/grub.texi index 7ab1e0ab40ef..5fb074f66869 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4301,6 +4301,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 @@ -4833,6 +4834,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 04549e868591..784f0a2136c2 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 000000000000..5d2ab1a36ff4 --- /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 0e1ccf65ad2e..974fed8cb55c 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -303,7 +303,7 @@ grub_efi_get_variable (const char *var, const grub_efi_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; @@ -332,7 +332,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 e873ef5298ff..ae8c2e1e499b 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 000000000000..c2d2a03b06f1 --- /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 7071b8dc9783..5ec5af71eeb6 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -127,7 +127,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); -- 2.34.1