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

Last change on this file since b36c5209 was b36c5209, checked in by Chris Johns <chrisj@…>, on May 3, 2019 at 12:15:20 AM

libdl: Do not access the ELF file while the allocator is locked.

  • Load symbols before allocation.
  • Parse reloc records and place any reloc recs in a cache to use while the allocator is locked.
  • Relocate symbols after section allocation.
  • Split section loading into allocation/locating and loading.
  • Update all arch back-ends with a new reloc interface to control tramp handling.
  • Add -a and -t to the object list shell command.

Closes #3741

  • Property mode set to 100644
File size: 7.1 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
89rtems_rtl_elf_rel_status
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 rtems_rtl_elf_rel_no_error;
104}
105
106rtems_rtl_elf_rel_status
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 rtems_rtl_elf_rel_failure;
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 rtems_rtl_elf_rel_failure;
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 rtems_rtl_elf_rel_failure;
200  }
201
202  return rtems_rtl_elf_rel_no_error;
203}
204
205rtems_rtl_elf_rel_status
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 rtems_rtl_elf_rel_failure;
221}
222
223rtems_rtl_elf_rel_status
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 rtems_rtl_elf_rel_failure;
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.