blob: 83007709ed3e2b27a830f910e4355596ecbc5a1b [file] [log] [blame]
Nick Kledzikabb69812012-05-31 22:34:00 +00001//===- lib/FileFormat/MachO/ReferenceKinds.cpp ----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "ReferenceKinds.h"
12
13#include "llvm/ADT/StringRef.h"
Nick Kledzikd6a27322012-06-15 20:29:27 +000014#include "llvm/ADT/StringSwitch.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000015
16
17namespace lld {
18namespace mach_o {
19
Nick Kledzik40b68552012-06-11 22:53:15 +000020//===----------------------------------------------------------------------===//
21// KindHandler
22//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +000023
Nick Kledzik40b68552012-06-11 22:53:15 +000024KindHandler::KindHandler() {
25}
Nick Kledzikabb69812012-05-31 22:34:00 +000026
Nick Kledzik40b68552012-06-11 22:53:15 +000027KindHandler::~KindHandler() {
28}
Nick Kledzikabb69812012-05-31 22:34:00 +000029
Nick Kledzik40b68552012-06-11 22:53:15 +000030KindHandler *KindHandler::makeHandler(WriterOptionsMachO::Architecture arch) {
31 switch( arch ) {
32 case WriterOptionsMachO::arch_x86_64:
33 return new KindHandler_x86_64();
34 break;
35 case WriterOptionsMachO::arch_x86:
36 return new KindHandler_x86();
37 break;
38 case WriterOptionsMachO::arch_armv6:
39 case WriterOptionsMachO::arch_armv7:
40 return new KindHandler_arm();
41 break;
42 default:
43 assert(0 && "arch not supported");
Nick Kledzikabb69812012-05-31 22:34:00 +000044 }
Nick Kledzik40b68552012-06-11 22:53:15 +000045}
46
47
48//===----------------------------------------------------------------------===//
49// KindHandler_x86_64
50//===----------------------------------------------------------------------===//
51
52KindHandler_x86_64::~KindHandler_x86_64() {
53}
54
55Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +000056 return llvm::StringSwitch<Reference::Kind>(str)
57 .Case("none", none)
58 .Case("branch32", branch32)
59 .Case("ripRel32", ripRel32)
60 .Case("ripRel32_1", ripRel32_1)
61 .Case("ripRel32_2", ripRel32_2)
62 .Case("ripRel32_4", ripRel32_4)
63 .Case("gotLoadRipRel32", gotLoadRipRel32)
64 .Case("gotLoadRipRel32NowLea", gotLoadRipRel32NowLea)
65 .Case("gotUseRipRel32", gotUseRipRel32)
66 .Case("tlvLoadRipRel32", tlvLoadRipRel32)
67 .Case("tlvLoadRipRel32NowLea", tlvLoadRipRel32NowLea)
68 .Case("pointer64", pointer64)
69 .Case("pointerRel32", pointerRel32)
70 .Case("lazyTarget", lazyTarget)
71 .Case("lazyImmediate", lazyImmediate)
72 .Case("subordinateFDE", subordinateFDE)
73 .Case("subordinateLSDA", subordinateLSDA);
74
Nick Kledzik40b68552012-06-11 22:53:15 +000075 assert(0 && "invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +000076 return 0;
77}
78
Nick Kledzik40b68552012-06-11 22:53:15 +000079StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
80 switch ( (Kinds)kind ) {
81 case none:
82 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +000083 case branch32:
84 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +000085 case ripRel32:
86 return StringRef("ripRel32");
Nick Kledzikc890ae42012-06-12 23:01:30 +000087 case ripRel32_1:
88 return StringRef("ripRel32_1");
89 case ripRel32_2:
90 return StringRef("ripRel32_2");
91 case ripRel32_4:
92 return StringRef("ripRel32_4");
93 case gotLoadRipRel32:
94 return StringRef("gotLoadRipRel32");
95 case gotLoadRipRel32NowLea:
96 return StringRef("gotLoadRipRel32NowLea");
97 case gotUseRipRel32:
98 return StringRef("gotUseRipRel32");
99 case tlvLoadRipRel32:
100 return StringRef("tlvLoadRipRel32");
101 case tlvLoadRipRel32NowLea:
102 return StringRef("tlvLoadRipRel32NowLea");
Nick Kledzik40b68552012-06-11 22:53:15 +0000103 case pointer64:
104 return StringRef("pointer64");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000105 case pointerRel32:
106 return StringRef("pointerRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000107 case lazyTarget:
108 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000109 case lazyImmediate:
110 return StringRef("lazyImmediate");
111 case subordinateFDE:
112 return StringRef("subordinateFDE");
113 case subordinateLSDA:
114 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000115 }
Nick Kledzik40b68552012-06-11 22:53:15 +0000116 assert(0 && "invalid x86_64 Reference kind");
117 return StringRef();
Nick Kledzikabb69812012-05-31 22:34:00 +0000118}
119
Nick Kledzik40b68552012-06-11 22:53:15 +0000120bool KindHandler_x86_64::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000121 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000122}
123
124bool KindHandler_x86_64::isPointer(Kind kind) {
125 return (kind == pointer64);
126}
Nick Kledzik40b68552012-06-11 22:53:15 +0000127
128bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000129 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000130}
Nick Kledzik40b68552012-06-11 22:53:15 +0000131
132bool KindHandler_x86_64::isLazyTarget(Kind kind) {
133 return (kind == lazyTarget);
134}
135
136
Nick Kledzikc890ae42012-06-12 23:01:30 +0000137void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
138 uint8_t *location, uint64_t fixupAddress,
139 uint64_t targetAddress) {
Nick Kledzik40b68552012-06-11 22:53:15 +0000140 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
141 uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
142 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000143 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000144 case ripRel32:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000145 case gotLoadRipRel32:
146 case gotUseRipRel32:
147 case tlvLoadRipRel32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000148 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
149 break;
150 case pointer64:
151 *loc64 = targetAddress + addend;
152 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000153 case ripRel32_1:
154 *loc32 = (targetAddress - (fixupAddress+5)) + addend;
155 break;
156 case ripRel32_2:
157 *loc32 = (targetAddress - (fixupAddress+6)) + addend;
158 break;
159 case ripRel32_4:
160 *loc32 = (targetAddress - (fixupAddress+8)) + addend;
161 break;
162 case pointerRel32:
163 *loc32 = (targetAddress - fixupAddress) + addend;
164 break;
165 case gotLoadRipRel32NowLea:
166 case tlvLoadRipRel32NowLea:
167 // Change MOVQ to LEA
168 assert(location[-2] == 0x8B);
169 location[-2] = 0x8D;
170 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
Nick Kledzik40b68552012-06-11 22:53:15 +0000171 break;
172 case none:
173 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000174 case lazyImmediate:
175 case subordinateFDE:
176 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000177 // do nothing
178 break;
Nick Kledzikabb69812012-05-31 22:34:00 +0000179 }
180}
181
Nick Kledzik40b68552012-06-11 22:53:15 +0000182
183//===----------------------------------------------------------------------===//
184// KindHandler_x86
185//===----------------------------------------------------------------------===//
186
187KindHandler_x86::~KindHandler_x86() {
Nick Kledzikabb69812012-05-31 22:34:00 +0000188}
189
Nick Kledzik40b68552012-06-11 22:53:15 +0000190Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000191 return llvm::StringSwitch<Reference::Kind>(str)
192 .Case("none", none)
193 .Case("branch32", branch32)
194 .Case("abs32", abs32)
195 .Case("funcRel32", funcRel32)
196 .Case("pointer32", pointer32)
197 .Case("lazyTarget", lazyTarget)
198 .Case("lazyImmediate", lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000199
200 assert(0 && "invalid x86 Reference kind");
201 return 0;
202}
203
204StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
205 switch ( (Kinds)kind ) {
206 case none:
207 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000208 case branch32:
209 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000210 case abs32:
211 return StringRef("abs32");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000212 case funcRel32:
213 return StringRef("funcRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000214 case pointer32:
215 return StringRef("pointer32");
216 case lazyTarget:
217 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000218 case lazyImmediate:
219 return StringRef("lazyImmediate");
220 case subordinateFDE:
221 return StringRef("subordinateFDE");
222 case subordinateLSDA:
223 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000224 }
Nick Kledzik40b68552012-06-11 22:53:15 +0000225 assert(0 && "invalid x86 Reference kind");
226 return StringRef();
227}
228
229bool KindHandler_x86::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000230 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000231}
232
233bool KindHandler_x86::isPointer(Kind kind) {
234 return (kind == pointer32);
235}
236
237
238bool KindHandler_x86::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000239 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000240}
241
242
243bool KindHandler_x86::isLazyTarget(Kind kind) {
244 return (kind == lazyTarget);
245}
246
247
248void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
249 uint64_t fixupAddress, uint64_t targetAddress) {
250 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
251 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000252 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000253 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
254 break;
255 case pointer32:
256 case abs32:
257 *loc32 = targetAddress + addend;
258 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000259 case funcRel32:
260 *loc32 = targetAddress + addend;
261 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000262 case none:
263 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000264 case lazyImmediate:
265 case subordinateFDE:
266 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000267 // do nothing
268 break;
269 }
Nick Kledzikabb69812012-05-31 22:34:00 +0000270}
271
272
Nick Kledzik40b68552012-06-11 22:53:15 +0000273//===----------------------------------------------------------------------===//
274// KindHandler_arm
275//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +0000276
Nick Kledzik40b68552012-06-11 22:53:15 +0000277KindHandler_arm::~KindHandler_arm() {
278}
Nick Kledzikabb69812012-05-31 22:34:00 +0000279
Nick Kledzik40b68552012-06-11 22:53:15 +0000280Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000281 return llvm::StringSwitch<Reference::Kind>(str)
282 .Case("none", none)
283 .Case("thumbBranch22", thumbBranch22)
284 .Case("armBranch24", armBranch24)
285 .Case("thumbAbsLow16", thumbAbsLow16)
286 .Case("thumbAbsHigh16", thumbAbsHigh16)
287 .Case("thumbPcRelLow16", thumbPcRelLow16)
288 .Case("thumbPcRelHigh16", thumbPcRelHigh16)
289 .Case("abs32", abs32)
290 .Case("pointer32", pointer32)
291 .Case("lazyTarget", lazyTarget)
292 .Case("lazyImmediate", lazyImmediate)
293 .Case("subordinateLSDA", subordinateLSDA);
Nick Kledzik40b68552012-06-11 22:53:15 +0000294
295 assert(0 && "invalid ARM Reference kind");
296 return 0;
297}
298
299StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
300 switch ( (Kinds)kind ) {
301 case none:
302 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000303 case thumbBranch22:
304 return StringRef("thumbBranch22");
305 case armBranch24:
306 return StringRef("armBranch24");
307 case thumbAbsLow16:
308 return StringRef("thumbAbsLow16");
309 case thumbAbsHigh16:
310 return StringRef("thumbAbsHigh16");
311 case thumbPcRelLow16:
312 return StringRef("thumbPcRelLow16");
313 case thumbPcRelHigh16:
314 return StringRef("thumbPcRelHigh16");
315 case abs32:
316 return StringRef("abs32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000317 case pointer32:
318 return StringRef("pointer32");
319 case lazyTarget:
320 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000321 case lazyImmediate:
322 return StringRef("lazyImmediate");
323 case subordinateLSDA:
324 return StringRef("subordinateLSDA");
Nick Kledzik40b68552012-06-11 22:53:15 +0000325 }
326 assert(0 && "invalid ARM Reference kind");
327 return StringRef();
328}
329
330bool KindHandler_arm::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000331 return (kind == thumbBranch22) || (kind == armBranch24);
Nick Kledzik40b68552012-06-11 22:53:15 +0000332}
333
334bool KindHandler_arm::isPointer(Kind kind) {
335 return (kind == pointer32);
336}
337
338
339bool KindHandler_arm::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000340 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000341}
342
343
344bool KindHandler_arm::isLazyTarget(Kind kind) {
345 return (kind == lazyTarget);
346}
347
348
349void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
350 uint64_t fixupAddress, uint64_t targetAddress) {
351 //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
352 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000353 case thumbBranch22:
354 // FIXME
355 break;
356 case armBranch24:
357 // FIXME
358 break;
359 case thumbAbsLow16:
360 // FIXME
361 break;
362 case thumbAbsHigh16:
363 // FIXME
364 break;
365 case thumbPcRelLow16:
366 // FIXME
367 break;
368 case thumbPcRelHigh16:
369 // FIXME
370 break;
371 case abs32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000372 // FIXME
373 break;
374 case pointer32:
375 // FIXME
376 break;
377 case none:
378 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000379 case lazyImmediate:
380 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000381 // do nothing
382 break;
383 }
384}
385
Nick Kledzikabb69812012-05-31 22:34:00 +0000386
387} // namespace mach_o
388} // namespace lld
389
390
391