source: rtems/cpukit/libdl/rtl-mdreloc-lm32.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: 6.0 KB
Line 
1#include <sys/cdefs.h>
2
3#include <errno.h>
4#include <stdio.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
8#include <rtems/rtl/rtl.h>
9#include "rtl-elf.h"
10#include "rtl-error.h"
11#include <rtems/rtl/rtl-trace.h>
12#include "rtl-unwind.h"
13#include "rtl-unwind-dw2.h"
14
15uint32_t
16rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
17                             const Elf_Shdr*      shdr)
18{
19  return 0;
20}
21
22uint32_t
23rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
24                                  int                  section,
25                                  const char*          name,
26                                  const Elf_Shdr*      shdr,
27                                  const uint32_t       flags)
28{
29  (void) obj;
30  (void) section;
31  (void) name;
32  (void) shdr;
33  return flags;
34}
35
36bool
37rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
38                                  rtems_rtl_obj_sect*  sect)
39{
40  (void) obj;
41  (void) sect;
42  return false;
43}
44
45bool
46rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
47                                  rtems_rtl_obj_sect*  sect)
48{
49  (void) obj;
50  (void) sect;
51  return false;
52}
53
54bool
55rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
56{
57  return true;
58}
59
60size_t
61rtems_rtl_elf_relocate_tramp_max_size (void)
62{
63  /*
64   * Disable by returning 0.
65   */
66  return 0;
67}
68
69rtems_rtl_elf_rel_status
70rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
71                                   const Elf_Rela*           rela,
72                                   const rtems_rtl_obj_sect* sect,
73                                   const char*               symname,
74                                   const Elf_Byte            syminfo,
75                                   const Elf_Word            symvalue)
76{
77  (void) obj;
78  (void) rela;
79  (void) sect;
80  (void) symname;
81  (void) syminfo;
82  (void) symvalue;
83  return rtems_rtl_elf_rel_no_error;
84}
85
86rtems_rtl_elf_rel_status
87rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
88                             const Elf_Rela*           rela,
89                             const rtems_rtl_obj_sect* sect,
90                             const char*               symname,
91                             const Elf_Byte            syminfo,
92                             const Elf_Word            symvalue)
93{
94  Elf_Addr *where;
95  Elf32_Word tmp;
96  Elf32_Word insn;
97
98
99  where = (Elf_Addr *)(sect->base + rela->r_offset);
100
101  switch (ELF_R_TYPE(rela->r_info)) {
102    case R_TYPE(NONE):
103      break;
104
105    case R_TYPE(HI16):
106      insn = *where;
107      /* orhi/mvhi instruction
108       *  31--------26|25-21|20-16|15----0|
109       * |0 1 1 1 1 0 |rY   |rX   |imm16  |
110       */
111      if (0x1e == (insn >> 26)) {
112        insn &= 0xffff0000;
113        insn |= ((symvalue + rela->r_addend) >> 16);
114        *where = insn;
115      }
116      break;
117
118    case R_TYPE(LO16):
119      insn = *where;
120      /* ori instruction
121       *  31--------26|25-21|20-16|15----0|
122       * |0 0 1 1 1 0 |rY   |rX   |imm16  |
123       */
124      if (0xe == (insn >> 26)) {
125        insn &= 0xffff0000;
126        insn |= ((symvalue + rela->r_addend) & 0xffff);
127        *where = insn;
128      }
129      break;
130
131    case R_TYPE(CALL):
132      insn = *where;
133      /*
134       * calli instruction
135       *  31-------26|25---0|
136       * |1 1 1 1 1 0|imm26 |
137       * Syntax: call imm26
138       * Operation: ra = pc + 4; pc = pc + sign_extend(imm26<<2)
139       */
140      if (0x3e == (insn >> 26)) {
141        Elf_Sword imm26 = symvalue +rela->r_addend - (Elf_Addr)where;
142        imm26 = (imm26 >> 2) & 0x3ffffff;
143        insn = 0xf8000000 + imm26;
144        *where = insn;
145      }
146      break;
147
148    case R_TYPE(BRANCH):
149      insn = *where;
150      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
151      tmp = (Elf32_Sword)tmp >> 2;
152      if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -0x8000)){
153        printf("BRANCH Overflow\n");
154        return rtems_rtl_elf_rel_failure;
155      }
156
157      *where = (*where & 0xffff0000) | (tmp & 0xffff);
158      break;
159
160    case R_TYPE(32):
161      *where = symvalue + rela->r_addend;
162      break;
163
164    default:
165      rtems_rtl_set_error (EINVAL, "rela type record not supported");
166      printf("Unsupported reloc types\n");
167      return rtems_rtl_elf_rel_failure;
168  }
169
170  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
171      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
172      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
173  }
174
175  return rtems_rtl_elf_rel_no_error;
176}
177
178rtems_rtl_elf_rel_status
179rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
180                                  const Elf_Rel*            rel,
181                                  const rtems_rtl_obj_sect* sect,
182                                  const char*               symname,
183                                  const Elf_Byte            syminfo,
184                                  const Elf_Word            symvalue)
185{
186  (void) obj;
187  (void) rela;
188  (void) sect;
189  (void) symname;
190  (void) syminfo;
191  (void) symvalue;
192  rtems_rtl_set_error (EINVAL, "rel type record not supported");
193  return rtems_rtl_elf_rel_failure;
194}
195
196rtems_rtl_elf_rel_status
197rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
198                            const Elf_Rel*            rel,
199                            const rtems_rtl_obj_sect* sect,
200                            const char*               symname,
201                            const Elf_Byte            syminfo,
202                            const Elf_Word            symvalue)
203{
204  (void) obj;
205  (void) rela;
206  (void) sect;
207  (void) symname;
208  (void) syminfo;
209  (void) symvalue;
210  rtems_rtl_set_error (EINVAL, "rela type record not supported");
211  return rtems_rtl_elf_rel_failure;
212}
213
214bool
215rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
216                            const char*          name,
217                            uint32_t             flags)
218{
219  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
220}
221
222bool
223rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
224{
225  return rtems_rtl_elf_unwind_dw2_register (obj);
226}
227
228bool
229rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
230{
231  return rtems_rtl_elf_unwind_dw2_deregister (obj);
232}
Note: See TracBrowser for help on using the repository browser.