Confirmed working, nice work. Michael
On Tue, Feb 3, 2015 at 11:11 PM, Vladimir 'φ-coder/phcoder' Serbinenko <phco...@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.lindh...@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 > _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel