blob: 75c9f1b88b07a6f69978be56b0e1d4afb162bb36 [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)
74 .Case("subordinateLSDA", subordinateLSDA);
75
Nick Kledzik751eb3d2012-06-15 20:37:24 +000076 llvm_unreachable("invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +000077}
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 Kledzik751eb3d2012-06-15 20:37:24 +0000116 llvm_unreachable("invalid x86_64 Reference kind");
Nick Kledzikabb69812012-05-31 22:34:00 +0000117}
118
Nick Kledzik40b68552012-06-11 22:53:15 +0000119bool KindHandler_x86_64::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000120 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000121}
122
123bool KindHandler_x86_64::isPointer(Kind kind) {
124 return (kind == pointer64);
125}
Nick Kledzik40b68552012-06-11 22:53:15 +0000126
127bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000128 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000129}
Nick Kledzik40b68552012-06-11 22:53:15 +0000130
131bool KindHandler_x86_64::isLazyTarget(Kind kind) {
132 return (kind == lazyTarget);
133}
134
135
Nick Kledzikc890ae42012-06-12 23:01:30 +0000136void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
137 uint8_t *location, uint64_t fixupAddress,
138 uint64_t targetAddress) {
Nick Kledzik40b68552012-06-11 22:53:15 +0000139 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
140 uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
141 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000142 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000143 case ripRel32:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000144 case gotLoadRipRel32:
145 case gotUseRipRel32:
146 case tlvLoadRipRel32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000147 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
148 break;
149 case pointer64:
150 *loc64 = targetAddress + addend;
151 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000152 case ripRel32_1:
153 *loc32 = (targetAddress - (fixupAddress+5)) + addend;
154 break;
155 case ripRel32_2:
156 *loc32 = (targetAddress - (fixupAddress+6)) + addend;
157 break;
158 case ripRel32_4:
159 *loc32 = (targetAddress - (fixupAddress+8)) + addend;
160 break;
161 case pointerRel32:
162 *loc32 = (targetAddress - fixupAddress) + addend;
163 break;
164 case gotLoadRipRel32NowLea:
165 case tlvLoadRipRel32NowLea:
166 // Change MOVQ to LEA
167 assert(location[-2] == 0x8B);
168 location[-2] = 0x8D;
169 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
Nick Kledzik40b68552012-06-11 22:53:15 +0000170 break;
171 case none:
172 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000173 case lazyImmediate:
174 case subordinateFDE:
175 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000176 // do nothing
177 break;
Nick Kledzikabb69812012-05-31 22:34:00 +0000178 }
179}
180
Nick Kledzik40b68552012-06-11 22:53:15 +0000181
182//===----------------------------------------------------------------------===//
183// KindHandler_x86
184//===----------------------------------------------------------------------===//
185
186KindHandler_x86::~KindHandler_x86() {
Nick Kledzikabb69812012-05-31 22:34:00 +0000187}
188
Nick Kledzik40b68552012-06-11 22:53:15 +0000189Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000190 return llvm::StringSwitch<Reference::Kind>(str)
191 .Case("none", none)
192 .Case("branch32", branch32)
193 .Case("abs32", abs32)
194 .Case("funcRel32", funcRel32)
195 .Case("pointer32", pointer32)
196 .Case("lazyTarget", lazyTarget)
197 .Case("lazyImmediate", lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000198
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000199 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000200}
201
202StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
203 switch ( (Kinds)kind ) {
204 case none:
205 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000206 case branch32:
207 return StringRef("branch32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000208 case abs32:
209 return StringRef("abs32");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000210 case funcRel32:
211 return StringRef("funcRel32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000212 case pointer32:
213 return StringRef("pointer32");
214 case lazyTarget:
215 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000216 case lazyImmediate:
217 return StringRef("lazyImmediate");
218 case subordinateFDE:
219 return StringRef("subordinateFDE");
220 case subordinateLSDA:
221 return StringRef("subordinateLSDA");
Nick Kledzikabb69812012-05-31 22:34:00 +0000222 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000223 llvm_unreachable("invalid x86 Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000224}
225
226bool KindHandler_x86::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000227 return (kind == branch32);
Nick Kledzik40b68552012-06-11 22:53:15 +0000228}
229
230bool KindHandler_x86::isPointer(Kind kind) {
231 return (kind == pointer32);
232}
233
234
235bool KindHandler_x86::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000236 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000237}
238
239
240bool KindHandler_x86::isLazyTarget(Kind kind) {
241 return (kind == lazyTarget);
242}
243
244
245void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
246 uint64_t fixupAddress, uint64_t targetAddress) {
247 int32_t *loc32 = reinterpret_cast<int32_t*>(location);
248 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000249 case branch32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000250 *loc32 = (targetAddress - (fixupAddress+4)) + addend;
251 break;
252 case pointer32:
253 case abs32:
254 *loc32 = targetAddress + addend;
255 break;
Nick Kledzikc890ae42012-06-12 23:01:30 +0000256 case funcRel32:
257 *loc32 = targetAddress + addend;
258 break;
Nick Kledzik40b68552012-06-11 22:53:15 +0000259 case none:
260 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000261 case lazyImmediate:
262 case subordinateFDE:
263 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000264 // do nothing
265 break;
266 }
Nick Kledzikabb69812012-05-31 22:34:00 +0000267}
268
269
Nick Kledzik40b68552012-06-11 22:53:15 +0000270//===----------------------------------------------------------------------===//
271// KindHandler_arm
272//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +0000273
Nick Kledzik40b68552012-06-11 22:53:15 +0000274KindHandler_arm::~KindHandler_arm() {
275}
Nick Kledzikabb69812012-05-31 22:34:00 +0000276
Nick Kledzik40b68552012-06-11 22:53:15 +0000277Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
Nick Kledzikd6a27322012-06-15 20:29:27 +0000278 return llvm::StringSwitch<Reference::Kind>(str)
279 .Case("none", none)
280 .Case("thumbBranch22", thumbBranch22)
281 .Case("armBranch24", armBranch24)
282 .Case("thumbAbsLow16", thumbAbsLow16)
283 .Case("thumbAbsHigh16", thumbAbsHigh16)
284 .Case("thumbPcRelLow16", thumbPcRelLow16)
285 .Case("thumbPcRelHigh16", thumbPcRelHigh16)
286 .Case("abs32", abs32)
287 .Case("pointer32", pointer32)
288 .Case("lazyTarget", lazyTarget)
289 .Case("lazyImmediate", lazyImmediate)
290 .Case("subordinateLSDA", subordinateLSDA);
Nick Kledzik40b68552012-06-11 22:53:15 +0000291
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000292 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000293}
294
295StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
296 switch ( (Kinds)kind ) {
297 case none:
298 return StringRef("none");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000299 case thumbBranch22:
300 return StringRef("thumbBranch22");
301 case armBranch24:
302 return StringRef("armBranch24");
303 case thumbAbsLow16:
304 return StringRef("thumbAbsLow16");
305 case thumbAbsHigh16:
306 return StringRef("thumbAbsHigh16");
307 case thumbPcRelLow16:
308 return StringRef("thumbPcRelLow16");
309 case thumbPcRelHigh16:
310 return StringRef("thumbPcRelHigh16");
311 case abs32:
312 return StringRef("abs32");
Nick Kledzik40b68552012-06-11 22:53:15 +0000313 case pointer32:
314 return StringRef("pointer32");
315 case lazyTarget:
316 return StringRef("lazyTarget");
Nick Kledzikc890ae42012-06-12 23:01:30 +0000317 case lazyImmediate:
318 return StringRef("lazyImmediate");
319 case subordinateLSDA:
320 return StringRef("subordinateLSDA");
Nick Kledzik40b68552012-06-11 22:53:15 +0000321 }
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000322 llvm_unreachable("invalid ARM Reference kind");
Nick Kledzik40b68552012-06-11 22:53:15 +0000323}
324
325bool KindHandler_arm::isCallSite(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000326 return (kind == thumbBranch22) || (kind == armBranch24);
Nick Kledzik40b68552012-06-11 22:53:15 +0000327}
328
329bool KindHandler_arm::isPointer(Kind kind) {
330 return (kind == pointer32);
331}
332
333
334bool KindHandler_arm::isLazyImmediate(Kind kind) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000335 return (kind == lazyImmediate);
Nick Kledzik40b68552012-06-11 22:53:15 +0000336}
337
338
339bool KindHandler_arm::isLazyTarget(Kind kind) {
340 return (kind == lazyTarget);
341}
342
343
344void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
345 uint64_t fixupAddress, uint64_t targetAddress) {
346 //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
347 switch ( (Kinds)kind ) {
Nick Kledzikc890ae42012-06-12 23:01:30 +0000348 case thumbBranch22:
349 // FIXME
350 break;
351 case armBranch24:
352 // FIXME
353 break;
354 case thumbAbsLow16:
355 // FIXME
356 break;
357 case thumbAbsHigh16:
358 // FIXME
359 break;
360 case thumbPcRelLow16:
361 // FIXME
362 break;
363 case thumbPcRelHigh16:
364 // FIXME
365 break;
366 case abs32:
Nick Kledzik40b68552012-06-11 22:53:15 +0000367 // FIXME
368 break;
369 case pointer32:
370 // FIXME
371 break;
372 case none:
373 case lazyTarget:
Nick Kledzikc890ae42012-06-12 23:01:30 +0000374 case lazyImmediate:
375 case subordinateLSDA:
Nick Kledzik40b68552012-06-11 22:53:15 +0000376 // do nothing
377 break;
378 }
379}
380
Nick Kledzikabb69812012-05-31 22:34:00 +0000381
382} // namespace mach_o
383} // namespace lld
384
385
386