]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2007-02-20 Hollis Blanchard <hollis@penguinppc.org>
authorhollisb <hollisb@localhost>
Tue, 20 Feb 2007 22:46:12 +0000 (22:46 +0000)
committerhollisb <hollisb@localhost>
Tue, 20 Feb 2007 22:46:12 +0000 (22:46 +0000)
* include/grub/elfload.h (grub_elf32_load_hook_t): Return grub_err_t.
All users updated.
(grub_elf64_load_hook_t): Likewise.
* kern/elf.c: Call `grub_error_push' before `grub_error'. Improve
debug output.

ChangeLog
include/grub/elfload.h
kern/elf.c
loader/powerpc/ieee1275/linux.c

index 9a782a613e27005982ebdd1c5a0cf3ac2160c8e9..9633c838f85c2200f6aca2331c89aaca4a98639b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-02-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+       * include/grub/elfload.h (grub_elf32_load_hook_t): Return grub_err_t.
+       All users updated.
+       (grub_elf64_load_hook_t): Likewise.
+       * kern/elf.c: Call `grub_error_push' before `grub_error'. Improve
+       debug output.
+
 2007-02-20  Hollis Blanchard  <hollis@penguinppc.org>
 
        * kern/mm.c: Update copyright.
index 7e17435d82daf30e4446eff88e5db0fbfe4ad7e1..d4f44b8d2d71469c60ad3c9a226da20f88573b69 100644 (file)
@@ -37,8 +37,10 @@ struct grub_elf_file
 };
 typedef struct grub_elf_file *grub_elf_t;
 
-typedef int (*grub_elf32_load_hook_t) (Elf32_Phdr *phdr, grub_addr_t *addr);
-typedef int (*grub_elf64_load_hook_t) (Elf64_Phdr *phdr, grub_addr_t *addr);
+typedef grub_err_t (*grub_elf32_load_hook_t)
+  (Elf32_Phdr *phdr, grub_addr_t *addr);
+typedef grub_err_t (*grub_elf64_load_hook_t)
+  (Elf64_Phdr *phdr, grub_addr_t *addr);
 
 grub_elf_t grub_elf_open (const char *);
 grub_elf_t grub_elf_file (grub_file_t);
index d10dca08dcb1e011d0003bcf42ea652d0b4d3f8a..4d616cc74b420d606f483188bc4279fa8be3153f 100644 (file)
@@ -75,6 +75,7 @@ grub_elf_file (grub_file_t file)
   if (grub_file_read (elf->file, (char *) &elf->ehdr, sizeof (elf->ehdr))
       != sizeof (elf->ehdr))
     {
+      grub_error_push ();
       grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header.");
       goto fail;
     }
@@ -129,7 +130,10 @@ grub_elf32_load_phdrs (grub_elf_t elf)
 
   if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1)
       || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
-    return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    }
 
   return GRUB_ERR_NONE;
 }
@@ -150,10 +154,13 @@ grub_elf32_phdr_iterate (grub_elf_t elf,
   for (i = 0; i < elf->ehdr.ehdr32.e_phnum; i++)
     {
       Elf32_Phdr *phdr = phdrs + i;
-      grub_dprintf ("elf", "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx.\n",
+      grub_dprintf ("elf",
+                   "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
+                   "filesz %lx\n",
                    i, phdr->p_type,
                    (unsigned long) phdr->p_paddr,
-                   (unsigned long) phdr->p_memsz);
+                   (unsigned long) phdr->p_memsz,
+                   (unsigned long) phdr->p_filesz);
       if (hook (elf, phdr, hook_arg))
        break;
     }
@@ -230,20 +237,30 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
     if (load_addr < load_base)
       load_base = load_addr;
 
-    grub_dprintf ("elf", "Loading segment at %llx, size 0x%llx\n",
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
                  (unsigned long long) load_addr,
-                 (unsigned long long) phdr->p_filesz);
+                 (unsigned long long) phdr->p_memsz);
 
     if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
       {
-       return grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
+       grub_error_push ();
+       return grub_error (GRUB_ERR_BAD_OS,
+                          "Invalid offset in program header.");
       }
 
