]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
On MIPS handle got16 relocations to local symbols in an ABI-compliant
authorVladimir Serbinenko <phcoder@gmail.com>
Fri, 22 Nov 2013 04:03:17 +0000 (05:03 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Fri, 22 Nov 2013 04:03:17 +0000 (05:03 +0100)
way.

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

index 8fac253ef818d46be8b7aaf0bea9dc62b0267dec..4f5b0c52d9b51faed3646f0e60f1a7709796d1a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       On MIPS handle got16 relocations to local symbols in an ABI-compliant
+       way.
+
 2013-11-22  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Add support for a new magic symbol _gp_disp on mips to handle PIC
index 111241831ee3c94101dd6e17ebb360dc48a20b8e..b97510a1e1460fac57c831e5412458406321df5c 100644 (file)
@@ -245,6 +245,30 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
                    }
                    break;
                  case R_MIPS_GOT16:
+                   if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
+                     {
+                       Elf_Rel *rel2;
+                       /* Handle partner lo16 relocation. Lower part is
+                          treated as signed. Hence add 0x8000 to compensate.
+                       */
+                       sym_value += (*(grub_uint16_t *) addr << 16)
+                         + 0x8000;
+                       for (rel2 = rel + 1; rel2 < max; rel2++)
+                         if (ELF_R_SYM (rel2->r_info)
+                             == ELF_R_SYM (rel->r_info)
+                             && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
+                           {
+                             sym_value += *(grub_int16_t *)
+                               ((char *) seg->addr + rel2->r_offset
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+                                + 2
+#endif
+                                );
+                             break;
+                           }
+                       sym_value &= 0xffff0000;
+                       *(grub_uint16_t *) addr = 0;
+                     }
                  case R_MIPS_CALL16:
                    /* FIXME: reuse*/
 #ifdef GRUB_CPU_WORDS_BIGENDIAN