c789522
From 030095a01a205aba04a0849ac0c0329ac429a9ed Mon Sep 17 00:00:00 2001
f4c76c0
From: Peter Jones <pjones@redhat.com>
f4c76c0
Date: Thu, 25 Jun 2015 15:11:36 -0400
63f1a98
Subject: [PATCH 214/250] Make a "gdb" dprintf that tells us load addresses.
f4c76c0
f4c76c0
This makes a grub_dprintf() call during platform init and during module
f4c76c0
loading that tells us the virtual addresses of the .text and .data
f4c76c0
sections of grub-core/kernel.exec and any modules it loads.
f4c76c0
f4c76c0
Specifically, it displays them in the gdb "add-symbol-file" syntax, with
f4c76c0
the presumption that there's a variable $grubdir that reflects the path
f4c76c0
to any such binaries.
f4c76c0
f4c76c0
Signed-off-by: Peter Jones <pjones@redhat.com>
f4c76c0
---
bc092b9
 grub-core/kern/dl.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
bc092b9
 grub-core/kern/efi/efi.c  |  4 ++--
f4c76c0
 grub-core/kern/efi/init.c | 26 +++++++++++++++++++++++-
f4c76c0
 include/grub/efi/efi.h    |  2 +-
bc092b9
 4 files changed, 78 insertions(+), 4 deletions(-)
f4c76c0
f4c76c0
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
78e1a10
index 5028d157c46..eb8b969cded 100644
f4c76c0
--- a/grub-core/kern/dl.c
f4c76c0
+++ b/grub-core/kern/dl.c
78e1a10
@@ -501,6 +501,23 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name)
bc092b9
       return s;
f4c76c0
   return NULL;
f4c76c0
 }
f4c76c0
+static long
f4c76c0
+grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
f4c76c0
+{
f4c76c0
+  Elf_Shdr *s;
f4c76c0
+  const char *str;
f4c76c0
+  unsigned i;
f4c76c0
+
f4c76c0
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
f4c76c0
+  str = (char *) e + s->sh_offset;
f4c76c0
+
f4c76c0
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
f4c76c0
+       i < e->e_shnum;
f4c76c0
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
f4c76c0
+    if (grub_strcmp (str + s->sh_name, name) == 0)
f4c76c0
+      return (long)i;
f4c76c0
+  return -1;
f4c76c0
+}
bc092b9
 
f4c76c0
 /* Me, Vladimir Serbinenko, hereby I add this module check as per new
f4c76c0
    GNU module policy. Note that this license check is informative only.
78e1a10
@@ -644,6 +661,37 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
bc092b9
 
f4c76c0
   return GRUB_ERR_NONE;
f4c76c0
 }
f4c76c0
+static void
f4c76c0
+grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e)
f4c76c0
+{
f4c76c0
+  void *text, *data = NULL;
f4c76c0
+  long idx;
f4c76c0
+
f4c76c0
+  idx = grub_dl_find_section_index (e, ".text");
f4c76c0
+  if (idx < 0)
f4c76c0
+    return;
f4c76c0
+
f4c76c0
+  text = grub_dl_get_section_addr (mod, idx);
f4c76c0
+  if (!text)
f4c76c0
+    return;
f4c76c0
+
f4c76c0
+  idx = grub_dl_find_section_index (e, ".data");
f4c76c0
+  if (idx >= 0)
f4c76c0
+    data = grub_dl_get_section_addr (mod, idx);
f4c76c0
+
f4c76c0
+  if (data)
f4c76c0
+    grub_qdprintf ("gdb", "add-symbol-file \\\n"
f4c76c0
+		          "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug "
f4c76c0
+			  "\\\n %p -s .data %p\n",
f4c76c0
+		  GRUB_TARGET_CPU, GRUB_PLATFORM,
f4c76c0
+		  mod->name, text, data);
f4c76c0
+  else
f4c76c0
+    grub_qdprintf ("gdb", "add-symbol-file \\\n"
f4c76c0
+			   "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug "
f4c76c0
+			   "\\\n%p\n",
f4c76c0
+		  GRUB_TARGET_CPU, GRUB_PLATFORM,
f4c76c0
+		  mod->name, text);
f4c76c0
+}
bc092b9
 
f4c76c0
 /* Load a module from core memory.  */
f4c76c0
 grub_dl_t
78e1a10
@@ -703,6 +751,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
f4c76c0
   grub_dprintf ("modules", "module name: %s\n", mod->name);
