diff -rup grub2.orig/genkernsyms.sh.in grub2/genkernsyms.sh.in --- grub2.orig/genkernsyms.sh.in 2006-07-12 22:42:52.000000000 +0200 +++ grub2/genkernsyms.sh.in 2007-10-06 12:59:29.000000000 +0200 @@ -16,9 +16,12 @@ srcdir=@srcdir@ CC="@CC@" +u= +grep "^#define HAVE_ASM_USCORE" config.h >/dev/null 2>&1 && u="_" + $CC -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I$srcdir/include $* \ | grep -v '^#' \ | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/\1 kernel/;p;}' \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \ | sort -u diff -rup grub2.orig/genmk.rb grub2/genmk.rb --- grub2.orig/genmk.rb 2007-10-20 22:49:38.968750000 +0200 +++ grub2/genmk.rb 2007-11-10 19:37:17.562500000 +0100 @@ -115,7 +115,7 @@ UNDSYMFILES += #{undsym} #{@name}: #{pre_obj} #{mod_obj} -rm -f $@ $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^ - $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str} -rm -f $@ @@ -187,7 +187,7 @@ class Utility deps = objs.collect {|obj| obj.suffix('d')} deps_str = deps.join(' '); - "CLEANFILES += #{@name} #{objs_str} + "CLEANFILES += #{@name}$(EXEEXT) #{objs_str} MOSTLYCLEANFILES += #{deps_str} #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} diff -rup grub2.orig/kern/dl.c grub2/kern/dl.c --- grub2.orig/kern/dl.c 2007-07-22 01:32:26.000000000 +0200 +++ grub2/kern/dl.c 2007-11-10 19:44:34.140625000 +0100 @@ -156,6 +156,9 @@ grub_dl_resolve_symbol (const char *name { grub_symbol_t sym; + if (*name == '_') + name++; + for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next) if (grub_strcmp (sym->name, name) == 0) return sym->addr; @@ -169,6 +172,11 @@ grub_dl_register_symbol (const char *nam { grub_symbol_t sym; unsigned k; + + /* Ignore leading underscore used for C symbols. + Done at runtime to allow loading modules compiled on other OS. */ + if (*name == '_') + name++; sym = (grub_symbol_t) grub_malloc (sizeof (*sym)); if (! sym) @@ -347,6 +355,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, unsigned char type = ELF_ST_TYPE (sym->st_info); unsigned char bind = ELF_ST_BIND (sym->st_info); const char *name = str + sym->st_name; + int check_mod_func = 0; switch (type) { @@ -359,6 +368,12 @@ grub_dl_resolve_symbols (grub_dl_t mod, return grub_error (GRUB_ERR_BAD_MODULE, "the symbol `%s' not found", name); } + else if (sym->st_name != 0 && bind == STB_LOCAL) + { /* Static functions have no type if initial format was not ELF. */ + sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + check_mod_func = 1; + } else sym->st_value = 0; break; @@ -374,14 +389,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, case STT_FUNC: sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); - if (bind != STB_LOCAL) + if (bind == STB_LOCAL) + check_mod_func = 1; + else if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) return grub_errno; - - if (grub_strcmp (name, "grub_mod_init") == 0) - mod->init = (void (*) (grub_dl_t)) sym->st_value; - else if (grub_strcmp (name, "grub_mod_fini") == 0) - mod->fini = (void (*) (void)) sym->st_value; break; case STT_SECTION: @@ -397,6 +409,15 @@ grub_dl_resolve_symbols (grub_dl_t mod, return grub_error (GRUB_ERR_BAD_MODULE, "unknown symbol type `%d'", (int) type); } + if (check_mod_func) + { + if (*name == '_') + name++; + if (grub_strcmp (name, "grub_mod_init") == 0) + mod->init = (void (*) (grub_dl_t)) sym->st_value; + else if (grub_strcmp (name, "grub_mod_fini") == 0) + mod->fini = (void (*) (void)) sym->st_value; + } } return GRUB_ERR_NONE; @@ -454,7 +475,7 @@ grub_dl_resolve_dependencies (grub_dl_t const char *name = (char *) e + s->sh_offset; const char *max = name + s->sh_size; - while (name < max) + while (name < max && *name) /* Segment may contain trailing 0. */ { grub_dl_t m; grub_dl_dep_t dep;