From b7e8ad7e6de253bf82c9cb757e57bc94845d4338 Mon Sep 17 00:00:00 2001 From: okuji Date: Tue, 3 Jul 2001 13:52:28 +0000 Subject: [PATCH] ELF symbol loading support is added. --- ChangeLog | 6 +++ NEWS | 1 + THANKS | 1 + stage2/boot.c | 79 +++++++++++++++++++++++++++-- stage2/i386-elf.h | 125 ++++++++++++++++++++++++++-------------------- 5 files changed, 154 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d4317d90..883f1eddb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-07-03 OKUJI Yoshinori + + From Julien Bordet : + * stage2/i386-elf.h (Elf32_Shdr): New type. + * stage2/boot.c (load_image): Added ELF symbol loading support. + 2001-06-22 OKUJI Yoshinori * stage2/char_io.c [STAGE1_5] (grub_strcmp): Defined, even diff --git a/NEWS b/NEWS index 3f96a8adf..7828b249c 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,7 @@ New in 1.0 - XXXX-XX-XX: `--with-configfile', so that you can load a remotely specified configuration file automatically, like the network boot images. * VSTa filesystem support is added. +* ELF symbol loading support is added. New in 0.5.96 - 2000-10-04: * New commands, "reboot" and "halt". diff --git a/THANKS b/THANKS index 87545b815..9e1510008 100644 --- a/THANKS +++ b/THANKS @@ -41,6 +41,7 @@ Jochen Hoenicke Johannes Kroeger John Tobey Josip Rodin +Julien Bordet Kalle Olavi Niemitalo Khimenko Victor Klaus Reichl diff --git a/stage2/boot.c b/stage2/boot.c index 3d2000c55..3563abcff 100644 --- a/stage2/boot.c +++ b/stage2/boot.c @@ -552,13 +552,86 @@ load_image (char *kernel, char *arg, kernel_t suggested_type, } } - if (!errnum) + if (! errnum) { - if (!loaded) + if (! loaded) errnum = ERR_EXEC_FORMAT; else { - /* FIXME: load ELF symbols */ + /* Load ELF symbols. */ + Elf32_Shdr *shdr = NULL; + int tab_size, sec_size; + int symtab_err = 0; + + mbi.syms.e.num = pu.elf->e_shnum; + mbi.syms.e.size = pu.elf->e_shentsize; + mbi.syms.e.shndx = pu.elf->e_shstrndx; + + /* We should align to a 4K boundary here for good measure. */ + if (align_4k) + cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; + + tab_size = pu.elf->e_shentsize * pu.elf->e_shnum; + + grub_seek (pu.elf->e_shoff); + if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size) + == tab_size) + { + mbi.syms.e.addr = cur_addr; + shdr = (Elf32_Shdr *) mbi.syms.e.addr; + cur_addr += tab_size; + + printf (", shtab=0x%x", cur_addr); + + for (i = 0; i < mbi.syms.e.num; i++) + { + /* This section is a loaded section, + so we don't care. */ + if (shdr[i].sh_addr != 0) + continue; + + /* This section is empty, so we don't care. */ + if (shdr[i].sh_size == 0) + continue; + + /* Align the section to a sh_addralign bits boundary. */ + cur_addr = ((cur_addr + shdr[i].sh_addralign) & + - (int) shdr[i].sh_addralign); + + grub_seek (shdr[i].sh_offset); + + sec_size = shdr[i].sh_size; + + if (! (memcheck (cur_addr, sec_size) + && (grub_read ((char *) RAW_ADDR (cur_addr), + sec_size) + == sec_size))) + { + symtab_err = 1; + break; + } + + shdr[i].sh_addr = cur_addr; + cur_addr += sec_size; + } + } + else + symtab_err = 1; + + if (mbi.syms.e.addr < RAW_ADDR(0x10000)) + symtab_err = 1; + + if (symtab_err) + { + printf ("(bad)"); + mbi.syms.e.num = 0; + mbi.syms.e.size = 0; + mbi.syms.e.addr = 0; + mbi.syms.e.shndx = 0; + cur_addr = 0; + } + else + mbi.flags |= MB_INFO_ELF_SHDR; } } } diff --git a/stage2/i386-elf.h b/stage2/i386-elf.h index 576aa0fec..ded22856d 100644 --- a/stage2/i386-elf.h +++ b/stage2/i386-elf.h @@ -1,7 +1,7 @@ - /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 2001 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,11 +29,11 @@ typedef unsigned long Elf32_Word; /* ELF header */ typedef struct - { - +{ + #define EI_NIDENT 16 - - /* first four characters are defined below */ + + /* first four characters are defined below */ #define EI_MAG0 0 #define ELFMAG0 0x7f #define EI_MAG1 1 @@ -42,40 +42,40 @@ typedef struct #define ELFMAG2 'L' #define EI_MAG3 3 #define ELFMAG3 'F' - + #define EI_CLASS 4 /* data sizes */ #define ELFCLASS32 1 /* i386 -- up to 32-bit data sizes present */ - + #define EI_DATA 5 /* data type and ordering */ #define ELFDATA2LSB 1 /* i386 -- LSB 2's complement */ - + #define EI_VERSION 6 /* version number. "e_version" must be the same */ #define EV_CURRENT 1 /* current version number */ - + #define EI_PAD 7 /* from here in is just padding */ - + #define EI_BRAND 8 /* start of OS branding (This is obviously illegal against the ELF standard.) */ - - unsigned char e_ident[EI_NIDENT]; /* basic identification block */ - + + unsigned char e_ident[EI_NIDENT]; /* basic identification block */ + #define ET_EXEC 2 /* we only care about executable types */ - Elf32_Half e_type; /* file types */ - + Elf32_Half e_type; /* file types */ + #define EM_386 3 /* i386 -- obviously use this one */ - Elf32_Half e_machine; /* machine types */ - Elf32_Word e_version; /* use same as "EI_VERSION" above */ - Elf32_Addr e_entry; /* entry point of the program */ - Elf32_Off e_phoff; /* program header table file offset */ - Elf32_Off e_shoff; /* section header table file offset */ - Elf32_Word e_flags; /* flags */ - Elf32_Half e_ehsize; /* elf header size in bytes */ - Elf32_Half e_phentsize; /* program header entry size */ - Elf32_Half e_phnum; /* number of entries in program header */ - Elf32_Half e_shentsize; /* section header entry size */ - Elf32_Half e_shnum; /* number of entries in section header */ - + Elf32_Half e_machine; /* machine types */ + Elf32_Word e_version; /* use same as "EI_VERSION" above */ + Elf32_Addr e_entry; /* entry point of the program */ + Elf32_Off e_phoff; /* program header table file offset */ + Elf32_Off e_shoff; /* section header table file offset */ + Elf32_Word e_flags; /* flags */ + Elf32_Half e_ehsize; /* elf header size in bytes */ + Elf32_Half e_phentsize; /* program header entry size */ + Elf32_Half e_phnum; /* number of entries in program header */ + Elf32_Half e_shentsize; /* section header entry size */ + Elf32_Half e_shnum; /* number of entries in section header */ + #define SHN_UNDEF 0 #define SHN_LORESERVE 0xff00 #define SHN_LOPROC 0xff00 @@ -83,8 +83,8 @@ typedef struct #define SHN_ABS 0xfff1 #define SHN_COMMON 0xfff2 #define SHN_HIRESERVE 0xffff - Elf32_Half e_shstrndx; /* section header table index */ - } + Elf32_Half e_shstrndx; /* section header table index */ +} Elf32_Ehdr; @@ -95,17 +95,32 @@ Elf32_Ehdr; & (h.e_ident[EI_VERSION] == EV_CURRENT) & (h.e_type == ET_EXEC) \ & (h.e_machine == EM_386) & (h.e_version == EV_CURRENT)) +/* section table - ? */ +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} +Elf32_Shdr; /* symbol table - page 4-25, figure 4-15 */ typedef struct - { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; - } +{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; /* symbol type and binding attributes - page 4-26 */ @@ -143,16 +158,16 @@ Elf32_Sym; /* program header - page 5-2, figure 5-1 */ typedef struct - { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; - } +{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; /* segment types - page 5-3, figure 5-2 */ @@ -179,15 +194,15 @@ Elf32_Phdr; /* dynamic structure - page 5-15, figure 5-9 */ typedef struct +{ + Elf32_Sword d_tag; + union { - Elf32_Sword d_tag; - union - { - Elf32_Word d_val; - Elf32_Addr d_ptr; - } - d_un; + Elf32_Word d_val; + Elf32_Addr d_ptr; } + d_un; +} Elf32_Dyn; /* Dynamic array tags - page 5-16, figure 5-10. */