diff --git a/conf/mips.rmk b/conf/mips.rmk
index cd99cca75..233e21180 100644
--- a/conf/mips.rmk
+++ b/conf/mips.rmk
@@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
symbol.h term.h time.h types.h loader.h partition.h \
msdos_partition.h machine/kernel.h handler.h list.h \
- command.h machine/memory.h cpu/libgcc.h cpu/cache.h cpu/dl.h
+ command.h machine/memory.h cpu/libgcc.h cpu/cache.h
symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
diff --git a/genmoddep.awk b/genmoddep.awk
index f7f085e99..19ac80c71 100644
--- a/genmoddep.awk
+++ b/genmoddep.awk
@@ -29,7 +29,7 @@ FNR == 1 {
if ($1 in symtab) {
modtab[module] = modtab[module] " " symtab[$1];
}
- else {
+ else if ($1 != "__gnu_local_gp") {
printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
error++;
exit;
diff --git a/include/grub/dl.h b/include/grub/dl.h
index 3f8b328da..5bfcb0cf7 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -116,4 +116,11 @@ grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr,
grub_err_t grub_arch_dl_check_header (void *ehdr);
grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
+grub_err_t grub_arch_dl_check_header (void *ehdr);
+
+#if defined (_mips) && ! defined (GRUB_UTIL)
+#define GRUB_LINKER_HAVE_INIT 1
+void grub_arch_dl_init_linker (void);
+#endif
+
#endif /* ! GRUB_DL_H */
diff --git a/include/grub/mips/dl.h b/include/grub/mips/dl.h
deleted file mode 100644
index 9f8404e72..000000000
--- a/include/grub/mips/dl.h
+++ /dev/null
@@ -1,25 +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 .
- */
-
-#ifndef GRUB_CPU_DL_H
-#define GRUB_CPU_DL_H 1
-
-/* Dummy __gnu_local_gp. Resolved by linker. */
-extern char EXPORT_VAR (__gnu_local_gp);
-
-#endif /* ! GRUB_CPU_DL_H */
diff --git a/kern/main.c b/kern/main.c
index 084ce621b..fa6fba42a 100644
--- a/kern/main.c
+++ b/kern/main.c
@@ -154,6 +154,9 @@ grub_main (void)
/* Load pre-loaded modules and free the space. */
grub_register_exported_symbols ();
+#ifdef GRUB_LINKER_HAVE_INIT
+ grub_arch_dl_init_linker ();
+#endif
grub_load_modules ();
/* Hello. */
diff --git a/kern/mips/dl.c b/kern/mips/dl.c
index a937c79b4..f2a0af0d5 100644
--- a/kern/mips/dl.c
+++ b/kern/mips/dl.c
@@ -23,10 +23,9 @@
#include
#include
#include
-#include
/* Dummy __gnu_local_gp. Resolved by linker. */
-char __gnu_local_gp;
+static char __gnu_local_gp_dummy;
/* Check if EHDR is a valid ELF header. */
grub_err_t
@@ -155,7 +154,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
- if (sym->st_value == (grub_addr_t) &__gnu_local_gp)
+ if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym->st_value = (grub_addr_t) gp;
switch (ELF_R_TYPE (rel->r_info))
@@ -224,3 +223,10 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
return GRUB_ERR_NONE;
}
+
+void
+grub_arch_dl_init_linker (void)
+{
+ grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
+}
+