grub2/0110-Make-grub_fatal-dump-a...

180 lines
4.7 KiB
Diff

From fe5b4ca9a6a76f4695e96736b0ff8f6c26cc96c5 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 27 Jan 2016 09:22:42 -0500
Subject: [PATCH 110/225] Make grub_fatal() dump a backtrace.
This also adds a grub_backtrace() implementation for ARM AArch64.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/Makefile.core.def | 4 +++
grub-core/kern/misc.c | 8 +++++-
grub-core/lib/arm64/backtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++
grub-core/lib/backtrace.c | 2 ++
grub-core/lib/i386/backtrace.c | 14 +++++++++-
5 files changed, 88 insertions(+), 2 deletions(-)
create mode 100644 grub-core/lib/arm64/backtrace.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 2c1d62cee..540955519 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -175,6 +175,10 @@ kernel = {
softdiv = lib/division.c;
+ arm64 = lib/arm64/backtrace.c;
+ x86 = lib/i386/backtrace.c;
+ x86 = lib/backtrace.c;
+
i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index 2656a670e..f4461451a 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -24,6 +24,7 @@
#include <grub/term.h>
#include <grub/env.h>
#include <grub/i18n.h>
+#include <grub/backtrace.h>
union printf_arg
{
@@ -1088,8 +1089,13 @@ grub_xasprintf (const char *fmt, ...)
static void __attribute__ ((noreturn))
grub_abort (void)
{
+#ifndef GRUB_UTIL
+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
+ grub_backtrace();
+#endif
+#endif
grub_printf ("\nAborted.");
-
+
#ifndef GRUB_UTIL
if (grub_term_inputs)
#endif
diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c
new file mode 100644
index 000000000..1079b5380
--- /dev/null
+++ b/grub-core/lib/arm64/backtrace.c
@@ -0,0 +1,62 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/backtrace.h>
+
+#define MAX_STACK_FRAME 102400
+
+void
+grub_backtrace_pointer (int frame)
+{
+ while (1)
+ {
+ void *lp = __builtin_return_address (frame);
+ if (!lp)
+ break;
+
+ lp = __builtin_extract_return_addr (lp);
+
+ grub_printf ("%p: ", lp);
+ grub_backtrace_print_address (lp);
+ grub_printf (" (");
+ for (i = 0; i < 2; i++)
+ grub_printf ("%p,", ((void **)ptr) [i + 2]);
+ grub_printf ("%p)\n", ((void **)ptr) [i + 2]);
+ nptr = *(void **)ptr;
+ if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME
+ || nptr == ptr)
+ {
+ grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr);
+ break;
+ }
+ ptr = nptr;
+ }
+}
+
+void
+grub_backtrace (void)
+{
+ grub_backtrace_pointer (1);
+}
+
diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c
index 825a8800e..8659d00e0 100644
--- a/grub-core/lib/backtrace.c
+++ b/grub-core/lib/backtrace.c
@@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
void
grub_backtrace_print_address (void *addr)
{
+#ifndef GRUB_UTIL
grub_dl_t mod;
FOR_DL_MODULES (mod)
@@ -43,6 +44,7 @@ grub_backtrace_print_address (void *addr)
return;
}
}
+#endif
grub_printf ("%p", addr);
}
diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c
index c3e03c727..c67273db3 100644
--- a/grub-core/lib/i386/backtrace.c
+++ b/grub-core/lib/i386/backtrace.c
@@ -15,11 +15,23 @@
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
+#ifdef GRUB_UTIL
+#define REALLY_GRUB_UTIL GRUB_UTIL
+#undef GRUB_UTIL
+#endif
+
+#include <grub/symbol.h>
+#include <grub/dl.h>
+
+#ifdef REALLY_GRUB_UTIL
+#define GRUB_UTIL REALLY_GRUB_UTIL
+#undef REALLY_GRUB_UTIL
+#endif
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/err.h>
-#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/term.h>
#include <grub/backtrace.h>
--
2.14.3