/* * Taken from NetBSD and stripped of the relocations not needed on RTEMS. */ /* $NetBSD: mdreloc.c,v 1.33 2010/01/14 12:12:07 skrll Exp $ */ #include #include #include #include #include #include #include "rtl-elf.h" #include "rtl-error.h" #include /* * It is possible for the compiler to emit relocations for unaligned data. * We handle this situation with these inlines. */ #define RELOC_ALIGNED_P(x) \ (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0) static inline Elf_Addr load_ptr(void *where) { Elf_Addr res; memcpy(&res, where, sizeof(res)); return (res); } static inline void store_ptr(void *where, Elf_Addr val) { memcpy(where, &val, sizeof(val)); } /* * The address of Thumb function symbols is it's real address plus one. * This is done by compiler, thus do not consider symtype here. */ static inline int isThumb(Elf_Word symvalue) { if ((symvalue & 0x1) == 0x1) return true; else return false; } bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type) { return true; } bool rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj, const Elf_Rela* rela, const rtems_rtl_obj_sect_t* sect, const char* symname, const Elf_Byte syminfo, const Elf_Word symvalue) { rtems_rtl_set_error (EINVAL, "rela type record not supported"); return false; } bool rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj, const Elf_Rel* rel, const rtems_rtl_obj_sect_t* sect, const char* symname, const Elf_Byte syminfo, const Elf_Word symvalue) { Elf_Addr *where; Elf_Addr tmp; Elf_Word insn, addend; Elf_Word sign, i1, i2; uint16_t lower_insn, upper_insn; where = (Elf_Addr *)(sect->base + rel->r_offset); switch (ELF_R_TYPE(rel->r_info)) { case R_TYPE(NONE): break; case R_TYPE(CALL): /* BL/BLX */ case R_TYPE(JUMP24): /* B/BL */ insn = *where; if (insn & 0x00800000) addend = insn | 0xff000000; else addend = insn & 0x00ffffff; if (isThumb(symvalue)) { if ((insn & 0xfe000000) == 0xfa000000); /* Already blx */ else { if ((insn & 0xff000000) == 0xeb000000) { /* BL