source: rtems/cpukit/libdl/rtl-mdreloc-moxie.c @ 194eb403

5
Last change on this file since 194eb403 was d8c70ba6, checked in by Chris Johns <chrisj@…>, on 01/15/19 at 06:47:41

libdl: Add support for trampolines

  • Trampolines or fixups for veneers provide long jump support for instruciton sets that implement short relative address branches. The linker provides trampolines when creating a static image. This patch adds trampoline support to libdl and the ARM architecture.
  • The dl09 test requires enough memory so modules are outside the relative branch instruction ranges for the architecture.

Updates #3685

  • Property mode set to 100644
File size: 4.5 KB
Line 
1
2#include <sys/cdefs.h>
3
4#include <errno.h>
5#include <stdio.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8
9#include <rtems/rtl/rtl.h>
10#include "rtl-elf.h"
11#include "rtl-error.h"
12#include <rtems/rtl/rtl-trace.h>
13#include "rtl-unwind.h"
14#include "rtl-unwind-dw2.h"
15
16uint32_t
17rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
18                             const Elf_Shdr*      shdr)
19{
20  return 0;
21}
22
23bool
24rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
25{
26  return true;
27}
28
29size_t
30rtems_rtl_elf_relocate_tramp_max_size (void)
31{
32  /*
33   * Disable by returning 0.
34   */
35  return 0;
36}
37
38bool
39rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
40                                   const Elf_Rela*           rela,
41                                   const rtems_rtl_obj_sect* sect,
42                                   const char*               symname,
43                                   const Elf_Byte            syminfo,
44                                   const Elf_Word            symvalue)
45{
46  (void) obj;
47  (void) rela;
48  (void) sect;
49  (void) symname;
50  (void) syminfo;
51  (void) symvalue;
52  return true;
53}
54
55bool
56rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
57                             const Elf_Rela*           rela,
58                             const rtems_rtl_obj_sect* sect,
59                             const char*               symname,
60                             const Elf_Byte            syminfo,
61                             const Elf_Word            symvalue)
62{
63  Elf_Addr *where;
64  Elf_Sword tmp;
65
66  where = (Elf_Addr *)(sect->base + rela->r_offset);
67
68  /* Handle the not 4byte aligned address carefully */
69
70  switch (ELF_R_TYPE(rela->r_info)) {
71    case R_TYPE(NONE):
72      break;
73
74    case R_TYPE(32):
75      *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
76      *((uint16_t *)where + 1) = (symvalue + rela->r_addend) & 0xffff;
77
78      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
79          printf("*where 0x%04x%04x\n", *((uint16_t *)where + 1), *(uint16_t *)where);
80      }
81      break;
82
83    case R_TYPE(PCREL10):
84      /* beq, bge, bgeu, bgt, bgtu, ble, bleu, blt, bltu, bne */
85      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
86        printf("*where %x\n", *(uint16_t *)where);
87        printf("symvalue - where %x\n", (int)(symvalue - (Elf_Word)where));
88      }
89      tmp = (symvalue + rela->r_addend - ((Elf_Word)where + 2)); /* pc is the next instruction */
90      tmp = (Elf_Sword)tmp >> 1;
91      if (((Elf32_Sword)tmp > 0x1ff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x200)){
92        printf("Overflow for PCREL10: %ld exceed -0x200:0x1ff\n", tmp);
93        return false;
94      }
95
96      *(uint16_t *)where = (*(uint16_t *)where & 0xfc00) | (tmp & 0x3ff);
97
98      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
99          printf("*where 0x%04x\n",  *(uint16_t *)where);
100      }
101
102      break;
103
104    default:
105      rtems_rtl_set_error (EINVAL, "rela type record not supported");
106      printf("Unsupported reloc types\n");
107      return false;
108  }
109
110  return true;
111}
112
113bool
114rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
115                                  const Elf_Rel*            rel,
116                                  const rtems_rtl_obj_sect* sect,
117                                  const char*               symname,
118                                  const Elf_Byte            syminfo,
119                                  const Elf_Word            symvalue)
120{
121  (void) obj;
122  (void) rel;
123  (void) sect;
124  (void) symname;
125  (void) syminfo;
126  (void) symvalue;
127  rtems_rtl_set_error (EINVAL, "rel type record not supported");
128  return false;
129}
130
131bool
132rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
133                            const Elf_Rel*            rel,
134                            const rtems_rtl_obj_sect* sect,
135                            const char*               symname,
136                            const Elf_Byte            syminfo,
137                            const Elf_Word            symvalue)
138{
139  (void) obj;
140  (void) rel;
141  (void) sect;
142  (void) symname;
143  (void) syminfo;
144  (void) symvalue;
145  rtems_rtl_set_error (EINVAL, "rel type record not supported");
146  return false;
147}
148
149bool
150rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
151                            const char*          name,
152                            uint32_t             flags)
153{
154  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
155}
156
157bool
158rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
159{
160  return rtems_rtl_elf_unwind_dw2_register (obj);
161}
162
163bool
164rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
165{
166  return rtems_rtl_elf_unwind_dw2_deregister (obj);
167}
Note: See TracBrowser for help on using the repository browser.