* [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
* Re: [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3
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
0 siblings, 1 reply; 3+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2015-02-03 22:11 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 3415 bytes --]
Go ahead
On 03.02.2015 22:30, Leif Lindholm wrote:
> 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
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3
2015-02-03 22:11 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2015-02-04 5:36 ` Michael Zimmermann
0 siblings, 0 replies; 3+ messages in thread
From: Michael Zimmermann @ 2015-02-04 5:36 UTC (permalink / raw)
To: The development of GNU GRUB
Confirmed working, nice work.
Michael
On Tue, Feb 3, 2015 at 11:11 PM, Vladimir 'φ-coder/phcoder' Serbinenko
<phcoder@gmail.com> wrote:
> Go ahead
> On 03.02.2015 22:30, Leif Lindholm wrote:
>> 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
>>
>
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
^ permalink raw reply [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.