From 2abe387d568cd015afc9cbf88f9f2099cdb93ccf Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Nov 2017 18:31:56 -0500 Subject: [PATCH] make better backtraces Signed-off-by: Peter Jones --- grub-core/Makefile.core.def | 15 ++-- grub-core/{lib => commands}/backtrace.c | 2 +- grub-core/gdb/cstub.c | 1 - grub-core/kern/arm64/backtrace.c | 94 +++++++++++++++++++++++++ grub-core/kern/backtrace.c | 95 +++++++++++++++++++++++++ grub-core/kern/dl.c | 45 ++++++++++++ grub-core/kern/i386/backtrace.c | 121 ++++++++++++++++++++++++++++++++ grub-core/kern/i386/pc/init.c | 4 +- grub-core/kern/ieee1275/init.c | 1 - grub-core/kern/misc.c | 13 ++-- grub-core/kern/mm.c | 6 +- grub-core/lib/arm64/backtrace.c | 62 ---------------- grub-core/lib/i386/backtrace.c | 78 -------------------- include/grub/backtrace.h | 10 ++- include/grub/dl.h | 2 + include/grub/kernel.h | 3 + grub-core/kern/arm/efi/startup.S | 2 + grub-core/kern/arm/startup.S | 2 + grub-core/kern/arm64/efi/startup.S | 2 + grub-core/kern/i386/qemu/startup.S | 3 +- grub-core/kern/ia64/efi/startup.S | 3 +- grub-core/kern/sparc64/ieee1275/crt0.S | 3 +- grub-core/Makefile.am | 1 + 23 files changed, 402 insertions(+), 166 deletions(-) rename grub-core/{lib => commands}/backtrace.c (98%) 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/i386/backtrace.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7edff60ccd4..1153ec4d2cf 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -130,6 +130,12 @@ kernel = { common = kern/rescue_reader.c; common = kern/term.c; common = kern/qsort.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; @@ -176,9 +182,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; @@ -2288,13 +2291,11 @@ module = { module = { name = backtrace; - x86 = 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; enable = x86_64_xen; + enable = arm64; }; module = { diff --git a/grub-core/lib/backtrace.c b/grub-core/commands/backtrace.c similarity index 98% rename from grub-core/lib/backtrace.c rename to grub-core/commands/backtrace.c index c0ad6ab8be1..8b5ec3913b5 100644 --- a/grub-core/lib/backtrace.c +++ b/grub-core/commands/backtrace.c @@ -54,7 +54,7 @@ grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_backtrace (); + grub_backtrace (1); return 0; } diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c index b64acd70fee..99281472d36 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/arm64/backtrace.c b/grub-core/kern/arm64/backtrace.c new file mode 100644 index 00000000000..019c6fdfef2 --- /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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#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/backtrace.c b/grub-core/kern/backtrace.c new file mode 100644 index 00000000000..bd6a783f6d0 --- /dev/null +++ b/grub-core/kern/backtrace.c @@ -0,0 +1,95 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static void +grub_backtrace_print_address_default (void *addr) +{ + 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 + 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 621070918d4..5028d157c46 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 00000000000..c4f7e3f0e90 --- /dev/null +++ b/grub-core/kern/i386/backtrace.c @@ -0,0 +1,121 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#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; + +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 27bc68b8a53..b51d0abfa6e 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/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index e01bc6eab19..e731a57a47b 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -60,7 +60,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 e758ab3416d..5c2d2039d0b 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(); +#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL) + grub_backtrace (1); +#else + grub_printf ("\n"); #endif -#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 ee88ff61187..002cbfa4f3d 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/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c deleted file mode 100644 index 1079b5380e1..00000000000 --- 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#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/i386/backtrace.c b/grub-core/lib/i386/backtrace.c deleted file mode 100644 index c67273db3ae..00000000000 --- 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 . - */ -#include -#ifdef GRUB_UTIL -#define REALLY_GRUB_UTIL GRUB_UTIL -#undef GRUB_UTIL -#endif - -#include -#include - -#ifdef REALLY_GRUB_UTIL -#define GRUB_UTIL REALLY_GRUB_UTIL -#undef REALLY_GRUB_UTIL -#endif - -#include -#include -#include -#include -#include -#include - -#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 395519762f0..275cf85e2d3 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 +#include + +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 b1ed3c33317..7b5bfb07ce6 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -244,6 +244,8 @@ grub_dl_get (const char *name) #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 ecd88ca72c6..ae69218af20 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -108,6 +108,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)); diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S index 9f8265315a9..f3bc41f9d0f 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 3946fe8e183..5679a1d00ad 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/efi/startup.S b/grub-core/kern/arm64/efi/startup.S index 666a7ee3c92..41676bdb2b8 100644 --- a/grub-core/kern/arm64/efi/startup.S +++ b/grub-core/kern/arm64/efi/startup.S @@ -19,7 +19,9 @@ #include .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/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 0d89858d9b3..939f182fc74 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 d75c6d7cc74..8f2a593e529 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/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index 03b916f0534..701bf63abcf 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/Makefile.am b/grub-core/Makefile.am index 75e8715e631..5c7a2c8f808 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