@ -90,11 +90,16 @@ void efi_print_image_infos(void *pc)
}
static efi_status_t efi_loader_relocate ( const IMAGE_BASE_RELOCATION * rel ,
unsigned long rel_size , void * efi_reloc )
unsigned long rel_size , void * efi_reloc ,
unsigned long pref_address )
{
unsigned long delta = ( unsigned long ) efi_reloc - pref_address ;
const IMAGE_BASE_RELOCATION * end ;
int i ;
if ( delta = = 0 )
return EFI_SUCCESS ;
end = ( const IMAGE_BASE_RELOCATION * ) ( ( const char * ) rel + rel_size ) ;
while ( rel < end - 1 & & rel - > SizeOfBlock ) {
const uint16_t * relocs = ( const uint16_t * ) ( rel + 1 ) ;
@ -103,7 +108,6 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
uint32_t offset = ( uint32_t ) ( * relocs & 0xfff ) +
rel - > VirtualAddress ;
int type = * relocs > > EFI_PAGE_SHIFT ;
unsigned long delta = ( unsigned long ) efi_reloc ;
uint64_t * x64 = efi_reloc + offset ;
uint32_t * x32 = efi_reloc + offset ;
uint16_t * x16 = efi_reloc + offset ;
@ -191,6 +195,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
unsigned long rel_size ;
int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC ;
void * entry ;
uint64_t image_base ;
uint64_t image_size ;
unsigned long virt_size = 0 ;
int supported = 0 ;
@ -234,6 +239,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
if ( nt - > OptionalHeader . Magic = = IMAGE_NT_OPTIONAL_HDR64_MAGIC ) {
IMAGE_NT_HEADERS64 * nt64 = ( void * ) nt ;
IMAGE_OPTIONAL_HEADER64 * opt = & nt64 - > OptionalHeader ;
image_base = opt - > ImageBase ;
image_size = opt - > SizeOfImage ;
efi_set_code_and_data_type ( loaded_image_info , opt - > Subsystem ) ;
efi_reloc = efi_alloc ( virt_size ,
@ -249,6 +255,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
virt_size = ALIGN ( virt_size , opt - > SectionAlignment ) ;
} else if ( nt - > OptionalHeader . Magic = = IMAGE_NT_OPTIONAL_HDR32_MAGIC ) {
IMAGE_OPTIONAL_HEADER32 * opt = & nt - > OptionalHeader ;
image_base = opt - > ImageBase ;
image_size = opt - > SizeOfImage ;
efi_set_code_and_data_type ( loaded_image_info , opt - > Subsystem ) ;
efi_reloc = efi_alloc ( virt_size ,
@ -279,7 +286,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
}
/* Run through relocations */
if ( efi_loader_relocate ( rel , rel_size , efi_reloc ) ! = EFI_SUCCESS ) {
if ( efi_loader_relocate ( rel , rel_size , efi_reloc ,
( unsigned long ) image_base ) ! = EFI_SUCCESS ) {
efi_free_pages ( ( uintptr_t ) efi_reloc ,
( virt_size + EFI_PAGE_MASK ) > > EFI_PAGE_SHIFT ) ;
return NULL ;