blob: f6c2dc510cbef2bc359ddea9057eaa539a72ebca [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
Nick Kledzik751eb3d2012-06-15 20:37:24 +000016#include "llvm/Support/ErrorHandling.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000017
18namespace lld {
19namespace mach_o {
20
Nick Kledzik40b68552012-06-11 22:53:15 +000021//===----------------------------------------------------------------------===//
22// KindHandler
23//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +000024
Nick Kledzik40b68552012-06-11 22:53:15 +000025KindHandler::KindHandler() {
26}
Nick Kledzikabb69812012-05-31 22:34:00 +000027
Nick Kledzik40b68552012-06-11 22:53:15 +000028KindHandler::~KindHandler() {
29}
Nick Kledzikabb69812012-05-31 22:34:00 +000030
Nick Kledzik40b68552012-06-11 22:53:15 +000031KindHandler *KindHandler::makeHandler(WriterOptionsMachO::Architecture arch) {
32 switch( arch ) {
33 case WriterOptionsMachO::arch_x86_64:
34 return new KindHandler_x86_64();
35 break;
36 case WriterOptionsMachO::arch_x86:
37 return new KindHandler_x86();
38 break;
39 case WriterOptionsMachO::arch_armv6:
40 case WriterOptionsMachO::arch_armv7:
41 return new KindHandler_arm();
42 break;
43 default:
44 assert(0 && "arch not supported");
Nick Kledzikabb69812012-05-31 22:34:00 +000045 }
Nick Kledzik40b68552012-06-11 22:53:15 +000046}
47
48
49//===----------------------------------------------------------------------===//
50// KindHandler_x86_64
51//===----------------------------------------------------------------------===//
52
53KindHandler_x86_64::~KindHandler_x86_64() {
54}
55
56Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +000057 return llvm::StringSwitch<Reference::Kind>(str)
58 .Case("none", none)
59 .Case("branch32", branch32)
60 .Case("ripRel32", ripRel32)
61 .Case("ripRel32_1", ripRel32_1)
62 .Case("ripRel32_2", ripRel32_2)
63 .Case("ripRel32_4", ripRel32_4)
64 .Case("gotLoadRipRel32", gotLoadRipRel32)
65 .Case("gotLoadRipRel32NowLea", gotLoadRipRel32NowLea)
66 .Case("gotUseRipRel32", gotUseRipRel32)
67 .Case("tlvLoadRipRel32", tlvLoadRipRel32)
68 .Case("tlvLoadRipRel32NowLea", tlvLoadRipRel32NowLea)
69 .Case("pointer64", pointer64)
70 .Case("pointerRel32", pointerRel32)
71 .Case("lazyTarget", lazyTarget)
72 .Case("lazyImmediate", lazyImmediate)
73 .Case("subordinateFDE", subordinateFDE)
Nick Kledzik7145cf62012-06-15 21:26:18 +000074 .Case("subordinateLSDA", subordinateLSDA)
75 .Default(invalid);
Nick Kledzikd6a27322012-06-15 20:29:27 +000076
Nick Kledzik751eb3d2012-06-15 20:37:24 +000077 llvm_unreachable("invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +000078}
79
Nick Kledzik40b68552012-06-11 22:53:15 +000080StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
81 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +000082 case invalid:
83 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +000084 case none:
85 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +000086 case branch32:
87 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +000088 case ripRel32:
89 return StringRef("ripRel32");
Nick Kledzikc890ae42012-06-12 23:01:30 +000090 case ripRel32_1:
91 return StringRef("ripRel32_1");
92 case ripRel32_2:
93 return StringRef("ripRel32_2");
94 case ripRel32_4:
95 return StringRef("ripRel32_4");
96 case gotLoadRipRel32:
97 return StringRef("gotLoadRipRel32");
98 case gotLoadRipRel32NowLea:
99 return StringRef("gotLoadRipRel32NowLea");
100 case gotUseRipRel32:
101 return StringRef("gotUseRipRel32");
102 case tlvLoadRipRel32:
103 return StringRef("tlvLoadRipRel32");
104 case tlvLoadRipRel32NowLea:
105 return StringRef("tlvLoadRipRel32NowLea");
Nick Kledzik40b68552012-06-11 22:53:15 +0000106 case pointer64:
107 return StringRef("pointer64");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000108 case pointerRel32:
109 return StringRef("pointerRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000110 case lazyTarget:
111 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000112 case lazyImmediate:
113 return StringRef("lazyImmediate");
114 case subordinateFDE:
115 return StringRef("subordinateFDE");
116 case subordinateLSDA:
117 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000118 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000119 llvm_unreachable("invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +0000120}
121
Nick Kledzik40b68552012-06-11 22:53:15 +0000122bool KindHandler_x86_64::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000123 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000124}
125
126bool KindHandler_x86_64::isPointer(Kind kind) {
127 return (kind == pointer64);
128}
Nick Kledzik40b68552012-06-11 22:53:15 +0000129
130bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000131 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000132}
Nick Kledzik40b68552012-06-11 22:53:15 +0000133
134bool KindHandler_x86_64::isLazyTarget(Kind kind) {
135 return (kind == lazyTarget);
136}
137
138
Nick Kledzikc890ae42012-06-12 23:01:30 +0000139void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
140 uint8_t *location, uint64_t fixupAddress,
141 uint64_t targetAddress) {
Nick Kledzik40b68552012-06-11 22:53:15 +0000142 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
143 uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
144 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000145 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000146 case ripRel32:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000147 case gotLoadRipRel32:
148 case gotUseRipRel32:
149 case tlvLoadRipRel32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000150 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
151 break;
152 case pointer64:
153 *loc64 = targetAddress + addend;
154 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000155 case ripRel32_1:
156 *loc32 = (targetAddress - (fixupAddress+5)) + addend;
157 break;
158 case ripRel32_2:
159 *loc32 = (targetAddress - (fixupAddress+6)) + addend;
160 break;
161 case ripRel32_4:
162 *loc32 = (targetAddress - (fixupAddress+8)) + addend;
163 break;
164 case pointerRel32:
165 *loc32 = (targetAddress - fixupAddress) + addend;
166 break;
167 case gotLoadRipRel32NowLea:
168 case tlvLoadRipRel32NowLea:
169 // Change MOVQ to LEA
170 assert(location[-2] == 0x8B);
171 location[-2] = 0x8D;
172 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
Nick Kledzik40b68552012-06-11 22:53:15 +0000173 break;
174 case none:
175 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000176 case lazyImmediate:
177 case subordinateFDE:
178 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000179 // do nothing
180 break;
Nick Kledzik7145cf62012-06-15 21:26:18 +0000181 case invalid:
182 assert(0 && "invalid Reference Kind");
183 break;
Nick Kledzikabb69812012-05-31 22:34:00 +0000184 }
185}
186
Nick Kledzik40b68552012-06-11 22:53:15 +0000187
188//===----------------------------------------------------------------------===//
189// KindHandler_x86
190//===----------------------------------------------------------------------===//
191
192KindHandler_x86::~KindHandler_x86() {
Nick Kledzikabb69812012-05-31 22:34:00 +0000193}
194
Nick Kledzik40b68552012-06-11 22:53:15 +0000195Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000196 return llvm::StringSwitch<Reference::Kind>(str)
197 .Case("none", none)
198 .Case("branch32", branch32)
199 .Case("abs32", abs32)
200 .Case("funcRel32", funcRel32)
201 .Case("pointer32", pointer32)
202 .Case("lazyTarget", lazyTarget)
Nick Kledzik7145cf62012-06-15 21:26:18 +0000203 .Case("lazyImmediate", lazyImmediate)
204 .Default(invalid);
Nick Kledzik40b68552012-06-11 22:53:15 +0000205
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000206 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000207}
208
209StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
210 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +0000211 case invalid:
212 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +0000213 case none:
214 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000215 case branch32:
216 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000217 case abs32:
218 return StringRef("abs32");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000219 case funcRel32:
220 return StringRef("funcRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000221 case pointer32:
222 return StringRef("pointer32");
223 case lazyTarget:
224 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000225 case lazyImmediate:
226 return StringRef("lazyImmediate");
227 case subordinateFDE:
228 return StringRef("subordinateFDE");
229 case subordinateLSDA:
230 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000231 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000232 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000233}
234
235bool KindHandler_x86::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000236 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000237}
238
239bool KindHandler_x86::isPointer(Kind kind) {
240 return (kind == pointer32);
241}
242
243
244bool KindHandler_x86::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000245 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000246}
247
248
249bool KindHandler_x86::isLazyTarget(Kind kind) {
250 return (kind == lazyTarget);
251}
252
253
254void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
255 uint64_t fixupAddress, uint64_t targetAddress) {
256 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
257 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000258 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000259 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
260 break;
261 case pointer32:
262 case abs32:
263 *loc32 = targetAddress + addend;
264 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000265 case funcRel32:
266 *loc32 = targetAddress + addend;
267 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000268 case none:
269 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000270 case lazyImmediate:
271 case subordinateFDE:
272 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000273 // do nothing
274 break;
Nick Kledzik7145cf62012-06-15 21:26:18 +0000275 case invalid:
276 assert(0 && "invalid Reference Kind");
277 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000278 }
Nick Kledzikabb69812012-05-31 22:34:00 +0000279}
280
281
Nick Kledzik40b68552012-06-11 22:53:15 +0000282//===----------------------------------------------------------------------===//
283// KindHandler_arm
284//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +0000285
Nick Kledzik40b68552012-06-11 22:53:15 +0000286KindHandler_arm::~KindHandler_arm() {
287}
Nick Kledzikabb69812012-05-31 22:34:00 +0000288
Nick Kledzik40b68552012-06-11 22:53:15 +0000289Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000290 return llvm::StringSwitch<Reference::Kind>(str)
291 .Case("none", none)
292 .Case("thumbBranch22", thumbBranch22)
293 .Case("armBranch24", armBranch24)
294 .Case("thumbAbsLow16", thumbAbsLow16)
295 .Case("thumbAbsHigh16", thumbAbsHigh16)
296 .Case("thumbPcRelLow16", thumbPcRelLow16)
297 .Case("thumbPcRelHigh16", thumbPcRelHigh16)
298 .Case("abs32", abs32)
299 .Case("pointer32", pointer32)
300 .Case("lazyTarget", lazyTarget)
301 .Case("lazyImmediate", lazyImmediate)
Nick Kledzik7145cf62012-06-15 21:26:18 +0000302 .Case("subordinateLSDA", subordinateLSDA)
303 .Default(invalid);
Nick Kledzik40b68552012-06-11 22:53:15 +0000304
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000305 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000306}
307
308StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
309 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +0000310 case invalid:
311 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +0000312 case none:
313 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000314 case thumbBranch22:
315 return StringRef("thumbBranch22");
316 case armBranch24:
317 return StringRef("armBranch24");
318 case thumbAbsLow16:
319 return StringRef("thumbAbsLow16");
320 case thumbAbsHigh16:
321 return StringRef("thumbAbsHigh16");
322 case thumbPcRelLow16:
323 return StringRef("thumbPcRelLow16");
324 case thumbPcRelHigh16:
325 return StringRef("thumbPcRelHigh16");
326 case abs32:
327 return StringRef("abs32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000328 case pointer32:
329 return StringRef("pointer32");
330 case lazyTarget:
331 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000332 case lazyImmediate:
333 return StringRef("lazyImmediate");
334 case subordinateLSDA:
335 return StringRef("subordinateLSDA");
Nick Kledzik40b68552012-06-11 22:53:15 +0000336 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000337 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000338}
339
340bool KindHandler_arm::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000341 return (kind == thumbBranch22) || (kind == armBranch24);
Nick Kledzik40b68552012-06-11 22:53:15 +0000342}
343
344bool KindHandler_arm::isPointer(Kind kind) {
345 return (kind == pointer32);
346}
347
348
349bool KindHandler_arm::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000350 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000351}
352
353
354bool KindHandler_arm::isLazyTarget(Kind kind) {
355 return (kind == lazyTarget);
356}
357
358
359void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
360 uint64_t fixupAddress, uint64_t targetAddress) {
361 //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
362 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000363 case thumbBranch22:
364 // FIXME
365 break;
366 case armBranch24:
367 // FIXME
368 break;
369 case thumbAbsLow16:
370 // FIXME
371 break;
372 case thumbAbsHigh16:
373 // FIXME
374 break;
375 case thumbPcRelLow16:
376 // FIXME
377 break;
378 case thumbPcRelHigh16:
379 // FIXME
380 break;
381 case abs32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000382 // FIXME
383 break;
384 case pointer32:
385 // FIXME
386 break;
387 case none:
388 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000389 case lazyImmediate:
390 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000391 // do nothing
392 break;
Nick Kledzik7145cf62012-06-15 21:26:18 +0000393 case invalid:
394 assert(0 && "invalid Reference Kind");
395 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000396 }
397}
398
Nick Kledzikabb69812012-05-31 22:34:00 +0000399
400} // namespace mach_o
401} // namespace lld
402
403
404