blob: 85116cb2737934de80b19f446b585134d2afa21b [file] [log] [blame]
Eric Christopher6256b032011-04-22 03:19:48 +00001//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the MachOObjectFile class, which binds the MachOObject
11// class to the generic ObjectFile wrapper.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ADT/Triple.h"
Owen Andersonf7c93a32011-10-11 17:32:27 +000016#include "llvm/Object/MachO.h"
Eric Christopher6256b032011-04-22 03:19:48 +000017#include "llvm/Object/MachOFormat.h"
Owen Anderson1832f4d2011-10-26 20:42:54 +000018#include "llvm/Support/Format.h"
Eric Christopher6256b032011-04-22 03:19:48 +000019#include "llvm/Support/MemoryBuffer.h"
20
21#include <cctype>
22#include <cstring>
23#include <limits>
24
25using namespace llvm;
26using namespace object;
27
28namespace llvm {
Owen Andersonf7c93a32011-10-11 17:32:27 +000029namespace object {
Eric Christopher6256b032011-04-22 03:19:48 +000030
Benjamin Kramer0fcab072011-09-08 20:52:17 +000031MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO,
32 error_code &ec)
David Meyer6f9489a2012-03-09 20:41:57 +000033 : ObjectFile(Binary::ID_MachO, Object, ec),
Benjamin Kramer0fcab072011-09-08 20:52:17 +000034 MachOObj(MOO),
35 RegisteredStringTable(std::numeric_limits<uint32_t>::max()) {
36 DataRefImpl DRI;
Benjamin Kramer0fcab072011-09-08 20:52:17 +000037 moveToNextSection(DRI);
38 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
39 while (DRI.d.a < LoadCommandCount) {
40 Sections.push_back(DRI);
Benjamin Kramer0fcab072011-09-08 20:52:17 +000041 DRI.d.b++;
42 moveToNextSection(DRI);
43 }
44}
45
46
Eric Christopher6256b032011-04-22 03:19:48 +000047ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
Michael J. Spencer001c9202011-06-25 17:54:50 +000048 error_code ec;
Eric Christopher6256b032011-04-22 03:19:48 +000049 std::string Err;
50 MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err);
51 if (!MachOObj)
52 return NULL;
Jim Grosbach596e4742012-11-29 19:14:11 +000053 // MachOObject takes ownership of the Buffer we passed to it, and
54 // MachOObjectFile does, too, so we need to make sure they don't get the
55 // same object. A MemoryBuffer is cheap (it's just a reference to memory,
56 // not a copy of the memory itself), so just make a new copy here for
57 // the MachOObjectFile.
58 MemoryBuffer *NewBuffer =
Benjamin Kramerf56c3e22012-11-29 20:08:03 +000059 MemoryBuffer::getMemBuffer(Buffer->getBuffer(),
60 Buffer->getBufferIdentifier(), false);
Jim Grosbach596e4742012-11-29 19:14:11 +000061 return new MachOObjectFile(NewBuffer, MachOObj, ec);
Eric Christopher6256b032011-04-22 03:19:48 +000062}
63
64/*===-- Symbols -----------------------------------------------------------===*/
65
66void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const {
67 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
68 while (DRI.d.a < LoadCommandCount) {
69 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
70 if (LCI.Command.Type == macho::LCT_Symtab) {
71 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
72 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
73 if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
74 return;
75 }
76
77 DRI.d.a++;
78 DRI.d.b = 0;
79 }
80}
81
82void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI,
83 InMemoryStruct<macho::SymbolTableEntry> &Res) const {
84 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
85 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
86 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
87
88 if (RegisteredStringTable != DRI.d.a) {
89 MachOObj->RegisterStringTable(*SymtabLoadCmd);
90 RegisteredStringTable = DRI.d.a;
91 }
92
93 MachOObj->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b,
94 Res);
95}
96
Benjamin Kramer32fb2af2011-07-15 17:32:45 +000097void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI,
98 InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
99 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
100 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
101 MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
102
103 if (RegisteredStringTable != DRI.d.a) {
104 MachOObj->RegisterStringTable(*SymtabLoadCmd);
105 RegisteredStringTable = DRI.d.a;
106 }
107
108 MachOObj->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b,
109 Res);
110}
111
Eric Christopher6256b032011-04-22 03:19:48 +0000112
Michael J. Spencer25b15772011-06-25 17:55:23 +0000113error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI,
114 SymbolRef &Result) const {
Eric Christopher6256b032011-04-22 03:19:48 +0000115 DRI.d.b++;
116 moveToNextSymbol(DRI);
Michael J. Spencer25b15772011-06-25 17:55:23 +0000117 Result = SymbolRef(DRI, this);
118 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000119}
120
Michael J. Spencer25b15772011-06-25 17:55:23 +0000121error_code MachOObjectFile::getSymbolName(DataRefImpl DRI,
122 StringRef &Result) const {
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000123 if (MachOObj->is64Bit()) {
124 InMemoryStruct<macho::Symbol64TableEntry> Entry;
125 getSymbol64TableEntry(DRI, Entry);
126 Result = MachOObj->getStringAtIndex(Entry->StringIndex);
127 } else {
128 InMemoryStruct<macho::SymbolTableEntry> Entry;
129 getSymbolTableEntry(DRI, Entry);
130 Result = MachOObj->getStringAtIndex(Entry->StringIndex);
131 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000132 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000133}
134
Danil Malyshevb0436a72011-11-29 17:40:10 +0000135error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI,
136 uint64_t &Result) const {
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000137 if (MachOObj->is64Bit()) {
138 InMemoryStruct<macho::Symbol64TableEntry> Entry;
139 getSymbol64TableEntry(DRI, Entry);
140 Result = Entry->Value;
Danil Malyshevb0436a72011-11-29 17:40:10 +0000141 if (Entry->SectionIndex) {
142 InMemoryStruct<macho::Section64> Section;
143 getSection64(Sections[Entry->SectionIndex-1], Section);
144 Result += Section->Offset - Section->Address;
145 }
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000146 } else {
147 InMemoryStruct<macho::SymbolTableEntry> Entry;
148 getSymbolTableEntry(DRI, Entry);
149 Result = Entry->Value;
Danil Malyshevb0436a72011-11-29 17:40:10 +0000150 if (Entry->SectionIndex) {
151 InMemoryStruct<macho::Section> Section;
152 getSection(Sections[Entry->SectionIndex-1], Section);
153 Result += Section->Offset - Section->Address;
154 }
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000155 }
Owen Anderson95f8db42011-10-12 22:37:10 +0000156
Michael J. Spencer25b15772011-06-25 17:55:23 +0000157 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000158}
159
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000160error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI,
161 uint64_t &Result) const {
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000162 if (MachOObj->is64Bit()) {
163 InMemoryStruct<macho::Symbol64TableEntry> Entry;
164 getSymbol64TableEntry(DRI, Entry);
Owen Anderson95f8db42011-10-12 22:37:10 +0000165 Result = Entry->Value;
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000166 } else {
167 InMemoryStruct<macho::SymbolTableEntry> Entry;
168 getSymbolTableEntry(DRI, Entry);
Owen Anderson95f8db42011-10-12 22:37:10 +0000169 Result = Entry->Value;
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000170 }
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000171 return object_error::success;
172}
173
Michael J. Spencer25b15772011-06-25 17:55:23 +0000174error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
175 uint64_t &Result) const {
Danil Malyshevb0436a72011-11-29 17:40:10 +0000176 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
177 uint64_t BeginOffset;
178 uint64_t EndOffset = 0;
179 uint8_t SectionIndex;
180 if (MachOObj->is64Bit()) {
181 InMemoryStruct<macho::Symbol64TableEntry> Entry;
182 getSymbol64TableEntry(DRI, Entry);
183 BeginOffset = Entry->Value;
184 SectionIndex = Entry->SectionIndex;
185 if (!SectionIndex) {
Preston Gurdc68dda82012-04-12 20:13:57 +0000186 uint32_t flags = SymbolRef::SF_None;
187 getSymbolFlags(DRI, flags);
188 if (flags & SymbolRef::SF_Common)
189 Result = Entry->Value;
190 else
191 Result = UnknownAddressOrSize;
Danil Malyshevb0436a72011-11-29 17:40:10 +0000192 return object_error::success;
193 }
194 // Unfortunately symbols are unsorted so we need to touch all
195 // symbols from load command
196 DRI.d.b = 0;
197 uint32_t Command = DRI.d.a;
198 while (Command == DRI.d.a) {
199 moveToNextSymbol(DRI);
200 if (DRI.d.a < LoadCommandCount) {
201 getSymbol64TableEntry(DRI, Entry);
202 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
203 if (!EndOffset || Entry->Value < EndOffset)
204 EndOffset = Entry->Value;
205 }
206 DRI.d.b++;
207 }
208 } else {
209 InMemoryStruct<macho::SymbolTableEntry> Entry;
210 getSymbolTableEntry(DRI, Entry);
211 BeginOffset = Entry->Value;
212 SectionIndex = Entry->SectionIndex;
213 if (!SectionIndex) {
Preston Gurdc68dda82012-04-12 20:13:57 +0000214 uint32_t flags = SymbolRef::SF_None;
215 getSymbolFlags(DRI, flags);
216 if (flags & SymbolRef::SF_Common)
217 Result = Entry->Value;
218 else
219 Result = UnknownAddressOrSize;
Danil Malyshevb0436a72011-11-29 17:40:10 +0000220 return object_error::success;
221 }
222 // Unfortunately symbols are unsorted so we need to touch all
223 // symbols from load command
224 DRI.d.b = 0;
225 uint32_t Command = DRI.d.a;
226 while (Command == DRI.d.a) {
227 moveToNextSymbol(DRI);
228 if (DRI.d.a < LoadCommandCount) {
229 getSymbolTableEntry(DRI, Entry);
230 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
231 if (!EndOffset || Entry->Value < EndOffset)
232 EndOffset = Entry->Value;
233 }
234 DRI.d.b++;
235 }
236 }
237 if (!EndOffset) {
238 uint64_t Size;
239 getSectionSize(Sections[SectionIndex-1], Size);
240 getSectionAddress(Sections[SectionIndex-1], EndOffset);
241 EndOffset += Size;
242 }
243 Result = EndOffset - BeginOffset;
Michael J. Spencer25b15772011-06-25 17:55:23 +0000244 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000245}
246
Michael J. Spencer25b15772011-06-25 17:55:23 +0000247error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI,
248 char &Result) const {
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000249 uint8_t Type, Flags;
250 if (MachOObj->is64Bit()) {
251 InMemoryStruct<macho::Symbol64TableEntry> Entry;
252 getSymbol64TableEntry(DRI, Entry);
253 Type = Entry->Type;
254 Flags = Entry->Flags;
255 } else {
256 InMemoryStruct<macho::SymbolTableEntry> Entry;
257 getSymbolTableEntry(DRI, Entry);
258 Type = Entry->Type;
259 Flags = Entry->Flags;
260 }
Eric Christopher6256b032011-04-22 03:19:48 +0000261
262 char Char;
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000263 switch (Type & macho::STF_TypeMask) {
Eric Christopher6256b032011-04-22 03:19:48 +0000264 case macho::STT_Undefined:
265 Char = 'u';
266 break;
267 case macho::STT_Absolute:
268 case macho::STT_Section:
269 Char = 's';
270 break;
271 default:
272 Char = '?';
273 break;
274 }
275
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000276 if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
Eric Christopher6256b032011-04-22 03:19:48 +0000277 Char = toupper(Char);
Michael J. Spencer25b15772011-06-25 17:55:23 +0000278 Result = Char;
279 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000280}
281
David Meyerc46255a2012-02-28 23:47:53 +0000282error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
283 uint32_t &Result) const {
284 uint16_t MachOFlags;
285 uint8_t MachOType;
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000286 if (MachOObj->is64Bit()) {
287 InMemoryStruct<macho::Symbol64TableEntry> Entry;
288 getSymbol64TableEntry(DRI, Entry);
David Meyerc46255a2012-02-28 23:47:53 +0000289 MachOFlags = Entry->Flags;
290 MachOType = Entry->Type;
Benjamin Kramer32fb2af2011-07-15 17:32:45 +0000291 } else {
292 InMemoryStruct<macho::SymbolTableEntry> Entry;
293 getSymbolTableEntry(DRI, Entry);
David Meyerc46255a2012-02-28 23:47:53 +0000294 MachOFlags = Entry->Flags;
295 MachOType = Entry->Type;
Michael J. Spencer9b2b8122011-10-17 23:54:46 +0000296 }
297
Preston Gurdc68dda82012-04-12 20:13:57 +0000298 // TODO: Correctly set SF_ThreadLocal
David Meyerc46255a2012-02-28 23:47:53 +0000299 Result = SymbolRef::SF_None;
David Meyer2c677272012-02-29 02:11:55 +0000300
301 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
302 Result |= SymbolRef::SF_Undefined;
303
David Meyerc46255a2012-02-28 23:47:53 +0000304 if (MachOFlags & macho::STF_StabsEntryMask)
305 Result |= SymbolRef::SF_FormatSpecific;
306
Preston Gurdc68dda82012-04-12 20:13:57 +0000307 if (MachOType & MachO::NlistMaskExternal) {
David Meyerc46255a2012-02-28 23:47:53 +0000308 Result |= SymbolRef::SF_Global;
Preston Gurdc68dda82012-04-12 20:13:57 +0000309 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
310 Result |= SymbolRef::SF_Common;
311 }
David Meyerc46255a2012-02-28 23:47:53 +0000312
313 if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
314 Result |= SymbolRef::SF_Weak;
315
316 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
317 Result |= SymbolRef::SF_Absolute;
318
Michael J. Spencer9b2b8122011-10-17 23:54:46 +0000319 return object_error::success;
320}
321
322error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
323 section_iterator &Res) const {
324 uint8_t index;
325 if (MachOObj->is64Bit()) {
326 InMemoryStruct<macho::Symbol64TableEntry> Entry;
327 getSymbol64TableEntry(Symb, Entry);
328 index = Entry->SectionIndex;
329 } else {
330 InMemoryStruct<macho::SymbolTableEntry> Entry;
331 getSymbolTableEntry(Symb, Entry);
332 index = Entry->SectionIndex;
333 }
334
335 if (index == 0)
336 Res = end_sections();
337 else
Danil Malyshevb0436a72011-11-29 17:40:10 +0000338 Res = section_iterator(SectionRef(Sections[index-1], this));
Michael J. Spencer9b2b8122011-10-17 23:54:46 +0000339
340 return object_error::success;
341}
342
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000343error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
Michael J. Spencer1130a792011-10-17 20:19:29 +0000344 SymbolRef::Type &Res) const {
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000345 uint8_t n_type;
346 if (MachOObj->is64Bit()) {
347 InMemoryStruct<macho::Symbol64TableEntry> Entry;
348 getSymbol64TableEntry(Symb, Entry);
349 n_type = Entry->Type;
350 } else {
351 InMemoryStruct<macho::SymbolTableEntry> Entry;
352 getSymbolTableEntry(Symb, Entry);
353 n_type = Entry->Type;
354 }
355 Res = SymbolRef::ST_Other;
Owen Anderson10a8c622011-10-12 22:23:12 +0000356
357 // If this is a STAB debugging symbol, we can do nothing more.
Owen Andersona48aab92011-10-21 19:26:54 +0000358 if (n_type & MachO::NlistMaskStab) {
359 Res = SymbolRef::ST_Debug;
Owen Anderson10a8c622011-10-12 22:23:12 +0000360 return object_error::success;
Owen Andersona48aab92011-10-21 19:26:54 +0000361 }
Owen Anderson10a8c622011-10-12 22:23:12 +0000362
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000363 switch (n_type & MachO::NlistMaskType) {
364 case MachO::NListTypeUndefined :
David Meyer2c677272012-02-29 02:11:55 +0000365 Res = SymbolRef::ST_Unknown;
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000366 break;
367 case MachO::NListTypeSection :
368 Res = SymbolRef::ST_Function;
369 break;
370 }
371 return object_error::success;
372}
373
Tim Northovera41dce32012-10-29 10:47:00 +0000374error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
375 uint64_t &Val) const {
376 report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
377}
Benjamin Kramerac241fe2011-09-14 01:22:52 +0000378
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000379symbol_iterator MachOObjectFile::begin_symbols() const {
Eric Christopher6256b032011-04-22 03:19:48 +0000380 // DRI.d.a = segment number; DRI.d.b = symbol index.
381 DataRefImpl DRI;
Eric Christopher6256b032011-04-22 03:19:48 +0000382 moveToNextSymbol(DRI);
383 return symbol_iterator(SymbolRef(DRI, this));
384}
385
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000386symbol_iterator MachOObjectFile::end_symbols() const {
Eric Christopher6256b032011-04-22 03:19:48 +0000387 DataRefImpl DRI;
388 DRI.d.a = MachOObj->getHeader().NumLoadCommands;
Eric Christopher6256b032011-04-22 03:19:48 +0000389 return symbol_iterator(SymbolRef(DRI, this));
390}
391
Michael J. Spencerdfa18962012-02-28 00:40:37 +0000392symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
393 // TODO: implement
394 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
395}
396
397symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
398 // TODO: implement
399 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
400}
Eric Christopher6256b032011-04-22 03:19:48 +0000401
David Meyer5c2b4ea2012-03-01 01:36:50 +0000402library_iterator MachOObjectFile::begin_libraries_needed() const {
403 // TODO: implement
404 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
405}
406
407library_iterator MachOObjectFile::end_libraries_needed() const {
408 // TODO: implement
409 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
410}
411
David Meyer97f77872012-03-01 22:19:54 +0000412StringRef MachOObjectFile::getLoadName() const {
413 // TODO: Implement
414 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
415}
416
Eric Christopher6256b032011-04-22 03:19:48 +0000417/*===-- Sections ----------------------------------------------------------===*/
418
419void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
420 uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
421 while (DRI.d.a < LoadCommandCount) {
422 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
423 if (LCI.Command.Type == macho::LCT_Segment) {
424 InMemoryStruct<macho::SegmentLoadCommand> SegmentLoadCmd;
425 MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd);
426 if (DRI.d.b < SegmentLoadCmd->NumSections)
427 return;
428 } else if (LCI.Command.Type == macho::LCT_Segment64) {
429 InMemoryStruct<macho::Segment64LoadCommand> Segment64LoadCmd;
430 MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd);
431 if (DRI.d.b < Segment64LoadCmd->NumSections)
432 return;
433 }
434
435 DRI.d.a++;
436 DRI.d.b = 0;
437 }
438}
439
Michael J. Spencer25b15772011-06-25 17:55:23 +0000440error_code MachOObjectFile::getSectionNext(DataRefImpl DRI,
441 SectionRef &Result) const {
Eric Christopher6256b032011-04-22 03:19:48 +0000442 DRI.d.b++;
443 moveToNextSection(DRI);
Michael J. Spencer25b15772011-06-25 17:55:23 +0000444 Result = SectionRef(DRI, this);
445 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000446}
447
448void
449MachOObjectFile::getSection(DataRefImpl DRI,
450 InMemoryStruct<macho::Section> &Res) const {
451 InMemoryStruct<macho::SegmentLoadCommand> SLC;
452 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
453 MachOObj->ReadSegmentLoadCommand(LCI, SLC);
454 MachOObj->ReadSection(LCI, DRI.d.b, Res);
455}
456
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000457std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
458 SectionList::const_iterator loc =
459 std::find(Sections.begin(), Sections.end(), Sec);
460 assert(loc != Sections.end() && "Sec is not a valid section!");
461 return std::distance(Sections.begin(), loc);
462}
463
Benjamin Kramer7d145782011-07-15 00:14:48 +0000464void
465MachOObjectFile::getSection64(DataRefImpl DRI,
466 InMemoryStruct<macho::Section64> &Res) const {
467 InMemoryStruct<macho::Segment64LoadCommand> SLC;
468 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
469 MachOObj->ReadSegment64LoadCommand(LCI, SLC);
470 MachOObj->ReadSection64(LCI, DRI.d.b, Res);
471}
472
473static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
474 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
475 if (LCI.Command.Type == macho::LCT_Segment64)
476 return true;
477 assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type.");
478 return false;
479}
480
Michael J. Spencer25b15772011-06-25 17:55:23 +0000481error_code MachOObjectFile::getSectionName(DataRefImpl DRI,
482 StringRef &Result) const {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000483 // FIXME: thread safety.
Michael J. Spencer25b15772011-06-25 17:55:23 +0000484 static char result[34];
Jim Grosbach596e4742012-11-29 19:14:11 +0000485 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000486 InMemoryStruct<macho::Segment64LoadCommand> SLC;
487 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
488 MachOObj->ReadSegment64LoadCommand(LCI, SLC);
489 InMemoryStruct<macho::Section64> Sect;
490 MachOObj->ReadSection64(LCI, DRI.d.b, Sect);
491
Benjamin Kramer291e7672011-07-15 00:29:02 +0000492 strcpy(result, Sect->SegmentName);
Benjamin Kramer7d145782011-07-15 00:14:48 +0000493 strcat(result, ",");
494 strcat(result, Sect->Name);
495 } else {
496 InMemoryStruct<macho::SegmentLoadCommand> SLC;
497 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
498 MachOObj->ReadSegmentLoadCommand(LCI, SLC);
499 InMemoryStruct<macho::Section> Sect;
500 MachOObj->ReadSection(LCI, DRI.d.b, Sect);
501
Benjamin Kramer291e7672011-07-15 00:29:02 +0000502 strcpy(result, Sect->SegmentName);
Benjamin Kramer7d145782011-07-15 00:14:48 +0000503 strcat(result, ",");
504 strcat(result, Sect->Name);
505 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000506 Result = StringRef(result);
507 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000508}
509
Michael J. Spencer25b15772011-06-25 17:55:23 +0000510error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
511 uint64_t &Result) const {
Jim Grosbach596e4742012-11-29 19:14:11 +0000512 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000513 InMemoryStruct<macho::Section64> Sect;
514 getSection64(DRI, Sect);
515 Result = Sect->Address;
516 } else {
517 InMemoryStruct<macho::Section> Sect;
518 getSection(DRI, Sect);
519 Result = Sect->Address;
520 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000521 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000522}
523
Michael J. Spencer25b15772011-06-25 17:55:23 +0000524error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
525 uint64_t &Result) const {
Jim Grosbach596e4742012-11-29 19:14:11 +0000526 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000527 InMemoryStruct<macho::Section64> Sect;
528 getSection64(DRI, Sect);
529 Result = Sect->Size;
530 } else {
531 InMemoryStruct<macho::Section> Sect;
532 getSection(DRI, Sect);
533 Result = Sect->Size;
534 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000535 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000536}
537
Michael J. Spencer25b15772011-06-25 17:55:23 +0000538error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
539 StringRef &Result) const {
Jim Grosbach596e4742012-11-29 19:14:11 +0000540 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000541 InMemoryStruct<macho::Section64> Sect;
542 getSection64(DRI, Sect);
543 Result = MachOObj->getData(Sect->Offset, Sect->Size);
544 } else {
545 InMemoryStruct<macho::Section> Sect;
546 getSection(DRI, Sect);
547 Result = MachOObj->getData(Sect->Offset, Sect->Size);
548 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000549 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000550}
551
Michael J. Spencere2f2f072011-10-10 21:55:43 +0000552error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
553 uint64_t &Result) const {
Jim Grosbach596e4742012-11-29 19:14:11 +0000554 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Michael J. Spencere2f2f072011-10-10 21:55:43 +0000555 InMemoryStruct<macho::Section64> Sect;
556 getSection64(DRI, Sect);
Michael J. Spencer15565ad2011-10-10 23:36:56 +0000557 Result = uint64_t(1) << Sect->Align;
Michael J. Spencere2f2f072011-10-10 21:55:43 +0000558 } else {
559 InMemoryStruct<macho::Section> Sect;
560 getSection(DRI, Sect);
Michael J. Spencer15565ad2011-10-10 23:36:56 +0000561 Result = uint64_t(1) << Sect->Align;
Michael J. Spencere2f2f072011-10-10 21:55:43 +0000562 }
563 return object_error::success;
564}
565
Michael J. Spencer25b15772011-06-25 17:55:23 +0000566error_code MachOObjectFile::isSectionText(DataRefImpl DRI,
567 bool &Result) const {
Jim Grosbach596e4742012-11-29 19:14:11 +0000568 if (is64BitLoadCommand(MachOObj.get(), DRI)) {
Benjamin Kramer7d145782011-07-15 00:14:48 +0000569 InMemoryStruct<macho::Section64> Sect;
570 getSection64(DRI, Sect);
571 Result = !strcmp(Sect->Name, "__text");
572 } else {
573 InMemoryStruct<macho::Section> Sect;
574 getSection(DRI, Sect);
575 Result = !strcmp(Sect->Name, "__text");
576 }
Michael J. Spencer25b15772011-06-25 17:55:23 +0000577 return object_error::success;
Eric Christopher6256b032011-04-22 03:19:48 +0000578}
579
Michael J. Spencer13afc5e2011-09-28 20:57:30 +0000580error_code MachOObjectFile::isSectionData(DataRefImpl DRI,
581 bool &Result) const {
582 // FIXME: Unimplemented.
583 Result = false;
584 return object_error::success;
585}
586
587error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
588 bool &Result) const {
589 // FIXME: Unimplemented.
590 Result = false;
591 return object_error::success;
592}
593
Preston Gurdc68dda82012-04-12 20:13:57 +0000594error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
595 bool &Result) const {
Andrew Kaylor30b20eb2012-10-10 01:45:52 +0000596 // FIXME: Unimplemented.
Preston Gurdc68dda82012-04-12 20:13:57 +0000597 Result = true;
598 return object_error::success;
599}
600
601error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
Andrew Kaylor30b20eb2012-10-10 01:45:52 +0000602 bool &Result) const {
603 // FIXME: Unimplemented.
Preston Gurdc68dda82012-04-12 20:13:57 +0000604 Result = false;
605 return object_error::success;
606}
607
608error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI,
609 bool &Result) const {
610 if (MachOObj->is64Bit()) {
611 InMemoryStruct<macho::Section64> Sect;
612 getSection64(DRI, Sect);
Eli Friedman41827f92012-05-02 02:31:28 +0000613 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
614 Result = (SectionType == MachO::SectionTypeZeroFill ||
615 SectionType == MachO::SectionTypeZeroFillLarge);
Preston Gurdc68dda82012-04-12 20:13:57 +0000616 } else {
617 InMemoryStruct<macho::Section> Sect;
618 getSection(DRI, Sect);
Eli Friedman41827f92012-05-02 02:31:28 +0000619 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
620 Result = (SectionType == MachO::SectionTypeZeroFill ||
621 SectionType == MachO::SectionTypeZeroFillLarge);
Preston Gurdc68dda82012-04-12 20:13:57 +0000622 }
623
624 return object_error::success;
625}
626
Andrew Kaylor3a129c82012-10-10 01:41:33 +0000627error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
628 bool &Result) const {
629 // Consider using the code from isSectionText to look for __const sections.
630 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
631 // to use section attributes to distinguish code from data.
632
633 // FIXME: Unimplemented.
634 Result = false;
635 return object_error::success;
636}
637
Benjamin Kramer07ea23a2011-07-15 18:39:21 +0000638error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
639 DataRefImpl Symb,
640 bool &Result) const {
Michael J. Spencer1130a792011-10-17 20:19:29 +0000641 SymbolRef::Type ST;
Owen Andersoncd749882011-10-12 22:21:32 +0000642 getSymbolType(Symb, ST);
David Meyer2c677272012-02-29 02:11:55 +0000643 if (ST == SymbolRef::ST_Unknown) {
Owen Andersoncd749882011-10-12 22:21:32 +0000644 Result = false;
645 return object_error::success;
646 }
647
648 uint64_t SectBegin, SectEnd;
649 getSectionAddress(Sec, SectBegin);
650 getSectionSize(Sec, SectEnd);
651 SectEnd += SectBegin;
652
Benjamin Kramer07ea23a2011-07-15 18:39:21 +0000653 if (MachOObj->is64Bit()) {
654 InMemoryStruct<macho::Symbol64TableEntry> Entry;
655 getSymbol64TableEntry(Symb, Entry);
Owen Andersoncd749882011-10-12 22:21:32 +0000656 uint64_t SymAddr= Entry->Value;
657 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
Benjamin Kramer07ea23a2011-07-15 18:39:21 +0000658 } else {
659 InMemoryStruct<macho::SymbolTableEntry> Entry;
660 getSymbolTableEntry(Symb, Entry);
Owen Andersoncd749882011-10-12 22:21:32 +0000661 uint64_t SymAddr= Entry->Value;
662 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
Benjamin Kramer07ea23a2011-07-15 18:39:21 +0000663 }
Owen Andersoncd749882011-10-12 22:21:32 +0000664
Benjamin Kramer07ea23a2011-07-15 18:39:21 +0000665 return object_error::success;
666}
667
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000668relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
669 DataRefImpl ret;
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000670 ret.d.b = getSectionIndex(Sec);
671 return relocation_iterator(RelocationRef(ret, this));
672}
673relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
674 uint32_t last_reloc;
Jim Grosbach596e4742012-11-29 19:14:11 +0000675 if (is64BitLoadCommand(MachOObj.get(), Sec)) {
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000676 InMemoryStruct<macho::Section64> Sect;
677 getSection64(Sec, Sect);
678 last_reloc = Sect->NumRelocationTableEntries;
679 } else {
680 InMemoryStruct<macho::Section> Sect;
681 getSection(Sec, Sect);
682 last_reloc = Sect->NumRelocationTableEntries;
683 }
684 DataRefImpl ret;
685 ret.d.a = last_reloc;
686 ret.d.b = getSectionIndex(Sec);
687 return relocation_iterator(RelocationRef(ret, this));
688}
689
690section_iterator MachOObjectFile::begin_sections() const {
Eric Christopher6256b032011-04-22 03:19:48 +0000691 DataRefImpl DRI;
Eric Christopher6256b032011-04-22 03:19:48 +0000692 moveToNextSection(DRI);
693 return section_iterator(SectionRef(DRI, this));
694}
695
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000696section_iterator MachOObjectFile::end_sections() const {
Eric Christopher6256b032011-04-22 03:19:48 +0000697 DataRefImpl DRI;
698 DRI.d.a = MachOObj->getHeader().NumLoadCommands;
Eric Christopher6256b032011-04-22 03:19:48 +0000699 return section_iterator(SectionRef(DRI, this));
700}
701
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000702/*===-- Relocations -------------------------------------------------------===*/
703
704void MachOObjectFile::
705getRelocation(DataRefImpl Rel,
706 InMemoryStruct<macho::RelocationEntry> &Res) const {
707 uint32_t relOffset;
708 if (MachOObj->is64Bit()) {
709 InMemoryStruct<macho::Section64> Sect;
710 getSection64(Sections[Rel.d.b], Sect);
711 relOffset = Sect->RelocationTableOffset;
712 } else {
713 InMemoryStruct<macho::Section> Sect;
714 getSection(Sections[Rel.d.b], Sect);
715 relOffset = Sect->RelocationTableOffset;
716 }
717 MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res);
718}
719error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
720 RelocationRef &Res) const {
721 ++Rel.d.a;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000722 Res = RelocationRef(Rel, this);
723 return object_error::success;
724}
725error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
726 uint64_t &Res) const {
Owen Anderson0135fe12011-10-24 21:44:00 +0000727 const uint8_t* sectAddress = 0;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000728 if (MachOObj->is64Bit()) {
729 InMemoryStruct<macho::Section64> Sect;
730 getSection64(Sections[Rel.d.b], Sect);
Owen Anderson0135fe12011-10-24 21:44:00 +0000731 sectAddress += Sect->Address;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000732 } else {
733 InMemoryStruct<macho::Section> Sect;
734 getSection(Sections[Rel.d.b], Sect);
Owen Anderson0135fe12011-10-24 21:44:00 +0000735 sectAddress += Sect->Address;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000736 }
737 InMemoryStruct<macho::RelocationEntry> RE;
738 getRelocation(Rel, RE);
Owen Anderson1832f4d2011-10-26 20:42:54 +0000739
740 unsigned Arch = getArch();
741 bool isScattered = (Arch != Triple::x86_64) &&
742 (RE->Word0 & macho::RF_Scattered);
743 uint64_t RelAddr = 0;
Danil Malyshevb0436a72011-11-29 17:40:10 +0000744 if (isScattered)
Owen Anderson1832f4d2011-10-26 20:42:54 +0000745 RelAddr = RE->Word0 & 0xFFFFFF;
746 else
747 RelAddr = RE->Word0;
748
749 Res = reinterpret_cast<uintptr_t>(sectAddress + RelAddr);
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000750 return object_error::success;
751}
Danil Malyshevb0436a72011-11-29 17:40:10 +0000752error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
753 uint64_t &Res) const {
754 InMemoryStruct<macho::RelocationEntry> RE;
755 getRelocation(Rel, RE);
756
757 unsigned Arch = getArch();
758 bool isScattered = (Arch != Triple::x86_64) &&
759 (RE->Word0 & macho::RF_Scattered);
760 if (isScattered)
761 Res = RE->Word0 & 0xFFFFFF;
762 else
763 Res = RE->Word0;
764 return object_error::success;
765}
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000766error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
767 SymbolRef &Res) const {
768 InMemoryStruct<macho::RelocationEntry> RE;
769 getRelocation(Rel, RE);
770 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
771 bool isExtern = (RE->Word1 >> 27) & 1;
772
773 DataRefImpl Sym;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000774 moveToNextSymbol(Sym);
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000775 if (isExtern) {
776 for (unsigned i = 0; i < SymbolIdx; i++) {
777 Sym.d.b++;
778 moveToNextSymbol(Sym);
Nick Lewycky58856ea2011-09-09 00:16:50 +0000779 assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands &&
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000780 "Relocation symbol index out of range!");
781 }
782 }
783 Res = SymbolRef(Sym, this);
784 return object_error::success;
785}
786error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
Owen Anderson9472b8d2011-10-26 17:08:49 +0000787 uint64_t &Res) const {
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000788 InMemoryStruct<macho::RelocationEntry> RE;
789 getRelocation(Rel, RE);
Owen Andersonf8261e72011-10-26 17:10:22 +0000790 Res = RE->Word0;
791 Res <<= 32;
792 Res |= RE->Word1;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000793 return object_error::success;
794}
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000795error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
796 SmallVectorImpl<char> &Result) const {
Owen Anderson0135fe12011-10-24 21:44:00 +0000797 // TODO: Support scattered relocations.
798 StringRef res;
799 InMemoryStruct<macho::RelocationEntry> RE;
800 getRelocation(Rel, RE);
Owen Anderson0135fe12011-10-24 21:44:00 +0000801
802 unsigned Arch = getArch();
Owen Anderson1832f4d2011-10-26 20:42:54 +0000803 bool isScattered = (Arch != Triple::x86_64) &&
804 (RE->Word0 & macho::RF_Scattered);
805
806 unsigned r_type;
807 if (isScattered)
808 r_type = (RE->Word0 >> 24) & 0xF;
809 else
810 r_type = (RE->Word1 >> 28) & 0xF;
811
Owen Anderson0135fe12011-10-24 21:44:00 +0000812 switch (Arch) {
813 case Triple::x86: {
Craig Toppere3298102012-05-24 06:35:32 +0000814 static const char *const Table[] = {
Owen Anderson0135fe12011-10-24 21:44:00 +0000815 "GENERIC_RELOC_VANILLA",
816 "GENERIC_RELOC_PAIR",
817 "GENERIC_RELOC_SECTDIFF",
Owen Andersoneb6bd332011-10-27 20:46:09 +0000818 "GENERIC_RELOC_PB_LA_PTR",
Owen Anderson0135fe12011-10-24 21:44:00 +0000819 "GENERIC_RELOC_LOCAL_SECTDIFF",
Owen Andersoneb6bd332011-10-27 20:46:09 +0000820 "GENERIC_RELOC_TLV" };
Owen Anderson0135fe12011-10-24 21:44:00 +0000821
Owen Andersoneb6bd332011-10-27 20:46:09 +0000822 if (r_type > 6)
Owen Anderson0135fe12011-10-24 21:44:00 +0000823 res = "Unknown";
824 else
825 res = Table[r_type];
826 break;
827 }
828 case Triple::x86_64: {
Craig Toppere3298102012-05-24 06:35:32 +0000829 static const char *const Table[] = {
Owen Andersond8fa76d2011-10-24 23:20:07 +0000830 "X86_64_RELOC_UNSIGNED",
831 "X86_64_RELOC_SIGNED",
Owen Anderson0135fe12011-10-24 21:44:00 +0000832 "X86_64_RELOC_BRANCH",
833 "X86_64_RELOC_GOT_LOAD",
834 "X86_64_RELOC_GOT",
Owen Andersond8fa76d2011-10-24 23:20:07 +0000835 "X86_64_RELOC_SUBTRACTOR",
836 "X86_64_RELOC_SIGNED_1",
837 "X86_64_RELOC_SIGNED_2",
838 "X86_64_RELOC_SIGNED_4",
839 "X86_64_RELOC_TLV" };
Owen Anderson0135fe12011-10-24 21:44:00 +0000840
Owen Andersond8fa76d2011-10-24 23:20:07 +0000841 if (r_type > 9)
Owen Anderson0135fe12011-10-24 21:44:00 +0000842 res = "Unknown";
843 else
844 res = Table[r_type];
845 break;
846 }
847 case Triple::arm: {
Craig Toppere3298102012-05-24 06:35:32 +0000848 static const char *const Table[] = {
Owen Anderson0135fe12011-10-24 21:44:00 +0000849 "ARM_RELOC_VANILLA",
850 "ARM_RELOC_PAIR",
851 "ARM_RELOC_SECTDIFF",
852 "ARM_RELOC_LOCAL_SECTDIFF",
853 "ARM_RELOC_PB_LA_PTR",
854 "ARM_RELOC_BR24",
855 "ARM_THUMB_RELOC_BR22",
856 "ARM_THUMB_32BIT_BRANCH",
857 "ARM_RELOC_HALF",
858 "ARM_RELOC_HALF_SECTDIFF" };
859
860 if (r_type > 9)
861 res = "Unknown";
862 else
863 res = Table[r_type];
864 break;
865 }
866 case Triple::ppc: {
Craig Toppere3298102012-05-24 06:35:32 +0000867 static const char *const Table[] = {
Owen Anderson0135fe12011-10-24 21:44:00 +0000868 "PPC_RELOC_VANILLA",
869 "PPC_RELOC_PAIR",
870 "PPC_RELOC_BR14",
871 "PPC_RELOC_BR24",
872 "PPC_RELOC_HI16",
873 "PPC_RELOC_LO16",
874 "PPC_RELOC_HA16",
875 "PPC_RELOC_LO14",
876 "PPC_RELOC_SECTDIFF",
877 "PPC_RELOC_PB_LA_PTR",
878 "PPC_RELOC_HI16_SECTDIFF",
879 "PPC_RELOC_LO16_SECTDIFF",
880 "PPC_RELOC_HA16_SECTDIFF",
881 "PPC_RELOC_JBSR",
882 "PPC_RELOC_LO14_SECTDIFF",
883 "PPC_RELOC_LOCAL_SECTDIFF" };
884
885 res = Table[r_type];
886 break;
887 }
888 case Triple::UnknownArch:
889 res = "Unknown";
890 break;
891 }
Owen Anderson5f4e02c2011-10-24 20:19:18 +0000892 Result.append(res.begin(), res.end());
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000893 return object_error::success;
894}
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000895error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
896 int64_t &Res) const {
897 InMemoryStruct<macho::RelocationEntry> RE;
898 getRelocation(Rel, RE);
899 bool isExtern = (RE->Word1 >> 27) & 1;
900 Res = 0;
901 if (!isExtern) {
902 const uint8_t* sectAddress = base();
903 if (MachOObj->is64Bit()) {
904 InMemoryStruct<macho::Section64> Sect;
905 getSection64(Sections[Rel.d.b], Sect);
906 sectAddress += Sect->Offset;
907 } else {
908 InMemoryStruct<macho::Section> Sect;
909 getSection(Sections[Rel.d.b], Sect);
910 sectAddress += Sect->Offset;
911 }
912 Res = reinterpret_cast<uintptr_t>(sectAddress);
913 }
914 return object_error::success;
915}
Owen Andersond8fa76d2011-10-24 23:20:07 +0000916
917// Helper to advance a section or symbol iterator multiple increments at a time.
918template<class T>
919error_code advance(T &it, size_t Val) {
920 error_code ec;
921 while (Val--) {
922 it.increment(ec);
923 }
924 return ec;
925}
926
927template<class T>
928void advanceTo(T &it, size_t Val) {
929 if (error_code ec = advance(it, Val))
930 report_fatal_error(ec.message());
931}
932
Owen Anderson1832f4d2011-10-26 20:42:54 +0000933void MachOObjectFile::printRelocationTargetName(
934 InMemoryStruct<macho::RelocationEntry>& RE,
935 raw_string_ostream &fmt) const {
936 unsigned Arch = getArch();
937 bool isScattered = (Arch != Triple::x86_64) &&
938 (RE->Word0 & macho::RF_Scattered);
939
940 // Target of a scattered relocation is an address. In the interest of
941 // generating pretty output, scan through the symbol table looking for a
942 // symbol that aligns with that address. If we find one, print it.
943 // Otherwise, we just print the hex address of the target.
944 if (isScattered) {
945 uint32_t Val = RE->Word1;
946
947 error_code ec;
948 for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
949 SI.increment(ec)) {
950 if (ec) report_fatal_error(ec.message());
951
952 uint64_t Addr;
953 StringRef Name;
954
955 if ((ec = SI->getAddress(Addr)))
956 report_fatal_error(ec.message());
957 if (Addr != Val) continue;
958 if ((ec = SI->getName(Name)))
959 report_fatal_error(ec.message());
960 fmt << Name;
961 return;
962 }
963
Owen Andersonb28bdbf2011-10-27 21:53:50 +0000964 // If we couldn't find a symbol that this relocation refers to, try
965 // to find a section beginning instead.
966 for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
967 SI.increment(ec)) {
968 if (ec) report_fatal_error(ec.message());
969
970 uint64_t Addr;
971 StringRef Name;
972
973 if ((ec = SI->getAddress(Addr)))
974 report_fatal_error(ec.message());
975 if (Addr != Val) continue;
976 if ((ec = SI->getName(Name)))
977 report_fatal_error(ec.message());
978 fmt << Name;
979 return;
980 }
981
Owen Anderson1832f4d2011-10-26 20:42:54 +0000982 fmt << format("0x%x", Val);
983 return;
984 }
985
986 StringRef S;
987 bool isExtern = (RE->Word1 >> 27) & 1;
988 uint32_t Val = RE->Word1 & 0xFFFFFF;
Owen Andersond8fa76d2011-10-24 23:20:07 +0000989
990 if (isExtern) {
991 symbol_iterator SI = begin_symbols();
992 advanceTo(SI, Val);
Owen Anderson1832f4d2011-10-26 20:42:54 +0000993 SI->getName(S);
Owen Andersond8fa76d2011-10-24 23:20:07 +0000994 } else {
995 section_iterator SI = begin_sections();
996 advanceTo(SI, Val);
Owen Anderson1832f4d2011-10-26 20:42:54 +0000997 SI->getName(S);
Owen Andersond8fa76d2011-10-24 23:20:07 +0000998 }
999
Owen Anderson1832f4d2011-10-26 20:42:54 +00001000 fmt << S;
Owen Andersond8fa76d2011-10-24 23:20:07 +00001001}
1002
Michael J. Spencer4344b1e2011-10-07 19:25:32 +00001003error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
1004 SmallVectorImpl<char> &Result) const {
Owen Anderson0135fe12011-10-24 21:44:00 +00001005 InMemoryStruct<macho::RelocationEntry> RE;
1006 getRelocation(Rel, RE);
1007
Owen Anderson1832f4d2011-10-26 20:42:54 +00001008 unsigned Arch = getArch();
1009 bool isScattered = (Arch != Triple::x86_64) &&
1010 (RE->Word0 & macho::RF_Scattered);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001011
Owen Anderson013d7562011-10-25 18:48:41 +00001012 std::string fmtbuf;
1013 raw_string_ostream fmt(fmtbuf);
1014
Owen Anderson1832f4d2011-10-26 20:42:54 +00001015 unsigned Type;
1016 if (isScattered)
1017 Type = (RE->Word0 >> 24) & 0xF;
1018 else
1019 Type = (RE->Word1 >> 28) & 0xF;
1020
Owen Andersoneb6bd332011-10-27 20:46:09 +00001021 bool isPCRel;
1022 if (isScattered)
1023 isPCRel = ((RE->Word0 >> 30) & 1);
1024 else
1025 isPCRel = ((RE->Word1 >> 24) & 1);
1026
Owen Andersond8fa76d2011-10-24 23:20:07 +00001027 // Determine any addends that should be displayed with the relocation.
1028 // These require decoding the relocation type, which is triple-specific.
Owen Andersond8fa76d2011-10-24 23:20:07 +00001029
1030 // X86_64 has entirely custom relocation types.
1031 if (Arch == Triple::x86_64) {
Owen Anderson929e27c2011-10-26 17:05:20 +00001032 bool isPCRel = ((RE->Word1 >> 24) & 1);
Owen Anderson013d7562011-10-25 18:48:41 +00001033
Owen Andersond8fa76d2011-10-24 23:20:07 +00001034 switch (Type) {
Owen Anderson1832f4d2011-10-26 20:42:54 +00001035 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
1036 case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
1037 printRelocationTargetName(RE, fmt);
1038 fmt << "@GOT";
Owen Anderson929e27c2011-10-26 17:05:20 +00001039 if (isPCRel) fmt << "PCREL";
1040 break;
1041 }
Owen Anderson1832f4d2011-10-26 20:42:54 +00001042 case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
Owen Anderson013d7562011-10-25 18:48:41 +00001043 InMemoryStruct<macho::RelocationEntry> RENext;
1044 DataRefImpl RelNext = Rel;
1045 RelNext.d.a++;
1046 getRelocation(RelNext, RENext);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001047
1048 // X86_64_SUBTRACTOR must be followed by a relocation of type
1049 // X86_64_RELOC_UNSIGNED.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001050 // NOTE: Scattered relocations don't exist on x86_64.
Owen Anderson013d7562011-10-25 18:48:41 +00001051 unsigned RType = (RENext->Word1 >> 28) & 0xF;
Owen Andersond8fa76d2011-10-24 23:20:07 +00001052 if (RType != 0)
1053 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1054 "X86_64_RELOC_SUBTRACTOR.");
1055
Owen Andersonef22f782011-10-26 17:28:49 +00001056 // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
1057 // X86_64_SUBTRACTOR contains to the subtrahend.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001058 printRelocationTargetName(RENext, fmt);
1059 fmt << "-";
1060 printRelocationTargetName(RE, fmt);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001061 }
Owen Andersoneb6bd332011-10-27 20:46:09 +00001062 case macho::RIT_X86_64_TLV:
1063 printRelocationTargetName(RE, fmt);
1064 fmt << "@TLV";
1065 if (isPCRel) fmt << "P";
1066 break;
Owen Anderson1832f4d2011-10-26 20:42:54 +00001067 case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
1068 printRelocationTargetName(RE, fmt);
1069 fmt << "-1";
Owen Andersond8fa76d2011-10-24 23:20:07 +00001070 break;
Owen Anderson1832f4d2011-10-26 20:42:54 +00001071 case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
1072 printRelocationTargetName(RE, fmt);
1073 fmt << "-2";
Owen Andersond8fa76d2011-10-24 23:20:07 +00001074 break;
Owen Anderson1832f4d2011-10-26 20:42:54 +00001075 case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
1076 printRelocationTargetName(RE, fmt);
1077 fmt << "-4";
Owen Anderson013d7562011-10-25 18:48:41 +00001078 break;
1079 default:
Owen Anderson1832f4d2011-10-26 20:42:54 +00001080 printRelocationTargetName(RE, fmt);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001081 break;
1082 }
Owen Andersond8fa76d2011-10-24 23:20:07 +00001083 // X86 and ARM share some relocation types in common.
Owen Anderson013d7562011-10-25 18:48:41 +00001084 } else if (Arch == Triple::x86 || Arch == Triple::arm) {
1085 // Generic relocation types...
Owen Andersond8fa76d2011-10-24 23:20:07 +00001086 switch (Type) {
Owen Anderson1832f4d2011-10-26 20:42:54 +00001087 case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
Owen Andersond8fa76d2011-10-24 23:20:07 +00001088 return object_error::success;
Owen Andersoneb6bd332011-10-27 20:46:09 +00001089 case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
Owen Anderson013d7562011-10-25 18:48:41 +00001090 InMemoryStruct<macho::RelocationEntry> RENext;
1091 DataRefImpl RelNext = Rel;
1092 RelNext.d.a++;
1093 getRelocation(RelNext, RENext);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001094
1095 // X86 sect diff's must be followed by a relocation of type
1096 // GENERIC_RELOC_PAIR.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001097 bool isNextScattered = (Arch != Triple::x86_64) &&
1098 (RENext->Word0 & macho::RF_Scattered);
1099 unsigned RType;
1100 if (isNextScattered)
1101 RType = (RENext->Word0 >> 24) & 0xF;
1102 else
1103 RType = (RENext->Word1 >> 28) & 0xF;
Owen Andersond8fa76d2011-10-24 23:20:07 +00001104 if (RType != 1)
1105 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
Owen Andersoneb6bd332011-10-27 20:46:09 +00001106 "GENERIC_RELOC_SECTDIFF.");
Owen Andersond8fa76d2011-10-24 23:20:07 +00001107
Owen Anderson1832f4d2011-10-26 20:42:54 +00001108 printRelocationTargetName(RE, fmt);
1109 fmt << "-";
1110 printRelocationTargetName(RENext, fmt);
Owen Anderson013d7562011-10-25 18:48:41 +00001111 break;
Owen Andersond8fa76d2011-10-24 23:20:07 +00001112 }
1113 }
Owen Anderson013d7562011-10-25 18:48:41 +00001114
Owen Anderson1832f4d2011-10-26 20:42:54 +00001115 if (Arch == Triple::x86) {
Owen Anderson013d7562011-10-25 18:48:41 +00001116 // All X86 relocations that need special printing were already
1117 // handled in the generic code.
Owen Andersoneb6bd332011-10-27 20:46:09 +00001118 switch (Type) {
1119 case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
1120 InMemoryStruct<macho::RelocationEntry> RENext;
1121 DataRefImpl RelNext = Rel;
1122 RelNext.d.a++;
1123 getRelocation(RelNext, RENext);
1124
1125 // X86 sect diff's must be followed by a relocation of type
1126 // GENERIC_RELOC_PAIR.
1127 bool isNextScattered = (Arch != Triple::x86_64) &&
1128 (RENext->Word0 & macho::RF_Scattered);
1129 unsigned RType;
1130 if (isNextScattered)
1131 RType = (RENext->Word0 >> 24) & 0xF;
1132 else
1133 RType = (RENext->Word1 >> 28) & 0xF;
1134 if (RType != 1)
1135 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1136 "GENERIC_RELOC_LOCAL_SECTDIFF.");
1137
1138 printRelocationTargetName(RE, fmt);
1139 fmt << "-";
1140 printRelocationTargetName(RENext, fmt);
1141 break;
1142 }
1143 case macho::RIT_Generic_TLV: {
1144 printRelocationTargetName(RE, fmt);
1145 fmt << "@TLV";
1146 if (isPCRel) fmt << "P";
1147 break;
1148 }
1149 default:
1150 printRelocationTargetName(RE, fmt);
1151 }
Owen Anderson013d7562011-10-25 18:48:41 +00001152 } else { // ARM-specific relocations
1153 switch (Type) {
Owen Anderson1832f4d2011-10-26 20:42:54 +00001154 case macho::RIT_ARM_Half: // ARM_RELOC_HALF
1155 case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
Owen Anderson013d7562011-10-25 18:48:41 +00001156 // Half relocations steal a bit from the length field to encode
1157 // whether this is an upper16 or a lower16 relocation.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001158 bool isUpper;
1159 if (isScattered)
1160 isUpper = (RE->Word0 >> 28) & 1;
Owen Anderson013d7562011-10-25 18:48:41 +00001161 else
Owen Anderson1832f4d2011-10-26 20:42:54 +00001162 isUpper = (RE->Word1 >> 25) & 1;
1163
1164 if (isUpper)
1165 fmt << ":upper16:(";
1166 else
1167 fmt << ":lower16:(";
1168 printRelocationTargetName(RE, fmt);
Owen Anderson013d7562011-10-25 18:48:41 +00001169
1170 InMemoryStruct<macho::RelocationEntry> RENext;
1171 DataRefImpl RelNext = Rel;
1172 RelNext.d.a++;
1173 getRelocation(RelNext, RENext);
1174
1175 // ARM half relocs must be followed by a relocation of type
1176 // ARM_RELOC_PAIR.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001177 bool isNextScattered = (Arch != Triple::x86_64) &&
1178 (RENext->Word0 & macho::RF_Scattered);
1179 unsigned RType;
1180 if (isNextScattered)
1181 RType = (RENext->Word0 >> 24) & 0xF;
1182 else
1183 RType = (RENext->Word1 >> 28) & 0xF;
1184
Owen Anderson013d7562011-10-25 18:48:41 +00001185 if (RType != 1)
1186 report_fatal_error("Expected ARM_RELOC_PAIR after "
1187 "GENERIC_RELOC_HALF");
1188
Owen Anderson1832f4d2011-10-26 20:42:54 +00001189 // NOTE: The half of the target virtual address is stashed in the
1190 // address field of the secondary relocation, but we can't reverse
1191 // engineer the constant offset from it without decoding the movw/movt
1192 // instruction to find the other half in its immediate field.
Owen Anderson013d7562011-10-25 18:48:41 +00001193
1194 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1195 // symbol/section pointer of the follow-on relocation.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001196 if (Type == macho::RIT_ARM_HalfDifference) {
1197 fmt << "-";
1198 printRelocationTargetName(RENext, fmt);
Owen Anderson013d7562011-10-25 18:48:41 +00001199 }
1200
Owen Anderson013d7562011-10-25 18:48:41 +00001201 fmt << ")";
1202 break;
1203 }
1204 default: {
Owen Anderson1832f4d2011-10-26 20:42:54 +00001205 printRelocationTargetName(RE, fmt);
Owen Anderson013d7562011-10-25 18:48:41 +00001206 }
1207 }
1208 }
Owen Anderson1832f4d2011-10-26 20:42:54 +00001209 } else
1210 printRelocationTargetName(RE, fmt);
Owen Andersond8fa76d2011-10-24 23:20:07 +00001211
Owen Anderson0135fe12011-10-24 21:44:00 +00001212 fmt.flush();
1213 Result.append(fmtbuf.begin(), fmtbuf.end());
Michael J. Spencer4344b1e2011-10-07 19:25:32 +00001214 return object_error::success;
Benjamin Kramer0fcab072011-09-08 20:52:17 +00001215}
1216
Owen Anderson0685e942011-10-25 20:35:53 +00001217error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
1218 bool &Result) const {
1219 InMemoryStruct<macho::RelocationEntry> RE;
1220 getRelocation(Rel, RE);
1221
Owen Anderson0685e942011-10-25 20:35:53 +00001222 unsigned Arch = getArch();
Owen Anderson1832f4d2011-10-26 20:42:54 +00001223 bool isScattered = (Arch != Triple::x86_64) &&
1224 (RE->Word0 & macho::RF_Scattered);
1225 unsigned Type;
1226 if (isScattered)
1227 Type = (RE->Word0 >> 24) & 0xF;
1228 else
1229 Type = (RE->Word1 >> 28) & 0xF;
Owen Anderson0685e942011-10-25 20:35:53 +00001230
1231 Result = false;
1232
1233 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1234 // is always hidden.
1235 if (Arch == Triple::x86 || Arch == Triple::arm) {
Owen Anderson1832f4d2011-10-26 20:42:54 +00001236 if (Type == macho::RIT_Pair) Result = true;
Owen Anderson0685e942011-10-25 20:35:53 +00001237 } else if (Arch == Triple::x86_64) {
1238 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1239 // an X864_64_RELOC_SUBTRACTOR.
Owen Anderson1832f4d2011-10-26 20:42:54 +00001240 if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
Owen Anderson0685e942011-10-25 20:35:53 +00001241 DataRefImpl RelPrev = Rel;
1242 RelPrev.d.a--;
1243 InMemoryStruct<macho::RelocationEntry> REPrev;
1244 getRelocation(RelPrev, REPrev);
1245
1246 unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
1247
Owen Anderson1832f4d2011-10-26 20:42:54 +00001248 if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
Owen Anderson0685e942011-10-25 20:35:53 +00001249 }
1250 }
1251
1252 return object_error::success;
1253}
1254
David Meyer5c2b4ea2012-03-01 01:36:50 +00001255error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1256 LibraryRef &Res) const {
1257 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1258}
1259
1260error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1261 StringRef &Res) const {
1262 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1263}
1264
1265
Eric Christopher6256b032011-04-22 03:19:48 +00001266/*===-- Miscellaneous -----------------------------------------------------===*/
1267
1268uint8_t MachOObjectFile::getBytesInAddress() const {
1269 return MachOObj->is64Bit() ? 8 : 4;
1270}
1271
1272StringRef MachOObjectFile::getFileFormatName() const {
1273 if (!MachOObj->is64Bit()) {
1274 switch (MachOObj->getHeader().CPUType) {
Eric Christopherf4b2f932011-04-22 06:34:01 +00001275 case llvm::MachO::CPUTypeI386:
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001276 return "Mach-O 32-bit i386";
Eric Christopherf4b2f932011-04-22 06:34:01 +00001277 case llvm::MachO::CPUTypeARM:
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001278 return "Mach-O arm";
Eric Christopherf4b2f932011-04-22 06:34:01 +00001279 case llvm::MachO::CPUTypePowerPC:
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001280 return "Mach-O 32-bit ppc";
1281 default:
Eric Christopherf4b2f932011-04-22 06:34:01 +00001282 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 &&
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001283 "64-bit object file when we're not 64-bit?");
1284 return "Mach-O 32-bit unknown";
Eric Christopher6256b032011-04-22 03:19:48 +00001285 }
1286 }
1287
1288 switch (MachOObj->getHeader().CPUType) {
Eric Christopherf4b2f932011-04-22 06:34:01 +00001289 case llvm::MachO::CPUTypeX86_64:
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001290 return "Mach-O 64-bit x86-64";
Eric Christopherf4b2f932011-04-22 06:34:01 +00001291 case llvm::MachO::CPUTypePowerPC64:
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001292 return "Mach-O 64-bit ppc64";
Eric Christopher6256b032011-04-22 03:19:48 +00001293 default:
Eric Christopherf4b2f932011-04-22 06:34:01 +00001294 assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 &&
Eric Christopher9ab1d7f2011-04-22 04:08:58 +00001295 "32-bit object file when we're 64-bit?");
1296 return "Mach-O 64-bit unknown";
Eric Christopher6256b032011-04-22 03:19:48 +00001297 }
1298}
1299
1300unsigned MachOObjectFile::getArch() const {
1301 switch (MachOObj->getHeader().CPUType) {
Eric Christopherf4b2f932011-04-22 06:34:01 +00001302 case llvm::MachO::CPUTypeI386:
Eric Christopher6256b032011-04-22 03:19:48 +00001303 return Triple::x86;
Eric Christopherf4b2f932011-04-22 06:34:01 +00001304 case llvm::MachO::CPUTypeX86_64:
Eric Christopher6256b032011-04-22 03:19:48 +00001305 return Triple::x86_64;
Eric Christopherf4b2f932011-04-22 06:34:01 +00001306 case llvm::MachO::CPUTypeARM:
Eric Christopher6256b032011-04-22 03:19:48 +00001307 return Triple::arm;
Eric Christopherf4b2f932011-04-22 06:34:01 +00001308 case llvm::MachO::CPUTypePowerPC:
Eric Christopher6256b032011-04-22 03:19:48 +00001309 return Triple::ppc;
Eric Christopherf4b2f932011-04-22 06:34:01 +00001310 case llvm::MachO::CPUTypePowerPC64:
Eric Christopher6256b032011-04-22 03:19:48 +00001311 return Triple::ppc64;
1312 default:
1313 return Triple::UnknownArch;
1314 }
1315}
1316
Owen Andersonf7c93a32011-10-11 17:32:27 +00001317} // end namespace object
Eric Christopher6256b032011-04-22 03:19:48 +00001318} // end namespace llvm