[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] arm: implement additional relocations generated by gcc 4.9 a
From: |
Michael Zimmermann |
Subject: |
Re: [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3 |
Date: |
Wed, 4 Feb 2015 06:36:59 +0100 |
Confirmed working, nice work.
Michael
On Tue, Feb 3, 2015 at 11:11 PM, Vladimir 'φ-coder/phcoder' Serbinenko
<address@hidden> 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 <address@hidden>
>> ---
>> 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
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel
>