From 979742bc7e5e16d87b9eab9934f6f74ec2cf1b16 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 11 Dec 2013 11:28:48 +0100 Subject: [PATCH] * grub-core/kern/ia64/dl.c (grub_arch_dl_relocate_symbols): Handle non-function pcrel21b relocation. It happens with .text.unlikely section. --- ChangeLog | 6 ++++++ grub-core/kern/ia64/dl.c | 21 +++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62fdb03b2..ea697a806 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-11 Vladimir Serbinenko + + * grub-core/kern/ia64/dl.c (grub_arch_dl_relocate_symbols): Handle + non-function pcrel21b relocation. It happens with .text.unlikely + section. + 2013-12-10 Leif Lindholm * make MAX_USABLE_ADDRESS platform-specific diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index e623cdc81..d6c183d33 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -76,15 +76,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, { case R_IA64_PCREL21B: { - grub_uint64_t noff; - struct grub_ia64_trampoline *tr = mod->trampptr; - grub_ia64_make_trampoline (tr, value); - noff = ((char *) tr - (char *) (addr & ~3)) >> 4; - mod->trampptr = tr + 1; + grub_int64_t noff; + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + { + struct grub_ia64_trampoline *tr = mod->trampptr; + grub_ia64_make_trampoline (tr, value); + noff = ((char *) tr - (char *) (addr & ~3)) >> 4; + mod->trampptr = tr + 1; + } + else + noff = ((char *) value - (char *) (addr & ~3)) >> 4; - if (noff & ~MASK19) - return grub_error (GRUB_ERR_BAD_OS, - "trampoline offset too big (%lx)", noff); + if ((noff & ~MASK19) && ((-noff) & ~MASK19)) + return grub_error (GRUB_ERR_BAD_MODULE, + "jump offset too big (%lx)", noff); grub_ia64_add_value_to_slot_20b (addr, noff); } break;