]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/kern/ia64/dl.c (grub_arch_dl_relocate_symbols): Handle
authorVladimir Serbinenko <phcoder@gmail.com>
Wed, 11 Dec 2013 10:28:48 +0000 (11:28 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Wed, 11 Dec 2013 10:28:48 +0000 (11:28 +0100)
non-function pcrel21b relocation. It happens with .text.unlikely
section.

ChangeLog
grub-core/kern/ia64/dl.c

index 62fdb03b2b8237209145b9df1470f2001683ba2c..ea697a8068696949518036648b02d8cf56cf3a3b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-12-11  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * 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 <leif.lindholm@linaro.org>
 
        * make MAX_USABLE_ADDRESS platform-specific
index e623cdc81328f0f0dd719f16f178545bb8fca43f..d6c183d33333ccb41137daf8c15e386fe7862be2 100644 (file)
@@ -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;