All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] new ELF64 patch
@ 2005-07-17 22:32 Ruslan Nikolaev
  2005-07-18  3:34 ` Joel Buckley
  2005-07-18  9:15 ` Yoshinori K. Okuji
  0 siblings, 2 replies; 7+ messages in thread
From: Ruslan Nikolaev @ 2005-07-17 22:32 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]

Hi!

I sent new patch for mutiboot:
http://lists.gnu.org/archive/html/grub-devel/2005-07/msg00130.html

 Is it correct now?

By the way... I have seen that grub2 has a 4Gb limit when detecting
memory size and mmap. I think that is not good for both x86 and x86_64.
i686 for example can use 64 Gb of RAM. As for x86_64 it is 2^52 bytes. I
can try to fix this... But I also need an answer about ELF64 multiboot.

Best regards, Ruslan.

-- 
___________________________________________________________
Sign-up for Ads Free at Mail.com
http://promo.mail.com/adsfreejump.htm


[-- Attachment #2: Type: text/html, Size: 830 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH] new ELF64 patch
@ 2005-07-16 22:54 Ruslan Nikolaev
  2005-07-18 15:18 ` Hollis Blanchard
  0 siblings, 1 reply; 7+ messages in thread
From: Ruslan Nikolaev @ 2005-07-16 22:54 UTC (permalink / raw)
  To: grub-devel

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




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-07-19 19:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-17 22:32 [PATCH] new ELF64 patch Ruslan Nikolaev
2005-07-18  3:34 ` Joel Buckley
2005-07-18  9:19   ` Yoshinori K. Okuji
2005-07-18  9:15 ` Yoshinori K. Okuji
  -- strict thread matches above, loose matches on Subject: below --
2005-07-16 22:54 Ruslan Nikolaev
2005-07-18 15:18 ` Hollis Blanchard
2005-07-19 19:33   ` Yoshinori K. Okuji

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.