source: rtems/cpukit/libdl/rtl-mdreloc-lm32.c @ c6eead1

5
Last change on this file since c6eead1 was c6eead1, checked in by Chris Johns <chrisj@…>, on 12/07/16 at 06:20:38

libdl: Add C++ exception support to loaded modules.

This has been tested on SPARC, i386, PowerPC and ARM.

Closes #2767.

  • Property mode set to 100644
File size: 3.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 "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_t* 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
28bool
29rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
30                             const Elf_Rela*             rela,
31                             const rtems_rtl_obj_sect_t* sect,
32                             const char*                 symname,
33                             const Elf_Byte              syminfo,
34                             const Elf_Word              symvalue)
35{
36  Elf_Addr *where;
37  Elf32_Word tmp;
38  Elf32_Word insn;
39
40
41  where = (Elf_Addr *)(sect->base + rela->r_offset);
42
43  switch (ELF_R_TYPE(rela->r_info)) {
44    case R_TYPE(NONE):
45      break;
46
47    case R_TYPE(HI16):
48      insn = *where;
49      /* orhi/mvhi instruction
50       *  31--------26|25-21|20-16|15----0|
51       * |0 1 1 1 1 0 |rY   |rX   |imm16  |
52       */
53      if (0x1e == (insn >> 26)) {
54        insn &= 0xffff0000;
55        insn |= ((symvalue + rela->r_addend) >> 16);
56        *where = insn;
57      }
58      break;
59
60    case R_TYPE(LO16):
61      insn = *where;
62      /* ori instruction
63       *  31--------26|25-21|20-16|15----0|
64       * |0 0 1 1 1 0 |rY   |rX   |imm16  |
65       */
66      if (0xe == (insn >> 26)) {
67        insn &= 0xffff0000;
68        insn |= ((symvalue + rela->r_addend) & 0xffff);
69        *where = insn;
70      }
71      break;
72
73    case R_TYPE(CALL):
74      insn = *where;
75      /*
76       * calli instruction
77       *  31-------26|25---0|
78       * |1 1 1 1 1 0|imm26 |
79       * Syntax: call imm26
80       * Operation: ra = pc + 4; pc = pc + sign_extend(imm26<<2)
81       */
82      if (0x3e == (insn >> 26)) {
83        Elf_Sword imm26 = symvalue +rela->r_addend - (Elf_Addr)where;
84        imm26 = (imm26 >> 2) & 0x3ffffff;
85        insn = 0xf8000000 + imm26;
86        *where = insn;
87      }
88      break;
89
90    case R_TYPE(BRANCH):
91      insn = *where;
92      tmp = symvalue + rela->r_addend - (Elf_Addr)where;
93      tmp = (Elf32_Sword)tmp >> 2;
94      if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -0x8000)){
95        printf("BRANCH Overflow\n");
96        return false;
97      }
98
99      *where = (*where & 0xffff0000) | (tmp & 0xffff);
100      break;
101
102    case R_TYPE(32):
103      *where = symvalue + rela->r_addend;
104      break;
105
106    default:
107      rtems_rtl_set_error (EINVAL, "rela type record not supported");
108      printf("Unsupported reloc types\n");
109      return false;
110  }
111
112  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
113      printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
114      printf("relocated address 0x%08lx\n", (Elf_Addr)where);
115  }
116  return true;
117}
118
119bool
120rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
121                            const Elf_Rel*              rel,
122                            const rtems_rtl_obj_sect_t* sect,
123                            const char*                 symname,
124                            const Elf_Byte              syminfo,
125                            const Elf_Word              symvalue)
126{
127  rtems_rtl_set_error (EINVAL, "rela type record not supported");
128  return false;
129}
130
131bool
132rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
133                            const char*            name,
134                            uint32_t               flags)
135{
136  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
137}
138
139bool
140rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
141{
142  return rtems_rtl_elf_unwind_dw2_register (obj);
143}
144
145bool
146rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
147{
148  return rtems_rtl_elf_unwind_dw2_deregister (obj);
149}
Note: See TracBrowser for help on using the repository browser.