source: rtems/cpukit/libdl/rtl-mdreloc-i386.c

Last change on this file 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: 5.9 KB
Line 
1/*
2 * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
3 */
4
5/*  $NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $  */
6
7#include <sys/cdefs.h>
8
9#include <errno.h>
10#include <inttypes.h>
11#include <stdio.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14
15#include <rtems/rtl/rtl.h>
16#include "rtl-elf.h"
17#include "rtl-error.h"
18#include <rtems/rtl/rtl-trace.h>
19#include "rtl-unwind.h"
20#include "rtl-unwind-dw2.h"
21
22uint32_t
23rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
24                             const Elf_Shdr*      shdr)
25{
26  return 0;
27}
28
29uint32_t
30rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
31                                  int                  section,
32                                  const char*          name,
33                                  const Elf_Shdr*      shdr,
34                                  const uint32_t       flags)
35{
36  (void) obj;
37  (void) section;
38  (void) name;
39  (void) shdr;
40  return flags;
41}
42
43bool
44rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
45                                  rtems_rtl_obj_sect*  sect)
46{
47  (void) obj;
48  (void) sect;
49  return false;
50}
51
52bool
53rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
54                                  rtems_rtl_obj_sect*  sect)
55{
56  (void) obj;
57  (void) sect;
58  return false;
59}
60
61bool
62rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
63{
64  return true;
65}
66
67size_t
68rtems_rtl_elf_relocate_tramp_max_size (void)
69{
70  /*
71   * Disable by returning 0.
72   */
73  return 0;
74}
75
76rtems_rtl_elf_rel_status
77rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
78                                   const Elf_Rela*           rela,
79                                   const rtems_rtl_obj_sect* sect,
80                                   const char*               symname,
81                                   const Elf_Byte            syminfo,
82                                   const Elf_Word            symvalue)
83{
84  (void) obj;
85  (void) rela;
86  (void) sect;
87  (void) symname;
88  (void) syminfo;
89  (void) symvalue;
90  rtems_rtl_set_error (EINVAL, "rela type record not supported");
91  return rtems_rtl_elf_rel_failure;
92}
93
94rtems_rtl_elf_rel_status
95rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
96                             const Elf_Rela*           rel,
97                             const rtems_rtl_obj_sect* sect,
98                             const char*               symname,
99                             const Elf_Byte            syminfo,
100                             const Elf_Word            symvalue)
101{
102  (void) obj;
103  (void) rel;
104  (void) sect;
105  (void) symname;
106  (void) syminfo;
107  (void) symvalue;
108  rtems_rtl_set_error (EINVAL, "rela type record not supported");
109  return rtems_rtl_elf_rel_failure;
110}
111
112rtems_rtl_elf_rel_status
113rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
114                                  const Elf_Rel*            rel,
115                                  const rtems_rtl_obj_sect* sect,
116                                  const char*               symname,
117                                  const Elf_Byte            syminfo,
118                                  const Elf_Word            symvalue)
119{
120  (void) obj;
121  (void) rel;
122  (void) sect;
123  (void) symname;
124  (void) syminfo;
125  (void) symvalue;
126  return rtems_rtl_elf_rel_no_error;
127}
128
129rtems_rtl_elf_rel_status
130rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
131                            const Elf_Rel*            rel,
132                            const rtems_rtl_obj_sect* sect,
133                            const char*               symname,
134                            const Elf_Byte            syminfo,
135                            const Elf_Word            symvalue)
136{
137  Elf_Addr  target = 0;
138  Elf_Addr* where;
139  Elf_Addr  tmp;
140
141  where = (Elf_Addr *)(sect->base + rel->r_offset);
142
143  switch (ELF_R_TYPE(rel->r_info)) {
144    case R_TYPE(NONE):
145      break;
146
147    case R_TYPE(PC32):
148      target = (Elf_Addr) symvalue;
149      *where += target - (Elf_Addr)where;
150
151      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
152        printf ("rtl: reloc PC32 in %s --> %p (%p @ %p) in %s\n",
153                sect->name, (void*) symvalue,
154                (void *)*where, where, rtems_rtl_obj_oname (obj));
155      break;
156
157    case R_TYPE(GOT32):
158    case R_TYPE(32):
159    case R_TYPE(GLOB_DAT):
160      target = (Elf_Addr) symvalue;
161
162      tmp = target + *where;
163      if (*where != tmp)
164        *where = tmp;
165      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
166        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p @ %p in %s\n",
167                sect->name, (void *)*where, where,
168                rtems_rtl_obj_oname (obj));
169      break;
170
171    case R_TYPE(RELATIVE):
172      *where += (Elf_Addr)sect->base;
173      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
174        printf ("rtl: reloc RELATIVE in %s --> %p @ %p\n",
175                rtems_rtl_obj_oname (obj), (void *)*where, where);
176      break;
177
178    case R_TYPE(COPY):
179      printf ("rtl: reloc COPY (please report)\n");
180      break;
181
182    default:
183      printf ("rtl: reloc unknown: sym = %i, type = %" PRIu32 ", offset = %p, "
184              "contents = %p\n",
185              (int) ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
186              (void *)rel->r_offset, (void *)*where);
187      rtems_rtl_set_error (EINVAL,
188                           "%s: Unsupported relocation type %" PRIu32 " "
189                           "in non-PLT relocations",
190                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
191      return rtems_rtl_elf_rel_failure;
192  }
193
194  return rtems_rtl_elf_rel_no_error;
195}
196
197bool
198rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
199                            const char*          name,
200                            uint32_t             flags)
201{
202  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
203}
204
205bool
206rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
207{
208  return rtems_rtl_elf_unwind_dw2_register (obj);
209}
210
211bool
212rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
213{
214  return rtems_rtl_elf_unwind_dw2_deregister (obj);
215}
Note: See TracBrowser for help on using the repository browser.