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: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: Re: [PATCH] arm: implement additional relocations generated by gcc 4.9 at -O3
Date: Tue, 03 Feb 2015 23:11:44 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.4.0

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
> 


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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