source: rtems/cpukit/libdl/rtl-mdreloc-lm32.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: 5.8 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
69bool
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 true;
84}
85
86bool
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 false;
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 false;
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  return true;
175}
176
177bool
178rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
179                                  const Elf_Rel*            rel,
180                                  const rtems_rtl_obj_sect* sect,
181                                  const char*               symname,
182                                  const Elf_Byte            syminfo,
183                                  const Elf_Word            symvalue)
184{
185  (void) obj;
186  (void) rela;
187  (void) sect;
188  (void) symname;
189  (void) syminfo;
190  (void) symvalue;
191  rtems_rtl_set_error (EINVAL, "rel type record not supported");
192  return false;
193}
194
195bool
196rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
197                            const Elf_Rel*            rel,
198                            const rtems_rtl_obj_sect* sect,
199                            const char*               symname,
200                            const Elf_Byte            syminfo,
201                            const Elf_Word            symvalue)
202{
203  (void) obj;
204  (void) rela;
205  (void) sect;
206  (void) symname;
207  (void) syminfo;
208  (void) symvalue;
209  rtems_rtl_set_error (EINVAL, "rela type record not supported");
210  return false;
211}
212
213bool
214rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
215                            const char*          name,
216                            uint32_t             flags)
217{
218  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
219}
220
221bool
222rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
223{
224  return rtems_rtl_elf_unwind_dw2_register (obj);
225}
226
227bool
228rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
229{
230  return rtems_rtl_elf_unwind_dw2_deregister (obj);
231}
Note: See TracBrowser for help on using the repository browser.