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

5
Last change on this file since 194eb403 was 194eb403, checked in by Chris Johns <chrisj@…>, on 01/21/19 at 21:48:19

libdl: Add support for large memory programs

  • Add trampolines to support relocs that are out of range on support architectures.
  • Support not loading separate text/data sections in an object file if the symbol provided in the section is a duplicate. A base image may have pulled in part of an object and another part needs to be dynamically loaded.
  • Refactor the unresolved handling to scale to hundreds of unresolved symbols when loading large number of files.

Updates #3685

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
3 */
4
5/*  $NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $  */
6
7#include <sys/cdefs.h>
8
9#include <errno.h>
10#include <inttypes.h>
11#include <stdio.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14
15#include <rtems/rtl/rtl.h>
16#include "rtl-elf.h"
17#include "rtl-error.h"
18#include <rtems/rtl/rtl-trace.h>
19#include "rtl-unwind.h"
20#include "rtl-unwind-dw2.h"
21
22uint32_t
23rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
24                             const Elf_Shdr*      shdr)
25{
26  return 0;
27}
28
29bool
30rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
31{
32  return true;
33}
34
35size_t
36rtems_rtl_elf_relocate_tramp_max_size (void)
37{
38  /*
39   * Disable by returning 0.
40   */
41  return 0;
42}
43
44bool
45rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
46                                   const Elf_Rela*           rela,
47                                   const rtems_rtl_obj_sect* sect,
48                                   const char*               symname,
49                                   const Elf_Byte            syminfo,
50                                   const Elf_Word            symvalue)
51{
52  (void) obj;
53  (void) rela;
54  (void) sect;
55  (void) symname;
56  (void) syminfo;
57  (void) symvalue;
58  rtems_rtl_set_error (EINVAL, "rela type record not supported");
59  return false;
60}
61
62bool
63rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
64                             const Elf_Rela*           rel,
65                             const rtems_rtl_obj_sect* sect,
66                             const char*               symname,
67                             const Elf_Byte            syminfo,
68                             const Elf_Word            symvalue)
69{
70  (void) obj;
71  (void) rel;
72  (void) sect;
73  (void) symname;
74  (void) syminfo;
75  (void) symvalue;
76  rtems_rtl_set_error (EINVAL, "rela type record not supported");
77  return false;
78}
79
80bool
81rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
82                                  const Elf_Rel*            rel,
83                                  const rtems_rtl_obj_sect* sect,
84                                  const char*               symname,
85                                  const Elf_Byte            syminfo,
86                                  const Elf_Word            symvalue)
87{
88  (void) obj;
89  (void) rel;
90  (void) sect;
91  (void) symname;
92  (void) syminfo;
93  (void) symvalue;
94  return true;
95}
96
97bool
98rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
99                            const Elf_Rel*            rel,
100                            const rtems_rtl_obj_sect* sect,
101                            const char*               symname,
102                            const Elf_Byte            syminfo,
103                            const Elf_Word            symvalue)
104{
105  Elf_Addr  target = 0;
106  Elf_Addr* where;
107  Elf_Addr  tmp;
108
109  where = (Elf_Addr *)(sect->base + rel->r_offset);
110
111  switch (ELF_R_TYPE(rel->r_info)) {
112    case R_TYPE(NONE):
113      break;
114
115    case R_TYPE(PC32):
116      target = (Elf_Addr) symvalue;
117      *where += target - (Elf_Addr)where;
118
119      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
120        printf ("rtl: reloc PC32 in %s --> %p (%p @ %p) in %s\n",
121                sect->name, (void*) symvalue,
122                (void *)*where, where, rtems_rtl_obj_oname (obj));
123      break;
124
125    case R_TYPE(GOT32):
126    case R_TYPE(32):
127    case R_TYPE(GLOB_DAT):
128      target = (Elf_Addr) symvalue;
129
130      tmp = target + *where;
131      if (*where != tmp)
132        *where = tmp;
133      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
134        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p @ %p in %s\n",
135                sect->name, (void *)*where, where,
136                rtems_rtl_obj_oname (obj));
137      break;
138
139    case R_TYPE(RELATIVE):
140      *where += (Elf_Addr)sect->base;
141      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
142        printf ("rtl: reloc RELATIVE in %s --> %p @ %p\n",
143                rtems_rtl_obj_oname (obj), (void *)*where, where);
144      break;
145
146    case R_TYPE(COPY):
147      printf ("rtl: reloc COPY (please report)\n");
148      break;
149
150    default:
151      printf ("rtl: reloc unknown: sym = %i, type = %" PRIu32 ", offset = %p, "
152              "contents = %p\n",
153              (int) ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
154              (void *)rel->r_offset, (void *)*where);
155      rtems_rtl_set_error (EINVAL,
156                           "%s: Unsupported relocation type %" PRIu32 " "
157                           "in non-PLT relocations",
158                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
159      return false;
160  }
161
162  return true;
163}
164
165bool
166rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
167                            const char*          name,
168                            uint32_t             flags)
169{
170  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
171}
172
173bool
174rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
175{
176  return rtems_rtl_elf_unwind_dw2_register (obj);
177}
178
179bool
180rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
181{
182  return rtems_rtl_elf_unwind_dw2_deregister (obj);
183}
Note: See TracBrowser for help on using the repository browser.