1 Star 0 Fork 71

dingwei / grub2

forked from src-openEuler / grub2 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0100-make-better-backtraces.patch 29.09 KB
一键复制 编辑 原始数据 按行查看 历史
hanzj0122_admin 提交于 2020-07-29 20:47 . update to 2.04
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
From 69fbc18e0758e780236f713b579a951551d7e829 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 Jul 2019 17:05:03 +0200
Subject: [PATCH 100/220] make better backtraces
Signed-off-by: Peter Jones <pjones@redhat.com>
---
Makefile.util.def | 6 ++
grub-core/Makefile.am | 1 +
grub-core/Makefile.core.def | 16 ++---
grub-core/commands/backtrace.c | 72 +++++++++++++++++++
grub-core/gdb/cstub.c | 1 -
grub-core/kern/arm/efi/startup.S | 2 +
grub-core/kern/arm/startup.S | 2 +
grub-core/kern/arm64/backtrace.c | 94 +++++++++++++++++++++++++
grub-core/kern/arm64/efi/startup.S | 2 +
grub-core/kern/backtrace.c | 97 +++++++++++++++++++++++++
grub-core/kern/dl.c | 45 ++++++++++++
grub-core/kern/i386/backtrace.c | 125 +++++++++++++++++++++++++++++++++
grub-core/kern/i386/pc/init.c | 4 +-
grub-core/kern/i386/qemu/startup.S | 3 +-
grub-core/kern/ia64/efi/startup.S | 3 +-
grub-core/kern/ieee1275/init.c | 1 -
grub-core/kern/misc.c | 13 ++--
grub-core/kern/mm.c | 6 +-
grub-core/kern/sparc64/ieee1275/crt0.S | 3 +-
grub-core/lib/arm64/backtrace.c | 62 ----------------
grub-core/lib/backtrace.c | 72 -------------------
grub-core/lib/i386/backtrace.c | 78 --------------------
include/grub/backtrace.h | 10 ++-
include/grub/dl.h | 2 +
include/grub/kernel.h | 3 +
25 files changed, 485 insertions(+), 238 deletions(-)
create mode 100644 grub-core/commands/backtrace.c
create mode 100644 grub-core/kern/arm64/backtrace.c
create mode 100644 grub-core/kern/backtrace.c
create mode 100644 grub-core/kern/i386/backtrace.c
delete mode 100644 grub-core/lib/arm64/backtrace.c
delete mode 100644 grub-core/lib/backtrace.c
delete mode 100644 grub-core/lib/i386/backtrace.c
diff --git a/Makefile.util.def b/Makefile.util.def
index f55473c..c13ca68 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -49,6 +49,12 @@ library = {
common = grub-core/partmap/msdos.c;
common = grub-core/fs/proc.c;
common = grub-core/fs/archelp.c;
+ common = grub-core/kern/backtrace.c;
+
+ x86 = grub-core/kern/i386/backtrace.c;
+ i386_xen = grub-core/kern/i386/backtrace.c;
+ x86_64_xen = grub-core/kern/i386/backtrace.c;
+ arm64 = grub-core/kern/arm64/backtrace.c;
};
library = {
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 5ff3afd..d9ad300 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -66,6 +66,7 @@ CLEANFILES += grub_script.yy.c grub_script.yy.h
include $(srcdir)/Makefile.core.am
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/backtrace.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 528f76a..49c5dc4 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -140,6 +140,12 @@ kernel = {
common = kern/rescue_parser.c;
common = kern/rescue_reader.c;
common = kern/term.c;
+ common = kern/backtrace.c;
+
+ x86 = kern/i386/backtrace.c;
+ i386_xen = kern/i386/backtrace.c;
+ x86_64_xen = kern/i386/backtrace.c;
+ arm64 = kern/arm64/backtrace.c;
noemu = kern/compiler-rt.c;
noemu = kern/mm.c;
@@ -186,9 +192,6 @@ kernel = {
softdiv = lib/division.c;
- x86 = lib/i386/backtrace.c;
- x86 = lib/backtrace.c;
-
i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
i386_xen_pvh = kern/i386/dl.c;
@@ -2376,15 +2379,12 @@ module = {
module = {
name = backtrace;
- x86 = lib/i386/backtrace.c;
- i386_xen_pvh = lib/i386/backtrace.c;
- i386_xen = lib/i386/backtrace.c;
- x86_64_xen = lib/i386/backtrace.c;
- common = lib/backtrace.c;
+ common = commands/backtrace.c;
enable = x86;
enable = i386_xen_pvh;
enable = i386_xen;
enable = x86_64_xen;
+ enable = arm64;
};
module = {
diff --git a/grub-core/commands/backtrace.c b/grub-core/commands/backtrace.c
new file mode 100644
index 0000000..8b5ec39
--- /dev/null
+++ b/grub-core/commands/backtrace.c
@@ -0,0 +1,72 @@
+/*
+ * 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>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+void
+grub_backtrace_print_address (void *addr)
+{
+#ifndef GRUB_UTIL
+ grub_dl_t mod;
+
+ FOR_DL_MODULES (mod)
+ {
+ grub_dl_segment_t segment;
+ for (segment = mod->segment; segment; segment = segment->next)
+ if (segment->addr <= addr && (grub_uint8_t *) segment->addr
+ + segment->size > (grub_uint8_t *) addr)
+ {
+ grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, segment->section,
+ (grub_size_t) ((grub_uint8_t *) addr - (grub_uint8_t *) segment->addr));
+ return;
+ }
+ }
+
+#endif
+ grub_printf ("%p", addr);
+}
+
+static grub_err_t
+grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ grub_backtrace (1);
+ return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(backtrace)
+{
+ cmd = grub_register_command ("backtrace", grub_cmd_backtrace,
+ 0, N_("Print backtrace."));
+}
+
+GRUB_MOD_FINI(backtrace)
+{
+ grub_unregister_command (cmd);
+}
diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c
index b64acd7..9928147 100644
--- a/grub-core/gdb/cstub.c
+++ b/grub-core/gdb/cstub.c
@@ -215,7 +215,6 @@ grub_gdb_trap (int trap_no)
grub_printf ("Unhandled exception 0x%x at ", trap_no);
grub_backtrace_print_address ((void *) grub_gdb_regs[PC]);
grub_printf ("\n");
- grub_backtrace_pointer ((void *) grub_gdb_regs[EBP]);
grub_fatal ("Unhandled exception");
}
diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S
index 9f82653..f3bc41f 100644
--- a/grub-core/kern/arm/efi/startup.S
+++ b/grub-core/kern/arm/efi/startup.S
@@ -23,6 +23,8 @@
.file "startup.S"
.text
.arm
+ .globl start, _start
+FUNCTION(start)
FUNCTION(_start)
/*
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0.
diff --git a/grub-core/kern/arm/startup.S b/grub-core/kern/arm/startup.S
index 3946fe8..5679a1d 100644
--- a/grub-core/kern/arm/startup.S
+++ b/grub-core/kern/arm/startup.S
@@ -48,6 +48,8 @@
.text
.arm
+ .globl start, _start
+FUNCTION(start)
FUNCTION(_start)
b codestart
diff --git a/grub-core/kern/arm64/backtrace.c b/grub-core/kern/arm64/backtrace.c
new file mode 100644
index 0000000..019c6fd
--- /dev/null
+++ b/grub-core/kern/arm64/backtrace.c
@@ -0,0 +1,94 @@
+/*
+ * 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
+
+struct fplr
+{
+ void *lr;
+ struct fplr *fp;
+};
+
+void
+grub_backtrace_pointer (void *frame, unsigned int skip)
+{
+ unsigned int x = 0;
+ struct fplr *fplr = (struct fplr *)frame;
+
+ while (fplr)
+ {
+ const char *name = NULL;
+ char *addr = NULL;
+
+ grub_dprintf("backtrace", "fp is %p next_fp is %p\n",
+ fplr, fplr->fp);
+
+ if (x >= skip)
+ {
+ name = grub_get_symbol_by_addr (fplr->lr, 1);
+ if (name)
+ addr = grub_resolve_symbol (name);
+ grub_backtrace_print_address (fplr->lr);
+
+ if (addr && addr != fplr->lr)
+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr,
+ (void *)((grub_uint64_t)fplr->lr - (grub_uint64_t)addr));
+ else
+ grub_printf(" %s() %p \n", name ? name : "unknown", addr);
+
+ }
+
+ x += 1;
+
+ if (fplr->fp < fplr ||
+ (grub_uint64_t)fplr->fp - (grub_uint64_t)fplr > MAX_STACK_FRAME ||
+ fplr->fp == fplr)
+ {
+ break;
+ }
+ fplr = fplr->fp;
+ }
+}
+
+asm ("\t.global \"_text\"\n"
+ "_text:\n"
+ "\t.quad .text\n"
+ "\t.global \"_data\"\n"
+ "_data:\n"
+ "\t.quad .data\n"
+ );
+
+extern grub_uint64_t _text;
+extern grub_uint64_t _data;
+
+void
+grub_backtrace_arch (unsigned int skip)
+{
+ grub_printf ("Backtrace (.text %p .data %p):\n",
+ (void *)_text, (void *)_data);
+ skip += 1;
+ grub_backtrace_pointer(__builtin_frame_address(0), skip);
+}
diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S
index 666a7ee..41676bd 100644
--- a/grub-core/kern/arm64/efi/startup.S
+++ b/grub-core/kern/arm64/efi/startup.S
@@ -19,7 +19,9 @@
#include <grub/symbol.h>
.file "startup.S"
+ .globl start, _start
.text
+FUNCTION(start)
FUNCTION(_start)
/*
* EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0.
diff --git a/grub-core/kern/backtrace.c b/grub-core/kern/backtrace.c
new file mode 100644
index 0000000..4a82e86
--- /dev/null
+++ b/grub-core/kern/backtrace.c
@@ -0,0 +1,97 @@
+/*
+ * 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>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static void
+grub_backtrace_print_address_default (void *addr)
+{
+#ifndef GRUB_UTIL
+ grub_dl_t mod;
+ void *start_addr;
+
+ FOR_DL_MODULES (mod)
+ {
+ grub_dl_segment_t segment;
+ for (segment = mod->segment; segment; segment = segment->next)
+ if (segment->addr <= addr && (grub_uint8_t *) segment->addr
+ + segment->size > (grub_uint8_t *) addr)
+ {
+ grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name,
+ segment->section,
+ (grub_size_t)
+ ((grub_uint8_t *)addr - (grub_uint8_t *)segment->addr));
+ return;
+ }
+ }
+
+ start_addr = grub_resolve_symbol ("_start");
+ if (start_addr && start_addr < addr)
+ grub_printf ("kernel+%" PRIxGRUB_SIZE,
+ (grub_size_t)
+ ((grub_uint8_t *)addr - (grub_uint8_t *)start_addr));
+ else
+#endif
+ grub_printf ("%p", addr);
+}
+
+static void
+grub_backtrace_pointer_default (void *frame __attribute__((__unused__)),
+ unsigned int skip __attribute__((__unused__)))
+{
+ return;
+}
+
+void
+grub_backtrace_pointer (void *frame, unsigned int skip)
+ __attribute__((__weak__,
+ __alias__(("grub_backtrace_pointer_default"))));
+
+void
+grub_backtrace_print_address (void *addr)
+ __attribute__((__weak__,
+ __alias__(("grub_backtrace_print_address_default"))));
+
+static void
+grub_backtrace_arch_default(unsigned int skip)
+{
+ grub_backtrace_pointer(__builtin_frame_address(0), skip + 1);
+}
+
+void grub_backtrace_arch (unsigned int skip)
+ __attribute__((__weak__, __alias__(("grub_backtrace_arch_default"))));
+
+void grub_backtrace (unsigned int skip)
+{
+ grub_backtrace_arch(skip + 1);
+}
+
+void grub_debug_backtrace (const char * const debug,
+ unsigned int skip)
+{
+ if (grub_debug_enabled (debug))
+ grub_backtrace (skip + 1);
+}
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index d7718d2..2e57e5e 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -124,6 +124,50 @@ grub_dl_resolve_symbol (const char *name)
return 0;
}
+void *
+grub_resolve_symbol (const char *name)
+{
+ grub_symbol_t sym;
+
+ sym = grub_dl_resolve_symbol (name);
+ if (sym)
+ return sym->addr;
+ return NULL;
+}
+
+const char *
+grub_get_symbol_by_addr(const void *addr, int isfunc)
+{
+ unsigned int i;
+ grub_symbol_t before = NULL, after = NULL;
+ for (i = 0; i < GRUB_SYMTAB_SIZE; i++)
+ {
+ grub_symbol_t sym;
+ for (sym = grub_symtab[i]; sym; sym = sym->next)
+ {
+ //grub_printf ("addr 0x%08llx symbol %s\n", (unsigned long long)sym->addr, sym->name);
+ if (sym->addr > addr)
+ {
+ if (!after || sym->addr > after->addr)
+ after = sym;
+ }
+
+ if (isfunc != sym->isfunc)
+ continue;
+ if (sym->addr > addr)
+ continue;
+
+ if ((!before && sym->addr <= addr) || (before && before->addr <= sym->addr))
+ before = sym;
+ }
+ }
+
+ if (before && addr < after->addr)
+ return before->name;
+
+ return NULL;
+}
+
/* Register a symbol with the name NAME and the address ADDR. */
grub_err_t
grub_dl_register_symbol (const char *name, void *addr, int isfunc,
@@ -336,6 +380,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
const char *str;
Elf_Word size, entsize;
+ grub_dprintf ("modules", "Resolving symbols for \"%s\"\n", mod->name);
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
diff --git a/grub-core/kern/i386/backtrace.c b/grub-core/kern/i386/backtrace.c
new file mode 100644
index 0000000..2413f9a
--- /dev/null
+++ b/grub-core/kern/i386/backtrace.c
@@ -0,0 +1,125 @@
+/*
+ * 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 (void *frame, unsigned int skip)
+{
+ void **ebp = (void **)frame;
+ unsigned long x = 0;
+
+ while (ebp)
+ {
+ void **next_ebp = (void **)ebp[0];
+ const char *name = NULL;
+ char *addr = NULL;
+
+ grub_dprintf("backtrace", "ebp is %p next_ebp is %p\n", ebp, next_ebp);
+
+ if (x >= skip)
+ {
+ name = grub_get_symbol_by_addr (ebp[1], 1);
+ if (name)
+ addr = grub_resolve_symbol (name);
+ grub_backtrace_print_address (ebp[1]);
+
+ if (addr && addr != ebp[1])
+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr,
+ (char *)((char *)ebp[1] - addr));
+ else
+ grub_printf(" %s() %p \n", name ? name : "unknown", addr);
+
+#if 0
+ grub_printf ("(");
+ for (i = 0, arg = ebp[2]; arg != next_ebp && i < 12; arg++, i++)
+ grub_printf ("%p,", arg);
+ grub_printf (")\n");
+#endif
+ }
+
+ x += 1;
+
+ if (next_ebp < ebp || next_ebp - ebp > MAX_STACK_FRAME || next_ebp == ebp)
+ {
+ //grub_printf ("Invalid stack frame at %p (%p)\n", ebp, next_ebp);
+ break;
+ }
+ ebp = next_ebp;
+ }
+}
+
+#if defined (__x86_64__)
+asm ("\t.global \"_text\"\n"
+ "_text:\n"
+ "\t.quad .text\n"
+ "\t.global \"_data\"\n"
+ "_data:\n"
+ "\t.quad .data\n"
+ );
+#elif defined(__i386__)
+asm ("\t.global \"_text\"\n"
+ "_text:\n"
+ "\t.long .text\n"
+ "\t.global \"_data\"\n"
+ "_data:\n"
+ "\t.long .data\n"
+ );
+#else
+#warning I dunno...
+#endif
+
+extern unsigned long _text;
+extern unsigned long _data;
+
+#ifdef GRUB_UTIL
+#define EXT_C(x) x
+#endif
+
+void
+grub_backtrace_arch (unsigned int skip)
+{
+ grub_printf ("Backtrace (.text %p .data %p):\n",
+ (void *)_text, (void *)_data);
+ skip += 1;
+#if defined (__x86_64__)
+ asm volatile ("movq %%rbp, %%rdi\n"
+ "movq 0, %%rsi\n"
+ "movl %0, %%esi\n"
+ "call " EXT_C("grub_backtrace_pointer")
+ :
+ : "r" (skip));
+#elif defined(__i386__)
+ asm volatile ("addl $8, %%esp\n"
+ "pushl %0\n"
+ "pushl %%ebp\n"
+ "call " EXT_C("grub_backtrace_pointer")
+ :
+ : "r" (skip));
+#else
+ grub_backtrace_pointer(__builtin_frame_address(0), skip);
+#endif
+}
diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c
index 27bc68b..b51d0ab 100644
--- a/grub-core/kern/i386/pc/init.c
+++ b/grub-core/kern/i386/pc/init.c
@@ -153,7 +153,7 @@ compact_mem_regions (void)
}
grub_addr_t grub_modbase;
-extern grub_uint8_t _start[], _edata[];
+extern grub_uint8_t _edata[];
/* Helper for grub_machine_init. */
static int
@@ -217,7 +217,7 @@ grub_machine_init (void)
/* This has to happen before any BIOS calls. */
grub_via_workaround_init ();
- grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
+ grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - (grub_uint8_t *)_start);
/* Initialize the console as early as possible. */
grub_console_init ();
diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S
index 0d89858..939f182 100644
--- a/grub-core/kern/i386/qemu/startup.S
+++ b/grub-core/kern/i386/qemu/startup.S
@@ -24,7 +24,8 @@
.text
.code32
- .globl _start
+ .globl start, _start
+start:
_start:
jmp codestart
diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S
index d75c6d7..8f2a593 100644
--- a/grub-core/kern/ia64/efi/startup.S
+++ b/grub-core/kern/ia64/efi/startup.S
@@ -24,8 +24,9 @@
.psr lsb
.lsb
- .global _start
+ .global start, _start
.proc _start
+start:
_start:
alloc loc0=ar.pfs,2,4,0,0
mov loc1=rp
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 0cd2a62..937c1bc 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -63,7 +63,6 @@
#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024)
#endif
-extern char _start[];
extern char _end[];
#ifdef __sparc__
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index e758ab3..5c2d203 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -1110,15 +1110,15 @@ grub_xasprintf (const char *fmt, ...)
}
/* Abort GRUB. This function does not return. */
-static void __attribute__ ((noreturn))
+static inline void __attribute__ ((noreturn))
grub_abort (void)
{
-#ifndef GRUB_UTIL
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU)
- grub_backtrace();
-#endif
+#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL)
+ grub_backtrace (1);
+#else
+ grub_printf ("\n");
#endif
- grub_printf ("\nAborted.");
+ grub_printf ("Aborted.");
#ifndef GRUB_UTIL
if (grub_term_inputs)
@@ -1145,6 +1145,7 @@ grub_fatal (const char *fmt, ...)
{
va_list ap;
+ grub_printf ("\n");
va_start (ap, fmt);
grub_vprintf (_(fmt), ap);
va_end (ap);
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
index ee88ff6..002cbfa 100644
--- a/grub-core/kern/mm.c
+++ b/grub-core/kern/mm.c
@@ -95,13 +95,13 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
break;
if (! *r)
- grub_fatal ("out of range pointer %p", ptr);
+ grub_fatal ("out of range pointer %p\n", ptr);
*p = (grub_mm_header_t) ptr - 1;
if ((*p)->magic == GRUB_MM_FREE_MAGIC)
- grub_fatal ("double free at %p", *p);
+ grub_fatal ("double free at %p\n", *p);
if ((*p)->magic != GRUB_MM_ALLOC_MAGIC)
- grub_fatal ("alloc magic is broken at %p: %lx", *p,
+ grub_fatal ("alloc magic is broken at %p: %lx\n", *p,
(unsigned long) (*p)->magic);
}
diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S
index 03b916f..701bf63 100644
--- a/grub-core/kern/sparc64/ieee1275/crt0.S
+++ b/grub-core/kern/sparc64/ieee1275/crt0.S
@@ -22,7 +22,8 @@
.text
.align 4
- .globl _start
+ .globl start, _start
+start:
_start:
ba codestart
mov %o4, %o0
diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c
deleted file mode 100644
index 1079b53..0000000
--- a/grub-core/lib/arm64/backtrace.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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
deleted file mode 100644
index c0ad6ab..0000000
--- a/grub-core/lib/backtrace.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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>
-
-GRUB_MOD_LICENSE ("GPLv3+");
-
-void
-grub_backtrace_print_address (void *addr)
-{
-#ifndef GRUB_UTIL
- grub_dl_t mod;
-
- FOR_DL_MODULES (mod)
- {
- grub_dl_segment_t segment;
- for (segment = mod->segment; segment; segment = segment->next)
- if (segment->addr <= addr && (grub_uint8_t *) segment->addr
- + segment->size > (grub_uint8_t *) addr)
- {
- grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, segment->section,
- (grub_size_t) ((grub_uint8_t *) addr - (grub_uint8_t *) segment->addr));
- return;
- }
- }
-
-#endif
- grub_printf ("%p", addr);
-}
-
-static grub_err_t
-grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)),
- int argc __attribute__ ((unused)),
- char **args __attribute__ ((unused)))
-{
- grub_backtrace ();
- return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(backtrace)
-{
- cmd = grub_register_command ("backtrace", grub_cmd_backtrace,
- 0, N_("Print backtrace."));
-}
-
-GRUB_MOD_FINI(backtrace)
-{
- grub_unregister_command (cmd);
-}
diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c
deleted file mode 100644
index c67273d..0000000
--- a/grub-core/lib/i386/backtrace.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 <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/mm.h>
-#include <grub/term.h>
-#include <grub/backtrace.h>
-
-#define MAX_STACK_FRAME 102400
-
-void
-grub_backtrace_pointer (void *ebp)
-{
- void *ptr, *nptr;
- unsigned i;
-
- ptr = ebp;
- while (1)
- {
- grub_printf ("%p: ", ptr);
- grub_backtrace_print_address (((void **) ptr)[1]);
- 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)
-{
-#ifdef __x86_64__
- asm volatile ("movq %%rbp, %%rdi\n"
- "callq *%%rax": :"a"(grub_backtrace_pointer));
-#else
- asm volatile ("movl %%ebp, %%eax\n"
- "calll *%%ecx": :"c"(grub_backtrace_pointer));
-#endif
-}
-
diff --git a/include/grub/backtrace.h b/include/grub/backtrace.h
index 3955197..275cf85 100644
--- a/include/grub/backtrace.h
+++ b/include/grub/backtrace.h
@@ -19,8 +19,14 @@
#ifndef GRUB_BACKTRACE_HEADER
#define GRUB_BACKTRACE_HEADER 1
-void grub_backtrace (void);
-void grub_backtrace_pointer (void *ptr);
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+void EXPORT_FUNC(grub_debug_backtrace) (const char * const debug,
+ unsigned int skip);
+void EXPORT_FUNC(grub_backtrace) (unsigned int skip);
+void grub_backtrace_arch (unsigned int skip);
+void grub_backtrace_pointer (void *ptr, unsigned int skip);
void grub_backtrace_print_address (void *addr);
#endif
diff --git a/include/grub/dl.h b/include/grub/dl.h
index 90dc9bb..4fe2b52 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -257,6 +257,8 @@ grub_dl_is_persistent (grub_dl_t mod)
#endif
+void * EXPORT_FUNC(grub_resolve_symbol) (const char *name);
+const char * EXPORT_FUNC(grub_get_symbol_by_addr) (const void *addr, int isfunc);
grub_err_t grub_dl_register_symbol (const char *name, void *addr,
int isfunc, grub_dl_t mod);
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index 133a37c..e5a5f43 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -110,6 +110,9 @@ grub_addr_t grub_modules_get_end (void);
#endif
+void EXPORT_FUNC(start) (void);
+void EXPORT_FUNC(_start) (void);
+
/* The start point of the C code. */
void grub_main (void) __attribute__ ((noreturn));
--
1.8.3.1
1
https://gitee.com/dingwei_chinamobile/grub2.git
git@gitee.com:dingwei_chinamobile/grub2.git
dingwei_chinamobile
grub2
grub2
master

搜索帮助