From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KKfsw-0005ly-Vb for mharc-grub-devel@gnu.org; Sun, 20 Jul 2008 16:52:03 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KKfsu-0005lU-F0 for grub-devel@gnu.org; Sun, 20 Jul 2008 16:52:00 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KKfss-0005kq-H2 for grub-devel@gnu.org; Sun, 20 Jul 2008 16:51:59 -0400 Received: from [199.232.76.173] (port=52462 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KKfss-0005kh-BD for grub-devel@gnu.org; Sun, 20 Jul 2008 16:51:58 -0400 Received: from mailout01.t-online.de ([194.25.134.80]:52896) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KKfsr-0001SP-Mo for grub-devel@gnu.org; Sun, 20 Jul 2008 16:51:58 -0400 Received: from fwd30.aul.t-online.de by mailout01.t-online.de with smtp id 1KKfso-0003fN-00; Sun, 20 Jul 2008 22:51:54 +0200 Received: from [10.3.2.2] (Tz49AoZH8hJesaXEx9K4TBAGO6xOoPP1xyJeLkY9AdhG3LiCuF9WtR0MDMKIsmPQE1@[217.235.253.196]) by fwd30.aul.t-online.de with esmtp id 1KKfsl-1TzPO40; Sun, 20 Jul 2008 22:51:51 +0200 Message-ID: <4883A568.10709@t-online.de> Date: Sun, 20 Jul 2008 22:51:52 +0200 From: Christian Franke User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071128 SeaMonkey/1.1.7 MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------080405010608070703010400" X-ID: Tz49AoZH8hJesaXEx9K4TBAGO6xOoPP1xyJeLkY9AdhG3LiCuF9WtR0MDMKIsmPQE1 X-TOI-MSGID: 3cbcab70-f41a-4521-a065-77a21f6405c8 X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Subject: [PATCH] Kernel fixes for Cygwin X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Jul 2008 20:52:00 -0000 This is a multi-part message in MIME format. --------------080405010608070703010400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit This adds Cygwin support to kernel sources. It handles the issues introduced by PE->ELF conversion and adds support for HAVE_ASM_USCORE. Christian 2007-07-20 Christian Franke * include/grub/dl.h: Remove .previous, gas supports this only for ELF format. * include/grub/symbol.h [__CYGWIN__] (#define FUNCTION/VARIABLE): Remove .type, gas supports this only for ELF format. * kern/dl.c (grub_dl_resolve_symbols): Add check for grub_mod_init and grub_mod_fini for symbols without a type. Handle HAVE_ASM_USCORE case for these symbols. (grub_dl_resolve_dependencies): Add check for trailing nullbytes in symbol table. This fixes an infinite loop if table is zero filled. * kern/i386/dl.c [__CYGWIN__] (fix_pc_rel_relocation): New function to fix bad PC relative relocation produced by objcopy. [__CYGWIN__] (grub_arch_dl_relocate_symbols): Add fix of PC relative relocation. (grub_arch_dl_relocate_symbols): Abort on unknown relocation type. --------------080405010608070703010400 Content-Type: text/x-diff; name="grub2-Cygwin-kern.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="grub2-Cygwin-kern.patch" diff --git a/include/grub/dl.h b/include/grub/dl.h index b630c6f..3029f95 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -40,11 +40,12 @@ grub_##name##_fini (void) { grub_mod_fini (); } \ static void \ grub_mod_fini (void) +/* Note: .previous not supported for non-ELF targets. */ #define GRUB_MOD_NAME(name) \ -__asm__ (".section .modname,\"S\"\n.string \"" #name "\"\n.previous") +__asm__ (".section .modname\n.string \"" #name "\"\n") #define GRUB_MOD_DEP(name) \ -__asm__ (".section .moddeps,\"S\"\n.string \"" #name "\"\n.previous") +__asm__ (".section .moddeps\n.string \"" #name "\"\n") struct grub_dl_segment { diff --git a/include/grub/symbol.h b/include/grub/symbol.h index aa0ea5a..72209d1 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -28,8 +28,14 @@ # define EXT_C(sym) sym #endif +#ifndef __CYGWIN__ #define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x): #define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x): +#else +/* .type not supported for non-ELF targets. XXX: Check this in configure? */ +#define FUNCTION(x) .globl EXT_C(x) ; EXT_C(x): +#define VARIABLE(x) .globl EXT_C(x) ; EXT_C(x): +#endif /* Mark an exported symbol. */ #ifndef GRUB_SYMBOL_GENERATOR diff --git a/kern/dl.c b/kern/dl.c index c0d9f1d..7950c0d 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -53,6 +53,12 @@ typedef Elf64_Sym Elf_Sym; #endif +#ifdef HAVE_ASM_USCORE +# define SYM_USCORE "_" +#else +# define SYM_USCORE "" +#endif + struct grub_dl_list @@ -347,17 +353,31 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) 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) { case STT_NOTYPE: - /* Resolve a global symbol. */ - if (sym->st_name != 0 && sym->st_shndx == 0) + if (sym->st_name != 0) { - sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); - if (! sym->st_value) - return grub_error (GRUB_ERR_BAD_MODULE, - "the symbol `%s' not found", name); + if (sym->st_shndx == 0) + { + /* Resolve a global symbol. */ + sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); + if (! sym->st_value) + return grub_error (GRUB_ERR_BAD_MODULE, + "the symbol `%s' not found", name); + } + else + { /* Static functions and global variables have no type + if initial format was not ELF. */ + sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + if (bind == STB_LOCAL) + check_mod_func = 1; + else if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; + } } else sym->st_value = 0; @@ -374,14 +394,10 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) case STT_FUNC: sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); - if (bind != STB_LOCAL) - 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; + if (bind == STB_LOCAL) + check_mod_func = 1; + else if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; break; case STT_SECTION: @@ -397,6 +413,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) return grub_error (GRUB_ERR_BAD_MODULE, "unknown symbol type `%d'", (int) type); } + if (check_mod_func) + { + if (grub_strcmp (name, SYM_USCORE "grub_mod_init") == 0) + mod->init = (void (*) (grub_dl_t)) sym->st_value; + else if (grub_strcmp (name, SYM_USCORE "grub_mod_fini") == 0) + mod->fini = (void (*) (void)) sym->st_value; + } } return GRUB_ERR_NONE; @@ -454,7 +477,7 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) 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; diff --git a/kern/i386/dl.c b/kern/i386/dl.c index e9e43e5..94d1510 100644 --- a/kern/i386/dl.c +++ b/kern/i386/dl.c @@ -37,6 +37,28 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } +#ifdef __CYGWIN__ +/* Fix PC relative relocation. Objcopy does not adjust +the addent when converting from pe-i386 to elf32-i386. */ +static int +fix_pc_rel_relocation (Elf32_Word *addr) +{ + /* To be safe, check instruction first. */ + const unsigned char * pc = (const unsigned char *)addr - 1; + if (!(*pc == 0xe8/*call*/ || *pc == 0xe9/*jmp*/)) + return grub_error (GRUB_ERR_BAD_MODULE, "unknown pc-relative instruction %02x", *pc); + /* Check and adjust offset. */ + if (*addr != (Elf32_Word)-4) + { + if (*addr != 0) + return grub_error (GRUB_ERR_BAD_MODULE, "invalid pc-relative relocation base %lx", + (long)(*addr)); + *addr = (Elf32_Word)-4; + } + return GRUB_ERR_NONE; +} +#endif + /* Relocate symbols. */ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) @@ -99,9 +121,17 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; case R_386_PC32: +#ifdef __CYGWIN__ + if (fix_pc_rel_relocation (addr)) + return grub_errno; +#endif *addr += (sym->st_value - (Elf32_Word) seg->addr - rel->r_offset); break; + + default: + return grub_error (GRUB_ERR_BAD_MODULE, "unknown relocation type %x.", + ELF32_R_TYPE (rel->r_info)); } } } --------------080405010608070703010400--