source: rtems/cpukit/libdl/rtl-mdreloc-h8300.c @ d8c70ba6

5
Last change on this file since d8c70ba6 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.7 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
22bool
23rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
24{
25  return true;
26}
27
28size_t
29rtems_rtl_elf_relocate_tramp_max_size (void)
30{
31  /*
32   * Disable by returning 0.
33   */
34  return 0;
35}
36
37bool
38rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
39                                   const Elf_Rela*           rela,
40                                   const rtems_rtl_obj_sect* sect,
41                                   const char*               symname,
42                                   const Elf_Byte            syminfo,
43                                   const Elf_Word            symvalue)
44{
45  (void) obj;
46  (void) rela;
47  (void) sect;
48  (void) symname;
49  (void) syminfo;
50  (void) symvalue;
51  return true;
52}
53
54bool
55rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
56                             const Elf_Rela*           rela,
57                             const rtems_rtl_obj_sect* sect,
58                             const char*               symname,
59                             const Elf_Byte            syminfo,
60                             const Elf_Word            symvalue)
61{
62  Elf_Addr *where;
63  Elf_Word tmp;
64
65  where = (Elf_Addr *)(sect->base + rela->r_offset);
66
67  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
68      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
69      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
70  }
71
72  tmp = symvalue;
73  switch (ELF_R_TYPE(rela->r_info)) {
74    case R_TYPE(NONE):
75      break;
76
77    case R_TYPE(DIR16):
78      *(uint16_t *)where += symvalue + rela->r_addend;
79      break;
80
81    case R_TYPE(DIR32):
82    case R_TYPE(DIR32A16):
83      *where += symvalue + rela->r_addend;
84      break;
85
86    case R_TYPE(DIR24A8):
87      if (ELF32_R_SYM(rela->r_info))
88        *where += symvalue + rela->r_addend;
89      break;
90
91    case R_TYPE(DIR24R8):
92      where = (uint32_t *)((uint32_t)where - 1);
93      *where = (*where & 0xff000000) | ((*where & 0xffffff) + symvalue + rela->r_addend);
94      break;
95
96    case R_TYPE(PCREL8):
97      /* bcc instruction */
98      tmp = symvalue + rela->r_addend - (Elf_Addr)where - 1;
99      if (((Elf32_Sword)tmp > 0x7f) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x80)){
100        printf("PCREL8 overflow\n");
101          return false;
102      } else {
103        *(uint8_t *)where = tmp;
104      }
105      break;
106
107    case R_TYPE(PCREL16):
108      /* bcc instruction */
109      tmp = symvalue + rela->r_addend - (Elf_Addr)where - 2;
110      if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x8000)){
111        printf("PCREL16 overflow\n");
112       return false;
113      } else {
114       *(uint16_t *)where = tmp;
115      }
116      break;
117
118    default:
119      rtems_rtl_set_error (EINVAL, "rela type record not supported");
120      printf("Unsupported reloc types\n");
121      return false;
122  }
123  return true;
124}
125
126bool
127rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*           obj,
128                                  const Elf_Rel*            rel,
129                                  const rtems_rtl_obj_sect* sect,
130                                  const char*               symname,
131                                  const Elf_Byte            syminfo,
132                                  const Elf_Word            symvalue)
133{
134  (void) obj;
135  (void) rel;
136  (void) sect;
137  (void) symname;
138  (void) syminfo;
139  (void) symvalue;
140  rtems_rtl_set_error (EINVAL, "rel type record not supported");
141  return false;
142}
143
144bool
145rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
146                            const Elf_Rel*            rel,
147                            const rtems_rtl_obj_sect* sect,
148                            const char*               symname,
149                            const Elf_Byte            syminfo,
150                            const Elf_Word            symvalue)
151{
152  (void) obj;
153  (void) rel;
154  (void) sect;
155  (void) symname;
156  (void) syminfo;
157  (void) symvalue;
158  rtems_rtl_set_error (EINVAL, "rel type record not supported");
159  return false;
160}
161
162bool
163rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
164                            const char*          name,
165                            uint32_t             flags)
166{
167  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
168}
169
170bool
171rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
172{
173  return rtems_rtl_elf_unwind_dw2_register (obj);
174}
175
176bool
177rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
178{
179  return rtems_rtl_elf_unwind_dw2_deregister (obj);
180}
Note: See TracBrowser for help on using the repository browser.