Re: conflicting types for 'grub_list_push' on MinGW (include loop)

2014-01-15 Thread Andrey Borzenkov
В Mon, 13 Jan 2014 23:00:47 +0100
Vladimir 'φ-coder/phcoder' Serbinenko  пишет:

> On 13.01.2014 20:44, Andrey Borzenkov wrote:
> > 
> > I'd rather move compiler features into separate file (like
> > grub/compiler.h) and include it from misc.h and separately from list.h.
> > 
> This would be a good idea.

Like below?

From: Andrey Borzenkov 
Subject: [PATCH] fix include loop on MinGW due to libintl.h pulling stdio.h

In file included from ./include/grub/dl.h:23:0,
 from grub-core/lib/libgcrypt-grub/cipher/rfc2268.c:3:
./include/grub/list.h:34:18: warning: conflicting types for 'grub_list_push' [en
abled by default]
 void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
  ^
./include/grub/symbol.h:68:25: note: in definition of macro 'EXPORT_FUNC'
 # define EXPORT_FUNC(x) x
 ^
In file included from ./include/grub/fs.h:30:0,
 from ./include/grub/file.h:25,
 from ./grub-core/lib/posix_wrap/stdio.h:23,
 from c:\mingw\include\libintl.h:314,
 from ./include/grub/i18n.h:33,
 from ./include/grub/misc.h:27,
 from ./include/grub/list.h:25,
 from ./include/grub/dl.h:28,
 from grub-core/lib/libgcrypt-grub/cipher/rfc2268.c:3:
./include/grub/partition.h:106:3: note: previous implicit declaration of 'grub_l
ist_push' was here
   grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
   ^
list.h needs just ATTRIBUTE_ERROR from misc.h; split compiler features
into separate file grub/compiler.h and include it instead.

---
 grub-core/commands/fileXX.c|  1 +
 grub-core/efiemu/prepare.c |  1 +
 grub-core/loader/i386/xen_file.c   |  1 +
 grub-core/loader/i386/xen_fileXX.c |  1 +
 grub-core/video/capture.c  |  1 +
 include/grub/command.h |  1 +
 include/grub/compiler.h| 51 ++
 include/grub/dl.h  |  1 +
 include/grub/list.h|  4 +--
 include/grub/misc.h| 29 +-
 include/grub/procfs.h  |  1 +
 11 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/grub-core/commands/fileXX.c b/grub-core/commands/fileXX.c
index c9857ff..58e1094 100644
--- a/grub-core/commands/fileXX.c
+++ b/grub-core/commands/fileXX.c
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 
 #pragma GCC diagnostic ignored "-Wcast-align"
 
diff --git a/grub-core/efiemu/prepare.c b/grub-core/efiemu/prepare.c
index fb1b25d..84c3368 100644
--- a/grub-core/efiemu/prepare.c
+++ b/grub-core/efiemu/prepare.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
diff --git a/grub-core/loader/i386/xen_file.c b/grub-core/loader/i386/xen_file.c
index ebbf6aa..ff23235 100644
--- a/grub-core/loader/i386/xen_file.c
+++ b/grub-core/loader/i386/xen_file.c
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 
 grub_elf_t
 grub_xen_file (grub_file_t file)
diff --git a/grub-core/loader/i386/xen_fileXX.c 
b/grub-core/loader/i386/xen_fileXX.c
index 6df0015..73a5f90 100644
--- a/grub-core/loader/i386/xen_fileXX.c
+++ b/grub-core/loader/i386/xen_fileXX.c
@@ -17,6 +17,7 @@
  */
 
 #include 
+#include 
 
 static grub_err_t
 parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c
