grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Load ELF module with bad pc-relative relocation info


From: Christian Franke
Subject: [PATCH] Load ELF module with bad pc-relative relocation info
Date: Mon, 19 Nov 2007 21:00:15 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4

This patch allows to load modules with bad pc-relative relocation info produced by "objcopy -I pe-i386 -O elf32-i386"
(See also thread "Building GRUB on platforms without ELF support")

Christian

2007-11-19 Christian Franke <address@hidden>
        * kern/i386/dl.c [__CYGWIN__] (fix_pc_rel_relocation): New function
        to fix bad PC relative relocation produced by objcopy.
        [__CYGWIN__] (grub_arch_dl_relocate_symbols): Add fix of PC relative 
relocation.
        (grub_arch_dl_relocate_symbols): Abort on unknown relocation type.


--- grub2.orig/kern/i386/dl.c   2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/i386/dl.c        2007-11-19 20:50:52.609375000 +0100
@@ -37,6 +37,28 @@ grub_arch_dl_check_header (void *ehdr)
   return GRUB_ERR_NONE;
 }
 
+#ifdef __CYGWIN__
+/* Fix PC relative relocation.  Objcopy does not adjust
+the addent when converting from pe-i386 to elf32-i386.  */
+static int
+fix_pc_rel_relocation (Elf32_Word *addr)
+{
+  /* To be safe, check instruction first.  */
+  const unsigned char * pc = (const unsigned char *)addr - 1;
+  if (!(*pc == 0xe8/*call*/ || *pc == 0xe9/*jmp*/))
+    return grub_error (GRUB_ERR_BAD_MODULE, "unknown pc-relative instruction 
%02x", *pc);
+  /* Check and adjust offset.  */
+  if (*addr != (Elf32_Word)-4)
+    {
+      if (*addr != 0)
+       return grub_error (GRUB_ERR_BAD_MODULE, "invalid pc-relative relocation 
base %lx",
+                          (long)(*addr));
+      *addr = (Elf32_Word)-4;
+    }
+  return GRUB_ERR_NONE;
+}
+#endif
+
 /* Relocate symbols.  */
 grub_err_t
 grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
@@ -99,9 +121,17 @@ grub_arch_dl_relocate_symbols (grub_dl_t
                    break;
 
                  case R_386_PC32:
+#ifdef __CYGWIN__
+                   if (fix_pc_rel_relocation (addr))
+                     return grub_errno;
+#endif
                    *addr += (sym->st_value - (Elf32_Word) seg->addr
                              - rel->r_offset);
                    break;
+
+                 default:
+                   return grub_error (GRUB_ERR_BAD_MODULE, "unknown relocation 
type %x.",
+                                      ELF32_R_TYPE (rel->r_info));
                  }
              }
          }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]