source: rtems/cpukit/libdl/rtl-mdreloc-m68k.c @ 8709aa04

5
Last change on this file since 8709aa04 was ae5fe7e6, checked in by Chris Johns <chrisj@…>, on 10/27/14 at 01:09:41

cpukit: Add libdl with the Runtime Loader (RTL) code.

This is a merge of the RTL project.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
3 */
4
5/*      $NetBSD: mdreloc.c,v 1.26 2010/01/14 11:58:32 skrll Exp $       */
6
7#include <sys/cdefs.h>
8
9#include <errno.h>
10#include <stdio.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13
14#include <rtems/rtl/rtl.h>
15#include "rtl-elf.h"
16#include "rtl-error.h"
17#include "rtl-trace.h"
18
19static inline int overflow_8_check(int value)
20{
21  if ((value & 0xffffff00) && (~value & 0xffffff80))
22    return true;
23  return false;
24}
25
26static inline int overflow_16_check(int value)
27{
28  if ((value & 0xffff0000) && (~value & 0xffff8000))
29    return true;
30  return false;
31}
32
33bool
34rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
35{
36  return true;
37}
38
39bool
40rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
41                             const Elf_Rela*             rela,
42                             const rtems_rtl_obj_sect_t* sect,
43                             const char*                 symnane,
44                             const Elf_Byte              syminfo,
45                             const Elf_Word              symvalue)
46{
47        Elf_Addr  target = 0;
48  Elf_Addr* where;
49  Elf_Word  tmp;
50
51  where = (Elf_Addr *)(sect->base + rela->r_offset);
52
53  switch (ELF_R_TYPE(rela->r_info)) {
54                case R_TYPE(NONE):
55                        break;
56
57    case R_TYPE(PC8):
58      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
59      if (overflow_8_check(tmp))
60        return false;
61
62      *(uint8_t *)where = tmp;
63
64      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
65        printf ("rtl: reloc R_TYPE_8/PC8 in %s --> %p (%p) in %s\n",
66                sect->name, (void*) (symvalue + rela->r_addend),
67                (void *)*where, rtems_rtl_obj_oname (obj));
68      break;
69
70    case R_TYPE(PC16):
71      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
72      if (overflow_16_check(tmp))
73        return false;
74
75      *(uint16_t*)where = tmp;
76
77      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
78        printf ("rtl: reloc R_TYPE_16/PC16 in %s --> %p (%p) in %s\n",
79                sect->name, (void*) (symvalue + rela->r_addend),
80                (void *)*where, rtems_rtl_obj_oname (obj));
81      break;
82                case R_TYPE(PC32):
83      target = (Elf_Addr) symvalue + rela->r_addend;
84      *where += target - (Elf_Addr)where;
85
86      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
87        printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n",
88                sect->name, (void*) (symvalue + rela->r_addend),
89                (void *)*where, rtems_rtl_obj_oname (obj));
90      break;
91
92                case R_TYPE(GOT32):
93                case R_TYPE(32):
94                case R_TYPE(GLOB_DAT):
95      target = (Elf_Addr) symvalue + rela->r_addend;
96
97                        if (*where != target)
98                                *where = target;
99
100      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
101        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n",
102                sect->name, (void *)*where,
103                rtems_rtl_obj_oname (obj));
104                        break;
105
106                case R_TYPE(RELATIVE):
107                        *where += (Elf_Addr) sect->base + rela->r_addend;
108      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
109        printf ("rtl: reloc RELATIVE in %s --> %p\n",
110                rtems_rtl_obj_oname (obj), (void *)*where);
111                        break;
112
113                case R_TYPE(COPY):
114                        /*
115                         * These are deferred until all other relocations have
116                         * been done.  All we do here is make sure that the
117                         * COPY relocation is not in a shared library.  They
118                         * are allowed only in executable files.
119                         */
120      printf ("rtl: reloc COPY (please report)\n");
121                        break;
122
123                default:
124      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
125              "contents = %p\n",
126              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
127              (void *)rela->r_offset, (void *)*where);
128      rtems_rtl_set_error (EINVAL,
129                           "%s: Unsupported relocation type %ld "
130                           "in non-PLT relocations",
131                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
132      return false;
133  }
134
135  return true;
136}
137
138bool
139rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
140                            const Elf_Rel*              rel,
141                            const rtems_rtl_obj_sect_t* sect,
142                            const char*                 symname,
143                            const Elf_Byte              syminfo,
144                            const Elf_Word              symvalue)
145{
146  rtems_rtl_set_error (EINVAL, "rel type record not supported");
147  return false;
148}
Note: See TracBrowser for help on using the repository browser.