2016-04-07 14:44:51 +00:00
|
|
|
From 5dbc4254266d8d8d64d5d2fe2ad02ff200f4a7a6 Mon Sep 17 00:00:00 2001
|
2015-07-22 14:14:34 +00:00
|
|
|
From: Peter Jones <pjones@redhat.com>
|
|
|
|
Date: Thu, 25 Jun 2015 15:11:36 -0400
|
2016-04-07 14:44:51 +00:00
|
|
|
Subject: [PATCH 10005/10006] Make a "gdb" dprintf that tells us load
|
|
|
|
addresses.
|
2015-07-22 14:14:34 +00:00
|
|
|
|
|
|
|
This makes a grub_dprintf() call during platform init and during module
|
|
|
|
loading that tells us the virtual addresses of the .text and .data
|
|
|
|
sections of grub-core/kernel.exec and any modules it loads.
|
|
|
|
|
|
|
|
Specifically, it displays them in the gdb "add-symbol-file" syntax, with
|
|
|
|
the presumption that there's a variable $grubdir that reflects the path
|
|
|
|
to any such binaries.
|
|
|
|
|
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
|
---
|
|
|
|
grub-core/kern/dl.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
grub-core/kern/efi/efi.c | 5 +++--
|
|
|
|
grub-core/kern/efi/init.c | 26 +++++++++++++++++++++++-
|
|
|
|
include/grub/efi/efi.h | 2 +-
|
|
|
|
4 files changed, 81 insertions(+), 4 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
2016-04-07 14:44:51 +00:00
|
|
|
index 247cd0a..f29691c 100644
|
2015-07-22 14:14:34 +00:00
|
|
|
--- a/grub-core/kern/dl.c
|
|
|
|
+++ b/grub-core/kern/dl.c
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -457,6 +457,24 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name)
|
2015-07-22 14:14:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static long
|
|
|
|
+grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
|
|
|
|
+{
|
|
|
|
+ Elf_Shdr *s;
|
|
|
|
+ const char *str;
|
|
|
|
+ unsigned i;
|
|
|
|
+
|
|
|
|
+ s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
|
|
|
|
+ str = (char *) e + s->sh_offset;
|
|
|
|
+
|
|
|
|
+ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
|
|
|
+ i < e->e_shnum;
|
|
|
|
+ i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
|
|
|
+ if (grub_strcmp (str + s->sh_name, name) == 0)
|
|
|
|
+ return (long)i;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Me, Vladimir Serbinenko, hereby I add this module check as per new
|
|
|
|
GNU module policy. Note that this license check is informative only.
|
|
|
|
Modules have to be licensed under GPLv3 or GPLv3+ (optionally
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -600,6 +618,38 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
2015-07-22 14:14:34 +00:00
|
|
|
return GRUB_ERR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e)
|
|
|
|
+{
|
|
|
|
+ void *text, *data = NULL;
|
|
|
|
+ long idx;
|
|
|
|
+
|
|
|
|
+ idx = grub_dl_find_section_index (e, ".text");
|
|
|
|
+ if (idx < 0)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ text = grub_dl_get_section_addr (mod, idx);
|
|
|
|
+ if (!text)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ idx = grub_dl_find_section_index (e, ".data");
|
|
|
|
+ if (idx >= 0)
|
|
|
|
+ data = grub_dl_get_section_addr (mod, idx);
|
|
|
|
+
|
|
|
|
+ if (data)
|
|
|
|
+ grub_qdprintf ("gdb", "add-symbol-file \\\n"
|
|
|
|
+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug "
|
|
|
|
+ "\\\n %p -s .data %p\n",
|
|
|
|
+ GRUB_TARGET_CPU, GRUB_PLATFORM,
|
|
|
|
+ mod->name, text, data);
|
|
|
|
+ else
|
|
|
|
+ grub_qdprintf ("gdb", "add-symbol-file \\\n"
|
|
|
|
+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug "
|
|
|
|
+ "\\\n%p\n",
|
|
|
|
+ GRUB_TARGET_CPU, GRUB_PLATFORM,
|
|
|
|
+ mod->name, text);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Load a module from core memory. */
|
|
|
|
grub_dl_t
|
|
|
|
grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -658,6 +708,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
2015-07-22 14:14:34 +00:00
|
|
|
grub_dprintf ("modules", "module name: %s\n", mod->name);
|
|
|
|
grub_dprintf ("modules", "init function: %p\n", mod->init);
|
|
|
|
|
|
|
|
+ grub_dl_print_gdb_info (mod, e);
|
|
|
|
+
|
|
|
|
if (grub_dl_add (mod))
|
|
|
|
{
|
|
|
|
grub_dl_unload (mod);
|
|
|
|
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
2016-04-07 14:44:51 +00:00
|
|
|
index 101307f..7492f9d 100644
|
2015-07-22 14:14:34 +00:00
|
|
|
--- a/grub-core/kern/efi/efi.c
|
|
|
|
+++ b/grub-core/kern/efi/efi.c
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -274,7 +274,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
2015-07-22 14:14:34 +00:00
|
|
|
/* 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_pe32_header *header;
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -288,6 +288,7 @@ grub_efi_modules_addr (void)
|
2015-07-22 14:14:34 +00:00
|
|
|
if (! image)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
+
|
|
|
|
header = image->image_base;
|
|
|
|
coff_header = &(header->coff_header);
|
|
|
|
sections
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -299,7 +300,7 @@ grub_efi_modules_addr (void)
|
2015-07-22 14:14:34 +00:00
|
|
|
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
|
2016-04-07 14:44:51 +00:00
|
|
|
index a5b6c1d..9939fde 100644
|
2015-07-22 14:14:34 +00:00
|
|
|
--- a/grub-core/kern/efi/init.c
|
|
|
|
+++ b/grub-core/kern/efi/init.c
|
|
|
|
@@ -59,10 +59,33 @@ grub_efi_env_init (void)
|
|
|
|
grub_free (envblk_s.buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+grub_efi_print_gdb_info (void)
|
|
|
|
+{
|
|
|
|
+ grub_addr_t text;
|
|
|
|
+ grub_addr_t data;
|
|
|
|
+
|
|
|
|
+ text = grub_efi_section_addr (".text");
|
|
|
|
+ if (!text)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ data = grub_efi_section_addr (".data");
|
|
|
|
+ if (data)
|
|
|
|
+ grub_qdprintf ("gdb",
|
|
|
|
+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/"
|
|
|
|
+ "kernel.exec %p -s .data %p\n",
|
|
|
|
+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text, (void *)data);
|
|
|
|
+ else
|
|
|
|
+ grub_qdprintf ("gdb",
|
|
|
|
+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/"
|
|
|
|
+ "kernel.exec %p\n",
|
|
|
|
+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
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 ();
|
|
|
|
@@ -74,6 +97,7 @@ grub_efi_init (void)
|
|
|
|
0, 0, 0, NULL);
|
|
|
|
|
|
|
|
grub_efi_env_init ();
|
|
|
|
+ grub_efi_print_gdb_info ();
|
|
|
|
grub_efidisk_init ();
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
2016-04-07 14:44:51 +00:00
|
|
|
index 9a2da0e..37d57d8 100644
|
2015-07-22 14:14:34 +00:00
|
|
|
--- a/include/grub/efi/efi.h
|
|
|
|
+++ b/include/grub/efi/efi.h
|
2016-04-07 14:44:51 +00:00
|
|
|
@@ -84,7 +84,7 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
|
2015-07-22 14:14:34 +00:00
|
|
|
char **device,
|
|
|
|
char **path);
|
|
|
|
|
|
|
|
-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);
|
|
|
|
--
|
2016-04-07 14:44:51 +00:00
|
|
|
2.5.0
|
2015-07-22 14:14:34 +00:00
|
|
|
|