From ae5fe7e6bca2874c5f1ef077204bb63124fb3db3 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Sun, 26 Oct 2014 18:09:41 -0700 Subject: cpukit: Add libdl with the Runtime Loader (RTL) code. This is a merge of the RTL project. --- cpukit/libdl/rtl-mdreloc-m68k.c | 148 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 cpukit/libdl/rtl-mdreloc-m68k.c (limited to 'cpukit/libdl/rtl-mdreloc-m68k.c') diff --git a/cpukit/libdl/rtl-mdreloc-m68k.c b/cpukit/libdl/rtl-mdreloc-m68k.c new file mode 100644 index 0000000000..36692ebf85 --- /dev/null +++ b/cpukit/libdl/rtl-mdreloc-m68k.c @@ -0,0 +1,148 @@ +/* + * Taken from NetBSD and stripped of the relocations not needed on RTEMS. + */ + +/* $NetBSD: mdreloc.c,v 1.26 2010/01/14 11:58:32 skrll Exp $ */ + +#include + +#include +#include +#include +#include + +#include +#include "rtl-elf.h" +#include "rtl-error.h" +#include "rtl-trace.h" + +static inline int overflow_8_check(int value) +{ + if ((value & 0xffffff00) && (~value & 0xffffff80)) + return true; + return false; +} + +static inline int overflow_16_check(int value) +{ + if ((value & 0xffff0000) && (~value & 0xffff8000)) + return true; + 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* symnane, + const Elf_Byte syminfo, + const Elf_Word symvalue) +{ + Elf_Addr target = 0; + Elf_Addr* where; + Elf_Word tmp; + + where = (Elf_Addr *)(sect->base + rela->r_offset); + + switch (ELF_R_TYPE(rela->r_info)) { + case R_TYPE(NONE): + break; + + case R_TYPE(PC8): + tmp = symvalue + rela->r_addend - (Elf_Addr)where; + if (overflow_8_check(tmp)) + return false; + + *(uint8_t *)where = tmp; + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ("rtl: reloc R_TYPE_8/PC8 in %s --> %p (%p) in %s\n", + sect->name, (void*) (symvalue + rela->r_addend), + (void *)*where, rtems_rtl_obj_oname (obj)); + break; + + case R_TYPE(PC16): + tmp = symvalue + rela->r_addend - (Elf_Addr)where; + if (overflow_16_check(tmp)) + return false; + + *(uint16_t*)where = tmp; + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ("rtl: reloc R_TYPE_16/PC16 in %s --> %p (%p) in %s\n", + sect->name, (void*) (symvalue + rela->r_addend), + (void *)*where, rtems_rtl_obj_oname (obj)); + break; + case R_TYPE(PC32): + target = (Elf_Addr) symvalue + rela->r_addend; + *where += target - (Elf_Addr)where; + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n", + sect->name, (void*) (symvalue + rela->r_addend), + (void *)*where, rtems_rtl_obj_oname (obj)); + break; + + case R_TYPE(GOT32): + case R_TYPE(32): + case R_TYPE(GLOB_DAT): + target = (Elf_Addr) symvalue + rela->r_addend; + + if (*where != target) + *where = target; + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n", + sect->name, (void *)*where, + rtems_rtl_obj_oname (obj)); + break; + + case R_TYPE(RELATIVE): + *where += (Elf_Addr) sect->base + rela->r_addend; + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ("rtl: reloc RELATIVE in %s --> %p\n", + rtems_rtl_obj_oname (obj), (void *)*where); + break; + + case R_TYPE(COPY): + /* + * These are deferred until all other relocations have + * been done. All we do here is make sure that the + * COPY relocation is not in a shared library. They + * are allowed only in executable files. + */ + printf ("rtl: reloc COPY (please report)\n"); + break; + + default: + printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, " + "contents = %p\n", + ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info), + (void *)rela->r_offset, (void *)*where); + rtems_rtl_set_error (EINVAL, + "%s: Unsupported relocation type %ld " + "in non-PLT relocations", + sect->name, (uint32_t) ELF_R_TYPE(rela->r_info)); + 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