diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 0d1e0d2e6..3904f73b7 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -250,9 +250,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) add_value_to_slot_21 (addr, value - (grub_addr_t) gp); break; - case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + value = *(grub_uint64_t *) sym->st_value + rel->r_addend; + case R_IA64_LTOFF_FPTR22: *gpptr = value; add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); gpptr++; diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 9bfb5de75..352291070 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -455,9 +455,20 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, } break; - case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + { + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (symtab_section->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host32 (symtab_section->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + + sym->st_value + - image_target->vaddr_offset)); + } + case R_IA64_LTOFF_FPTR22: *gpptr = grub_host_to_target64 (addend + sym_addr); add_value_to_slot_21 ((grub_addr_t) target, (char *) gpptr - (char *) pe_target