index 67c8edd..4f83c74 100644
--- a/grub-core/video/capture.c
+++ b/grub-core/video/capture.c
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static struct
 {
diff --git a/include/grub/command.h b/include/grub/command.h
index 8705a63..eee4e84 100644
--- a/include/grub/command.h
+++ b/include/grub/command.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 typedef enum grub_command_flags
   {
diff --git a/include/grub/compiler.h b/include/grub/compiler.h
new file mode 100644
index 000..3730ef2
--- /dev/null
+++ b/include/grub/compiler.h
@@ -0,0 +1,51 @@
+/* compiler.h - macros for various compiler features */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2014  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_COMPILER_HEADER
+#define GRUB_COMPILER_HEADER   1
+
+/* GCC version checking borrowed from glibc. */
+#if defined(__GNUC__) && defined(__GNUC_MINOR

Re: [PATCH] Adding Bi-Endian 32-bit and 64-bit Support to the Grub ELF Parser

2014-01-15 Thread Tomohiro B Berry
PowerPC is the only architecture that I know of currently asking for this 
biendianness, so is it sufficient to include config.h in elf.c and an 
#ifdef __powerpc__ to the grub_elfXX_byteswap_header function (as shown 
below)?   That way, it will only perform the byteswap on the powerpc 
architecture, and continue to fail to load an opposite endian kernel on 
other architectures when it checks the e_version.  Or is there a better 
way to do it? 

Tomo

diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c
index 5f99c43..2328b8e 100644
--- a/grub-core/kern/elf.c
+++ b/grub-core/kern/elf.c
@@ -17,6 +17,7 @@
  *  along with GRUB.  If not, see .
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -28,20 +29,45 @@
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
+void grub_elf32_byteswap_header (grub_elf_t elf);
+void grub_elf64_byteswap_header (grub_elf_t elf);
+grub_err_t grub_elf32_check_version (grub_elf_t elf);
+grub_err_t grub_elf64_check_version (grub_elf_t elf);
+
 /* Check if EHDR is a valid ELF header.  */
 static grub_err_t
 grub_elf_check_header (grub_elf_t elf)
 {
-  Elf32_Ehdr *e = &elf->ehdr.ehdr32;
+  /* e_ident is the same for both 64-bit and 32-bit */ 
+  Elf32_Ehdr *e = &elf->ehdr.ehdr32; 
 
+  /* check if it is an ELF image at all */ 
   if (e->e_ident[EI_MAG0] != ELFMAG0
   || e->e_ident[EI_MAG1] != ELFMAG1
   || e->e_ident[EI_MAG2] != ELFMAG2
   || e->e_ident[EI_MAG3] != ELFMAG3
-  || e->e_ident[EI_VERSION] != EV_CURRENT
-  || e->e_version != EV_CURRENT)
-return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF 
magic"));
-
+  || e->e_ident[EI_VERSION] != EV_CURRENT)
+return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF 
magic")); 
+ 
+  switch (e->e_ident[EI_CLASS])
+{
+  case ELFCLASS32:
+if (e->e_ident[EI_DATA] != ELFDATA_NATIVE)
+  grub_elf32_byteswap_header (elf);
+if (grub_elf32_check_version (elf) != GRUB_ERR_NONE)
+  return grub_errno;
+break;
+  case ELFCLASS64:
+if (e->e_ident[EI_DATA] != ELFDATA_NATIVE)
+  grub_elf64_byteswap_header (elf);
+if (grub_elf64_check_version (elf) != GRUB_ERR_NONE)
+  return grub_errno;
+break;
+  default:
+return grub_error (GRUB_ERR_BAD_OS, N_("unrecognized ELF 
class"));
+break;
+}
+ 
   return GRUB_ERR_NONE;
 }
 
@@ -127,7 +153,16 @@ grub_elf_open (const char *name)
 #define grub_elf_is_elfXX grub_elf_is_elf32
 #define grub_elfXX_load_phdrs grub_elf32_load_phdrs
 #define ElfXX_Phdr Elf32_Phdr
+#define ElfXX_Ehdr Elf32_Ehdr
 #define grub_uintXX_t grub_uint32_t
+/* for phdr/ehdr byte swaps */
+#define byte_swap_halfXX grub_swap_bytes16
+#define byte_swap_wordXX grub_swap_bytes32
+#define byte_swap_addrXX grub_swap_bytes32
+#define byte_swap_offXX grub_swap_bytes32
+#define byte_swap_XwordXX byte_swap_wordXX /* the 64-bit phdr uses Xwords 
and the 32-bit uses words */
+#define grub_elfXX_byteswap_header grub_elf32_byteswap_header
+#define grub_elfXX_check_version grub_elf32_check_version
 
 #include "elfXX.c"
 
@@ -140,7 +175,15 @@ grub_elf_open (const char *name)
 #undef grub_elf_is_elfXX
 #undef grub_elfXX_load_phdrs
 #undef ElfXX_Phdr
+#undef ElfXX_Ehdr
 #undef grub_uintXX_t
+#undef byte_swap_halfXX
+#undef byte_swap_wordXX
+#undef byte_swap_addrXX
+#undef byte_swap_offXX
+#undef byte_swap_XwordXX
+#undef grub_elfXX_byteswap_header
+#undef grub_elfXX_check_version
 
 

 /* 64-bit */
@@ -153,6 +196,16 @@ grub_elf_open (const char *name)
 #define grub_elf_is_elfXX grub_elf_is_elf64
 #define grub_elfXX_load_phdrs grub_elf64_load_phdrs
 #define ElfXX_Phdr Elf64_Phdr
+#define ElfXX_Ehdr Elf64_Ehdr
 #define grub_uintXX_t grub_uint64_t
+/* for phdr/ehdr byte swaps */
+#define byte_swap_halfXX grub_swap_bytes16
+#define byte_swap_wordXX grub_swap_bytes32
+#define byte_swap_addrXX grub_swap_bytes64
+#define byte_swap_offXX grub_swap_bytes64
+#define byte_swap_XwordXX grub_swap_bytes64
+#define grub_elfXX_byteswap_header grub_elf64_byteswap_header
+#define grub_elfXX_check_version grub_elf64_check_version
 
 #include "elfXX.c"
+
diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c
index 2e45449..aabfcdc 100644
--- a/grub-core/kern/elfXX.c
+++ b/grub-core/kern/elfXX.c
@@ -154,3 +154,54 @@ grub_elfXX_load (grub_elf_t elf, const char 
*filename,
 
   return grub_errno;
 }
+
+void 
+grub_elfXX_byteswap_header (grub_elf_t elf)
+{
+  ElfXX_Ehdr *e = &(elf->ehdr.ehdrXX);
+  ElfXX_Phdr *phdr; 
+
+ /* 
+  *  Swap bytes if the architecture supports bi-endian kernels.
+  *  So far the only architecture asking for it is powerpc. 
+  */
+
+#ifdef __powerpc__
+  e->e_type = byte_swap_halfXX (e->e_type);
+  e->e_machine = byte_swap_halfXX (e->e_machine);
+  e->e_version = byte_swap_wordXX (e->e_version);
+  e->e_entry = byte_swap_addrXX (e->e_entry);
+  e->e_phoff = byte_swap_offXX (e->e_phoff);
+  e->e_shoff = byte_swap_offXX (e->e_shoff);
+  e->e_flags = byte_swap_wordX