2009-06-26 Robert Millan
* kern/dl.c (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr, Elf_Sym): Remove
typedefs.
(ELF_ST_BIND, ELF_ST_TYPE): Remove macros.
* include/grub/elf.h (Elf_Word, Elf_Addr, Elf_Ehdr, Elf_Shdr)
(Elf_Sym, ELF_ST_BIND, ELF_ST_TYPE): New macros.
* efiemu/loadcore64.c: Include `'.
(Elf_Word, Elf_Ehdr, Elf_Shdr, Elf_Sym, ELF_ST_BIND)
(ELF_ST_TYPE): Rename to ...
(ElfW_Word, ElfW_Ehdr, ElfW_Shdr, ElfW_Sym, ELFW_ST_BIND)
(ELFW_ST_TYPE): ... this. Update all users.
* efiemu/loadcore32.c: Likewise.
* include/grub/dl.h: Include `' and
`'.
[GRUB_MACHINE_QEMU] (GRUB_MODULES_MACHINE_READONLY): New macro.
[GRUB_MODULES_MACHINE_READONLY] (struct grub_dl): Add `symtab' member.
(get_symtab): New macro.
* kern/dl.c [GRUB_MODULES_MACHINE_READONLY]
(grub_dl_resolve_symbols): Copy symbol table to `mod->symtab', and use
the copied structure for further writes rather than the original.
* kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Initialize
`symtab' using get_symtab().
* kern/sparc64/dl.c: Likewise.
* kern/i386/dl.c: Likewise.
* kern/x86_64/dl.c: Likewise.
Index: kern/powerpc/dl.c
===================================================================
--- kern/powerpc/dl.c (revision 2358)
+++ kern/powerpc/dl.c (working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
- symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+ symtab = get_symtab ();
entsize = s->sh_entsize;
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/dl.c
===================================================================
--- kern/dl.c (revision 2358)
+++ kern/dl.c (working copy)
@@ -1,7 +1,7 @@
/* dl.c - loadable module support */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2004,2005,2007,2008,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
@@ -29,30 +29,6 @@
#include
#include
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val) ELF32_ST_BIND (val)
-# define ELF_ST_TYPE(val) ELF32_ST_TYPE (val)
-
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sym Elf_Sym;
-
-# define ELF_ST_BIND(val) ELF64_ST_BIND (val)
-# define ELF_ST_TYPE(val) ELF64_ST_TYPE (val)
-
-#endif
-
struct grub_dl_list
@@ -333,9 +309,13 @@ grub_dl_resolve_symbols (grub_dl_t mod,
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
- sym = (Elf_Sym *) ((char *) e + s->sh_offset);
size = s->sh_size;
entsize = s->sh_entsize;
+#ifdef GRUB_MODULES_MACHINE_READONLY
+ mod->symtab = grub_malloc (size);
+ memcpy (mod->symtab, (char *) e + s->sh_offset, size);
+#endif
+ sym = get_symtab ();
s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
str = (char *) e + s->sh_offset;
@@ -695,6 +675,9 @@ grub_dl_unload (grub_dl_t mod)
}
grub_free (mod->name);
+#ifdef GRUB_MODULES_MACHINE_READONLY
+ grub_free (mod->symtab);
+#endif
grub_free (mod);
return 1;
}
Index: kern/sparc64/dl.c
===================================================================
--- kern/sparc64/dl.c (revision 2358)
+++ kern/sparc64/dl.c (working copy)
@@ -58,7 +58,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
- symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+ symtab = get_symtab ();
entsize = s->sh_entsize;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: kern/i386/dl.c
===================================================================
--- kern/i386/dl.c (revision 2358)
+++ kern/i386/dl.c (working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
- symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
+ symtab = get_symtab ();
entsize = s->sh_entsize;
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
Index: kern/x86_64/dl.c
===================================================================
--- kern/x86_64/dl.c (revision 2358)
+++ kern/x86_64/dl.c (working copy)
@@ -57,7 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
- symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
+ symtab = get_symtab ();
entsize = s->sh_entsize;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
Index: efiemu/loadcore64.c
===================================================================
--- efiemu/loadcore64.c (revision 2358)
+++ efiemu/loadcore64.c (working copy)
@@ -18,10 +18,14 @@
*/
#define SUFFIX(x) x ## 64
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Word Elf64_Word
-#define ELF_ST_TYPE ELF64_ST_TYPE
-#define ELF_ST_BIND ELF64_ST_BIND
+
+#include
+
+#define ElfW_Ehdr Elf64_Ehdr
+#define ElfW_Shdr Elf64_Shdr
+#define ElfW_Sym Elf64_Sym
+#define ElfW_Word Elf64_Word
+#define ELFW_ST_TYPE ELF64_ST_TYPE
+#define ELFW_ST_BIND ELF64_ST_BIND
+
#include "loadcore.c"
Index: efiemu/loadcore.c
===================================================================
--- efiemu/loadcore.c (revision 2358)
+++ efiemu/loadcore.c (working copy)
@@ -59,10 +59,10 @@ SUFFIX (grub_efiemu_loadcore_unload) (vo
int
SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
{
- Elf_Ehdr *e = ehdr;
+ ElfW_Ehdr *e = ehdr;
/* Check the header size. */
- if (size < sizeof (Elf_Ehdr))
+ if (size < sizeof (ElfW_Ehdr))
return 0;
/* Check the magic numbers. */
@@ -80,16 +80,16 @@ SUFFIX (grub_efiemu_check_header) (void
/* Load all segments from memory specified by E. */
static grub_err_t
-grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
+grub_efiemu_load_segments (grub_efiemu_segment_t segs, const ElfW_Ehdr *e)
{
- Elf_Shdr *s;
+ ElfW_Shdr *s;
grub_efiemu_segment_t cur;
grub_dprintf ("efiemu", "loading segments\n");
for (cur=segs; cur; cur = cur->next)
{
- s = (Elf_Shdr *)cur->srcptr;
+ s = (ElfW_Shdr *)cur->srcptr;
if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
{
@@ -115,14 +115,14 @@ grub_efiemu_load_segments (grub_efiemu_s
/* Get a string at offset OFFSET from strtab */
static char *
-grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
+grub_efiemu_get_string (unsigned offset, const ElfW_Ehdr *e)
{
unsigned i;
- Elf_Shdr *s;
+ ElfW_Shdr *s;
- for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+ for (i = 0, s = (ElfW_Shdr *)((char *) e + e->e_shoff);
i < e->e_shnum;
- i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+ i++, s = (ElfW_Shdr *)((char *) s + e->e_shentsize))
if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
return (char *) e + s->sh_offset + offset;
return 0;
@@ -130,14 +130,14 @@ grub_efiemu_get_string (unsigned offset,
/* Request memory for segments and fill segments info */
static grub_err_t
-grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
+grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const ElfW_Ehdr *e)
{
unsigned i;
- Elf_Shdr *s;
+ ElfW_Shdr *s;
- for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+ for (i = 0, s = (ElfW_Shdr *)((char *) e + e->e_shoff);
i < e->e_shnum;
- i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+ i++, s = (ElfW_Shdr *)((char *) s + e->e_shentsize))
{
if (s->sh_flags & SHF_ALLOC)
{
@@ -180,16 +180,16 @@ grub_efiemu_init_segments (grub_efiemu_s
/* Count symbols and relocators and allocate/request memory for them */
static grub_err_t
-grub_efiemu_count_symbols (const Elf_Ehdr *e)
+grub_efiemu_count_symbols (const ElfW_Ehdr *e)
{
unsigned i;
- Elf_Shdr *s;
+ ElfW_Shdr *s;
int num = 0;
/* Symbols */
- for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+ for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
- i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+ i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
@@ -201,9 +201,9 @@ grub_efiemu_count_symbols (const Elf_Ehd
grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
/* Relocators */
- for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+ for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
- i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+ i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);
@@ -214,38 +214,38 @@ grub_efiemu_count_symbols (const Elf_Ehd
/* Fill grub_efiemu_elfsyms with symbol values */
static grub_err_t
-grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
+grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, ElfW_Ehdr *e)
{
unsigned i;
- Elf_Shdr *s;
- Elf_Sym *sym;
+ ElfW_Shdr *s;
+ ElfW_Sym *sym;
const char *str;
- Elf_Word size, entsize;
+ ElfW_Word size, entsize;
grub_dprintf ("efiemu", "resolving symbols\n");
- for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+ for (i = 0, s = (ElfW_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
- i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+ i++, s = (ElfW_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
- sym = (Elf_Sym *) ((char *) e + s->sh_offset);
+ sym = (ElfW_Sym *) ((char *) e + s->sh_offset);
size = s->sh_size;
entsize = s->sh_entsize;
- s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+ s = (ElfW_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
str = (char *) e + s->sh_offset;
for (i = 0;
i < size / entsize;
- i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+ i++, sym = (ElfW_Sym *) ((char *) sym + entsize))
{
- unsigned char type = ELF_ST_TYPE (sym->st_info);
- unsigned char bind = ELF_ST_BIND (sym->st_info);
+ unsigned char type = ELFW_ST_TYPE (sym->st_info);
+ unsigned char bind = ELFW_ST_BIND (sym->st_info);
int handle;
grub_off_t off;
grub_err_t err;
@@ -325,7 +325,7 @@ grub_err_t
SUFFIX (grub_efiemu_loadcore_init) (void *core, grub_size_t core_size,
grub_efiemu_segment_t *segments)
{
- Elf_Ehdr *e = (Elf_Ehdr *) core;
+ ElfW_Ehdr *e = (ElfW_Ehdr *) core;
grub_err_t err;
if (e->e_type != ET_REL)
Index: efiemu/loadcore32.c
===================================================================
--- efiemu/loadcore32.c (revision 2358)
+++ efiemu/loadcore32.c (working copy)
@@ -18,10 +18,14 @@
*/
#define SUFFIX(x) x ## 32
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Word Elf32_Word
-#define ELF_ST_TYPE ELF32_ST_TYPE
-#define ELF_ST_BIND ELF32_ST_BIND
+
+#include
+
+#define ElfW_Ehdr Elf32_Ehdr
+#define ElfW_Shdr Elf32_Shdr
+#define ElfW_Sym Elf32_Sym
+#define ElfW_Word Elf32_Word
+#define ELFW_ST_TYPE ELF32_ST_TYPE
+#define ELFW_ST_BIND ELF32_ST_BIND
+
#include "loadcore.c"
Index: include/grub/elf.h
===================================================================
--- include/grub/elf.h (revision 2358)
+++ include/grub/elf.h (working copy)
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-1999, 2000, 2001, 2002,2008 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999,2000,2001,2002,2008,2009 Free Software Foundation, Inc.
This file was part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -2330,4 +2330,28 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_X86_64_NUM 24
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+
+#define Elf_Word Elf32_Word
+#define Elf_Addr Elf32_Addr
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+
+# define ELF_ST_BIND(val) ELF32_ST_BIND (val)
+# define ELF_ST_TYPE(val) ELF32_ST_TYPE (val)
+
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+
+#define Elf_Word Elf64_Word
+#define Elf_Addr Elf64_Addr
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+
+# define ELF_ST_BIND(val) ELF64_ST_BIND (val)
+# define ELF_ST_TYPE(val) ELF64_ST_TYPE (val)
+
+#endif
+
#endif /* ! GRUB_ELF_H */
Index: include/grub/dl.h
===================================================================
--- include/grub/dl.h (revision 2358)
+++ include/grub/dl.h (working copy)
@@ -1,7 +1,7 @@
/* dl.h - types and prototypes for loadable module support */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2004,2005,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2004,2005,2007,2008,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
@@ -23,6 +23,13 @@
#include
#include
#include
+#include
+#include
+
+/* Platforms where modules are in a readonly area of memory. */
+#if defined(GRUB_MACHINE_QEMU)
+#define GRUB_MODULES_MACHINE_READONLY
+#endif
#define GRUB_MOD_INIT(name) \
static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
@@ -78,6 +85,12 @@ struct grub_dl
int ref_count;
grub_dl_dep_t dep;
grub_dl_segment_t segment;
+#ifdef GRUB_MODULES_MACHINE_READONLY
+ Elf_Sym *symtab;
+#define get_symtab() mod->symtab
+#else
+#define get_symtab() ((Elf_Sym *) ((char *) e + s->sh_offset))
+#endif
void (*init) (struct grub_dl *mod);
void (*fini) (void);
};