6f1e3d5
From 37e08ec93e219ece7547b3d4bdbd594eb691fe1a Mon Sep 17 00:00:00 2001
9d15b4d
From: Peter Jones <pjones@redhat.com>
9d15b4d
Date: Wed, 27 Jan 2016 09:22:42 -0500
6f1e3d5
Subject: [PATCH 154/198] Make grub_fatal() also backtrace.
9d15b4d
9d15b4d
---
6f1e3d5
 grub-core/Makefile.core.def     |  3 ++
9d15b4d
 grub-core/kern/misc.c           |  8 +++++-
9d15b4d
 grub-core/lib/arm64/backtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++
9d15b4d
 grub-core/lib/backtrace.c       |  2 ++
9d15b4d
 grub-core/lib/i386/backtrace.c  | 14 +++++++++-
6f1e3d5
 5 files changed, 87 insertions(+), 2 deletions(-)
9d15b4d
 create mode 100644 grub-core/lib/arm64/backtrace.c
9d15b4d
9d15b4d
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
6f1e3d5
index 75a7ab344..3a5d450f3 100644
9d15b4d
--- a/grub-core/Makefile.core.def
9d15b4d
+++ b/grub-core/Makefile.core.def
6f1e3d5
@@ -175,6 +175,9 @@ kernel = {
9d15b4d
 
9d15b4d
   softdiv = lib/division.c;
9d15b4d
 
9d15b4d
+  x86 = lib/i386/backtrace.c;
9d15b4d
+  x86 = lib/backtrace.c;
9d15b4d
+
9d15b4d
   i386 = kern/i386/dl.c;
9d15b4d
   i386_xen = kern/i386/dl.c;
9d15b4d
 
9d15b4d
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
6f1e3d5
index f1fab7000..5ce89a40c 100644
9d15b4d
--- a/grub-core/kern/misc.c
9d15b4d
+++ b/grub-core/kern/misc.c
9d15b4d
@@ -24,6 +24,7 @@
9d15b4d
 #include <grub/term.h>
9d15b4d
 #include <grub/env.h>
9d15b4d
 #include <grub/i18n.h>
9d15b4d
+#include <grub/backtrace.h>
9d15b4d
 
9d15b4d
 union printf_arg
9d15b4d
 {
6f1e3d5
@@ -1101,8 +1102,13 @@ grub_xasprintf (const char *fmt, ...)
9d15b4d
 static void __attribute__ ((noreturn))
9d15b4d
 grub_abort (void)
9d15b4d
 {
9d15b4d
+#ifndef GRUB_UTIL
6f1e3d5
+#if defined(__i386__) || defined(__x86_64__)
9d15b4d
+  grub_backtrace();
9d15b4d
+#endif
9d15b4d
+#endif
9d15b4d
   grub_printf ("\nAborted.");
9d15b4d
-  
9d15b4d
+
9d15b4d
 #ifndef GRUB_UTIL
9d15b4d
   if (grub_term_inputs)
9d15b4d
 #endif
9d15b4d
diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c
9d15b4d
new file mode 100644
bc092b9
index 000000000..1079b5380
9d15b4d
--- /dev/null
9d15b4d
+++ b/grub-core/lib/arm64/backtrace.c
9d15b4d
@@ -0,0 +1,62 @@
9d15b4d
+/*
9d15b4d
+ *  GRUB  --  GRand Unified Bootloader
9d15b4d
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
9d15b4d
+ *
9d15b4d
+ *  GRUB is free software: you can redistribute it and/or modify
9d15b4d
+ *  it under the terms of the GNU General Public License as published by
9d15b4d
+ *  the Free Software Foundation, either version 3 of the License, or
9d15b4d
+ *  (at your option) any later version.
9d15b4d
+ *
9d15b4d
+ *  GRUB is distributed in the hope that it will be useful,
9d15b4d
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9d15b4d
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9d15b4d
+ *  GNU General Public License for more details.
9d15b4d
+ *
9d15b4d
+ *  You should have received a copy of the GNU General Public License
9d15b4d
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
9d15b4d
+ */
9d15b4d
+
9d15b4d
+#include <grub/misc.h>
9d15b4d
+#include <grub/command.h>
9d15b4d
+#include <grub/err.h>
9d15b4d
+#include <grub/dl.h>
9d15b4d
+#include <grub/mm.h>
9d15b4d
+#include <grub/term.h>
9d15b4d
+#include <grub/backtrace.h>
9d15b4d
+
9d15b4d
+#define MAX_STACK_FRAME 102400
9d15b4d
+
9d15b4d
+void
9d15b4d
+grub_backtrace_pointer (int frame)
9d15b4d
+{
9d15b4d
+  while (1)
9d15b4d
+    {
9d15b4d
+      void *lp = __builtin_return_address (frame);
9d15b4d
+      if (!lp)
9d15b4d
+	break;
9d15b4d
+
9d15b4d
+      lp = __builtin_extract_return_addr (lp);
9d15b4d
+
9d15b4d
+      grub_printf ("%p: ", lp);
9d15b4d
+      grub_backtrace_print_address (lp);
9d15b4d
+      grub_printf (" (");
9d15b4d
+      for (i = 0; i < 2; i++)
9d15b4d
+	grub_printf ("%p,", ((void **)ptr) [i + 2]);
9d15b4d
+      grub_printf ("%p)\n", ((void **)ptr) [i + 2]);
9d15b4d
+      nptr = *(void **)ptr;
9d15b4d
+      if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME
9d15b4d
+	  || nptr == ptr)
9d15b4d
+	{
9d15b4d
+	  grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr);
9d15b4d
+	  break;
9d15b4d
+	}
9d15b4d
+      ptr = nptr;
9d15b4d
+    }
9d15b4d
+}
9d15b4d
+
9d15b4d
+void
9d15b4d
+grub_backtrace (void)
9d15b4d
+{
9d15b4d
+  grub_backtrace_pointer (1);
9d15b4d
+}
9d15b4d
+
9d15b4d
diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c
6f1e3d5
index 825a8800e..c0ad6ab8b 100644
9d15b4d
--- a/grub-core/lib/backtrace.c
9d15b4d
+++ b/grub-core/lib/backtrace.c
9d15b4d
@@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
9d15b4d
 void
9d15b4d
 grub_backtrace_print_address (void *addr)
9d15b4d
 {
9d15b4d
+#ifndef GRUB_UTIL
9d15b4d
   grub_dl_t mod;
9d15b4d
 
9d15b4d
   FOR_DL_MODULES (mod)
6f1e3d5
@@ -44,6 +45,7 @@ grub_backtrace_print_address (void *addr)
9d15b4d
 	}
9d15b4d
   }
