[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] new ELF64 patch
From: |
Ruslan Nikolaev |
Subject: |
[PATCH] new ELF64 patch |
Date: |
Sat, 16 Jul 2005 17:54:39 -0500 |
Hi!
Ok patch for x86_64 ELF64 support was rewritten.
diff -urN old/multiboot.c new/multiboot.c
--- old/multiboot.c 2005-07-17 02:50:11.978394408 +0400
+++ new/multiboot.c 2005-07-17 02:49:41.069093336 +0400
@@ -89,7 +89,14 @@
struct grub_multiboot_header *header;
grub_ssize_t len;
int i;
- Elf32_Ehdr *ehdr;
+ union {
+ Elf32_Ehdr *ehdr32;
+ Elf64_Ehdr *ehdr64;
+ } hdr;
+ union {
+ Elf32_Phdr *phdr32;
+ Elf64_Phdr *phdr64;
+ } seg;
grub_dl_ref (my_mod);
@@ -138,64 +145,136 @@
goto fail;
}
- ehdr = (Elf32_Ehdr *) buffer;
+ hdr.ehdr32 = (Elf32_Ehdr *) buffer;
- if (grub_dl_check_header (ehdr, sizeof(*ehdr)))
+ if (hdr.ehdr32->e_ident[EI_CLASS] == ELFCLASS64) /* ELF64 */
{
- grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
- goto fail;
- }
-
- if (ehdr->e_type != ET_EXEC)
- {
- grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
- goto fail;
- }
-
- /* FIXME: Should we support program headers at strange locations? */
- if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_MB_SEARCH)
- {
- grub_error (GRUB_ERR_UNKNOWN_OS, "Program header at a too high offset");
- goto fail;
- }
+ /* we can't use grub_dl_check_header() for ELF64 under i386/amd64 */
+ if (hdr.ehdr64->e_ident[EI_MAG0] != ELFMAG0
+ || hdr.ehdr64->e_ident[EI_MAG1] != ELFMAG1
+ || hdr.ehdr64->e_ident[EI_MAG2] != ELFMAG2
+ || hdr.ehdr64->e_ident[EI_MAG3] != ELFMAG3
+ || hdr.ehdr64->e_version != EV_CURRENT
+ || hdr.ehdr64->e_ident[EI_DATA] != ELFDATA2LSB
+ || hdr.ehdr64->e_machine != EM_X86_64)
+ {
+ grub_error(GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
+ goto fail;
+ }
+ if (hdr.ehdr64->e_type != ET_EXEC)
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+ goto fail;
+ }
+
+ /* FIXME: Should we support program headers at strange locations? */
+ if (hdr.ehdr64->e_phoff + hdr.ehdr64->e_phnum * hdr.ehdr64->e_phentsize
> GRUB_MB_SEARCH)
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "Program header at a too high
offset");
+ goto fail;
+ }
+ /* we still in 32-bit mode */
+ if (hdr.ehdr64->e_entry >= 0xffffffff)
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "Invalid entry point for ELF64");
+ goto fail;
+ }
+ entry = hdr.ehdr64->e_entry;
+
+ /* Load every loadable segment in memory. */
+ for (i = 0; i < hdr.ehdr64->e_phnum; i++)
+ {
+ seg.phdr64 = (Elf64_Phdr *) (buffer + hdr.ehdr64->e_phoff + i *
hdr.ehdr64->e_phentsize);
+
+ if (seg.phdr64->p_type == PT_LOAD)
+ {
+ /* The segment should fit in the area reserved for the OS. */
+ if ((seg.phdr64->p_paddr < (grub_uint64_t)grub_os_area_addr)
+ || (seg.phdr64->p_paddr + seg.phdr64->p_memsz
+ > (grub_uint64_t)grub_os_area_addr +
(grub_uint64_t)grub_os_area_size))
+ {
+ grub_error (GRUB_ERR_BAD_OS,
+ "Segment doesn't fit in memory reserved for the OS");
+ goto fail;
+ }
+
+ if (grub_file_seek (file, seg.phdr64->p_offset) == -1)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program
header");
+ goto fail;
+ }
+
+ if (grub_file_read (file, (void
*)((grub_uint32_t)seg.phdr64->p_paddr), seg.phdr64->p_filesz)
+ != (grub_ssize_t) seg.phdr64->p_filesz)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "Couldn't read segment from file");
+ goto fail;
+ }
+
+ if (seg.phdr64->p_filesz < seg.phdr64->p_memsz)
+ grub_memset ((char *)((grub_uint32_t)seg.phdr64->p_paddr) +
seg.phdr64->p_filesz, 0,
+ seg.phdr64->p_memsz - seg.phdr64->p_filesz);
+ }
+ }
+ }
+ else /* ELF32 */
+ {
+ if (grub_dl_check_header (hdr.ehdr32, sizeof(Elf32_Ehdr)))
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
+ goto fail;
+ }
+
+ if (hdr.ehdr32->e_type != ET_EXEC)
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+ goto fail;
+ }
+
+ /* FIXME: Should we support program headers at strange locations? */
+ if (hdr.ehdr32->e_phoff + hdr.ehdr32->e_phnum * hdr.ehdr32->e_phentsize
> GRUB_MB_SEARCH)
+ {
+ grub_error (GRUB_ERR_UNKNOWN_OS, "Program header at a too high
offset");
+ goto fail;
+ }
+
+ entry = hdr.ehdr32->e_entry;
+
+ /* Load every loadable segment in memory. */
+ for (i = 0; i < hdr.ehdr32->e_phnum; i++)
+ {
+ seg.phdr32 = (Elf32_Phdr *) (buffer + hdr.ehdr32->e_phoff + i *
hdr.ehdr32->e_phentsize);
- entry = ehdr->e_entry;
-
- /* Load every loadable segment in memory. */
- for (i = 0; i < ehdr->e_phnum; i++)
- {
- Elf32_Phdr *phdr;
- phdr = (Elf32_Phdr *) (buffer + ehdr->e_phoff + i * ehdr->e_phentsize);
-
- if (phdr->p_type == PT_LOAD)
- {
- /* The segment should fit in the area reserved for the OS. */
- if ((phdr->p_paddr < grub_os_area_addr)
- || (phdr->p_paddr + phdr->p_memsz
- > grub_os_area_addr + grub_os_area_size))
+ if (seg.phdr32->p_type == PT_LOAD)
{
- grub_error (GRUB_ERR_BAD_OS,
- "Segment doesn't fit in memory reserved for the OS");
- goto fail;
- }
+ /* The segment should fit in the area reserved for the OS. */
+ if ((seg.phdr32->p_paddr < grub_os_area_addr)
+ || (seg.phdr32->p_paddr + seg.phdr32->p_memsz
+ > grub_os_area_addr + grub_os_area_size))
+ {
+ grub_error (GRUB_ERR_BAD_OS,
+ "Segment doesn't fit in memory reserved for the
OS");
+ goto fail;
+ }
- if (grub_file_seek (file, phdr->p_offset) == -1)
- {
- grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
- goto fail;
+ if (grub_file_seek (file, seg.phdr32->p_offset) == -1)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program
header");
+ goto fail;
+ }
+
+ if (grub_file_read (file, (void *) seg.phdr32->p_paddr,
seg.phdr32->p_filesz)
+ != (grub_ssize_t) seg.phdr32->p_filesz)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "Couldn't read segment from
file");
+ goto fail;
+ }
+
+ if (seg.phdr32->p_filesz < seg.phdr32->p_memsz)
+ grub_memset ((char *) seg.phdr32->p_paddr +
seg.phdr32->p_filesz, 0,
+ seg.phdr32->p_memsz - seg.phdr32->p_filesz);
}
-
- if (grub_file_read (file, (void *) phdr->p_paddr, phdr->p_filesz)
- != (grub_ssize_t) phdr->p_filesz)
- {
- grub_error (GRUB_ERR_BAD_OS, "Couldn't read segment from file");
- goto fail;
- }
-
- if (phdr->p_filesz < phdr->p_memsz)
- grub_memset ((char *) phdr->p_paddr + phdr->p_filesz, 0,
- phdr->p_memsz - phdr->p_filesz);
- }
+ }
}
mbi = grub_malloc (sizeof (struct grub_multiboot_info));
--
___________________________________________________________
Sign-up for Ads Free at Mail.com
http://promo.mail.com/adsfreejump.htm
- [PATCH] new ELF64 patch,
Ruslan Nikolaev <=