blob: 6186aa2d234d5e4b4914547adec87d28ea54c592 [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;
Nick Kledzikabb69812012-05-31 22:34:00 +000043 }
Nick Kledzik40b68552012-06-11 22:53:15 +000044}
45
46
47//===----------------------------------------------------------------------===//
48// KindHandler_x86_64
49//===----------------------------------------------------------------------===//
50
51KindHandler_x86_64::~KindHandler_x86_64() {
52}
53
54Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +000055 return llvm::StringSwitch<Reference::Kind>(str)
56 .Case("none", none)
57 .Case("branch32", branch32)
58 .Case("ripRel32", ripRel32)
59 .Case("ripRel32_1", ripRel32_1)
60 .Case("ripRel32_2", ripRel32_2)
61 .Case("ripRel32_4", ripRel32_4)
62 .Case("gotLoadRipRel32", gotLoadRipRel32)
63 .Case("gotLoadRipRel32NowLea", gotLoadRipRel32NowLea)
64 .Case("gotUseRipRel32", gotUseRipRel32)
65 .Case("tlvLoadRipRel32", tlvLoadRipRel32)
66 .Case("tlvLoadRipRel32NowLea", tlvLoadRipRel32NowLea)
67 .Case("pointer64", pointer64)
68 .Case("pointerRel32", pointerRel32)
69 .Case("lazyTarget", lazyTarget)
70 .Case("lazyImmediate", lazyImmediate)
71 .Case("subordinateFDE", subordinateFDE)
Nick Kledzik7145cf62012-06-15 21:26:18 +000072 .Case("subordinateLSDA", subordinateLSDA)
73 .Default(invalid);
Nick Kledzikd6a27322012-06-15 20:29:27 +000074
Nick Kledzik751eb3d2012-06-15 20:37:24 +000075 llvm_unreachable("invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +000076}
77
Nick Kledzik40b68552012-06-11 22:53:15 +000078StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
79 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +000080 case invalid:
81 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +000082 case none:
83 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +000084 case branch32:
85 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +000086 case ripRel32:
87 return StringRef("ripRel32");
Nick Kledzikc890ae42012-06-12 23:01:30 +000088 case ripRel32_1:
89 return StringRef("ripRel32_1");
90 case ripRel32_2:
91 return StringRef("ripRel32_2");
92 case ripRel32_4:
93 return StringRef("ripRel32_4");
94 case gotLoadRipRel32:
95 return StringRef("gotLoadRipRel32");
96 case gotLoadRipRel32NowLea:
97 return StringRef("gotLoadRipRel32NowLea");
98 case gotUseRipRel32:
99 return StringRef("gotUseRipRel32");
100 case tlvLoadRipRel32:
101 return StringRef("tlvLoadRipRel32");
102 case tlvLoadRipRel32NowLea:
103 return StringRef("tlvLoadRipRel32NowLea");
Nick Kledzik40b68552012-06-11 22:53:15 +0000104 case pointer64:
105 return StringRef("pointer64");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000106 case pointerRel32:
107 return StringRef("pointerRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000108 case lazyTarget:
109 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000110 case lazyImmediate:
111 return StringRef("lazyImmediate");
112 case subordinateFDE:
113 return StringRef("subordinateFDE");
114 case subordinateLSDA:
115 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000116 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000117 llvm_unreachable("invalid x86_64 Reference kind");
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 Kledzik7145cf62012-06-15 21:26:18 +0000179 case invalid:
180 assert(0 && "invalid Reference Kind");
181 break;
Nick Kledzikabb69812012-05-31 22:34:00 +0000182 }
183}
184
Nick Kledzik40b68552012-06-11 22:53:15 +0000185
186//===----------------------------------------------------------------------===//
187// KindHandler_x86
188//===----------------------------------------------------------------------===//
189
190KindHandler_x86::~KindHandler_x86() {
Nick Kledzikabb69812012-05-31 22:34:00 +0000191}
192
Nick Kledzik40b68552012-06-11 22:53:15 +0000193Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000194 return llvm::StringSwitch<Reference::Kind>(str)
195 .Case("none", none)
196 .Case("branch32", branch32)
197 .Case("abs32", abs32)
198 .Case("funcRel32", funcRel32)
199 .Case("pointer32", pointer32)
200 .Case("lazyTarget", lazyTarget)
Nick Kledzik7145cf62012-06-15 21:26:18 +0000201 .Case("lazyImmediate", lazyImmediate)
202 .Default(invalid);
Nick Kledzik40b68552012-06-11 22:53:15 +0000203
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000204 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000205}
206
207StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
208 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +0000209 case invalid:
210 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +0000211 case none:
212 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000213 case branch32:
214 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000215 case abs32:
216 return StringRef("abs32");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000217 case funcRel32:
218 return StringRef("funcRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000219 case pointer32:
220 return StringRef("pointer32");
221 case lazyTarget:
222 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000223 case lazyImmediate:
224 return StringRef("lazyImmediate");
225 case subordinateFDE:
226 return StringRef("subordinateFDE");
227 case subordinateLSDA:
228 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000229 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000230 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000231}
232
233bool KindHandler_x86::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000234 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000235}
236
237bool KindHandler_x86::isPointer(Kind kind) {
238 return (kind == pointer32);
239}
240
241
242bool KindHandler_x86::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000243 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000244}
245
246
247bool KindHandler_x86::isLazyTarget(Kind kind) {
248 return (kind == lazyTarget);
249}
250
251
252void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
253 uint64_t fixupAddress, uint64_t targetAddress) {
254 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
255 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000256 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000257 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
258 break;
259 case pointer32:
260 case abs32:
261 *loc32 = targetAddress + addend;
262 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000263 case funcRel32:
264 *loc32 = targetAddress + addend;
265 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000266 case none:
267 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000268 case lazyImmediate:
269 case subordinateFDE:
270 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000271 // do nothing
272 break;
Nick Kledzik7145cf62012-06-15 21:26:18 +0000273 case invalid:
274 assert(0 && "invalid Reference Kind");
275 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000276 }
Nick Kledzikabb69812012-05-31 22:34:00 +0000277}
278
279
Nick Kledzik40b68552012-06-11 22:53:15 +0000280//===----------------------------------------------------------------------===//
281// KindHandler_arm
282//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +0000283
Nick Kledzik40b68552012-06-11 22:53:15 +0000284KindHandler_arm::~KindHandler_arm() {
285}
Nick Kledzikabb69812012-05-31 22:34:00 +0000286
Nick Kledzik40b68552012-06-11 22:53:15 +0000287Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000288 return llvm::StringSwitch<Reference::Kind>(str)
289 .Case("none", none)
290 .Case("thumbBranch22", thumbBranch22)
291 .Case("armBranch24", armBranch24)
292 .Case("thumbAbsLow16", thumbAbsLow16)
293 .Case("thumbAbsHigh16", thumbAbsHigh16)
294 .Case("thumbPcRelLow16", thumbPcRelLow16)
295 .Case("thumbPcRelHigh16", thumbPcRelHigh16)
296 .Case("abs32", abs32)
297 .Case("pointer32", pointer32)
298 .Case("lazyTarget", lazyTarget)
299 .Case("lazyImmediate", lazyImmediate)
Nick Kledzik7145cf62012-06-15 21:26:18 +0000300 .Case("subordinateLSDA", subordinateLSDA)
301 .Default(invalid);
Nick Kledzik40b68552012-06-11 22:53:15 +0000302
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000303 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000304}
305
306StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
307 switch ( (Kinds)kind ) {
Nick Kledzik7145cf62012-06-15 21:26:18 +0000308 case invalid:
309 return StringRef("invalid");
Nick Kledzik40b68552012-06-11 22:53:15 +0000310 case none:
311 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000312 case thumbBranch22:
313 return StringRef("thumbBranch22");
314 case armBranch24:
315 return StringRef("armBranch24");
316 case thumbAbsLow16:
317 return StringRef("thumbAbsLow16");
318 case thumbAbsHigh16:
319 return StringRef("thumbAbsHigh16");
320 case thumbPcRelLow16:
321 return StringRef("thumbPcRelLow16");
322 case thumbPcRelHigh16:
323 return StringRef("thumbPcRelHigh16");
324 case abs32:
325 return StringRef("abs32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000326 case pointer32:
327 return StringRef("pointer32");
328 case lazyTarget:
329 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000330 case lazyImmediate:
331 return StringRef("lazyImmediate");
332 case subordinateLSDA:
333 return StringRef("subordinateLSDA");
Nick Kledzik40b68552012-06-11 22:53:15 +0000334 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000335 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000336}
337
338bool KindHandler_arm::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000339 return (kind == thumbBranch22) || (kind == armBranch24);
Nick Kledzik40b68552012-06-11 22:53:15 +0000340}
341
342bool KindHandler_arm::isPointer(Kind kind) {
343 return (kind == pointer32);
344}
345
346
347bool KindHandler_arm::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000348 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000349}
350
351
352bool KindHandler_arm::isLazyTarget(Kind kind) {
353 return (kind == lazyTarget);
354}
355
356
357void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
358 uint64_t fixupAddress, uint64_t targetAddress) {
359 //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
360 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000361 case thumbBranch22:
362 // FIXME
363 break;
364 case armBranch24:
365 // FIXME
366 break;
367 case thumbAbsLow16:
368 // FIXME
369 break;
370 case thumbAbsHigh16:
371 // FIXME
372 break;
373 case thumbPcRelLow16:
374 // FIXME
375 break;
376 case thumbPcRelHigh16:
377 // FIXME
378 break;
379 case abs32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000380 // FIXME
381 break;
382 case pointer32:
383 // FIXME
384 break;
385 case none:
386 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000387 case lazyImmediate:
388 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000389 // do nothing
390 break;
Nick Kledzik7145cf62012-06-15 21:26:18 +0000391 case invalid:
392 assert(0 && "invalid Reference Kind");
393 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000394 }
395}
396
Nick Kledzikabb69812012-05-31 22:34:00 +0000397
398} // namespace mach_o
399} // namespace lld
400
401
402