da63b36
 
6f1e3d5
+#endif
9d15b4d
   grub_printf ("%p", addr);
9d15b4d
 }
6f1e3d5
 
9d15b4d
diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c
bc092b9
index c3e03c727..c67273db3 100644
9d15b4d
--- a/grub-core/lib/i386/backtrace.c
9d15b4d
+++ b/grub-core/lib/i386/backtrace.c
9d15b4d
@@ -15,11 +15,23 @@
9d15b4d
  *  You should have received a copy of the GNU General Public License
9d15b4d
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
9d15b4d
  */
9d15b4d
+#include <config.h>
9d15b4d
+#ifdef GRUB_UTIL
9d15b4d
+#define REALLY_GRUB_UTIL GRUB_UTIL
9d15b4d
+#undef GRUB_UTIL
9d15b4d
+#endif
9d15b4d
+
9d15b4d
+#include <grub/symbol.h>
9d15b4d
+#include <grub/dl.h>
9d15b4d
+
9d15b4d
+#ifdef REALLY_GRUB_UTIL
9d15b4d
+#define GRUB_UTIL REALLY_GRUB_UTIL
9d15b4d
+#undef REALLY_GRUB_UTIL
9d15b4d
+#endif
9d15b4d
 
9d15b4d
 #include <grub/misc.h>
9d15b4d
 #include <grub/command.h>
9d15b4d
 #include <grub/err.h>
9d15b4d
-#include <grub/dl.h>
9d15b4d
 #include <grub/mm.h>
9d15b4d
 #include <grub/term.h>
9d15b4d
 #include <grub/backtrace.h>
9d15b4d
-- 
da63b36
2.14.3
9d15b4d