All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3
@ 2015-02-03 21:30 Leif Lindholm
  2015-02-03 22:11 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 3+ messages in thread
From: Leif Lindholm @ 2015-02-03 21:30 UTC (permalink / raw)
  To: grub-devel

GCC 4.9 also generates R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS,
as an alternative to ABS32.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 grub-core/kern/arm/dl.c        | 15 +++++++++++++++
 grub-core/kern/arm/dl_helper.c | 39 +++++++++++++++++++++++++++++++++++++++
 include/grub/arm/reloc.h       |  5 +++++
 3 files changed, 59 insertions(+)

diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c
index 57cac2e..5cbd65e 100644
--- a/grub-core/kern/arm/dl.c
+++ b/grub-core/kern/arm/dl.c
@@ -205,6 +205,21 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
 	   */
 	case R_ARM_V4BX:
 	  break;
+	case R_ARM_THM_MOVW_ABS_NC:
+	case R_ARM_THM_MOVT_ABS:
+	  {
+	    grub_uint32_t offset;
+	    offset = grub_arm_thm_movw_movt_get_value((grub_uint16_t *) target);
+	    offset += sym_addr;
+
+	    if (ELF_R_TYPE (rel->r_info) == R_ARM_THM_MOVT_ABS)
+	      offset >>= 16;
+	    else
+	      offset &= 0xffff;
+
+	    grub_arm_thm_movw_movt_set_value((grub_uint16_t *) target, offset);
+	  }
+	  break;
 	case R_ARM_THM_JUMP19:
 	  {
 	    /* Thumb instructions can be 16-bit aligned */
diff --git a/grub-core/kern/arm/dl_helper.c b/grub-core/kern/arm/dl_helper.c
index 5721939..8a72632 100644
--- a/grub-core/kern/arm/dl_helper.c
+++ b/grub-core/kern/arm/dl_helper.c
@@ -25,6 +25,20 @@
 #include <grub/i18n.h>
 #include <grub/arm/reloc.h>
 
+static inline grub_uint32_t
+thumb_get_instruction_word(grub_uint16_t *target)
+{
+  /* Extract instruction word in alignment-safe manner */
+  return grub_le_to_cpu16 ((*target)) << 16 | grub_le_to_cpu16 (*(target + 1));
+}
+
+static inline void
+thumb_set_instruction_word(grub_uint16_t *target, grub_uint32_t insword)
+{
+  *target = grub_cpu_to_le16 (insword >> 16);
+  *(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
+}
+
 /*
  * R_ARM_ABS32
  *
@@ -214,3 +228,28 @@ grub_arm_jump24_set_offset (grub_uint32_t *target,
 
   *target = grub_cpu_to_le32 (insword);
 }
+
+grub_uint16_t
+grub_arm_thm_movw_movt_get_value (grub_uint16_t *target)
+{
+  grub_uint32_t insword;
+
+  insword = thumb_get_instruction_word (target);
+
+  return ((insword & 0xf0000) >> 4) | ((insword & 0x04000000) >> 15) | \
+    ((insword & 0x7000) >> 4) | (insword & 0xff);
+}
+
+void
+grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value)
+{
+  grub_uint32_t insword;
+
+  insword = thumb_get_instruction_word (target);
+  insword &= 0xfbf08f00;
+
+  insword |= ((value & 0xf000) << 4) | ((value & 0x0800) << 15) | \
+    ((value & 0x0700) << 4) | (value & 0xff);
+
+  thumb_set_instruction_word (target, insword);
+}
diff --git a/include/grub/arm/reloc.h b/include/grub/arm/reloc.h
index b938037..ae92e21 100644
--- a/include/grub/arm/reloc.h
+++ b/include/grub/arm/reloc.h
@@ -43,4 +43,9 @@ void
 grub_arm_jump24_set_offset (grub_uint32_t *target,
 			    grub_int32_t offset);
 
+grub_uint16_t
+grub_arm_thm_movw_movt_get_value (grub_uint16_t *target);
+void
+grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value);
+
 #endif
-- 
2.1.3



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-02-04  5:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-03 21:30 [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3 Leif Lindholm
2015-02-03 22:11 ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-02-04  5:36   ` Michael Zimmermann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.