-    if (phdr->p_filesz
-       && grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz)
-       != (grub_ssize_t) phdr->p_filesz)
+    if (phdr->p_filesz)
       {
-       return grub_error (GRUB_ERR_BAD_OS, "Couldn't load segment");
+       grub_ssize_t read;
+       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+       if (read != (grub_ssize_t) phdr->p_filesz)
+         {
+           /* XXX How can we free memory from `load_hook'? */
+           grub_error_push ();
+           return grub_error (GRUB_ERR_BAD_OS,
+                              "Couldn't read segment from file: "
+                              "wanted 0x%lx bytes; read 0x%lx bytes.",
+                              phdr->p_filesz, read);
+         }
       }
 
     if (phdr->p_filesz < phdr->p_memsz)
@@ -292,7 +309,10 @@ grub_elf64_load_phdrs (grub_elf_t elf)
 
   if ((grub_file_seek (elf->file, elf->ehdr.ehdr64.e_phoff) == (grub_off_t) -1)
       || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
-    return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    }
 
   return GRUB_ERR_NONE;
 }
@@ -313,10 +333,13 @@ grub_elf64_phdr_iterate (grub_elf_t elf,
   for (i = 0; i < elf->ehdr.ehdr64.e_phnum; i++)
     {
       Elf64_Phdr *phdr = phdrs + i;
-      grub_dprintf ("elf", "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx.\n",
+      grub_dprintf ("elf",
+                   "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
+                   "filesz %lx\n",
                    i, phdr->p_type,
                    (unsigned long) phdr->p_paddr,
-                   (unsigned long) phdr->p_memsz);
+                   (unsigned long) phdr->p_memsz,
+                   (unsigned long) phdr->p_filesz);
       if (hook (elf, phdr, hook_arg))
        break;
     }
@@ -393,20 +416,28 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,
     if (load_addr < load_base)
       load_base = load_addr;
 
-    grub_dprintf ("elf", "Loading segment at %llx, size 0x%llx\n",
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
                  (unsigned long long) load_addr,
-                 (unsigned long long) phdr->p_filesz);
+                 (unsigned long long) phdr->p_memsz);
 
     if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
       {
-       return grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
+       grub_error_push ();
+       return grub_error (GRUB_ERR_BAD_OS,
+                          "Invalid offset in program header.");
       }
 
-    if (phdr->p_filesz
-       && grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz)
-       != (grub_ssize_t) phdr->p_filesz)
+    if (phdr->p_filesz)
       {
-       return grub_error (GRUB_ERR_BAD_OS, "Couldn't load segment");
+       grub_ssize_t read;
+       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+       if (read != (grub_ssize_t) phdr->p_filesz)
+         /* XXX How can we free memory from `load_hook'?  */
+         grub_error_push ();
+         return grub_error (GRUB_ERR_BAD_OS,
+                            "Couldn't read segment from file: "
+                            "wanted 0x%lx bytes; read 0x%lx bytes.",
+                            phdr->p_filesz, read);
       }
 
     if (phdr->p_filesz < phdr->p_memsz)
@@ -427,5 +458,3 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,
 
   return err;
 }
-
-
index 696e8ba01e3d6a9708abe89215af2d7be43ff674..3e37eafb21c5b41fa2003d1516854c7117e83596 100644 (file)
@@ -132,8 +132,8 @@ grub_linux_load32 (grub_elf_t elf)
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
 
   /* Now load the segments into the area we claimed.  */
-  auto int offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr);
-  int offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr)
+  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr);
+  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr)
     {
       /* Linux's program headers incorrectly contain virtual addresses.
        * Translate those to physical, and offset to the area we claimed.  */
@@ -175,8 +175,8 @@ grub_linux_load64 (grub_elf_t elf)
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
 
   /* Now load the segments into the area we claimed.  */
-  auto int offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr);
-  int offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr)
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr)
     {
       /* Linux's program headers incorrectly contain virtual addresses.
        * Translate those to physical, and offset to the area we claimed.  */