]> git.proxmox.com Git - grub2.git/commitdiff
Relocations cleanup
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 12 Apr 2013 14:53:58 +0000 (16:53 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 12 Apr 2013 14:53:58 +0000 (16:53 +0200)
grub-core/kern/arm/dl.c
include/grub/arm/reloc.h [new file with mode: 0644]
util/grub-mkimagexx.c

index 39a34ca5b2f2873cce251094f8affa72598aa50a..74e6b96b50cacf56a5767479c35600619ae552de 100644 (file)
 #include <grub/err.h>
 #include <grub/mm.h>
 #include <grub/i18n.h>
+#include <grub/arm/reloc.h>
 
 #ifdef GRUB_UTIL
 # include <grub/util/misc.h>
 #else
-# if !defined(__thumb2__)
-#  error "Relocations not implemented for A32 ("ARM") instruction set yet!"
-# endif
-
-grub_err_t reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
 
 #ifdef DL_DEBUG
 static const char *symstrtab;
@@ -104,7 +98,7 @@ reloc_abs32 (Elf_Word *target, Elf_Addr sym_addr)
  *   B.W, BL and BLX
  */
 grub_err_t
-reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
+grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
 {
   grub_int32_t offset, offset_low, offset_high;
   grub_uint32_t sign, j1, j2, is_blx;
@@ -122,14 +116,8 @@ reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
 
   /* If BLX, target symbol must be ARM (target address LSB == 0) */
   if (is_blx && (sym_addr & 1))
-    {
-#ifndef GRUB_UTIL
-      return grub_error
-       (GRUB_ERR_BUG, N_("Relocation targeting wrong execution state"));
-#else
-      grub_util_error ("Relocation targeting wrong execution state");
-#endif
-    }
+    return grub_error (GRUB_ERR_BUG,
+                      N_("Relocation targeting wrong execution state"));
 
   offset_low = -16777216;
   offset_high = is_blx ? 16777212 : 16777214;
@@ -159,18 +147,12 @@ reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
 #endif
 
   if ((offset < offset_low) || (offset > offset_high))
-    {
-#ifdef GRUB_UTIL
-      grub_util_error ("Relocation out of range");
-#else
-      return grub_error
-       (GRUB_ERR_OUT_OF_RANGE, N_("THM_CALL Relocation out of range."));
-#endif
-    }
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      N_("THM_CALL Relocation out of range."));
 
 #ifdef GRUB_UTIL
-  grub_util_info ("    relative destination = 0x%08x",
-                 (unsigned int)target + offset);
+  grub_util_info ("    relative destination = 0x%08lx",
+                 (unsigned long)target + offset);
 #endif
 
   /* Reassemble instruction word */
@@ -200,7 +182,7 @@ reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
  * Relocate conditional Thumb (T32) B<c>.W
  */
 grub_err_t
-reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr)
+grub_arm_reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr)
 {
   grub_int32_t offset;
   grub_uint32_t insword, insmask;
@@ -260,7 +242,7 @@ reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr)
  * Relocate ARM (A32) B
  */
 grub_err_t
-reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr)
+grub_arm_reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr)
 {
   grub_uint32_t insword;
   grub_int32_t offset;
@@ -358,9 +340,10 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
              return retval;
          }
          break;
+       case R_ARM_CALL:
        case R_ARM_JUMP24:
          {
-           retval = reloc_jump24 (target, sym_addr);
+           retval = grub_arm_reloc_jump24 (target, sym_addr);
            if (retval != GRUB_ERR_NONE)
              return retval;
          }
@@ -369,7 +352,7 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
        case R_ARM_THM_JUMP24:
          {
            /* Thumb instructions can be 16-bit aligned */
-           retval = reloc_thm_call ((grub_uint16_t *) target, sym_addr);
+           retval = grub_arm_reloc_thm_call ((grub_uint16_t *) target, sym_addr);
            if (retval != GRUB_ERR_NONE)
              return retval;
          }
@@ -377,7 +360,7 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
        case R_ARM_THM_JUMP19:
          {
            /* Thumb instructions can be 16-bit aligned */
-           retval = reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+           retval = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
            if (retval != GRUB_ERR_NONE)
              return retval;
          }
diff --git a/include/grub/arm/reloc.h b/include/grub/arm/reloc.h
new file mode 100644 (file)
index 0000000..b47792d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ARM_RELOC_H
+#define GRUB_ARM_RELOC_H 1
+
+grub_err_t grub_arm_reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr);
+grub_err_t grub_arm_reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
+grub_err_t grub_arm_reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
+
+#endif
index 812db900a05d9ef97bcd94c41dbd8c2a647457aa..b6a7dcbeea7a93aaf4b026c5f749a1479a5fecc7 100644 (file)
@@ -60,9 +60,6 @@
 
 static Elf_Addr SUFFIX (entry_point);
 
-grub_err_t reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
-
 /* Relocate symbols; note that this function overwrites the symbol table.
    Return the address of a start symbol.  */
 static Elf_Addr
@@ -553,19 +550,27 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
                   case R_ARM_THM_CALL:
                   case R_ARM_THM_JUMP24:
                     {
-                      grub_util_info ("  THM_JUMP24:\ttarget=0x%08x\toffset=(0x%08x)", (unsigned int) target, sym_addr);
+                      grub_err_t err;
+                      grub_util_info ("  THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",        (unsigned long) target, sym_addr);
                       sym_addr -= offset;
                       /* Thumb instructions can be 16-bit aligned */
-                      reloc_thm_call ((grub_uint16_t *) target, sym_addr);
+                      err = grub_arm_reloc_thm_call ((grub_uint16_t *) target,
+                                                     sym_addr);
+                      if (err)
+                        grub_util_error ("%s", grub_errmsg);
                     }
                     break;
                   case R_ARM_THM_JUMP19:
                     {
+                      grub_err_t err;
                       grub_util_info ("  THM_JUMP19:\toffset=%d\t(0x%08x)",
                                       sym_addr, sym_addr);
                       sym_addr -= offset;
                       /* Thumb instructions can be 16-bit aligned */
-                      reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+                      err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target,
+                                                       sym_addr);
+                      if (err)
+                        grub_util_error ("%s", grub_errmsg);
                     }
                     break;
                   default: