source: rtems/cpukit/libdl/rtl-mdreloc-bfin.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: 5.7 KB
Line 
1#include <sys/cdefs.h>
2
3#include <stdio.h>
4#include <rtems/rtl/rtl.h>
5#include <errno.h>
6#include "rtl-elf.h"
7#include "rtl-error.h"
8#include <rtems/rtl/rtl-trace.h>
9#include "rtl-unwind.h"
10#include "rtl-unwind-dw2.h"
11
12uint32_t
13rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
14                             const Elf_Shdr*        shdr)
15{
16  return 0;
17}
18
19uint32_t
20rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
21                                  int                  section,
22                                  const char*          name,
23                                  const Elf_Shdr*      shdr,
24                                  const uint32_t       flags)
25{
26  (void) obj;
27  (void) section;
28  (void) name;
29  (void) shdr;
30  return flags;
31}
32
33bool
34rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
35                                  rtems_rtl_obj_sect*  sect)
36{
37  (void) obj;
38  (void) sect;
39  return false;
40}
41
42bool
43rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
44                                  rtems_rtl_obj_sect*  sect)
45{
46  (void) obj;
47  (void) sect;
48  return false;
49}
50
51bool
52rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
53{
54  return true;
55}
56
57static inline Elf_Addr
58load_ptr(void *where)
59{
60        Elf_Addr res;
61
62        memcpy(&res, where, sizeof(res));
63
64        return (res);
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  return rtems_rtl_elf_rel_no_error;
91}
92
93rtems_rtl_elf_rel_status
94rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
95                             const Elf_Rela*           rela,
96                             const rtems_rtl_obj_sect* sect,
97                             const char*               symname,
98                             const Elf_Byte            syminfo,
99                             const Elf_Word            symvalue)
100{
101  Elf_Addr target = 0;
102  Elf_Addr *where;
103  Elf_Word tmp;
104  Elf_Word size; //byte
105
106  where = (Elf_Addr *)(sect->base + rela->r_offset);
107
108  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
109      printf("rela relocation type is %d relocated address 0x%08x",
110              ELF_R_TYPE(rela->r_info), where);
111  }
112
113  tmp = symvalue;
114  switch (ELF_R_TYPE(rela->r_info)) {
115    case R_TYPE(UNUSED0):
116      break;
117
118    case R_TYPE(HUIMM16):
119      tmp = symvalue >> 16;
120    case R_TYPE(LUIMM16):
121    case R_TYPE(RIMM16):
122      size = 2;
123      break;
124
125    case R_TYPE(BYTE4_DATA):
126      size = 4;
127      break;
128
129    case R_TYPE(PCREL24):
130    case R_TYPE(PCREL24_JU):
131      where = (Elf_Addr*)((Elf_Addr)where - 2); /* Back 2 bytes */
132      tmp = symvalue - (Elf_Addr)where;
133      tmp >>= 1;
134      if ((tmp & 0x20000000) == 0x20000000)
135        tmp |= 0xc0000000;
136
137      if ((tmp & 0xff000000) && (~tmp & 0xff800000)) {
138        printf("PCREL24/PCREL24_JU Overflow\n");
139        return rtems_rtl_elf_rel_failure;
140      }
141
142      tmp = (load_ptr(where) & 0x0000ff00) | ((tmp & 0x0000ffff) << 16) |
143             ((tmp & 0x00ff0000) >> 16);
144      size = 4;
145      break;
146
147    case R_TYPE(PCREL12_JUMP_S):
148      tmp = symvalue - (Elf_Addr)where;
149      tmp >>= 1;
150      if ((tmp & 0x20000000) == 0x20000000)
151        tmp |= 0xc0000000;
152
153      if ((tmp & 0xfffff000) && (~tmp & 0xfffff800)) {
154        printf("PCREL12_JUMP_S Overflow\n");
155        return rtems_rtl_elf_rel_failure;
156      }
157
158      tmp = ((*(uint16_t *)where) & 0xf000) | (tmp & 0xfff);
159      size = 2;
160      break;
161
162    default:
163      printf("Unspported rela type\n");
164      return rtems_rtl_elf_rel_failure;
165  }
166
167  memcpy((void*)where, &tmp, size);
168
169  return rtems_rtl_elf_rel_no_error;
170}
171
172rtems_rtl_elf_rel_status
173rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
174                                  const Elf_Rel*            rel,
175                                  const rtems_rtl_obj_sect* sect,
176                                  const char*               symname,
177                                  const Elf_Byte            syminfo,
178                                  const Elf_Word            symvalue)
179{
180  (void) obj;
181  (void) rel;
182  (void) sect;
183  (void) symname;
184  (void) syminfo;
185  (void) symvalue;
186  rtems_rtl_set_error (EINVAL, "rel type record not supported");
187  return rtems_rtl_elf_rel_failure;
188}
189
190rtems_rtl_elf_rel_status
191rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
192                            const Elf_Rel*            rel,
193                            const rtems_rtl_obj_sect* sect,
194                            const char*               symname,
195                            const Elf_Byte            syminfo,
196                            const Elf_Word            symvalue)
197{
198  (void) obj;
199  (void) rel;
200  (void) sect;
201  (void) symname;
202  (void) syminfo;
203  (void) symvalue;
204  rtems_rtl_set_error (EINVAL, "rel type record not supported");
205  return rtems_rtl_elf_rel_failure;
206}
207
208bool
209rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
210                            const char*          name,
211                            uint32_t             flags)
212{
213  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
214}
215
216bool
217rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
218{
219  return rtems_rtl_elf_unwind_dw2_register (obj);
220}
221
222bool
223rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
224{
225  return rtems_rtl_elf_unwind_dw2_deregister (obj);
226}
Note: See TracBrowser for help on using the repository browser.