Load ELF module with bad pc-relative relocation info
PATCH 1/1 Load ELF module with bad pc-relative relocation info
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.
kern/i386/dl.c +30 -0
@@ -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_tbreak ;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)); } } }