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 <[EMAIL PROTECTED]>
        * 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));
 		  }
 	      }
 	  }
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to