From 42d16f6d37130a3550b537d35698977f06908234 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 22 Jul 2013 10:56:13 +0800 Subject: H8300 Support Signed-off-by: Peng Fan --- rtl-mdreloc-h8300.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 rtl-mdreloc-h8300.c (limited to 'rtl-mdreloc-h8300.c') diff --git a/rtl-mdreloc-h8300.c b/rtl-mdreloc-h8300.c new file mode 100644 index 0000000..e9adeda --- /dev/null +++ b/rtl-mdreloc-h8300.c @@ -0,0 +1,101 @@ +#include + +#include +#include +#include +#include + +#include +#include "rtl-elf.h" +#include "rtl-error.h" +#include + +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) +{ + Elf_Addr *where; + Elf_Word tmp; + + where = (Elf_Addr *)(sect->base + rela->r_offset); + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) { + printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info)); + printf("relocated address 0x%08lx\n", (Elf_Addr)where); + } + + tmp = symvalue; + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(NONE): + break; + + case R_TYPE(DIR16): + *(uint16_t *)where += symvalue + rela->r_addend; + break; + + case R_TYPE(DIR32): + case R_TYPE(DIR32A16): + *where += symvalue + rela->r_addend; + break; + + case R_TYPE(DIR24A8): + if (ELF32_R_SYM(rela->r_info)) + *where += symvalue + rela->r_addend; + break; + + case R_TYPE(DIR24R8): + where = (uint32_t *)((uint32_t)where - 1); + *where = (*where & 0xff000000) | ((*where & 0xffffff) + symvalue + rela->r_addend); + break; + + case R_TYPE(PCREL8): + /* bcc instruction */ + tmp = symvalue + rela->r_addend - (Elf_Addr)where - 1; + if (((Elf32_Sword)tmp > 0x7f) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x80)){ + printf("PCREL8 overflow\n"); + return false; + } else { + *(uint8_t *)where = tmp; + } + break; + + case R_TYPE(PCREL16): + /* bcc instruction */ + tmp = symvalue + rela->r_addend - (Elf_Addr)where - 2; + if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x8000)){ + printf("PCREL16 overflow\n"); + return false; + } else { + *(uint16_t *)where = tmp; + } + break; + + default: + rtems_rtl_set_error (EINVAL, "rela type record not supported"); + printf("Unsupported reloc types\n"); + return false; + } + return true; +} + +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) +{ + rtems_rtl_set_error (EINVAL, "rel type record not supported"); + return false; +} -- cgit v1.2.3