Discard a bunch of junk code
This commit is contained in:
parent
5faa440cb0
commit
0718f66d12
8 changed files with 10 additions and 1327 deletions
|
@ -402,14 +402,12 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (bind != STB_LOCAL)
|
if (bind != STB_LOCAL)
|
||||||
{
|
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
||||||
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
|
return grub_errno;
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
if (grub_strcmp (name, "grub_mod_init") == 0)
|
if (grub_strcmp (name, "grub_mod_init") == 0)
|
||||||
mod->init = sym->st_value;
|
mod->init = (void (*) (grub_dl_t)) sym->st_value;
|
||||||
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
else if (grub_strcmp (name, "grub_mod_fini") == 0)
|
||||||
mod->fini = sym->st_value;
|
mod->fini = (void (*) (void)) sym->st_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STT_SECTION:
|
case STT_SECTION:
|
||||||
|
@ -434,9 +432,7 @@ static void
|
||||||
grub_dl_call_init (grub_dl_t mod)
|
grub_dl_call_init (grub_dl_t mod)
|
||||||
{
|
{
|
||||||
if (mod->init)
|
if (mod->init)
|
||||||
{
|
(mod->init) (mod);
|
||||||
((void (*) (grub_dl_t)) mod->init) (mod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -599,7 +595,7 @@ grub_dl_load_core (void *addr, grub_size_t size)
|
||||||
grub_dl_flush_cache (mod);
|
grub_dl_flush_cache (mod);
|
||||||
|
|
||||||
grub_dprintf ("modules", "module name: %s\n", mod->name);
|
grub_dprintf ("modules", "module name: %s\n", mod->name);
|
||||||
grub_dprintf ("modules", "init function: %" PRIxGRUB_ADDR "\n", mod->init);
|
grub_dprintf ("modules", "init function: %p\n", mod->init);
|
||||||
grub_dl_call_init (mod);
|
grub_dl_call_init (mod);
|
||||||
|
|
||||||
if (grub_dl_add (mod))
|
if (grub_dl_add (mod))
|
||||||
|
@ -699,9 +695,7 @@ grub_dl_unload (grub_dl_t mod)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (mod->fini)
|
if (mod->fini)
|
||||||
{
|
(mod->fini) ();
|
||||||
((void (*) (void)) mod->fini) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dl_remove (mod);
|
grub_dl_remove (mod);
|
||||||
grub_dl_unregister_symbols (mod);
|
grub_dl_unregister_symbols (mod);
|
||||||
|
|
|
@ -76,7 +76,6 @@ grub_modules_get_end (void)
|
||||||
static void
|
static void
|
||||||
grub_load_modules (void)
|
grub_load_modules (void)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
auto int hook (struct grub_module_header *);
|
auto int hook (struct grub_module_header *);
|
||||||
int hook (struct grub_module_header *header)
|
int hook (struct grub_module_header *header)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +94,6 @@ grub_load_modules (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_module_iterate (hook);
|
grub_module_iterate (hook);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -313,7 +313,7 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* Unload unneeded modules. */
|
/* Unload unneeded modules. */
|
||||||
// grub_dl_unload_unneeded ();
|
grub_dl_unload_unneeded ();
|
||||||
count++;
|
count++;
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,8 @@ struct grub_dl
|
||||||
grub_dl_dep_t dep;
|
grub_dl_dep_t dep;
|
||||||
grub_dl_segment_t segment;
|
grub_dl_segment_t segment;
|
||||||
Elf_Sym *symtab;
|
Elf_Sym *symtab;
|
||||||
grub_addr_t init;
|
void (*init) (struct grub_dl *mod);
|
||||||
grub_addr_t fini;
|
void (*fini) (void);
|
||||||
#ifdef __ia64__
|
#ifdef __ia64__
|
||||||
void *got;
|
void *got;
|
||||||
void *tramp;
|
void *tramp;
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2008 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void EXPORT_FUNC (__ia64_trampoline) (void);
|
|
||||||
void EXPORT_FUNC (grub_init_modules) (void);
|
|
||||||
|
|
||||||
void
|
|
||||||
grub_init_module (const char *name,
|
|
||||||
void (*init)(grub_dl_t), void (*fini)(void));
|
|
||||||
|
|
||||||
extern unsigned long EXPORT_VAR (__gp);
|
|
||||||
|
|
|
@ -1,812 +0,0 @@
|
||||||
/* elf2pe.c - convert elf binary to PE/Coff. */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2008 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <elf.h>
|
|
||||||
|
|
||||||
#if defined(ELF2PE_I386)
|
|
||||||
#define USE_ELF32
|
|
||||||
#define USE_PE32
|
|
||||||
#define ELF_MACHINE EM_386
|
|
||||||
#define EFI_MACHINE PE32_MACHINE_I386
|
|
||||||
#elif defined(ELF2PE_IA64)
|
|
||||||
#define USE_ELF64
|
|
||||||
#define USE_PE32PLUS
|
|
||||||
#define ELF_MACHINE EM_IA_64
|
|
||||||
#define EFI_MACHINE PE32_MACHINE_IA64
|
|
||||||
#else
|
|
||||||
#error "unknown architecture"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pe32.h"
|
|
||||||
|
|
||||||
const char *filename;
|
|
||||||
|
|
||||||
int
|
|
||||||
is_elf_header(uint8_t *buffer)
|
|
||||||
{
|
|
||||||
return (buffer[EI_MAG0] == ELFMAG0
|
|
||||||
&& buffer[EI_MAG1] == ELFMAG1
|
|
||||||
&& buffer[EI_MAG2] == ELFMAG2
|
|
||||||
&& buffer[EI_MAG3] == ELFMAG3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ELF32
|
|
||||||
typedef Elf32_Shdr Elf_Shdr;
|
|
||||||
typedef Elf32_Ehdr Elf_Ehdr;
|
|
||||||
typedef Elf32_Rel Elf_Rel;
|
|
||||||
typedef Elf32_Rela Elf_Rela;
|
|
||||||
typedef Elf32_Sym Elf_Sym;
|
|
||||||
#define ELFCLASS ELFCLASS32
|
|
||||||
#define ELF_R_TYPE(r) ELF32_R_TYPE(r)
|
|
||||||
#define ELF_R_SYM(r) ELF32_R_SYM(r)
|
|
||||||
#else
|
|
||||||
typedef Elf64_Shdr Elf_Shdr;
|
|
||||||
typedef Elf64_Ehdr Elf_Ehdr;
|
|
||||||
typedef Elf64_Rel Elf_Rel;
|
|
||||||
typedef Elf64_Rela Elf_Rela;
|
|
||||||
typedef Elf64_Sym Elf_Sym;
|
|
||||||
#define ELFCLASS ELFCLASS64
|
|
||||||
#define ELF_R_TYPE(r) ELF64_R_TYPE(r)
|
|
||||||
#define ELF_R_SYM(r) ELF64_R_SYM(r)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
#define ELF_ETYPE ET_DYN
|
|
||||||
#else
|
|
||||||
#define ELF_ETYPE ET_EXEC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Well known ELF structures. */
|
|
||||||
Elf_Ehdr *ehdr;
|
|
||||||
Elf_Shdr *shdr_base;
|
|
||||||
Elf_Shdr *shdr_dynamic;
|
|
||||||
const uint8_t *shdr_str;
|
|
||||||
|
|
||||||
/* PE section alignment. */
|
|
||||||
const uint32_t coff_alignment = 0x20;
|
|
||||||
const uint32_t coff_nbr_sections = 4;
|
|
||||||
|
|
||||||
/* Current offset in coff file. */
|
|
||||||
uint32_t coff_offset;
|
|
||||||
|
|
||||||
/* Result Coff file in memory. */
|
|
||||||
uint8_t *coff_file;
|
|
||||||
|
|
||||||
/* Offset in Coff file of headers and sections. */
|
|
||||||
uint32_t nt_hdr_offset;
|
|
||||||
uint32_t table_offset;
|
|
||||||
uint32_t text_offset;
|
|
||||||
uint32_t data_offset;
|
|
||||||
uint32_t reloc_offset;
|
|
||||||
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
uint32_t coff_entry_descr_offset;
|
|
||||||
uint32_t coff_entry_descr_func;
|
|
||||||
uint64_t plt_base;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ELF sections to offset in Coff file. */
|
|
||||||
uint32_t *coff_sections_offset;
|
|
||||||
|
|
||||||
struct pe32_fixup_block *coff_base_rel;
|
|
||||||
uint16_t *coff_entry_rel;
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
coff_align(uint32_t offset)
|
|
||||||
{
|
|
||||||
return (offset + coff_alignment - 1) & ~(coff_alignment - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Elf_Shdr *
|
|
||||||
get_shdr_by_index(uint32_t num)
|
|
||||||
{
|
|
||||||
if (num >= ehdr->e_shnum)
|
|
||||||
return NULL;
|
|
||||||
return (Elf_Shdr*)((uint8_t*)shdr_base + num * ehdr->e_shentsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_elf_header (void)
|
|
||||||
{
|
|
||||||
/* Note: Magic has already been tested. */
|
|
||||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
|
|
||||||
return 0;
|
|
||||||
if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
|
|
||||||
return 0;
|
|
||||||
if (ehdr->e_type != ELF_ETYPE)
|
|
||||||
return 0;
|
|
||||||
if (ehdr->e_machine != ELF_MACHINE)
|
|
||||||
return 0;
|
|
||||||
if (ehdr->e_version != EV_CURRENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
shdr_base = (Elf_Shdr *)((uint8_t *)ehdr + ehdr->e_shoff);
|
|
||||||
|
|
||||||
coff_sections_offset =
|
|
||||||
(uint32_t *)malloc (ehdr->e_shnum * sizeof (uint32_t));
|
|
||||||
memset (coff_sections_offset, 0, ehdr->e_shnum * sizeof(uint32_t));
|
|
||||||
|
|
||||||
if (ehdr->e_shstrndx != SHN_UNDEF)
|
|
||||||
shdr_str = (uint8_t*)ehdr + shdr_base[ehdr->e_shstrndx].sh_offset;
|
|
||||||
else
|
|
||||||
shdr_str = NULL;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
is_text_shdr (Elf_Shdr *shdr)
|
|
||||||
{
|
|
||||||
if (shdr->sh_type != SHT_PROGBITS) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
return (shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC))
|
|
||||||
== (SHF_ALLOC | SHF_EXECINSTR);
|
|
||||||
#else
|
|
||||||
return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
is_data_shdr (Elf_Shdr *shdr)
|
|
||||||
{
|
|
||||||
if (shdr->sh_type != SHT_PROGBITS && shdr->sh_type != SHT_NOBITS) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
create_section_header (const char *name, uint32_t offset, uint32_t size,
|
|
||||||
uint32_t flags)
|
|
||||||
{
|
|
||||||
struct pe32_section_header *hdr;
|
|
||||||
hdr = (struct pe32_section_header*)(coff_file + table_offset);
|
|
||||||
|
|
||||||
strcpy (hdr->name, name);
|
|
||||||
hdr->virtual_size = size;
|
|
||||||
hdr->virtual_address = offset;
|
|
||||||
hdr->raw_data_size = size;
|
|
||||||
hdr->raw_data_offset = offset;
|
|
||||||
hdr->relocations_offset = 0;
|
|
||||||
hdr->line_numbers_offset = 0;
|
|
||||||
hdr->num_relocations = 0;
|
|
||||||
hdr->num_line_numbers = 0;
|
|
||||||
hdr->characteristics = flags;
|
|
||||||
|
|
||||||
table_offset += sizeof (struct pe32_section_header);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
scan_sections (void)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
struct pe32_dos_header *doshdr;
|
|
||||||
struct pe32_nt_header *nt_hdr;
|
|
||||||
uint32_t coff_entry = 0;
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
coff_offset = 0;
|
|
||||||
|
|
||||||
/* Coff file start with a DOS header. */
|
|
||||||
coff_offset = sizeof(struct pe32_dos_header);
|
|
||||||
nt_hdr_offset = coff_offset;
|
|
||||||
coff_offset += sizeof(struct pe32_nt_header);
|
|
||||||
table_offset = coff_offset;
|
|
||||||
coff_offset += coff_nbr_sections * sizeof(struct pe32_section_header);
|
|
||||||
|
|
||||||
/* First text sections. */
|
|
||||||
coff_offset = coff_align(coff_offset);
|
|
||||||
text_offset = coff_offset;
|
|
||||||
for (i = 0; i < ehdr->e_shnum; i++) {
|
|
||||||
Elf_Shdr *shdr = get_shdr_by_index (i);
|
|
||||||
if (is_text_shdr (shdr)) {
|
|
||||||
/* Relocate entry. */
|
|
||||||
if (ehdr->e_entry >= shdr->sh_addr
|
|
||||||
&& ehdr->e_entry < shdr->sh_addr + shdr->sh_size) {
|
|
||||||
coff_entry = coff_offset + ehdr->e_entry - shdr->sh_addr;
|
|
||||||
}
|
|
||||||
coff_sections_offset[i] = coff_offset;
|
|
||||||
coff_offset += shdr->sh_size;
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
if (coff_sections_offset[i] != shdr->sh_addr) {
|
|
||||||
fprintf (stderr,
|
|
||||||
"Section %s: Coff offset (%x) != Elf offset (%lx)",
|
|
||||||
shdr_str + shdr->sh_name,
|
|
||||||
coff_sections_offset[i],
|
|
||||||
shdr->sh_addr);
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (shdr->sh_type == SHT_DYNAMIC) {
|
|
||||||
shdr_dynamic = shdr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
/* 16 bytes are reserved (by the ld script) for the entry point descriptor.
|
|
||||||
*/
|
|
||||||
coff_entry_descr_offset = coff_offset - 16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
coff_offset = coff_align (coff_offset);
|
|
||||||
|
|
||||||
/* Then data sections. */
|
|
||||||
data_offset = coff_offset;
|
|
||||||
for (i = 0; i < ehdr->e_shnum; i++) {
|
|
||||||
Elf_Shdr *shdr = get_shdr_by_index (i);
|
|
||||||
if (is_data_shdr (shdr)) {
|
|
||||||
coff_sections_offset[i] = coff_offset;
|
|
||||||
coff_offset += shdr->sh_size;
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
if (coff_sections_offset[i] != shdr->sh_addr) {
|
|
||||||
fprintf (stderr,
|
|
||||||
"Section %s: Coff offset (%x) != Elf offset (%lx)",
|
|
||||||
shdr_str + shdr->sh_name,
|
|
||||||
coff_sections_offset[i],
|
|
||||||
shdr->sh_addr);
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
coff_offset = coff_align (coff_offset);
|
|
||||||
|
|
||||||
reloc_offset = coff_offset;
|
|
||||||
|
|
||||||
/* Allocate base Coff file. Will be expanded later for relocations. */
|
|
||||||
coff_file = (uint8_t *)malloc (coff_offset);
|
|
||||||
memset (coff_file, 0, coff_offset);
|
|
||||||
|
|
||||||
/* Fill headers. */
|
|
||||||
doshdr = (struct pe32_dos_header *)coff_file;
|
|
||||||
doshdr->magic = 0x5A4D;
|
|
||||||
doshdr->new_hdr_offset = nt_hdr_offset;
|
|
||||||
|
|
||||||
nt_hdr = (struct pe32_nt_header*)(coff_file + nt_hdr_offset);
|
|
||||||
|
|
||||||
memcpy (nt_hdr->signature, "PE\0", 4);
|
|
||||||
|
|
||||||
nt_hdr->coff_header.machine = EFI_MACHINE;
|
|
||||||
nt_hdr->coff_header.num_sections = coff_nbr_sections;
|
|
||||||
nt_hdr->coff_header.time = time (NULL);
|
|
||||||
nt_hdr->coff_header.symtab_offset = 0;
|
|
||||||
nt_hdr->coff_header.num_symbols = 0;
|
|
||||||
nt_hdr->coff_header.optional_header_size = sizeof(nt_hdr->optional_header);
|
|
||||||
nt_hdr->coff_header.characteristics = PE32_EXECUTABLE_IMAGE
|
|
||||||
| PE32_LINE_NUMS_STRIPPED
|
|
||||||
| PE32_LOCAL_SYMS_STRIPPED
|
|
||||||
| PE32_32BIT_MACHINE;
|
|
||||||
|
|
||||||
#ifdef USE_PE32
|
|
||||||
nt_hdr->optional_header.magic = PE32_PE32_MAGIC;
|
|
||||||
#else
|
|
||||||
nt_hdr->optional_header.magic = PE32_PE64_MAGIC;
|
|
||||||
#endif
|
|
||||||
nt_hdr->optional_header.code_size = data_offset - text_offset;
|
|
||||||
nt_hdr->optional_header.data_size = reloc_offset - data_offset;
|
|
||||||
nt_hdr->optional_header.bss_size = 0;
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
nt_hdr->optional_header.entry_addr = coff_entry_descr_offset;
|
|
||||||
coff_entry_descr_func = coff_entry;
|
|
||||||
#else
|
|
||||||
nt_hdr->optional_header.entry_addr = coff_entry;
|
|
||||||
#endif
|
|
||||||
nt_hdr->optional_header.code_base = text_offset;
|
|
||||||
|
|
||||||
#ifdef USE_PE32
|
|
||||||
nt_hdr->optional_header.data_base = data_offset;
|
|
||||||
#endif
|
|
||||||
nt_hdr->optional_header.image_base = 0;
|
|
||||||
nt_hdr->optional_header.section_alignment = coff_alignment;
|
|
||||||
nt_hdr->optional_header.file_alignment = coff_alignment;
|
|
||||||
nt_hdr->optional_header.image_size = 0;
|
|
||||||
|
|
||||||
nt_hdr->optional_header.header_size = text_offset;
|
|
||||||
nt_hdr->optional_header.num_data_directories = PE32_NUM_DATA_DIRECTORIES;
|
|
||||||
|
|
||||||
/* Section headers. */
|
|
||||||
create_section_header (".text", text_offset, data_offset - text_offset,
|
|
||||||
PE32_SCN_CNT_CODE
|
|
||||||
| PE32_SCN_MEM_EXECUTE
|
|
||||||
| PE32_SCN_MEM_READ);
|
|
||||||
create_section_header (".data", data_offset, reloc_offset - data_offset,
|
|
||||||
PE32_SCN_CNT_INITIALIZED_DATA
|
|
||||||
| PE32_SCN_MEM_WRITE
|
|
||||||
| PE32_SCN_MEM_READ);
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
if (shdr_dynamic != NULL)
|
|
||||||
{
|
|
||||||
Elf64_Dyn *dyn = (Elf64_Dyn*)((uint8_t*)ehdr + shdr_dynamic->sh_offset);
|
|
||||||
while (dyn->d_tag != DT_NULL)
|
|
||||||
{
|
|
||||||
if (dyn->d_tag == DT_PLTGOT)
|
|
||||||
plt_base = dyn->d_un.d_ptr;
|
|
||||||
dyn++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
write_sections (int (*filter)(Elf_Shdr *))
|
|
||||||
{
|
|
||||||
uint32_t idx;
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
/* First: copy sections. */
|
|
||||||
for (idx = 0; idx < ehdr->e_shnum; idx++)
|
|
||||||
{
|
|
||||||
Elf_Shdr *shdr = get_shdr_by_index (idx);
|
|
||||||
if ((*filter)(shdr))
|
|
||||||
{
|
|
||||||
switch (shdr->sh_type) {
|
|
||||||
case SHT_PROGBITS:
|
|
||||||
/* Copy. */
|
|
||||||
memcpy (coff_file + coff_sections_offset[idx],
|
|
||||||
(uint8_t*)ehdr + shdr->sh_offset,
|
|
||||||
shdr->sh_size);
|
|
||||||
break;
|
|
||||||
case SHT_NOBITS:
|
|
||||||
memset (coff_file + coff_sections_offset[idx], 0, shdr->sh_size);
|
|
||||||
break;
|
|
||||||
case SHT_DYNAMIC:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf (stderr, "unhandled section type %x",
|
|
||||||
(unsigned int)shdr->sh_type);
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Second: apply relocations. */
|
|
||||||
for (idx = 0; idx < ehdr->e_shnum; idx++)
|
|
||||||
{
|
|
||||||
Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
|
|
||||||
if (rel_shdr->sh_type != SHT_REL && rel_shdr->sh_type != SHT_RELA)
|
|
||||||
continue;
|
|
||||||
Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
|
|
||||||
uint32_t sec_offset = coff_sections_offset[rel_shdr->sh_info];
|
|
||||||
|
|
||||||
if (rel_shdr->sh_info == 0 || (*filter)(sec_shdr))
|
|
||||||
{
|
|
||||||
uint32_t rel_idx;
|
|
||||||
Elf_Shdr *symtab_shdr = get_shdr_by_index(rel_shdr->sh_link);
|
|
||||||
uint8_t *symtab = (uint8_t*)ehdr + symtab_shdr->sh_offset;
|
|
||||||
|
|
||||||
if (rel_shdr->sh_type == SHT_REL)
|
|
||||||
{
|
|
||||||
for (rel_idx = 0;
|
|
||||||
rel_idx < rel_shdr->sh_size;
|
|
||||||
rel_idx += rel_shdr->sh_entsize)
|
|
||||||
{
|
|
||||||
Elf_Rel *rel = (Elf_Rel *)
|
|
||||||
((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
|
|
||||||
Elf_Sym *sym = (Elf_Sym *)
|
|
||||||
(symtab
|
|
||||||
+ ELF_R_SYM(rel->r_info) * symtab_shdr->sh_entsize);
|
|
||||||
Elf_Shdr *sym_shdr;
|
|
||||||
uint8_t *targ;
|
|
||||||
|
|
||||||
if (sym->st_shndx == SHN_UNDEF
|
|
||||||
|| sym->st_shndx == SHN_ABS
|
|
||||||
|| sym->st_shndx > ehdr->e_shnum)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "bad symbol definition");
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
sym_shdr = get_shdr_by_index(sym->st_shndx);
|
|
||||||
|
|
||||||
/* Note: r_offset in a memory address.
|
|
||||||
Convert it to a pointer in the coff file. */
|
|
||||||
targ = coff_file + sec_offset
|
|
||||||
+ (rel->r_offset - sec_shdr->sh_addr);
|
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rel->r_info)) {
|
|
||||||
case R_386_NONE:
|
|
||||||
break;
|
|
||||||
case R_386_32:
|
|
||||||
/* Absolute relocation. */
|
|
||||||
*(uint32_t *)targ = *(uint32_t *)targ - sym_shdr->sh_addr
|
|
||||||
+ coff_sections_offset[sym->st_shndx];
|
|
||||||
break;
|
|
||||||
case R_386_PC32:
|
|
||||||
/* Relative relocation: Symbol - Ip + Addend */
|
|
||||||
*(uint32_t *)targ = *(uint32_t *)targ
|
|
||||||
+ (coff_sections_offset[sym->st_shndx]
|
|
||||||
- sym_shdr->sh_addr)
|
|
||||||
- (sec_offset - sec_shdr->sh_addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf (stderr, "unhandled relocation type %lx",
|
|
||||||
ELF_R_TYPE(rel->r_info));
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rel_shdr->sh_type == SHT_RELA)
|
|
||||||
{
|
|
||||||
for (rel_idx = 0;
|
|
||||||
rel_idx < rel_shdr->sh_size;
|
|
||||||
rel_idx += rel_shdr->sh_entsize) {
|
|
||||||
Elf_Rela *rela = (Elf_Rela *)
|
|
||||||
((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
|
|
||||||
Elf_Sym *sym = (Elf_Sym *)
|
|
||||||
(symtab + ELF_R_SYM(rela->r_info) * symtab_shdr->sh_entsize);
|
|
||||||
Elf_Shdr *sym_shdr;
|
|
||||||
uint8_t *targ;
|
|
||||||
|
|
||||||
if (ELF_R_TYPE(rela->r_info) == R_IA64_NONE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (sym->st_shndx == SHN_UNDEF
|
|
||||||
|| sym->st_shndx == SHN_ABS
|
|
||||||
|| sym->st_shndx > ehdr->e_shnum) {
|
|
||||||
fprintf (stderr, "bad symbol definition %d",
|
|
||||||
ELF_R_SYM(rela->r_info));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sym_shdr = get_shdr_by_index (sym->st_shndx);
|
|
||||||
|
|
||||||
/* Note: r_offset in a memory address.
|
|
||||||
Convert it to a pointer in the coff file. */
|
|
||||||
targ = coff_file + sec_offset
|
|
||||||
+ (rela->r_offset - sec_shdr->sh_addr);
|
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rela->r_info)) {
|
|
||||||
case R_IA64_IPLTLSB:
|
|
||||||
/* If there is a descriptor with the same function
|
|
||||||
pointer as the ELF entry point, use that
|
|
||||||
descriptor for the PE/Coff entry. */
|
|
||||||
if (*(uint64_t*)targ == ehdr->e_entry) {
|
|
||||||
struct pe32_nt_header *nt_hdr;
|
|
||||||
|
|
||||||
nt_hdr =
|
|
||||||
(struct pe32_nt_header*)(coff_file + nt_hdr_offset);
|
|
||||||
nt_hdr->optional_header.entry_addr = targ - coff_file;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case R_IA64_REL64LSB:
|
|
||||||
case R_IA64_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf (stderr,
|
|
||||||
"unhandled relocation type %lx in section %d",
|
|
||||||
ELF_R_TYPE(rela->r_info), rel_shdr->sh_info);
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coff_add_fixup_entry (uint16_t val)
|
|
||||||
{
|
|
||||||
*coff_entry_rel = val;
|
|
||||||
coff_entry_rel++;
|
|
||||||
coff_base_rel->block_size += 2;
|
|
||||||
coff_offset += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coff_add_fixup (uint32_t offset, uint8_t type)
|
|
||||||
{
|
|
||||||
if (coff_base_rel == NULL
|
|
||||||
|| coff_base_rel->page_rva != (offset & ~0xfff)) {
|
|
||||||
if (coff_base_rel != NULL) {
|
|
||||||
/* Add a null entry (is it required ?) */
|
|
||||||
coff_add_fixup_entry (0);
|
|
||||||
/* Pad for alignment. */
|
|
||||||
if (coff_offset % 4 != 0)
|
|
||||||
coff_add_fixup_entry (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
coff_file = realloc
|
|
||||||
(coff_file,
|
|
||||||
coff_offset + sizeof(struct pe32_fixup_block) + 2*0x1000);
|
|
||||||
memset(coff_file + coff_offset, 0,
|
|
||||||
sizeof(struct pe32_fixup_block) + 2*0x1000);
|
|
||||||
|
|
||||||
coff_base_rel = (struct pe32_fixup_block*)(coff_file + coff_offset);
|
|
||||||
coff_base_rel->page_rva = offset & ~0xfff;
|
|
||||||
coff_base_rel->block_size = sizeof(struct pe32_fixup_block);
|
|
||||||
|
|
||||||
coff_entry_rel = (uint16_t *)(coff_base_rel + 1);
|
|
||||||
coff_offset += sizeof(struct pe32_fixup_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the entry. */
|
|
||||||
coff_add_fixup_entry ((type << 12) | (offset & 0xfff));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
write_relocations(void)
|
|
||||||
{
|
|
||||||
uint32_t idx;
|
|
||||||
struct pe32_nt_header *nt_hdr;
|
|
||||||
struct pe32_data_directory *dir;
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
for (idx = 0; idx < ehdr->e_shnum; idx++)
|
|
||||||
{
|
|
||||||
Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
|
|
||||||
if (rel_shdr->sh_type == SHT_REL)
|
|
||||||
{
|
|
||||||
Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
|
|
||||||
if (is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
|
|
||||||
{
|
|
||||||
uint32_t rel_idx;
|
|
||||||
for (rel_idx = 0;
|
|
||||||
rel_idx < rel_shdr->sh_size;
|
|
||||||
rel_idx += rel_shdr->sh_entsize)
|
|
||||||
{
|
|
||||||
Elf_Rel *rel = (Elf_Rel *)
|
|
||||||
((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
|
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rel->r_info))
|
|
||||||
{
|
|
||||||
case R_386_NONE:
|
|
||||||
case R_386_PC32:
|
|
||||||
break;
|
|
||||||
case R_386_32:
|
|
||||||
coff_add_fixup(coff_sections_offset[rel_shdr->sh_info]
|
|
||||||
+ (rel->r_offset - sec_shdr->sh_addr),
|
|
||||||
PE32_REL_BASED_HIGHLOW);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf (stderr, "unhandled relocation type %lx",
|
|
||||||
ELF_R_TYPE(rel->r_info));
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rel_shdr->sh_type == SHT_RELA)
|
|
||||||
{
|
|
||||||
Elf_Shdr *sec_shdr = get_shdr_by_index(rel_shdr->sh_info);
|
|
||||||
if (rel_shdr->sh_info == 0
|
|
||||||
|| is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
|
|
||||||
{
|
|
||||||
uint32_t rel_idx;
|
|
||||||
for (rel_idx = 0;
|
|
||||||
rel_idx < rel_shdr->sh_size;
|
|
||||||
rel_idx += rel_shdr->sh_entsize) {
|
|
||||||
Elf_Rela *rela = (Elf_Rela *)
|
|
||||||
((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
|
|
||||||
uint32_t Loc = coff_sections_offset[rel_shdr->sh_info]
|
|
||||||
+ (rela->r_offset - sec_shdr->sh_addr);
|
|
||||||
|
|
||||||
switch (ELF_R_TYPE(rela->r_info))
|
|
||||||
{
|
|
||||||
case R_IA64_IPLTLSB:
|
|
||||||
coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
|
|
||||||
coff_add_fixup(Loc + 8, PE32_REL_BASED_DIR64);
|
|
||||||
break;
|
|
||||||
case R_IA64_REL64LSB:
|
|
||||||
coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
|
|
||||||
break;
|
|
||||||
case R_IA64_DIR64LSB:
|
|
||||||
coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
|
|
||||||
break;
|
|
||||||
case R_IA64_IMM64:
|
|
||||||
coff_add_fixup(Loc, PE32_REL_BASED_IA64_IMM64);
|
|
||||||
break;
|
|
||||||
case R_IA64_PCREL21B:
|
|
||||||
case R_IA64_PCREL64LSB:
|
|
||||||
case R_IA64_SECREL32LSB:
|
|
||||||
case R_IA64_SEGREL64LSB:
|
|
||||||
break;
|
|
||||||
case R_IA64_GPREL22:
|
|
||||||
case R_IA64_LTOFF22X:
|
|
||||||
case R_IA64_LDXMOV:
|
|
||||||
case R_IA64_LTOFF_FPTR22:
|
|
||||||
case R_IA64_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf (stderr, "unhandled relocation type %lx",
|
|
||||||
ELF_R_TYPE(rela->r_info));
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
coff_add_fixup (coff_entry_descr_offset, PE32_REL_BASED_DIR64);
|
|
||||||
coff_add_fixup (coff_entry_descr_offset + 8, PE32_REL_BASED_DIR64);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Pad by adding empty entries. */
|
|
||||||
while (coff_offset & (coff_alignment - 1))
|
|
||||||
coff_add_fixup_entry (0);
|
|
||||||
|
|
||||||
create_section_header (".reloc", reloc_offset, coff_offset - reloc_offset,
|
|
||||||
PE32_SCN_CNT_INITIALIZED_DATA
|
|
||||||
| PE32_SCN_MEM_DISCARDABLE
|
|
||||||
| PE32_SCN_MEM_READ);
|
|
||||||
|
|
||||||
nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
|
|
||||||
dir = &nt_hdr->optional_header.base_relocation_table;
|
|
||||||
dir->rva = reloc_offset;
|
|
||||||
dir->size = coff_offset - reloc_offset;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
write_debug(void)
|
|
||||||
{
|
|
||||||
uint32_t len = strlen(filename) + 1;
|
|
||||||
uint32_t debug_offset = coff_offset;
|
|
||||||
struct pe32_nt_header *nt_hdr;
|
|
||||||
struct pe32_data_directory *data_dir;
|
|
||||||
struct pe32_debug_directory_entry *dir;
|
|
||||||
struct pe32_debug_codeview_nb10_entry *nb10;
|
|
||||||
|
|
||||||
coff_offset += sizeof (struct pe32_debug_directory_entry)
|
|
||||||
+ sizeof(struct pe32_debug_codeview_nb10_entry)
|
|
||||||
+ len;
|
|
||||||
coff_offset = coff_align(coff_offset);
|
|
||||||
|
|
||||||
coff_file = realloc
|
|
||||||
(coff_file, coff_offset);
|
|
||||||
memset(coff_file + debug_offset, 0, coff_offset - debug_offset);
|
|
||||||
|
|
||||||
dir = (struct pe32_debug_directory_entry*)(coff_file + debug_offset);
|
|
||||||
dir->type = PE32_DEBUG_TYPE_CODEVIEW;
|
|
||||||
dir->data_size = sizeof(struct pe32_debug_directory_entry) + len;
|
|
||||||
dir->rva = debug_offset + sizeof(struct pe32_debug_directory_entry);
|
|
||||||
dir->file_offset = debug_offset + sizeof(struct pe32_debug_directory_entry);
|
|
||||||
|
|
||||||
nb10 = (struct pe32_debug_codeview_nb10_entry*)(dir + 1);
|
|
||||||
nb10->signature = PE32_CODEVIEW_SIGNATURE_NB10;
|
|
||||||
strcpy (nb10->filename, filename);
|
|
||||||
|
|
||||||
create_section_header (".debug", debug_offset, coff_offset - debug_offset,
|
|
||||||
PE32_SCN_CNT_INITIALIZED_DATA
|
|
||||||
| PE32_SCN_MEM_DISCARDABLE
|
|
||||||
| PE32_SCN_MEM_READ);
|
|
||||||
|
|
||||||
nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
|
|
||||||
data_dir = &nt_hdr->optional_header.debug;
|
|
||||||
data_dir->rva = debug_offset;
|
|
||||||
data_dir->size = coff_offset - debug_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
convert_elf (uint8_t **file_buffer, unsigned int *file_length)
|
|
||||||
{
|
|
||||||
struct pe32_nt_header *nt_hdr;
|
|
||||||
|
|
||||||
/* Check header, read section table. */
|
|
||||||
ehdr = (Elf_Ehdr*)*file_buffer;
|
|
||||||
if (!check_elf_header ())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Compute sections new address. */
|
|
||||||
if (scan_sections () != 0)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
/* Write and relocate sections. */
|
|
||||||
if (write_sections (is_text_shdr) != 0)
|
|
||||||
return -3;
|
|
||||||
|
|
||||||
#ifdef ELF2PE_IA64
|
|
||||||
*(uint64_t*)(coff_file + coff_entry_descr_offset) = coff_entry_descr_func;
|
|
||||||
*(uint64_t*)(coff_file + coff_entry_descr_offset + 8) = plt_base;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (write_sections (is_data_shdr) != 0)
|
|
||||||
return -4;
|
|
||||||
|
|
||||||
/* Translate and write relocations. */
|
|
||||||
if (write_relocations () != 0)
|
|
||||||
return -5;
|
|
||||||
|
|
||||||
/* Write debug info. */
|
|
||||||
write_debug ();
|
|
||||||
|
|
||||||
nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
|
|
||||||
nt_hdr->optional_header.image_size = coff_offset;
|
|
||||||
|
|
||||||
nt_hdr->optional_header.subsystem = PE32_SUBSYSTEM_EFI_APPLICATION;
|
|
||||||
|
|
||||||
/* Replace. */
|
|
||||||
free (*file_buffer);
|
|
||||||
*file_buffer = coff_file;
|
|
||||||
*file_length = coff_offset;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
unsigned int size;
|
|
||||||
uint8_t *buffer;
|
|
||||||
const char *outfile;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (argc != 3)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "usage: %s elf-file pe-file\n", argv[0]);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = argv[1];
|
|
||||||
outfile = argv[2];
|
|
||||||
f = fopen (filename, "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
size = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
|
|
||||||
buffer = malloc (size);
|
|
||||||
if (buffer == NULL)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "cannot allocate %u bytes of memory\n", size);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
if (fread (buffer, size, 1, f) != 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "cannot read %s\n", filename);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
fclose (f);
|
|
||||||
|
|
||||||
if (!is_elf_header (buffer))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s is not an elf file\n", filename);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = convert_elf (&buffer, &size);
|
|
||||||
if (status != 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "cannot convert %s to pe (err=%d)\n", filename, status);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen (outfile, "wb");
|
|
||||||
if (f == NULL)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "cannot open %s\n", outfile);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
if (fwrite (buffer, size, 1, f) != 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "cannot write to %s\n", outfile);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
fclose (f);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,233 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
# Install GRUB on your EFI partition.
|
|
||||||
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 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 <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
# Initialize some variables.
|
|
||||||
prefix=@prefix@
|
|
||||||
exec_prefix=@exec_prefix@
|
|
||||||
sbindir=@sbindir@
|
|
||||||
bindir=@bindir@
|
|
||||||
libdir=@libdir@
|
|
||||||
datadir=@datadir@
|
|
||||||
PACKAGE_NAME=@PACKAGE_NAME@
|
|
||||||
PACKAGE_TARNAME=@PACKAGE_TARNAME@
|
|
||||||
PACKAGE_VERSION=@PACKAGE_VERSION@
|
|
||||||
target_cpu=@target_cpu@
|
|
||||||
platform=@platform@
|
|
||||||
pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
|
|
||||||
pkgdatadir=${datadir}/${PACKAGE_TARNAME}
|
|
||||||
|
|
||||||
|
|
||||||
TARGET_CC=@TARGET_CC@
|
|
||||||
TARGET_CFLAGS="@TARGET_CFLAGS@"
|
|
||||||
TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
|
|
||||||
TARGET_LDFLAGS="@TARGET_LDFLAGS@"
|
|
||||||
OBJCOPY=@OBJCOPY@
|
|
||||||
|
|
||||||
grub_setup=${sbindir}/grub-setup
|
|
||||||
grub_mkimage=${bindir}/grub-mkimage
|
|
||||||
grub_mkdevicemap=${sbindir}/grub-mkdevicemap
|
|
||||||
grub_probefs=${sbindir}/grub-probefs
|
|
||||||
rootdir=
|
|
||||||
grub_prefix=/boot/grub
|
|
||||||
modules=
|
|
||||||
|
|
||||||
install_device=
|
|
||||||
recheck=no
|
|
||||||
debug=no
|
|
||||||
|
|
||||||
# Usage: usage
|
|
||||||
# Print the usage.
|
|
||||||
usage () {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: grub-install [OPTION] install_device
|
|
||||||
Install GRUB on your drive.
|
|
||||||
|
|
||||||
-h, --help print this message and exit
|
|
||||||
-v, --version print the version information and exit
|
|
||||||
--modules=MODULES pre-load specified modules MODULES
|
|
||||||
--root-directory=DIR install GRUB images under the directory DIR
|
|
||||||
instead of the root directory
|
|
||||||
--grub-setup=FILE use FILE as grub-setup
|
|
||||||
--grub-mkimage=FILE use FILE as grub-mkimage
|
|
||||||
--grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
|
|
||||||
--grub-probefs=FILE use FILE as grub-probefs
|
|
||||||
--no-floppy do not probe any floppy drive
|
|
||||||
--recheck probe a device map even if it already exists
|
|
||||||
|
|
||||||
INSTALL_DEVICE can be a GRUB device name or a system device filename.
|
|
||||||
|
|
||||||
grub-install copies GRUB images into the DIR/boot directory specfied by
|
|
||||||
--root-directory, and uses grub-setup to install grub into the boot
|
|
||||||
sector.
|
|
||||||
|
|
||||||
Report bugs to <bug-grub@gnu.org>.
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check the arguments.
|
|
||||||
for option in "$@"; do
|
|
||||||
case "$option" in
|
|
||||||
-h | --help)
|
|
||||||
usage
|
|
||||||
exit 0 ;;
|
|
||||||
-v | --version)
|
|
||||||
echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
|
|
||||||
exit 0 ;;
|
|
||||||
--modules=*)
|
|
||||||
modules=`echo "$option" | sed 's/--modules=//'` ;;
|
|
||||||
--root-directory=*)
|
|
||||||
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
|
|
||||||
--grub-setup=*)
|
|
||||||
grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
|
|
||||||
--grub-mkimage=*)
|
|
||||||
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
|
|
||||||
--grub-mkdevicemap=*)
|
|
||||||
grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
|
|
||||||
--grub-probefs=*)
|
|
||||||
grub_probefs=`echo "$option" | sed 's/--grub-probefs=//'` ;;
|
|
||||||
--pkglibdir=*)
|
|
||||||
pkglibdir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
|
|
||||||
--pkgdatadir=*)
|
|
||||||
pkgdatadir=`echo "$option" | sed 's/--pkgdatadir=//'` ;;
|
|
||||||
--recheck)
|
|
||||||
recheck=yes ;;
|
|
||||||
# This is an undocumented feature...
|
|
||||||
--debug)
|
|
||||||
debug=yes ;;
|
|
||||||
-*)
|
|
||||||
echo "Unrecognized option \`$option'" 1>&2
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if test "x$install_device" != x; then
|
|
||||||
echo "More than one install_devices?" 1>&2
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
install_device="${option}" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
#if test "x$install_device" = x; then
|
|
||||||
# echo "install_device not specified." 1>&2
|
|
||||||
# usage
|
|
||||||
# exit 1
|
|
||||||
#fi
|
|
||||||
|
|
||||||
# If the debugging feature is enabled, print commands.
|
|
||||||
if test $debug = yes; then
|
|
||||||
set -x
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Initialize these directories here, since ROOTDIR was initialized.
|
|
||||||
bootdir=${rootdir}/boot/efi
|
|
||||||
|
|
||||||
grubdir=${bootdir}/grub
|
|
||||||
device_map=${grubdir}/device.map
|
|
||||||
|
|
||||||
# Create the GRUB directory if it is not present.
|
|
||||||
test -d "$bootdir" || mkdir "$bootdir" || exit 1
|
|
||||||
test -d "$grubdir" || mkdir "$grubdir" || exit 1
|
|
||||||
|
|
||||||
# Copy the GRUB images to the GRUB directory.
|
|
||||||
if false; then
|
|
||||||
for file in ${grubdir}/*.mod ${grubdir}/*.lst; do
|
|
||||||
if test -f $file; then
|
|
||||||
rm -f $file || exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
|
|
||||||
cp -f $file ${grubdir} || exit 1
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create the core image. First, auto-detect the filesystme module.
|
|
||||||
#fs_module=`$grub_probefs --device-map=${device_map} ${grubdir}`
|
|
||||||
#if test "x$fs_module" = x -a "x$modules" = x; then
|
|
||||||
# echo "Auto-detection of a filesystem module failed." 1>&2
|
|
||||||
# echo "Please specify the module with the option \`--modules' explicitly." 1>&2
|
|
||||||
# exit 1
|
|
||||||
#fi
|
|
||||||
|
|
||||||
# Typically, _chain and pc are required.
|
|
||||||
modules="$modules $fs_module _chain"
|
|
||||||
|
|
||||||
modules="kernel gzio gpt fat normal ls cat fshelp help _linux linux $modules"
|
|
||||||
modules="$modules memmap systab boot"
|
|
||||||
|
|
||||||
if [ $debug = yes ]; then
|
|
||||||
tmpdir=.
|
|
||||||
else
|
|
||||||
tmpdir=`mktemp -d /tmp/grub.XXXXXXXXXX` || exit 1
|
|
||||||
trap "rm -rf $tmpdir" 1 2 13 15
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate init/fini for modules.
|
|
||||||
modfile=$tmpdir/mod.c
|
|
||||||
echo "/* Dummy modules. */" > $modfile
|
|
||||||
list=""
|
|
||||||
init_list=""
|
|
||||||
fini_list=""
|
|
||||||
for m in $modules; do
|
|
||||||
file="$pkglibdir/${m}.mod"
|
|
||||||
name=`nm $file | sed -n "/ r grub_module_name/ s/.* r grub_module_name_\(.*\)/\1/p"`
|
|
||||||
init=`nm $file | sed -n "/ T grub_module_.*_init/ s/.* T //p"`
|
|
||||||
fini=`nm $file | sed -n "/ T grub_module_.*_fini/ s/.* T //p"`
|
|
||||||
init_list="$init_list $init"
|
|
||||||
fini_list="$fini_list $fini"
|
|
||||||
arg="\"$name\",${init:-0},${fini:-0}"
|
|
||||||
list="$list $arg"
|
|
||||||
done
|
|
||||||
echo "extern void grub_init_module (const char *, void (*init)(void *), void (*fini)(void));" >> $modfile
|
|
||||||
echo "extern void grub_init_modules (void);" >> $modfile
|
|
||||||
for m in $init_list; do
|
|
||||||
echo "extern void $m(void *);" >> $modfile
|
|
||||||
done
|
|
||||||
for m in $fini_list; do
|
|
||||||
echo "extern void $m(void);" >> $modfile
|
|
||||||
done
|
|
||||||
echo "void grub_init_modules (void)" >> $modfile
|
|
||||||
echo "{" >> $modfile
|
|
||||||
for m in $list; do
|
|
||||||
echo " grub_init_module($m);" >> $modfile
|
|
||||||
done
|
|
||||||
echo "}" >> $modfile
|
|
||||||
|
|
||||||
$TARGET_CC -c $TARGET_CFLAGS -o $tmpdir/mod.o $modfile
|
|
||||||
|
|
||||||
mod_objs=
|
|
||||||
for m in $modules; do mod_objs="$mod_objs $pkglibdir/${m}.mod"; done
|
|
||||||
|
|
||||||
ld -pie -nostdlib -T $pkgdatadir/elf_ia64_efi.lds \
|
|
||||||
$mod_objs $tmpdir/mod.o -o $tmpdir/grub.elf
|
|
||||||
|
|
||||||
|
|
||||||
if ! $bindir/grub-elf2pe $tmpdir/grub.elf $grubdir/grub.efi; then
|
|
||||||
echo "Failed to build efi binary"
|
|
||||||
[ $debug = no ] && rm -rf $tmpdir
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "grub.efi generated"
|
|
||||||
|
|
||||||
[ $debug = no ] && rm -rf $tmpdir
|
|
||||||
|
|
||||||
# Bye.
|
|
||||||
exit 0
|
|
|
@ -1,237 +0,0 @@
|
||||||
/* pe32.h - PE/Coff definitions. */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2008 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#ifdef USE_PE32PLUS
|
|
||||||
typedef uint64_t pe32_uintptr_t;
|
|
||||||
#else
|
|
||||||
typedef uint32_t pe32_uintptr_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct pe32_coff_header
|
|
||||||
{
|
|
||||||
uint16_t machine;
|
|
||||||
uint16_t num_sections;
|
|
||||||
uint32_t time;
|
|
||||||
uint32_t symtab_offset;
|
|
||||||
uint32_t num_symbols;
|
|
||||||
uint16_t optional_header_size;
|
|
||||||
uint16_t characteristics;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PE32_MACHINE_I386 0x014c
|
|
||||||
#define PE32_MACHINE_IA64 0x0200
|
|
||||||
#define PE32_MACHINE_EBC 0x0EBC
|
|
||||||
#define PE32_MACHINE_X64 0x8664
|
|
||||||
|
|
||||||
#define PE32_RELOCS_STRIPPED 0x0001
|
|
||||||
#define PE32_EXECUTABLE_IMAGE 0x0002
|
|
||||||
#define PE32_LINE_NUMS_STRIPPED 0x0004
|
|
||||||
#define PE32_LOCAL_SYMS_STRIPPED 0x0008
|
|
||||||
#define PE32_AGGRESSIVE_WS_TRIM 0x0010
|
|
||||||
#define PE32_LARGE_ADDRESS_AWARE 0x0020
|
|
||||||
#define PE32_16BIT_MACHINE 0x0040
|
|
||||||
#define PE32_BYTES_REVERSED_LO 0x0080
|
|
||||||
#define PE32_32BIT_MACHINE 0x0100
|
|
||||||
#define PE32_DEBUG_STRIPPED 0x0200
|
|
||||||
#define PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
|
|
||||||
#define PE32_SYSTEM 0x1000
|
|
||||||
#define PE32_DLL 0x2000
|
|
||||||
#define PE32_UP_SYSTEM_ONLY 0x4000
|
|
||||||
#define PE32_BYTES_REVERSED_HI 0x8000
|
|
||||||
|
|
||||||
struct pe32_data_directory
|
|
||||||
{
|
|
||||||
uint32_t rva;
|
|
||||||
uint32_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pe32_optional_header
|
|
||||||
{
|
|
||||||
uint16_t magic;
|
|
||||||
uint8_t major_linker_version;
|
|
||||||
uint8_t minor_linker_version;
|
|
||||||
uint32_t code_size;
|
|
||||||
uint32_t data_size;
|
|
||||||
uint32_t bss_size;
|
|
||||||
uint32_t entry_addr;
|
|
||||||
uint32_t code_base;
|
|
||||||
|
|
||||||
#ifndef USE_PE32PLUS
|
|
||||||
uint32_t data_base;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pe32_uintptr_t image_base;
|
|
||||||
uint32_t section_alignment;
|
|
||||||
uint32_t file_alignment;
|
|
||||||
uint16_t major_os_version;
|
|
||||||
uint16_t minor_os_version;
|
|
||||||
uint16_t major_image_version;
|
|
||||||
uint16_t minor_image_version;
|
|
||||||
uint16_t major_subsystem_version;
|
|
||||||
uint16_t minor_subsystem_version;
|
|
||||||
uint32_t reserved;
|
|
||||||
uint32_t image_size;
|
|
||||||
uint32_t header_size;
|
|
||||||
uint32_t checksum;
|
|
||||||
uint16_t subsystem;
|
|
||||||
uint16_t dll_characteristics;
|
|
||||||
pe32_uintptr_t stack_reserve_size;
|
|
||||||
pe32_uintptr_t stack_commit_size;
|
|
||||||
pe32_uintptr_t heap_reserve_size;
|
|
||||||
pe32_uintptr_t heap_commit_size;
|
|
||||||
uint32_t loader_flags;
|
|
||||||
uint32_t num_data_directories;
|
|
||||||
|
|
||||||
/* Data directories. */
|
|
||||||
struct pe32_data_directory export_table;
|
|
||||||
struct pe32_data_directory import_table;
|
|
||||||
struct pe32_data_directory resource_table;
|
|
||||||
struct pe32_data_directory exception_table;
|
|
||||||
struct pe32_data_directory certificate_table;
|
|
||||||
struct pe32_data_directory base_relocation_table;
|
|
||||||
struct pe32_data_directory debug;
|
|
||||||
struct pe32_data_directory architecture;
|
|
||||||
struct pe32_data_directory global_ptr;
|
|
||||||
struct pe32_data_directory tls_table;
|
|
||||||
struct pe32_data_directory load_config_table;
|
|
||||||
struct pe32_data_directory bound_import;
|
|
||||||
struct pe32_data_directory iat;
|
|
||||||
struct pe32_data_directory delay_import_descriptor;
|
|
||||||
struct pe32_data_directory com_runtime_header;
|
|
||||||
struct pe32_data_directory reserved_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PE32_PE32_MAGIC 0x10b
|
|
||||||
#define PE32_PE64_MAGIC 0x20b
|
|
||||||
|
|
||||||
#define PE32_SUBSYSTEM_EFI_APPLICATION 10
|
|
||||||
#define PE32_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
|
|
||||||
#define PE32_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
|
|
||||||
#define PE32_SUBSYSTEM_EFI_EFI_ROM 13
|
|
||||||
|
|
||||||
#define PE32_NUM_DATA_DIRECTORIES 16
|
|
||||||
|
|
||||||
struct pe32_section_header
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
uint32_t virtual_size;
|
|
||||||
uint32_t virtual_address;
|
|
||||||
uint32_t raw_data_size;
|
|
||||||
uint32_t raw_data_offset;
|
|
||||||
uint32_t relocations_offset;
|
|
||||||
uint32_t line_numbers_offset;
|
|
||||||
uint16_t num_relocations;
|
|
||||||
uint16_t num_line_numbers;
|
|
||||||
uint32_t characteristics;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PE32_SCN_CNT_CODE 0x00000020
|
|
||||||
#define PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
|
|
||||||
#define PE32_SCN_MEM_DISCARDABLE 0x02000000
|
|
||||||
#define PE32_SCN_MEM_EXECUTE 0x20000000
|
|
||||||
#define PE32_SCN_MEM_READ 0x40000000
|
|
||||||
#define PE32_SCN_MEM_WRITE 0x80000000
|
|
||||||
|
|
||||||
struct pe32_dos_header
|
|
||||||
{
|
|
||||||
uint16_t magic; // Magic number
|
|
||||||
uint16_t cblp; // Bytes on last page of file
|
|
||||||
uint16_t cp; // Pages in file
|
|
||||||
uint16_t crlc; // Relocations
|
|
||||||
uint16_t cparhdr; // Size of header in paragraphs
|
|
||||||
uint16_t minalloc; // Minimum extra paragraphs needed
|
|
||||||
uint16_t maxalloc; // Maximum extra paragraphs needed
|
|
||||||
uint16_t ss; // Initial (relative) SS value
|
|
||||||
uint16_t sp; // Initial SP value
|
|
||||||
uint16_t csum; // Checksum
|
|
||||||
uint16_t ip; // Initial IP value
|
|
||||||
uint16_t cs; // Initial (relative) CS value
|
|
||||||
uint16_t lfa_rlc; // File address of relocation table
|
|
||||||
uint16_t ov_no; // Overlay number
|
|
||||||
uint16_t res[4]; // Reserved words
|
|
||||||
uint16_t oem_id; // OEM identifier (for e_oeminfo)
|
|
||||||
uint16_t oem_info; // OEM information; e_oemid specific
|
|
||||||
uint16_t res2[10]; // Reserved words
|
|
||||||
uint32_t new_hdr_offset;
|
|
||||||
|
|
||||||
uint16_t stub[0x20];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pe32_nt_header
|
|
||||||
{
|
|
||||||
/* This is always PE\0\0. */
|
|
||||||
char signature[4];
|
|
||||||
|
|
||||||
/* The COFF file header. */
|
|
||||||
struct pe32_coff_header coff_header;
|
|
||||||
|
|
||||||
/* The Optional header. */
|
|
||||||
struct pe32_optional_header optional_header;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pe32_base_relocation
|
|
||||||
{
|
|
||||||
uint32_t page_rva;
|
|
||||||
uint32_t block_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pe32_fixup_block
|
|
||||||
{
|
|
||||||
uint32_t page_rva;
|
|
||||||
uint32_t block_size;
|
|
||||||
uint16_t entries[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
|
|
||||||
|
|
||||||
#define PE32_REL_BASED_ABSOLUTE 0
|
|
||||||
#define PE32_REL_BASED_HIGHLOW 3
|
|
||||||
#define PE32_REL_BASED_IA64_IMM64 9
|
|
||||||
#define PE32_REL_BASED_DIR64 10
|
|
||||||
|
|
||||||
#define PE32_DEBUG_TYPE_CODEVIEW 2
|
|
||||||
struct pe32_debug_directory_entry {
|
|
||||||
uint32_t characteristics;
|
|
||||||
uint32_t time;
|
|
||||||
uint16_t major_version;
|
|
||||||
uint16_t minor_version;
|
|
||||||
uint32_t type;
|
|
||||||
uint32_t data_size;
|
|
||||||
uint32_t rva;
|
|
||||||
uint32_t file_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PE32_CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
|
|
||||||
struct pe32_debug_codeview_nb10_entry {
|
|
||||||
uint32_t signature; // "NB10"
|
|
||||||
uint32_t unknown[3];
|
|
||||||
char filename[0]; /* Filename of .PDB */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
#define pe32_check(name, x) extern char pe32_check_##name [x ? 1 : -1]
|
|
||||||
#ifdef USE_PE32PLUS
|
|
||||||
#define PE32_HEADER_SIZE 112
|
|
||||||
#else
|
|
||||||
#define PE32_HEADER_SIZE 96
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pe32_check(optional_header, sizeof (struct pe32_optional_header) == PE32_HEADER_SIZE + PE32_NUM_DATA_DIRECTORIES * 8);
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in a new issue