grub-devel
[Top][All Lists]
Advanced

[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
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]