source: rtems/cpukit/libdl/rtl-mdreloc-m68k.c @ 6c9f017

Last change on this file since 6c9f017 was 6c9f017, checked in by Chris Johns <chrisj@…>, on Feb 2, 2019 at 4:09:53 AM

libdl: Add powerpc large memory and small data support.

  • Add support for architecure sections that can be handled by the architecture back end.
  • Add trampoline/fixup support for PowerPC. This means the PowerPC now supports large memory loading of applications.
  • Add a bit allocator to manage small block based regions of memory.
  • Add small data (sdata/sbss) support for the PowerPC. The support makes the linker allocated small data region of memory a global resource available to libdl loaded object files.

Updates #3687
Updates #3685

  • Property mode set to 100644
File size: 7.0 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 <rtems/rtl/rtl-trace.h>
18#include "rtl-unwind.h"
19#include "rtl-unwind-dw2.h"
20
21static inline int overflow_8_check(int value)
22{
23  if ((value & 0xffffff00) && (~value & 0xffffff80))
24    return true;
25  return false;
26}
27
28static inline int overflow_16_check(int value)
29{
30  if ((value & 0xffff0000) && (~value & 0xffff8000))
31    return true;
32  return false;
33}
34
35uint32_t
36rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
37                             const Elf_Shdr*      shdr)
38{
39  return 0;
40}
41
42uint32_t
43rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
44                                  int                  section,
45                                  const char*          name,
46                                  const Elf_Shdr*      shdr,
47                                  const uint32_t       flags)
48{
49  (void) obj;
50  (void) section;
51  (void) name;
52  (void) shdr;
53  return flags;
54}
55
56bool
57rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
58                                  rtems_rtl_obj_sect*  sect)
59{
60  (void) obj;
61  (void) sect;
62  return false;
63}
64
65bool
66rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
67                                  rtems_rtl_obj_sect*  sect)
68{
69  (void) obj;
70  (void) sect;
71  return false;
72}
73
74bool
75rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
76{
77  return true;
78}
79
80size_t
81rtems_rtl_elf_relocate_tramp_max_size (void)
82{
83  /*
84   * Disable by returning 0.
85   */
86  return 0;
87}
88
89bool
90rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
91                                   const Elf_Rela*           rela,
92                                   const rtems_rtl_obj_sect* sect,
93                                   const char*               symname,
94                                   const Elf_Byte            syminfo,
95                                   const Elf_Word            symvalue)
96{
97  (void) obj;
98  (void) rela;
99  (void) sect;
100  (void) symname;
101  (void) syminfo;
102  (void) symvalue;
103  return true;
104}
105
106bool
107rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
108                             const Elf_Rela*           rela,
109                             const rtems_rtl_obj_sect* sect,
110                             const char*               symnane,
111                             const Elf_Byte            syminfo,
112                             const Elf_Word            symvalue)
113{
114  Elf_Addr  target = 0;
115  Elf_Addr* where;
116  Elf_Word  tmp;
117
118  where = (Elf_Addr *)(sect->base + rela->r_offset);
119
120  switch (ELF_R_TYPE(rela->r_info)) {
121                case R_TYPE(NONE):
122                        break;
123
124    case R_TYPE(PC8):
125      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
126      if (overflow_8_check(tmp))
127        return false;
128
129      *(uint8_t *)where = tmp;
130
131      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
132        printf ("rtl: reloc R_TYPE_8/PC8 in %s --> %p (%p) in %s\n",
133                sect->name, (void*) (symvalue + rela->r_addend),
134                (void *)*where, rtems_rtl_obj_oname (obj));
135      break;
136
137    case R_TYPE(PC16):
138      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
139      if (overflow_16_check(tmp))
140        return false;
141
142      *(uint16_t*)where = tmp;
143
144      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
145        printf ("rtl: reloc R_TYPE_16/PC16 in %s --> %p (%p) in %s\n",
146                sect->name, (void*) (symvalue + rela->r_addend),
147                (void *)*where, rtems_rtl_obj_oname (obj));
148      break;
149                case R_TYPE(PC32):
150      target = (Elf_Addr) symvalue + rela->r_addend;
151      *where += target - (Elf_Addr)where;
152
153      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
154        printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n",
155                sect->name, (void*) (symvalue + rela->r_addend),
156                (void *)*where, rtems_rtl_obj_oname (obj));
157      break;
158
159                case R_TYPE(GOT32):
160                case R_TYPE(32):
161                case R_TYPE(GLOB_DAT):
162      target = (Elf_Addr) symvalue + rela->r_addend;
163
164                        if (*where != target)
165                                *where = target;
166
167      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
168        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n",
169                sect->name, (void *)*where,
170                rtems_rtl_obj_oname (obj));
171                        break;
172
173                case R_TYPE(RELATIVE):
174                        *where += (Elf_Addr) sect->base + rela->r_addend;
175      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
176        printf ("rtl: reloc RELATIVE in %s --> %p\n",
177                rtems_rtl_obj_oname (obj), (void *)*where);
178                        break;
179
180                case R_TYPE(COPY):
181                        /*
182                         * These are deferred until all other relocations have
183                         * been done.  All we do here is make sure that the
184                         * COPY relocation is not in a shared library.  They
185                         * are allowed only in executable files.
186                         */
187      printf ("rtl: reloc COPY (please report)\n");
188                        break;
189
190                default:
191      printf ("rtl: reloc unknown: sym = %u, type = %u, offset = %p, "
192              "contents = %p\n",
193              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
194              (void *)rela->r_offset, (void *)*where);
195      rtems_rtl_set_error (EINVAL,
196                           "%s: Unsupported relocation type %d "
197                           "in non-PLT relocations",
198                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
199      return false;
200  }
201
202  return true;
203}
204
205bool
206rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
207                                  const Elf_Rel*            rel,
208                                  const rtems_rtl_obj_sect* sect,
209                                  const char*               symname,
210                                  const Elf_Byte            syminfo,
211                                  const Elf_Word            symvalue)
212{
213  (void) obj;
214  (void) rel;
215  (void) sect;
216  (void) symname;
217  (void) syminfo;
218  (void) symvalue;
219  rtems_rtl_set_error (EINVAL, "rel type record not supported");
220  return false;
221}
222
223bool
224rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
225                            const Elf_Rel*            rel,
226                            const rtems_rtl_obj_sect* sect,
227                            const char*               symname,
228                            const Elf_Byte            syminfo,
229                            const Elf_Word            symvalue)
230{
231  (void) obj;
232  (void) rel;
233  (void) sect;
234  (void) symname;
235  (void) syminfo;
236  (void) symvalue;
237  rtems_rtl_set_error (EINVAL, "rel type record not supported");
238  return false;
239}
240
241bool
242rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
243                            const char*          name,
244                            uint32_t             flags)
245{
246  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
247}
248
249bool
250rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
251{
252  return rtems_rtl_elf_unwind_dw2_register (obj);
253}
254
255bool
256rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
257{
258  return rtems_rtl_elf_unwind_dw2_deregister (obj);
259}
Note: See TracBrowser for help on using the repository browser.