source: rtems/cpukit/libdl/rtl-mdreloc-powerpc.c @ 8709aa04

5
Last change on this file since 8709aa04 was a5201ea, checked in by Joel Sherrill <joel.sherrill@…>, on 11/19/14 at 19:57:21

libdl/rtl-mdreloc-powerpc.c: Fix warnings

This patch addresses the following warnings:

+ The variable "target" was unused.
+ The parentheses in the expression around line 72 were ambiguous.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
3 */
4
5/*  $NetBSD: ppc_reloc.c,v 1.44 2010/01/13 20:17:22 christos Exp $  */
6
7#include <sys/cdefs.h>
8
9#include <errno.h>
10#include <stdio.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13
14#include <rtems/rtl/rtl.h>
15#include "rtl-elf.h"
16#include "rtl-error.h"
17#include "rtl-trace.h"
18
19#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
20                 ((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
21#define l(x) ((u_int32_t)(x) & 0xffff)
22
23
24bool
25rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
26{
27  return true;
28}
29
30bool
31rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
32                             const Elf_Rela*             rela,
33                             const rtems_rtl_obj_sect_t* sect,
34                             const char*                 symname,
35                             const Elf_Byte              syminfo,
36                             const Elf_Word              symvalue)
37{
38  Elf_Addr* where;
39  Elf_Word tmp;
40  uint32_t mask = 0;
41  uint32_t bits = 0;
42
43  where = (Elf_Addr *)(sect->base + rela->r_offset);
44  switch (ELF_R_TYPE(rela->r_info)) {
45    case R_TYPE(NONE):
46      break;
47
48    case R_TYPE(32):
49      /*
50       * value:1; Field: word32; Expression: S + A
51       */
52      *where = symvalue + rela->r_addend;
53      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
54        printf ("rtl: ADDR32 %p @ %p in %s\n",
55                (void *)*(where), where, rtems_rtl_obj_oname (obj));
56      break;
57
58    case R_TYPE(14):
59      /*
60       * value:7; Field: low14*; Expression: (S + A) >> 2
61       */
62    case R_TYPE(24):
63      /*
64       * value:2; Field: low24*; Expression: (S + A) >> 2
65       */
66      if (ELF_R_TYPE(rela->r_info) == R_TYPE(14)) {
67        bits = 14;
68        mask = 0xfffc;
69      } else {
70        bits = 24;
71        mask = 0x3fffffc;
72      }
73      tmp = (symvalue + rela->r_addend) >> 2;
74      if (tmp > ((1<<bits) - 1 )) {
75        printf("Overflow ADDR14/ADDR24\n");
76        return false;
77      }
78      tmp = *where;
79      tmp &= ~mask;
80      tmp |= (symvalue + rela->r_addend) & mask;
81      *where = tmp;
82      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
83        printf ("rtl: ADDR14/ADDR24 %p @ %p in %s\n",
84                (void *)*where, where, rtems_rtl_obj_oname (obj));
85      break;
86
87    case R_TYPE(16_HA):
88      /*
89       * value:6; Field:half16; Expression: #ha(S+A)
90       */
91
92      tmp = symvalue + rela->r_addend;
93      *(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & 0xffff);
94      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
95        printf ("rtl: 16_HA %p @ %p in %s\n",
96                (void *)*(where), where, rtems_rtl_obj_oname (obj));
97      break;
98
99    case R_TYPE(16_HI):
100      /*
101       * value:5; Field:half16; Expression: #hi(S+A)
102       */
103      *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
104      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
105        printf ("rtl: 16_HI %p @ %p in %s\n",
106                (void *)*where, where, rtems_rtl_obj_oname (obj));
107      break;
108    case R_TYPE(16_LO):
109      /*
110       * value:4; Field:half16; Expression: #lo(S+A)
111       */
112      *(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff;
113      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
114        printf ("rtl: 16_LO %p @ %p in %s\n",
115                (void *)*where, where, rtems_rtl_obj_oname (obj));
116      break;
117
118    case R_TYPE(REL14):
119      /*
120       * value:11; Field:low14*; Expression:(S+A-P)>>2
121       */
122    case R_TYPE(REL24):
123      /*
124       * value:10; Field:low24*; Expression:(S+A-P)>>2
125       */
126      if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL24)) {
127        mask = 0x3fffffc;
128        bits = 24;
129      }
130      else if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL14)) {
131        mask = 0xfffc;
132        bits = 14;
133      }
134
135      tmp =((int) (symvalue + rela->r_addend - (Elf_Addr)where)) >> 2;
136      if (((Elf_Sword)tmp > ((1<<(bits-1)) - 1)) ||
137          ((Elf_Sword)tmp < -(1<<(bits-1)))) {
138        printf("Overflow REL14/REL24\n");
139        return false;
140      }
141
142      tmp = *where;
143      tmp &= ~mask;
144      tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
145      *where = tmp;
146      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
147        printf ("rtl: REL24/REL14 %p @ %p in %s\n",
148                (void *)*where, where, rtems_rtl_obj_oname (obj));
149      break;
150
151    case R_TYPE(REL32):
152      /*
153       * value:26; Field:word32*; Expression:S+A-P
154       */
155      *where = symvalue + rela->r_addend - (Elf_Addr)where;
156      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
157        printf ("rtl: REL32 %p @ %p in %s\n",
158                (void *)*where, where, rtems_rtl_obj_oname (obj));
159      break;
160
161    default:
162      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
163              "contents = %p\n",
164              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
165              (void *)rela->r_offset, (void *)*where);
166      rtems_rtl_set_error (EINVAL,
167                           "%s: Unsupported relocation type %ld "
168                           "in non-PLT relocations",
169                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
170      return false;
171  }
172  return true;
173}
174
175bool
176rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
177                            const Elf_Rel*              rel,
178                            const rtems_rtl_obj_sect_t* sect,
179                            const char*                 symname,
180                            const Elf_Byte              syminfo,
181                            const Elf_Word              symvalue)
182{
183  printf ("rtl: rel type record not supported; please report\n");
184  return false;
185}
Note: See TracBrowser for help on using the repository browser.