f4c76c0
   grub_dprintf ("modules", "init function: %p\n", mod->init);
f4c76c0
 
f4c76c0
+  grub_dl_print_gdb_info (mod, e);
f4c76c0
+
f4c76c0
   if (grub_dl_add (mod))
f4c76c0
     {
f4c76c0
       grub_dl_unload (mod);
f4c76c0
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
78e1a10
index 91f75fdb89a..621251242e1 100644
f4c76c0
--- a/grub-core/kern/efi/efi.c
f4c76c0
+++ b/grub-core/kern/efi/efi.c
1713515
@@ -274,7 +274,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
f4c76c0
 /* Search the mods section from the PE32/PE32+ image. This code uses
f4c76c0
    a PE32 header, but should work with PE32+ as well.  */
f4c76c0
 grub_addr_t
f4c76c0
-grub_efi_modules_addr (void)
f4c76c0
+grub_efi_section_addr (const char *section_name)
f4c76c0
 {
f4c76c0
   grub_efi_loaded_image_t *image;
f4c76c0
   struct grub_pe32_header *header;
bc092b9
@@ -299,7 +299,7 @@ grub_efi_modules_addr (void)
f4c76c0
        i < coff_header->num_sections;
f4c76c0
        i++, section++)
f4c76c0
     {
f4c76c0
-      if (grub_strcmp (section->name, "mods") == 0)
f4c76c0
+      if (grub_strcmp (section->name, section_name) == 0)
f4c76c0
 	break;
f4c76c0
     }
f4c76c0
 
f4c76c0
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
78e1a10
index f7782b6e114..79243b364a1 100644
f4c76c0
--- a/grub-core/kern/efi/init.c
f4c76c0
+++ b/grub-core/kern/efi/init.c
f4c76c0
@@ -59,10 +59,33 @@ grub_efi_env_init (void)
f4c76c0
   grub_free (envblk_s.buf);
f4c76c0
 }
f4c76c0
 
f4c76c0
+static void
f4c76c0
+grub_efi_print_gdb_info (void)
f4c76c0
+{
f4c76c0
+  grub_addr_t text;
f4c76c0
+  grub_addr_t data;
f4c76c0
+
f4c76c0
+  text = grub_efi_section_addr (".text");
f4c76c0
+  if (!text)
f4c76c0
+    return;
f4c76c0
+
f4c76c0
+  data = grub_efi_section_addr (".data");
f4c76c0
+  if (data)
f4c76c0
+    grub_qdprintf ("gdb",
f4c76c0
+		  "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/"
f4c76c0
+		  "kernel.exec %p -s .data %p\n",
f4c76c0
+		  GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text, (void *)data);
f4c76c0
+  else
f4c76c0
+    grub_qdprintf ("gdb",
f4c76c0
+		  "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/"
f4c76c0
+		  "kernel.exec %p\n",
f4c76c0
+		  GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text);
f4c76c0
+}
f4c76c0
+
f4c76c0
 void
f4c76c0
 grub_efi_init (void)
f4c76c0
 {
f4c76c0
-  grub_modbase = grub_efi_modules_addr ();
f4c76c0
+  grub_modbase = grub_efi_section_addr ("mods");
f4c76c0
   /* First of all, initialize the console so that GRUB can display
f4c76c0
      messages.  */
f4c76c0
   grub_console_init ();
f4c76c0
@@ -74,6 +97,7 @@ grub_efi_init (void)
f4c76c0
 	      0, 0, 0, NULL);
f4c76c0
 
f4c76c0
   grub_efi_env_init ();
f4c76c0
+  grub_efi_print_gdb_info ();
f4c76c0
   grub_efidisk_init ();
f4c76c0
 }
f4c76c0
 
f4c76c0
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
78e1a10
index 68326d96f5a..6702b312040 100644
f4c76c0
--- a/include/grub/efi/efi.h
f4c76c0
+++ b/include/grub/efi/efi.h
78e1a10
@@ -126,7 +126,7 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
bc092b9
 void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
bc092b9
 #endif
f4c76c0
 
f4c76c0
-grub_addr_t grub_efi_modules_addr (void);
f4c76c0
+grub_addr_t grub_efi_section_addr (const char *section);
f4c76c0
 
f4c76c0
 void grub_efi_mm_init (void);
f4c76c0
 void grub_efi_mm_fini (void);
f4c76c0
-- 
63f1a98
2.14.3
f4c76c0