blob: 00599efce05ef97adee8a6aebe2016d1deee5eeb [file] [log] [blame]
Eric Christopher7b015c72011-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
Owen Anderson27c579d2011-10-11 17:32:27 +000015#include "llvm/Object/MachO.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "llvm/ADT/Triple.h"
Rafael Espindola421305a2013-04-07 20:01:29 +000017#include "llvm/Support/DataExtractor.h"
Owen Andersonbc14bd32011-10-26 20:42:54 +000018#include "llvm/Support/Format.h"
Rafael Espindola56f976f2013-04-18 18:08:55 +000019#include "llvm/Support/Host.h"
Eric Christopher7b015c72011-04-22 03:19:48 +000020#include "llvm/Support/MemoryBuffer.h"
Jakub Staszak84a0ae72013-08-21 01:20:11 +000021#include "llvm/Support/raw_ostream.h"
Eric Christopher7b015c72011-04-22 03:19:48 +000022#include <cctype>
23#include <cstring>
24#include <limits>
25
26using namespace llvm;
27using namespace object;
28
29namespace llvm {
Owen Anderson27c579d2011-10-11 17:32:27 +000030namespace object {
Eric Christopher7b015c72011-04-22 03:19:48 +000031
Charles Davis8bdfafd2013-09-01 04:28:48 +000032struct nlist_base {
33 uint32_t n_strx;
34 uint8_t n_type;
35 uint8_t n_sect;
36 uint16_t n_desc;
Rafael Espindola56f976f2013-04-18 18:08:55 +000037};
38
Charles Davis8bdfafd2013-09-01 04:28:48 +000039struct section_base {
40 char sectname[16];
41 char segname[16];
Rafael Espindola56f976f2013-04-18 18:08:55 +000042};
43
44template<typename T>
45static void SwapValue(T &Value) {
46 Value = sys::SwapByteOrder(Value);
Benjamin Kramer022ecdf2011-09-08 20:52:17 +000047}
48
Rafael Espindola56f976f2013-04-18 18:08:55 +000049template<typename T>
50static void SwapStruct(T &Value);
51
52template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000053void SwapStruct(MachO::any_relocation_info &H) {
54 SwapValue(H.r_word0);
55 SwapValue(H.r_word1);
Rafael Espindola5ffc0792013-04-07 16:07:35 +000056}
57
Rafael Espindola56f976f2013-04-18 18:08:55 +000058template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000059void SwapStruct(MachO::load_command &L) {
60 SwapValue(L.cmd);
61 SwapValue(L.cmdsize);
Rafael Espindola56f976f2013-04-18 18:08:55 +000062}
Rafael Espindola421305a2013-04-07 20:01:29 +000063
Rafael Espindola56f976f2013-04-18 18:08:55 +000064template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000065void SwapStruct(nlist_base &S) {
66 SwapValue(S.n_strx);
67 SwapValue(S.n_desc);
Rafael Espindola56f976f2013-04-18 18:08:55 +000068}
69
70template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000071void SwapStruct(MachO::section &S) {
72 SwapValue(S.addr);
73 SwapValue(S.size);
74 SwapValue(S.offset);
75 SwapValue(S.align);
76 SwapValue(S.reloff);
77 SwapValue(S.nreloc);
78 SwapValue(S.flags);
79 SwapValue(S.reserved1);
80 SwapValue(S.reserved2);
Rafael Espindola56f976f2013-04-18 18:08:55 +000081}
82
83template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000084void SwapStruct(MachO::section_64 &S) {
85 SwapValue(S.addr);
86 SwapValue(S.size);
87 SwapValue(S.offset);
88 SwapValue(S.align);
89 SwapValue(S.reloff);
90 SwapValue(S.nreloc);
91 SwapValue(S.flags);
92 SwapValue(S.reserved1);
93 SwapValue(S.reserved2);
94 SwapValue(S.reserved3);
Rafael Espindola56f976f2013-04-18 18:08:55 +000095}
96
97template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +000098void SwapStruct(MachO::nlist &S) {
99 SwapValue(S.n_strx);
100 SwapValue(S.n_desc);
101 SwapValue(S.n_value);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000102}
103
104template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000105void SwapStruct(MachO::nlist_64 &S) {
106 SwapValue(S.n_strx);
107 SwapValue(S.n_desc);
108 SwapValue(S.n_value);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000109}
110
111template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000112void SwapStruct(MachO::mach_header &H) {
113 SwapValue(H.magic);
114 SwapValue(H.cputype);
115 SwapValue(H.cpusubtype);
116 SwapValue(H.filetype);
117 SwapValue(H.ncmds);
118 SwapValue(H.sizeofcmds);
119 SwapValue(H.flags);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000120}
121
122template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000123void SwapStruct(MachO::mach_header_64 &H) {
124 SwapValue(H.magic);
125 SwapValue(H.cputype);
126 SwapValue(H.cpusubtype);
127 SwapValue(H.filetype);
128 SwapValue(H.ncmds);
129 SwapValue(H.sizeofcmds);
130 SwapValue(H.flags);
131 SwapValue(H.reserved);
Rafael Espindola6e040c02013-04-26 20:07:33 +0000132}
133
134template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000135void SwapStruct(MachO::symtab_command &C) {
136 SwapValue(C.cmd);
137 SwapValue(C.cmdsize);
138 SwapValue(C.symoff);
139 SwapValue(C.nsyms);
140 SwapValue(C.stroff);
141 SwapValue(C.strsize);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000142}
143
144template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000145void SwapStruct(MachO::dysymtab_command &C) {
146 SwapValue(C.cmd);
147 SwapValue(C.cmdsize);
148 SwapValue(C.ilocalsym);
149 SwapValue(C.nlocalsym);
150 SwapValue(C.iextdefsym);
151 SwapValue(C.nextdefsym);
152 SwapValue(C.iundefsym);
153 SwapValue(C.nundefsym);
154 SwapValue(C.tocoff);
155 SwapValue(C.ntoc);
156 SwapValue(C.modtaboff);
157 SwapValue(C.nmodtab);
158 SwapValue(C.extrefsymoff);
159 SwapValue(C.nextrefsyms);
160 SwapValue(C.indirectsymoff);
161 SwapValue(C.nindirectsyms);
162 SwapValue(C.extreloff);
163 SwapValue(C.nextrel);
164 SwapValue(C.locreloff);
165 SwapValue(C.nlocrel);
Rafael Espindola6e040c02013-04-26 20:07:33 +0000166}
167
168template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000169void SwapStruct(MachO::linkedit_data_command &C) {
170 SwapValue(C.cmd);
171 SwapValue(C.cmdsize);
172 SwapValue(C.dataoff);
173 SwapValue(C.datasize);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000174}
175
176template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000177void SwapStruct(MachO::segment_command &C) {
178 SwapValue(C.cmd);
179 SwapValue(C.cmdsize);
180 SwapValue(C.vmaddr);
181 SwapValue(C.vmsize);
182 SwapValue(C.fileoff);
183 SwapValue(C.filesize);
184 SwapValue(C.maxprot);
185 SwapValue(C.initprot);
186 SwapValue(C.nsects);
187 SwapValue(C.flags);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000188}
189
190template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000191void SwapStruct(MachO::segment_command_64 &C) {
192 SwapValue(C.cmd);
193 SwapValue(C.cmdsize);
194 SwapValue(C.vmaddr);
195 SwapValue(C.vmsize);
196 SwapValue(C.fileoff);
197 SwapValue(C.filesize);
198 SwapValue(C.maxprot);
199 SwapValue(C.initprot);
200 SwapValue(C.nsects);
201 SwapValue(C.flags);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000202}
203
Rafael Espindola6e040c02013-04-26 20:07:33 +0000204template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000205void SwapStruct(uint32_t &C) {
206 SwapValue(C);
Rafael Espindola6e040c02013-04-26 20:07:33 +0000207}
208
209template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000210void SwapStruct(MachO::linker_options_command &C) {
211 SwapValue(C.cmd);
212 SwapValue(C.cmdsize);
213 SwapValue(C.count);
Rafael Espindola6e040c02013-04-26 20:07:33 +0000214}
215
216template<>
Charles Davis8bdfafd2013-09-01 04:28:48 +0000217void SwapStruct(MachO::data_in_code_entry &C) {
218 SwapValue(C.offset);
219 SwapValue(C.length);
220 SwapValue(C.kind);
Rafael Espindola6e040c02013-04-26 20:07:33 +0000221}
222
Rafael Espindola3cdeb172013-04-19 13:45:05 +0000223template<typename T>
224T getStruct(const MachOObjectFile *O, const char *P) {
225 T Cmd;
226 memcpy(&Cmd, P, sizeof(T));
227 if (O->isLittleEndian() != sys::IsLittleEndianHost)
228 SwapStruct(Cmd);
229 return Cmd;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000230}
231
Rafael Espindola56f976f2013-04-18 18:08:55 +0000232static uint32_t
233getSegmentLoadCommandNumSections(const MachOObjectFile *O,
234 const MachOObjectFile::LoadCommandInfo &L) {
235 if (O->is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000236 MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
237 return S.nsects;
Rafael Espindola421305a2013-04-07 20:01:29 +0000238 }
Charles Davis8bdfafd2013-09-01 04:28:48 +0000239 MachO::segment_command S = O->getSegmentLoadCommand(L);
240 return S.nsects;
Rafael Espindola5ffc0792013-04-07 16:07:35 +0000241}
242
Rafael Espindola6e040c02013-04-26 20:07:33 +0000243static const char *
244getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
245 unsigned Sec) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000246 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
247
248 bool Is64 = O->is64Bit();
Charles Davis8bdfafd2013-09-01 04:28:48 +0000249 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
250 sizeof(MachO::segment_command);
251 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
252 sizeof(MachO::section);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000253
254 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
Charles Davis1827bd82013-08-27 05:38:30 +0000255 return reinterpret_cast<const char*>(SectionAddr);
Rafael Espindola60689982013-04-07 19:05:30 +0000256}
257
Rafael Espindola56f976f2013-04-18 18:08:55 +0000258static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
259 return O->getData().substr(Offset, 1).data();
Rafael Espindola60689982013-04-07 19:05:30 +0000260}
261
Charles Davis8bdfafd2013-09-01 04:28:48 +0000262static nlist_base
Rafael Espindola56f976f2013-04-18 18:08:55 +0000263getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
Rafael Espindola75c30362013-04-24 19:47:55 +0000264 const char *P = reinterpret_cast<const char *>(DRI.p);
Charles Davis8bdfafd2013-09-01 04:28:48 +0000265 return getStruct<nlist_base>(O, P);
Eric Christopher7b015c72011-04-22 03:19:48 +0000266}
267
Rafael Espindola56f976f2013-04-18 18:08:55 +0000268static StringRef parseSegmentOrSectionName(const char *P) {
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000269 if (P[15] == 0)
270 // Null terminated.
271 return P;
272 // Not null terminated, so this is a 16 char string.
273 return StringRef(P, 16);
274}
275
Rafael Espindola56f976f2013-04-18 18:08:55 +0000276// Helper to advance a section or symbol iterator multiple increments at a time.
277template<class T>
Rafael Espindola5e812af2014-01-30 02:49:50 +0000278static void advance(T &it, size_t Val) {
279 while (Val--)
280 ++it;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000281}
282
283static unsigned getCPUType(const MachOObjectFile *O) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000284 return O->getHeader().cputype;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000285}
286
287static void printRelocationTargetName(const MachOObjectFile *O,
Charles Davis8bdfafd2013-09-01 04:28:48 +0000288 const MachO::any_relocation_info &RE,
Rafael Espindola56f976f2013-04-18 18:08:55 +0000289 raw_string_ostream &fmt) {
290 bool IsScattered = O->isRelocationScattered(RE);
291
292 // Target of a scattered relocation is an address. In the interest of
293 // generating pretty output, scan through the symbol table looking for a
294 // symbol that aligns with that address. If we find one, print it.
295 // Otherwise, we just print the hex address of the target.
296 if (IsScattered) {
297 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
298
Rafael Espindolab5155a52014-02-10 20:24:04 +0000299 for (symbol_iterator SI = O->symbol_begin(), SE = O->symbol_end();
Rafael Espindola5e812af2014-01-30 02:49:50 +0000300 SI != SE; ++SI) {
301 error_code ec;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000302 uint64_t Addr;
303 StringRef Name;
304
305 if ((ec = SI->getAddress(Addr)))
306 report_fatal_error(ec.message());
307 if (Addr != Val) continue;
308 if ((ec = SI->getName(Name)))
309 report_fatal_error(ec.message());
310 fmt << Name;
311 return;
312 }
313
314 // If we couldn't find a symbol that this relocation refers to, try
315 // to find a section beginning instead.
Rafael Espindolab5155a52014-02-10 20:24:04 +0000316 for (section_iterator SI = O->section_begin(), SE = O->section_end();
Rafael Espindola5e812af2014-01-30 02:49:50 +0000317 SI != SE; ++SI) {
318 error_code ec;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000319 uint64_t Addr;
320 StringRef Name;
321
322 if ((ec = SI->getAddress(Addr)))
323 report_fatal_error(ec.message());
324 if (Addr != Val) continue;
325 if ((ec = SI->getName(Name)))
326 report_fatal_error(ec.message());
327 fmt << Name;
328 return;
329 }
330
331 fmt << format("0x%x", Val);
332 return;
333 }
334
335 StringRef S;
336 bool isExtern = O->getPlainRelocationExternal(RE);
Ahmed Bougacha9dab0cc2013-05-14 22:41:29 +0000337 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000338
339 if (isExtern) {
Rafael Espindolab5155a52014-02-10 20:24:04 +0000340 symbol_iterator SI = O->symbol_begin();
Rafael Espindola5e812af2014-01-30 02:49:50 +0000341 advance(SI, Val);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000342 SI->getName(S);
343 } else {
Rafael Espindolab5155a52014-02-10 20:24:04 +0000344 section_iterator SI = O->section_begin();
Ahmed Bougacha9dab0cc2013-05-14 22:41:29 +0000345 // Adjust for the fact that sections are 1-indexed.
Rafael Espindola5e812af2014-01-30 02:49:50 +0000346 advance(SI, Val - 1);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000347 SI->getName(S);
348 }
349
350 fmt << S;
351}
352
Charles Davis8bdfafd2013-09-01 04:28:48 +0000353static uint32_t
354getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
355 return RE.r_word0;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000356}
357
358static unsigned
Charles Davis8bdfafd2013-09-01 04:28:48 +0000359getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
360 return RE.r_word0 & 0xffffff;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000361}
362
363static bool getPlainRelocationPCRel(const MachOObjectFile *O,
Charles Davis8bdfafd2013-09-01 04:28:48 +0000364 const MachO::any_relocation_info &RE) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000365 if (O->isLittleEndian())
Charles Davis8bdfafd2013-09-01 04:28:48 +0000366 return (RE.r_word1 >> 24) & 1;
367 return (RE.r_word1 >> 7) & 1;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000368}
369
370static bool
371getScatteredRelocationPCRel(const MachOObjectFile *O,
Charles Davis8bdfafd2013-09-01 04:28:48 +0000372 const MachO::any_relocation_info &RE) {
373 return (RE.r_word0 >> 30) & 1;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000374}
375
376static unsigned getPlainRelocationLength(const MachOObjectFile *O,
Charles Davis8bdfafd2013-09-01 04:28:48 +0000377 const MachO::any_relocation_info &RE) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000378 if (O->isLittleEndian())
Charles Davis8bdfafd2013-09-01 04:28:48 +0000379 return (RE.r_word1 >> 25) & 3;
380 return (RE.r_word1 >> 5) & 3;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000381}
382
383static unsigned
Charles Davis8bdfafd2013-09-01 04:28:48 +0000384getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
385 return (RE.r_word0 >> 28) & 3;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000386}
387
388static unsigned getPlainRelocationType(const MachOObjectFile *O,
Charles Davis8bdfafd2013-09-01 04:28:48 +0000389 const MachO::any_relocation_info &RE) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000390 if (O->isLittleEndian())
Charles Davis8bdfafd2013-09-01 04:28:48 +0000391 return RE.r_word1 >> 28;
392 return RE.r_word1 & 0xf;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000393}
394
Charles Davis8bdfafd2013-09-01 04:28:48 +0000395static unsigned
396getScatteredRelocationType(const MachO::any_relocation_info &RE) {
397 return (RE.r_word0 >> 24) & 0xf;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000398}
399
400static uint32_t getSectionFlags(const MachOObjectFile *O,
401 DataRefImpl Sec) {
402 if (O->is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000403 MachO::section_64 Sect = O->getSection64(Sec);
404 return Sect.flags;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000405 }
Charles Davis8bdfafd2013-09-01 04:28:48 +0000406 MachO::section Sect = O->getSection(Sec);
407 return Sect.flags;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000408}
409
Rafael Espindolaafcc3df2014-01-24 21:32:21 +0000410MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
411 bool Is64bits, error_code &EC,
412 bool BufferOwned)
413 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
Kevin Enderby273ae012013-06-06 17:20:50 +0000414 SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000415 uint32_t LoadCommandCount = this->getHeader().ncmds;
416 MachO::LoadCommandType SegmentLoadType = is64Bit() ?
417 MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000418
419 MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
Rafael Espindolafeef8c22013-04-19 11:36:47 +0000420 for (unsigned I = 0; ; ++I) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000421 if (Load.C.cmd == MachO::LC_SYMTAB) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000422 assert(!SymtabLoadCmd && "Multiple symbol tables");
423 SymtabLoadCmd = Load.Ptr;
Charles Davis8bdfafd2013-09-01 04:28:48 +0000424 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
Rafael Espindola6e040c02013-04-26 20:07:33 +0000425 assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
426 DysymtabLoadCmd = Load.Ptr;
Charles Davis8bdfafd2013-09-01 04:28:48 +0000427 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
Kevin Enderby273ae012013-06-06 17:20:50 +0000428 assert(!DataInCodeLoadCmd && "Multiple data in code tables");
429 DataInCodeLoadCmd = Load.Ptr;
Charles Davis8bdfafd2013-09-01 04:28:48 +0000430 } else if (Load.C.cmd == SegmentLoadType) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000431 uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
432 for (unsigned J = 0; J < NumSections; ++J) {
Rafael Espindola6e040c02013-04-26 20:07:33 +0000433 const char *Sec = getSectionPtr(this, Load, J);
434 Sections.push_back(Sec);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000435 }
436 }
Rafael Espindolafeef8c22013-04-19 11:36:47 +0000437
438 if (I == LoadCommandCount - 1)
439 break;
440 else
441 Load = getNextLoadCommandInfo(Load);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000442 }
443}
444
Rafael Espindola5e812af2014-01-30 02:49:50 +0000445void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Rafael Espindola75c30362013-04-24 19:47:55 +0000446 unsigned SymbolTableEntrySize = is64Bit() ?
Charles Davis8bdfafd2013-09-01 04:28:48 +0000447 sizeof(MachO::nlist_64) :
448 sizeof(MachO::nlist);
Rafael Espindola75c30362013-04-24 19:47:55 +0000449 Symb.p += SymbolTableEntrySize;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000450}
451
452error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
453 StringRef &Res) const {
Rafael Espindola6e040c02013-04-26 20:07:33 +0000454 StringRef StringTable = getStringTableData();
Charles Davis8bdfafd2013-09-01 04:28:48 +0000455 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
456 const char *Start = &StringTable.data()[Entry.n_strx];
Rafael Espindola56f976f2013-04-18 18:08:55 +0000457 Res = StringRef(Start);
458 return object_error::success;
459}
460
461error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
462 uint64_t &Res) const {
463 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000464 MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
465 Res = Entry.n_value;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000466 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000467 MachO::nlist Entry = getSymbolTableEntry(Symb);
468 Res = Entry.n_value;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000469 }
470 return object_error::success;
471}
472
473error_code
474MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
475 uint64_t &Res) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000476 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000477 getSymbolAddress(Symb, Res);
Charles Davis8bdfafd2013-09-01 04:28:48 +0000478 if (Entry.n_sect) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000479 uint64_t Delta;
480 DataRefImpl SecRel;
Charles Davis8bdfafd2013-09-01 04:28:48 +0000481 SecRel.d.a = Entry.n_sect-1;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000482 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000483 MachO::section_64 Sec = getSection64(SecRel);
484 Delta = Sec.offset - Sec.addr;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000485 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000486 MachO::section Sec = getSection(SecRel);
487 Delta = Sec.offset - Sec.addr;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000488 }
489
490 Res += Delta;
491 }
492
493 return object_error::success;
494}
495
Rafael Espindolae4dd2e02013-04-29 22:24:22 +0000496error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
497 uint32_t &Result) const {
Rafael Espindola20122a42014-01-31 20:57:12 +0000498 uint32_t flags = getSymbolFlags(DRI);
Rafael Espindolae4dd2e02013-04-29 22:24:22 +0000499 if (flags & SymbolRef::SF_Common) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000500 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
501 Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
Rafael Espindolae4dd2e02013-04-29 22:24:22 +0000502 } else {
503 Result = 0;
504 }
505 return object_error::success;
506}
507
Rafael Espindola56f976f2013-04-18 18:08:55 +0000508error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
509 uint64_t &Result) const {
510 uint64_t BeginOffset;
511 uint64_t EndOffset = 0;
512 uint8_t SectionIndex;
513
Charles Davis8bdfafd2013-09-01 04:28:48 +0000514 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000515 uint64_t Value;
516 getSymbolAddress(DRI, Value);
517
518 BeginOffset = Value;
519
Charles Davis8bdfafd2013-09-01 04:28:48 +0000520 SectionIndex = Entry.n_sect;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000521 if (!SectionIndex) {
Rafael Espindola20122a42014-01-31 20:57:12 +0000522 uint32_t flags = getSymbolFlags(DRI);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000523 if (flags & SymbolRef::SF_Common)
524 Result = Value;
525 else
526 Result = UnknownAddressOrSize;
527 return object_error::success;
528 }
529 // Unfortunately symbols are unsorted so we need to touch all
530 // symbols from load command
Rafael Espindolab5155a52014-02-10 20:24:04 +0000531 for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) {
Rafael Espindola75c30362013-04-24 19:47:55 +0000532 DataRefImpl DRI = I->getRawDataRefImpl();
Rafael Espindola56f976f2013-04-18 18:08:55 +0000533 Entry = getSymbolTableEntryBase(this, DRI);
534 getSymbolAddress(DRI, Value);
Charles Davis8bdfafd2013-09-01 04:28:48 +0000535 if (Entry.n_sect == SectionIndex && Value > BeginOffset)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000536 if (!EndOffset || Value < EndOffset)
537 EndOffset = Value;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000538 }
539 if (!EndOffset) {
540 uint64_t Size;
541 DataRefImpl Sec;
542 Sec.d.a = SectionIndex-1;
543 getSectionSize(Sec, Size);
544 getSectionAddress(Sec, EndOffset);
545 EndOffset += Size;
546 }
547 Result = EndOffset - BeginOffset;
548 return object_error::success;
549}
550
551error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
552 SymbolRef::Type &Res) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000553 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
554 uint8_t n_type = Entry.n_type;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000555
556 Res = SymbolRef::ST_Other;
557
558 // If this is a STAB debugging symbol, we can do nothing more.
Charles Davis74ec8b02013-08-27 05:00:13 +0000559 if (n_type & MachO::N_STAB) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000560 Res = SymbolRef::ST_Debug;
561 return object_error::success;
562 }
563
Charles Davis74ec8b02013-08-27 05:00:13 +0000564 switch (n_type & MachO::N_TYPE) {
565 case MachO::N_UNDF :
Rafael Espindola56f976f2013-04-18 18:08:55 +0000566 Res = SymbolRef::ST_Unknown;
567 break;
Charles Davis74ec8b02013-08-27 05:00:13 +0000568 case MachO::N_SECT :
Rafael Espindola56f976f2013-04-18 18:08:55 +0000569 Res = SymbolRef::ST_Function;
570 break;
571 }
572 return object_error::success;
573}
574
Rafael Espindola20122a42014-01-31 20:57:12 +0000575uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000576 nlist_base Entry = getSymbolTableEntryBase(this, DRI);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000577
Charles Davis8bdfafd2013-09-01 04:28:48 +0000578 uint8_t MachOType = Entry.n_type;
579 uint16_t MachOFlags = Entry.n_desc;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000580
Rafael Espindola20122a42014-01-31 20:57:12 +0000581 uint32_t Result = SymbolRef::SF_None;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000582
Charles Davis74ec8b02013-08-27 05:00:13 +0000583 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000584 Result |= SymbolRef::SF_Undefined;
585
Rafael Espindolaa1356322013-11-02 05:03:24 +0000586 if (MachOType & MachO::N_STAB)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000587 Result |= SymbolRef::SF_FormatSpecific;
588
Charles Davis74ec8b02013-08-27 05:00:13 +0000589 if (MachOType & MachO::N_EXT) {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000590 Result |= SymbolRef::SF_Global;
Charles Davis74ec8b02013-08-27 05:00:13 +0000591 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
Rafael Espindolae4dd2e02013-04-29 22:24:22 +0000592 uint64_t Value;
593 getSymbolAddress(DRI, Value);
594 if (Value)
595 Result |= SymbolRef::SF_Common;
596 }
Rafael Espindola56f976f2013-04-18 18:08:55 +0000597 }
598
Charles Davis74ec8b02013-08-27 05:00:13 +0000599 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
Rafael Espindola56f976f2013-04-18 18:08:55 +0000600 Result |= SymbolRef::SF_Weak;
601
Charles Davis74ec8b02013-08-27 05:00:13 +0000602 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000603 Result |= SymbolRef::SF_Absolute;
604
Rafael Espindola20122a42014-01-31 20:57:12 +0000605 return Result;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000606}
607
608error_code
609MachOObjectFile::getSymbolSection(DataRefImpl Symb,
610 section_iterator &Res) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000611 nlist_base Entry = getSymbolTableEntryBase(this, Symb);
612 uint8_t index = Entry.n_sect;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000613
614 if (index == 0) {
Rafael Espindolab5155a52014-02-10 20:24:04 +0000615 Res = section_end();
Rafael Espindola56f976f2013-04-18 18:08:55 +0000616 } else {
617 DataRefImpl DRI;
618 DRI.d.a = index - 1;
619 Res = section_iterator(SectionRef(DRI, this));
620 }
621
622 return object_error::success;
623}
624
625error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
Rafael Espindola137faa02013-04-24 15:14:22 +0000626 uint64_t &Val) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000627 report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
628}
629
Rafael Espindola5e812af2014-01-30 02:49:50 +0000630void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000631 Sec.d.a++;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000632}
633
634error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000635MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000636 ArrayRef<char> Raw = getSectionRawName(Sec);
637 Result = parseSegmentOrSectionName(Raw.data());
638 return object_error::success;
639}
640
641error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000642MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000643 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000644 MachO::section_64 Sect = getSection64(Sec);
645 Res = Sect.addr;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000646 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000647 MachO::section Sect = getSection(Sec);
648 Res = Sect.addr;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000649 }
650 return object_error::success;
651}
652
653error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000654MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000655 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000656 MachO::section_64 Sect = getSection64(Sec);
657 Res = Sect.size;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000658 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000659 MachO::section Sect = getSection(Sec);
660 Res = Sect.size;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000661 }
662
663 return object_error::success;
664}
665
666error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000667MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000668 uint32_t Offset;
669 uint64_t Size;
670
671 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000672 MachO::section_64 Sect = getSection64(Sec);
673 Offset = Sect.offset;
674 Size = Sect.size;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000675 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000676 MachO::section Sect = getSection(Sec);
677 Offset = Sect.offset;
678 Size = Sect.size;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000679 }
680
681 Res = this->getData().substr(Offset, Size);
682 return object_error::success;
683}
684
685error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000686MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000687 uint32_t Align;
688 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000689 MachO::section_64 Sect = getSection64(Sec);
690 Align = Sect.align;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000691 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000692 MachO::section Sect = getSection(Sec);
693 Align = Sect.align;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000694 }
695
696 Res = uint64_t(1) << Align;
697 return object_error::success;
698}
699
700error_code
701MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
702 uint32_t Flags = getSectionFlags(this, Sec);
Charles Davis8bdfafd2013-09-01 04:28:48 +0000703 Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000704 return object_error::success;
705}
706
Rafael Espindola137faa02013-04-24 15:14:22 +0000707error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const {
Michael J. Spencer800619f2011-09-28 20:57:30 +0000708 // FIXME: Unimplemented.
709 Result = false;
710 return object_error::success;
711}
712
Rafael Espindola137faa02013-04-24 15:14:22 +0000713error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const {
Andrew Kaylorb96a3202012-10-10 01:45:52 +0000714 // FIXME: Unimplemented.
Preston Gurd2138ef62012-04-12 20:13:57 +0000715 Result = false;
716 return object_error::success;
717}
718
Rafael Espindolac2413f52013-04-09 14:49:08 +0000719error_code
Rafael Espindola56f976f2013-04-18 18:08:55 +0000720MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
Rafael Espindola137faa02013-04-24 15:14:22 +0000721 bool &Result) const {
Rafael Espindolac2413f52013-04-09 14:49:08 +0000722 // FIXME: Unimplemented.
723 Result = true;
Preston Gurd2138ef62012-04-12 20:13:57 +0000724 return object_error::success;
725}
726
Rafael Espindola56f976f2013-04-18 18:08:55 +0000727error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
Rafael Espindola137faa02013-04-24 15:14:22 +0000728 bool &Result) const {
Rafael Espindolac2413f52013-04-09 14:49:08 +0000729 // FIXME: Unimplemented.
730 Result = false;
731 return object_error::success;
732}
733
Rafael Espindola56f976f2013-04-18 18:08:55 +0000734error_code
735MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
736 uint32_t Flags = getSectionFlags(this, Sec);
Charles Davis74ec8b02013-08-27 05:00:13 +0000737 unsigned SectionType = Flags & MachO::SECTION_TYPE;
738 Res = SectionType == MachO::S_ZEROFILL ||
739 SectionType == MachO::S_GB_ZEROFILL;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000740 return object_error::success;
741}
742
743error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
Rafael Espindola137faa02013-04-24 15:14:22 +0000744 bool &Result) const {
Andrew Kaylor3f31fa02012-10-10 01:41:33 +0000745 // Consider using the code from isSectionText to look for __const sections.
746 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
747 // to use section attributes to distinguish code from data.
748
749 // FIXME: Unimplemented.
750 Result = false;
751 return object_error::success;
752}
753
Rafael Espindola56f976f2013-04-18 18:08:55 +0000754error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000755MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
Rafael Espindola56f976f2013-04-18 18:08:55 +0000756 bool &Result) const {
757 SymbolRef::Type ST;
758 this->getSymbolType(Symb, ST);
759 if (ST == SymbolRef::ST_Unknown) {
760 Result = false;
761 return object_error::success;
762 }
763
764 uint64_t SectBegin, SectEnd;
765 getSectionAddress(Sec, SectBegin);
766 getSectionSize(Sec, SectEnd);
767 SectEnd += SectBegin;
768
769 uint64_t SymAddr;
770 getSymbolAddress(Symb, SymAddr);
771 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
772
773 return object_error::success;
774}
775
Rui Ueyamabc654b12013-09-27 21:47:05 +0000776relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
Rafael Espindola04d3f492013-04-25 12:45:46 +0000777 uint32_t Offset;
778 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000779 MachO::section_64 Sect = getSection64(Sec);
780 Offset = Sect.reloff;
Rafael Espindola04d3f492013-04-25 12:45:46 +0000781 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000782 MachO::section Sect = getSection(Sec);
783 Offset = Sect.reloff;
Rafael Espindola04d3f492013-04-25 12:45:46 +0000784 }
785
786 DataRefImpl Ret;
787 Ret.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
788 return relocation_iterator(RelocationRef(Ret, this));
Michael J. Spencere5fd0042011-10-07 19:25:32 +0000789}
Rafael Espindolac0406e12013-04-08 20:45:01 +0000790
Rafael Espindola56f976f2013-04-18 18:08:55 +0000791relocation_iterator
Rui Ueyamabc654b12013-09-27 21:47:05 +0000792MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
Rafael Espindola04d3f492013-04-25 12:45:46 +0000793 uint32_t Offset;
794 uint32_t Num;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000795 if (is64Bit()) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000796 MachO::section_64 Sect = getSection64(Sec);
797 Offset = Sect.reloff;
798 Num = Sect.nreloc;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000799 } else {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000800 MachO::section Sect = getSection(Sec);
801 Offset = Sect.reloff;
802 Num = Sect.nreloc;
Rafael Espindola56f976f2013-04-18 18:08:55 +0000803 }
Eric Christopher7b015c72011-04-22 03:19:48 +0000804
Charles Davis8bdfafd2013-09-01 04:28:48 +0000805 const MachO::any_relocation_info *P =
806 reinterpret_cast<const MachO::any_relocation_info *>(getPtr(this, Offset));
Rafael Espindola04d3f492013-04-25 12:45:46 +0000807
Rafael Espindola56f976f2013-04-18 18:08:55 +0000808 DataRefImpl Ret;
Rafael Espindola04d3f492013-04-25 12:45:46 +0000809 Ret.p = reinterpret_cast<uintptr_t>(P + Num);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000810 return relocation_iterator(RelocationRef(Ret, this));
811}
Benjamin Kramer022ecdf2011-09-08 20:52:17 +0000812
Rafael Espindola5e812af2014-01-30 02:49:50 +0000813void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000814 const MachO::any_relocation_info *P =
815 reinterpret_cast<const MachO::any_relocation_info *>(Rel.p);
Rafael Espindola04d3f492013-04-25 12:45:46 +0000816 Rel.p = reinterpret_cast<uintptr_t>(P + 1);
Benjamin Kramer022ecdf2011-09-08 20:52:17 +0000817}
Owen Anderson171f4852011-10-24 23:20:07 +0000818
Rafael Espindola56f976f2013-04-18 18:08:55 +0000819error_code
Rafael Espindola137faa02013-04-24 15:14:22 +0000820MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
Rafael Espindola1e483872013-04-25 12:28:45 +0000821 report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
Benjamin Kramer022ecdf2011-09-08 20:52:17 +0000822}
823
Rafael Espindola56f976f2013-04-18 18:08:55 +0000824error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
Rafael Espindola137faa02013-04-24 15:14:22 +0000825 uint64_t &Res) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000826 MachO::any_relocation_info RE = getRelocation(Rel);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000827 Res = getAnyRelocationAddress(RE);
828 return object_error::success;
David Meyer2fc34c52012-03-01 01:36:50 +0000829}
830
Rafael Espindola806f0062013-06-05 01:33:53 +0000831symbol_iterator
832MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000833 MachO::any_relocation_info RE = getRelocation(Rel);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000834 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
835 bool isExtern = getPlainRelocationExternal(RE);
Rafael Espindola806f0062013-06-05 01:33:53 +0000836 if (!isExtern)
Rafael Espindolab5155a52014-02-10 20:24:04 +0000837 return symbol_end();
Rafael Espindola75c30362013-04-24 19:47:55 +0000838
Charles Davis8bdfafd2013-09-01 04:28:48 +0000839 MachO::symtab_command S = getSymtabLoadCommand();
Rafael Espindola75c30362013-04-24 19:47:55 +0000840 unsigned SymbolTableEntrySize = is64Bit() ?
Charles Davis8bdfafd2013-09-01 04:28:48 +0000841 sizeof(MachO::nlist_64) :
842 sizeof(MachO::nlist);
843 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
Rafael Espindola75c30362013-04-24 19:47:55 +0000844 DataRefImpl Sym;
845 Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
Rafael Espindola806f0062013-06-05 01:33:53 +0000846 return symbol_iterator(SymbolRef(Sym, this));
Rafael Espindola56f976f2013-04-18 18:08:55 +0000847}
848
849error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
Rafael Espindola137faa02013-04-24 15:14:22 +0000850 uint64_t &Res) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000851 MachO::any_relocation_info RE = getRelocation(Rel);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000852 Res = getAnyRelocationType(RE);
853 return object_error::success;
854}
855
856error_code
857MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
858 SmallVectorImpl<char> &Result) const {
859 StringRef res;
860 uint64_t RType;
861 getRelocationType(Rel, RType);
862
863 unsigned Arch = this->getArch();
864
865 switch (Arch) {
866 case Triple::x86: {
867 static const char *const Table[] = {
868 "GENERIC_RELOC_VANILLA",
869 "GENERIC_RELOC_PAIR",
870 "GENERIC_RELOC_SECTDIFF",
871 "GENERIC_RELOC_PB_LA_PTR",
872 "GENERIC_RELOC_LOCAL_SECTDIFF",
873 "GENERIC_RELOC_TLV" };
874
Eric Christopher13250cb2013-12-06 02:33:38 +0000875 if (RType > 5)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000876 res = "Unknown";
877 else
878 res = Table[RType];
879 break;
880 }
881 case Triple::x86_64: {
882 static const char *const Table[] = {
883 "X86_64_RELOC_UNSIGNED",
884 "X86_64_RELOC_SIGNED",
885 "X86_64_RELOC_BRANCH",
886 "X86_64_RELOC_GOT_LOAD",
887 "X86_64_RELOC_GOT",
888 "X86_64_RELOC_SUBTRACTOR",
889 "X86_64_RELOC_SIGNED_1",
890 "X86_64_RELOC_SIGNED_2",
891 "X86_64_RELOC_SIGNED_4",
892 "X86_64_RELOC_TLV" };
893
894 if (RType > 9)
895 res = "Unknown";
896 else
897 res = Table[RType];
898 break;
899 }
900 case Triple::arm: {
901 static const char *const Table[] = {
902 "ARM_RELOC_VANILLA",
903 "ARM_RELOC_PAIR",
904 "ARM_RELOC_SECTDIFF",
905 "ARM_RELOC_LOCAL_SECTDIFF",
906 "ARM_RELOC_PB_LA_PTR",
907 "ARM_RELOC_BR24",
908 "ARM_THUMB_RELOC_BR22",
909 "ARM_THUMB_32BIT_BRANCH",
910 "ARM_RELOC_HALF",
911 "ARM_RELOC_HALF_SECTDIFF" };
912
913 if (RType > 9)
914 res = "Unknown";
915 else
916 res = Table[RType];
917 break;
918 }
919 case Triple::ppc: {
920 static const char *const Table[] = {
921 "PPC_RELOC_VANILLA",
922 "PPC_RELOC_PAIR",
923 "PPC_RELOC_BR14",
924 "PPC_RELOC_BR24",
925 "PPC_RELOC_HI16",
926 "PPC_RELOC_LO16",
927 "PPC_RELOC_HA16",
928 "PPC_RELOC_LO14",
929 "PPC_RELOC_SECTDIFF",
930 "PPC_RELOC_PB_LA_PTR",
931 "PPC_RELOC_HI16_SECTDIFF",
932 "PPC_RELOC_LO16_SECTDIFF",
933 "PPC_RELOC_HA16_SECTDIFF",
934 "PPC_RELOC_JBSR",
935 "PPC_RELOC_LO14_SECTDIFF",
936 "PPC_RELOC_LOCAL_SECTDIFF" };
937
Eric Christopher13250cb2013-12-06 02:33:38 +0000938 if (RType > 15)
939 res = "Unknown";
940 else
941 res = Table[RType];
Rafael Espindola56f976f2013-04-18 18:08:55 +0000942 break;
943 }
944 case Triple::UnknownArch:
945 res = "Unknown";
946 break;
947 }
948 Result.append(res.begin(), res.end());
949 return object_error::success;
950}
951
Rafael Espindola56f976f2013-04-18 18:08:55 +0000952error_code
953MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
Rafael Espindola137faa02013-04-24 15:14:22 +0000954 SmallVectorImpl<char> &Result) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000955 MachO::any_relocation_info RE = getRelocation(Rel);
David Meyer2fc34c52012-03-01 01:36:50 +0000956
Rafael Espindola56f976f2013-04-18 18:08:55 +0000957 unsigned Arch = this->getArch();
Eric Christopher7b015c72011-04-22 03:19:48 +0000958
Rafael Espindola56f976f2013-04-18 18:08:55 +0000959 std::string fmtbuf;
960 raw_string_ostream fmt(fmtbuf);
961 unsigned Type = this->getAnyRelocationType(RE);
962 bool IsPCRel = this->getAnyRelocationPCRel(RE);
963
964 // Determine any addends that should be displayed with the relocation.
965 // These require decoding the relocation type, which is triple-specific.
966
967 // X86_64 has entirely custom relocation types.
968 if (Arch == Triple::x86_64) {
969 bool isPCRel = getAnyRelocationPCRel(RE);
970
971 switch (Type) {
Charles Davis8bdfafd2013-09-01 04:28:48 +0000972 case MachO::X86_64_RELOC_GOT_LOAD:
973 case MachO::X86_64_RELOC_GOT: {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000974 printRelocationTargetName(this, RE, fmt);
975 fmt << "@GOT";
976 if (isPCRel) fmt << "PCREL";
977 break;
978 }
Charles Davis8bdfafd2013-09-01 04:28:48 +0000979 case MachO::X86_64_RELOC_SUBTRACTOR: {
Rafael Espindola56f976f2013-04-18 18:08:55 +0000980 DataRefImpl RelNext = Rel;
981 RelNext.d.a++;
Charles Davis8bdfafd2013-09-01 04:28:48 +0000982 MachO::any_relocation_info RENext = getRelocation(RelNext);
Rafael Espindola56f976f2013-04-18 18:08:55 +0000983
Charles Davis8bdfafd2013-09-01 04:28:48 +0000984 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
Rafael Espindola56f976f2013-04-18 18:08:55 +0000985 // X86_64_RELOC_UNSIGNED.
986 // NOTE: Scattered relocations don't exist on x86_64.
987 unsigned RType = getAnyRelocationType(RENext);
Charles Davis8bdfafd2013-09-01 04:28:48 +0000988 if (RType != MachO::X86_64_RELOC_UNSIGNED)
Rafael Espindola56f976f2013-04-18 18:08:55 +0000989 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
990 "X86_64_RELOC_SUBTRACTOR.");
991
Charles Davis8bdfafd2013-09-01 04:28:48 +0000992 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
993 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
Rafael Espindola56f976f2013-04-18 18:08:55 +0000994 printRelocationTargetName(this, RENext, fmt);
995 fmt << "-";
996 printRelocationTargetName(this, RE, fmt);
997 break;
998 }
Charles Davis8bdfafd2013-09-01 04:28:48 +0000999 case MachO::X86_64_RELOC_TLV:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001000 printRelocationTargetName(this, RE, fmt);
1001 fmt << "@TLV";
1002 if (isPCRel) fmt << "P";
1003 break;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001004 case MachO::X86_64_RELOC_SIGNED_1:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001005 printRelocationTargetName(this, RE, fmt);
1006 fmt << "-1";
1007 break;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001008 case MachO::X86_64_RELOC_SIGNED_2:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001009 printRelocationTargetName(this, RE, fmt);
1010 fmt << "-2";
1011 break;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001012 case MachO::X86_64_RELOC_SIGNED_4:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001013 printRelocationTargetName(this, RE, fmt);
1014 fmt << "-4";
1015 break;
1016 default:
1017 printRelocationTargetName(this, RE, fmt);
1018 break;
1019 }
1020 // X86 and ARM share some relocation types in common.
David Fangb88cdf62013-08-08 20:14:40 +00001021 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
1022 Arch == Triple::ppc) {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001023 // Generic relocation types...
1024 switch (Type) {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001025 case MachO::GENERIC_RELOC_PAIR: // prints no info
Rafael Espindola56f976f2013-04-18 18:08:55 +00001026 return object_error::success;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001027 case MachO::GENERIC_RELOC_SECTDIFF: {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001028 DataRefImpl RelNext = Rel;
1029 RelNext.d.a++;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001030 MachO::any_relocation_info RENext = getRelocation(RelNext);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001031
1032 // X86 sect diff's must be followed by a relocation of type
1033 // GENERIC_RELOC_PAIR.
1034 unsigned RType = getAnyRelocationType(RENext);
1035
Charles Davis8bdfafd2013-09-01 04:28:48 +00001036 if (RType != MachO::GENERIC_RELOC_PAIR)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001037 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1038 "GENERIC_RELOC_SECTDIFF.");
1039
1040 printRelocationTargetName(this, RE, fmt);
1041 fmt << "-";
1042 printRelocationTargetName(this, RENext, fmt);
1043 break;
1044 }
1045 }
1046
David Fangb88cdf62013-08-08 20:14:40 +00001047 if (Arch == Triple::x86 || Arch == Triple::ppc) {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001048 switch (Type) {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001049 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001050 DataRefImpl RelNext = Rel;
1051 RelNext.d.a++;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001052 MachO::any_relocation_info RENext = getRelocation(RelNext);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001053
1054 // X86 sect diff's must be followed by a relocation of type
1055 // GENERIC_RELOC_PAIR.
1056 unsigned RType = getAnyRelocationType(RENext);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001057 if (RType != MachO::GENERIC_RELOC_PAIR)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001058 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1059 "GENERIC_RELOC_LOCAL_SECTDIFF.");
1060
1061 printRelocationTargetName(this, RE, fmt);
1062 fmt << "-";
1063 printRelocationTargetName(this, RENext, fmt);
1064 break;
1065 }
Charles Davis8bdfafd2013-09-01 04:28:48 +00001066 case MachO::GENERIC_RELOC_TLV: {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001067 printRelocationTargetName(this, RE, fmt);
1068 fmt << "@TLV";
1069 if (IsPCRel) fmt << "P";
1070 break;
1071 }
1072 default:
1073 printRelocationTargetName(this, RE, fmt);
1074 }
1075 } else { // ARM-specific relocations
1076 switch (Type) {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001077 case MachO::ARM_RELOC_HALF:
1078 case MachO::ARM_RELOC_HALF_SECTDIFF: {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001079 // Half relocations steal a bit from the length field to encode
1080 // whether this is an upper16 or a lower16 relocation.
1081 bool isUpper = getAnyRelocationLength(RE) >> 1;
1082
1083 if (isUpper)
1084 fmt << ":upper16:(";
1085 else
1086 fmt << ":lower16:(";
1087 printRelocationTargetName(this, RE, fmt);
1088
1089 DataRefImpl RelNext = Rel;
1090 RelNext.d.a++;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001091 MachO::any_relocation_info RENext = getRelocation(RelNext);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001092
1093 // ARM half relocs must be followed by a relocation of type
1094 // ARM_RELOC_PAIR.
1095 unsigned RType = getAnyRelocationType(RENext);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001096 if (RType != MachO::ARM_RELOC_PAIR)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001097 report_fatal_error("Expected ARM_RELOC_PAIR after "
Charles Davis8bdfafd2013-09-01 04:28:48 +00001098 "ARM_RELOC_HALF");
Rafael Espindola56f976f2013-04-18 18:08:55 +00001099
1100 // NOTE: The half of the target virtual address is stashed in the
1101 // address field of the secondary relocation, but we can't reverse
1102 // engineer the constant offset from it without decoding the movw/movt
1103 // instruction to find the other half in its immediate field.
1104
1105 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1106 // symbol/section pointer of the follow-on relocation.
Charles Davis8bdfafd2013-09-01 04:28:48 +00001107 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001108 fmt << "-";
1109 printRelocationTargetName(this, RENext, fmt);
1110 }
1111
1112 fmt << ")";
1113 break;
1114 }
1115 default: {
1116 printRelocationTargetName(this, RE, fmt);
1117 }
1118 }
1119 }
1120 } else
1121 printRelocationTargetName(this, RE, fmt);
1122
1123 fmt.flush();
1124 Result.append(fmtbuf.begin(), fmtbuf.end());
1125 return object_error::success;
1126}
1127
1128error_code
Rafael Espindola137faa02013-04-24 15:14:22 +00001129MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001130 unsigned Arch = getArch();
1131 uint64_t Type;
1132 getRelocationType(Rel, Type);
1133
1134 Result = false;
1135
1136 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1137 // is always hidden.
David Fangb88cdf62013-08-08 20:14:40 +00001138 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001139 if (Type == MachO::GENERIC_RELOC_PAIR) Result = true;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001140 } else if (Arch == Triple::x86_64) {
1141 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
Eric Christopher1ff26ab62013-07-22 22:25:09 +00001142 // an X86_64_RELOC_SUBTRACTOR.
Charles Davis8bdfafd2013-09-01 04:28:48 +00001143 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001144 DataRefImpl RelPrev = Rel;
1145 RelPrev.d.a--;
1146 uint64_t PrevType;
1147 getRelocationType(RelPrev, PrevType);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001148 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001149 Result = true;
1150 }
1151 }
1152
1153 return object_error::success;
1154}
1155
1156error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
Rafael Espindola137faa02013-04-24 15:14:22 +00001157 LibraryRef &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001158 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1159}
1160
1161error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
Rafael Espindola137faa02013-04-24 15:14:22 +00001162 StringRef &Res) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001163 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1164}
1165
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001166basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001167 DataRefImpl DRI;
Rafael Espindola75c30362013-04-24 19:47:55 +00001168 if (!SymtabLoadCmd)
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001169 return basic_symbol_iterator(SymbolRef(DRI, this));
Rafael Espindola75c30362013-04-24 19:47:55 +00001170
Charles Davis8bdfafd2013-09-01 04:28:48 +00001171 MachO::symtab_command Symtab = getSymtabLoadCommand();
1172 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001173 return basic_symbol_iterator(SymbolRef(DRI, this));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001174}
1175
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001176basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001177 DataRefImpl DRI;
Rafael Espindola75c30362013-04-24 19:47:55 +00001178 if (!SymtabLoadCmd)
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001179 return basic_symbol_iterator(SymbolRef(DRI, this));
Rafael Espindola75c30362013-04-24 19:47:55 +00001180
Charles Davis8bdfafd2013-09-01 04:28:48 +00001181 MachO::symtab_command Symtab = getSymtabLoadCommand();
Rafael Espindola75c30362013-04-24 19:47:55 +00001182 unsigned SymbolTableEntrySize = is64Bit() ?
Charles Davis8bdfafd2013-09-01 04:28:48 +00001183 sizeof(MachO::nlist_64) :
1184 sizeof(MachO::nlist);
1185 unsigned Offset = Symtab.symoff +
1186 Symtab.nsyms * SymbolTableEntrySize;
Rafael Espindola75c30362013-04-24 19:47:55 +00001187 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
Rafael Espindolaf12b8282014-02-21 20:10:59 +00001188 return basic_symbol_iterator(SymbolRef(DRI, this));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001189}
1190
Rafael Espindolab5155a52014-02-10 20:24:04 +00001191section_iterator MachOObjectFile::section_begin() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001192 DataRefImpl DRI;
1193 return section_iterator(SectionRef(DRI, this));
1194}
1195
Rafael Espindolab5155a52014-02-10 20:24:04 +00001196section_iterator MachOObjectFile::section_end() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001197 DataRefImpl DRI;
1198 DRI.d.a = Sections.size();
1199 return section_iterator(SectionRef(DRI, this));
1200}
1201
Rafael Espindolab5155a52014-02-10 20:24:04 +00001202library_iterator MachOObjectFile::needed_library_begin() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001203 // TODO: implement
1204 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1205}
1206
Rafael Espindolab5155a52014-02-10 20:24:04 +00001207library_iterator MachOObjectFile::needed_library_end() const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001208 // TODO: implement
1209 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1210}
1211
1212uint8_t MachOObjectFile::getBytesInAddress() const {
Rafael Espindola60689982013-04-07 19:05:30 +00001213 return is64Bit() ? 8 : 4;
Eric Christopher7b015c72011-04-22 03:19:48 +00001214}
1215
Rafael Espindola56f976f2013-04-18 18:08:55 +00001216StringRef MachOObjectFile::getFileFormatName() const {
1217 unsigned CPUType = getCPUType(this);
1218 if (!is64Bit()) {
1219 switch (CPUType) {
Charles Davis74ec8b02013-08-27 05:00:13 +00001220 case llvm::MachO::CPU_TYPE_I386:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001221 return "Mach-O 32-bit i386";
Charles Davis74ec8b02013-08-27 05:00:13 +00001222 case llvm::MachO::CPU_TYPE_ARM:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001223 return "Mach-O arm";
Charles Davis74ec8b02013-08-27 05:00:13 +00001224 case llvm::MachO::CPU_TYPE_POWERPC:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001225 return "Mach-O 32-bit ppc";
1226 default:
Charles Davis74ec8b02013-08-27 05:00:13 +00001227 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 &&
Rafael Espindola56f976f2013-04-18 18:08:55 +00001228 "64-bit object file when we're not 64-bit?");
1229 return "Mach-O 32-bit unknown";
1230 }
1231 }
1232
1233 // Make sure the cpu type has the correct mask.
Charles Davis74ec8b02013-08-27 05:00:13 +00001234 assert((CPUType & llvm::MachO::CPU_ARCH_ABI64)
1235 == llvm::MachO::CPU_ARCH_ABI64 &&
Eric Christopher1d62c252013-07-22 22:25:07 +00001236 "32-bit object file when we're 64-bit?");
Rafael Espindola56f976f2013-04-18 18:08:55 +00001237
1238 switch (CPUType) {
Charles Davis74ec8b02013-08-27 05:00:13 +00001239 case llvm::MachO::CPU_TYPE_X86_64:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001240 return "Mach-O 64-bit x86-64";
Charles Davis74ec8b02013-08-27 05:00:13 +00001241 case llvm::MachO::CPU_TYPE_POWERPC64:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001242 return "Mach-O 64-bit ppc64";
1243 default:
1244 return "Mach-O 64-bit unknown";
1245 }
1246}
1247
Alexey Samsonove6388e62013-06-18 15:03:28 +00001248Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1249 switch (CPUType) {
Charles Davis74ec8b02013-08-27 05:00:13 +00001250 case llvm::MachO::CPU_TYPE_I386:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001251 return Triple::x86;
Charles Davis74ec8b02013-08-27 05:00:13 +00001252 case llvm::MachO::CPU_TYPE_X86_64:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001253 return Triple::x86_64;
Charles Davis74ec8b02013-08-27 05:00:13 +00001254 case llvm::MachO::CPU_TYPE_ARM:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001255 return Triple::arm;
Charles Davis74ec8b02013-08-27 05:00:13 +00001256 case llvm::MachO::CPU_TYPE_POWERPC:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001257 return Triple::ppc;
Charles Davis74ec8b02013-08-27 05:00:13 +00001258 case llvm::MachO::CPU_TYPE_POWERPC64:
Rafael Espindola56f976f2013-04-18 18:08:55 +00001259 return Triple::ppc64;
1260 default:
1261 return Triple::UnknownArch;
1262 }
1263}
1264
Alexey Samsonove6388e62013-06-18 15:03:28 +00001265unsigned MachOObjectFile::getArch() const {
1266 return getArch(getCPUType(this));
1267}
1268
Rafael Espindola56f976f2013-04-18 18:08:55 +00001269StringRef MachOObjectFile::getLoadName() const {
1270 // TODO: Implement
Charles Davis1827bd82013-08-27 05:38:30 +00001271 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
Rafael Espindola56f976f2013-04-18 18:08:55 +00001272}
1273
Rui Ueyamabc654b12013-09-27 21:47:05 +00001274relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
Rafael Espindola6e040c02013-04-26 20:07:33 +00001275 DataRefImpl DRI;
1276 DRI.d.a = Index;
Rui Ueyamabc654b12013-09-27 21:47:05 +00001277 return section_rel_begin(DRI);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001278}
1279
Rui Ueyamabc654b12013-09-27 21:47:05 +00001280relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
Rafael Espindola6e040c02013-04-26 20:07:33 +00001281 DataRefImpl DRI;
1282 DRI.d.a = Index;
Rui Ueyamabc654b12013-09-27 21:47:05 +00001283 return section_rel_end(DRI);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001284}
1285
Kevin Enderby273ae012013-06-06 17:20:50 +00001286dice_iterator MachOObjectFile::begin_dices() const {
1287 DataRefImpl DRI;
1288 if (!DataInCodeLoadCmd)
1289 return dice_iterator(DiceRef(DRI, this));
1290
Charles Davis8bdfafd2013-09-01 04:28:48 +00001291 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1292 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
Kevin Enderby273ae012013-06-06 17:20:50 +00001293 return dice_iterator(DiceRef(DRI, this));
1294}
1295
1296dice_iterator MachOObjectFile::end_dices() const {
1297 DataRefImpl DRI;
1298 if (!DataInCodeLoadCmd)
1299 return dice_iterator(DiceRef(DRI, this));
1300
Charles Davis8bdfafd2013-09-01 04:28:48 +00001301 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1302 unsigned Offset = DicLC.dataoff + DicLC.datasize;
Kevin Enderby273ae012013-06-06 17:20:50 +00001303 DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1304 return dice_iterator(DiceRef(DRI, this));
1305}
1306
Rafael Espindola56f976f2013-04-18 18:08:55 +00001307StringRef
1308MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1309 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1310 return parseSegmentOrSectionName(Raw.data());
1311}
1312
1313ArrayRef<char>
1314MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001315 const section_base *Base =
1316 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1317 return ArrayRef<char>(Base->sectname);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001318}
1319
1320ArrayRef<char>
1321MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001322 const section_base *Base =
1323 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1324 return ArrayRef<char>(Base->segname);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001325}
1326
1327bool
Charles Davis8bdfafd2013-09-01 04:28:48 +00001328MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001329 const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001330 if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
Rafael Espindola56f976f2013-04-18 18:08:55 +00001331 return false;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001332 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001333}
1334
Eric Christopher1d62c252013-07-22 22:25:07 +00001335unsigned MachOObjectFile::getPlainRelocationSymbolNum(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001336 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001337 if (isLittleEndian())
Charles Davis8bdfafd2013-09-01 04:28:48 +00001338 return RE.r_word1 & 0xffffff;
1339 return RE.r_word1 >> 8;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001340}
1341
Eric Christopher1d62c252013-07-22 22:25:07 +00001342bool MachOObjectFile::getPlainRelocationExternal(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001343 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001344 if (isLittleEndian())
Charles Davis8bdfafd2013-09-01 04:28:48 +00001345 return (RE.r_word1 >> 27) & 1;
1346 return (RE.r_word1 >> 4) & 1;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001347}
1348
Eric Christopher1d62c252013-07-22 22:25:07 +00001349bool MachOObjectFile::getScatteredRelocationScattered(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001350 const MachO::any_relocation_info &RE) const {
1351 return RE.r_word0 >> 31;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001352}
1353
Eric Christopher1d62c252013-07-22 22:25:07 +00001354uint32_t MachOObjectFile::getScatteredRelocationValue(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001355 const MachO::any_relocation_info &RE) const {
1356 return RE.r_word1;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001357}
1358
Eric Christopher1d62c252013-07-22 22:25:07 +00001359unsigned MachOObjectFile::getAnyRelocationAddress(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001360 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001361 if (isRelocationScattered(RE))
1362 return getScatteredRelocationAddress(RE);
1363 return getPlainRelocationAddress(RE);
1364}
1365
Charles Davis8bdfafd2013-09-01 04:28:48 +00001366unsigned MachOObjectFile::getAnyRelocationPCRel(
1367 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001368 if (isRelocationScattered(RE))
1369 return getScatteredRelocationPCRel(this, RE);
1370 return getPlainRelocationPCRel(this, RE);
1371}
1372
Eric Christopher1d62c252013-07-22 22:25:07 +00001373unsigned MachOObjectFile::getAnyRelocationLength(
Charles Davis8bdfafd2013-09-01 04:28:48 +00001374 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001375 if (isRelocationScattered(RE))
1376 return getScatteredRelocationLength(RE);
1377 return getPlainRelocationLength(this, RE);
1378}
1379
1380unsigned
Charles Davis8bdfafd2013-09-01 04:28:48 +00001381MachOObjectFile::getAnyRelocationType(
1382 const MachO::any_relocation_info &RE) const {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001383 if (isRelocationScattered(RE))
1384 return getScatteredRelocationType(RE);
1385 return getPlainRelocationType(this, RE);
1386}
1387
Rafael Espindola52501032013-04-30 15:40:54 +00001388SectionRef
Charles Davis8bdfafd2013-09-01 04:28:48 +00001389MachOObjectFile::getRelocationSection(
1390 const MachO::any_relocation_info &RE) const {
Rafael Espindola52501032013-04-30 15:40:54 +00001391 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
Rafael Espindolab5155a52014-02-10 20:24:04 +00001392 return *section_end();
Rafael Espindola52501032013-04-30 15:40:54 +00001393 unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
1394 DataRefImpl DRI;
1395 DRI.d.a = SecNum;
1396 return SectionRef(DRI, this);
1397}
1398
Rafael Espindola56f976f2013-04-18 18:08:55 +00001399MachOObjectFile::LoadCommandInfo
1400MachOObjectFile::getFirstLoadCommandInfo() const {
1401 MachOObjectFile::LoadCommandInfo Load;
1402
Charles Davis8bdfafd2013-09-01 04:28:48 +00001403 unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) :
1404 sizeof(MachO::mach_header);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001405 Load.Ptr = getPtr(this, HeaderSize);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001406 Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001407 return Load;
1408}
1409
1410MachOObjectFile::LoadCommandInfo
1411MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
1412 MachOObjectFile::LoadCommandInfo Next;
Charles Davis8bdfafd2013-09-01 04:28:48 +00001413 Next.Ptr = L.Ptr + L.C.cmdsize;
1414 Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001415 return Next;
1416}
1417
Charles Davis8bdfafd2013-09-01 04:28:48 +00001418MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
1419 return getStruct<MachO::section>(this, Sections[DRI.d.a]);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001420}
1421
Charles Davis8bdfafd2013-09-01 04:28:48 +00001422MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
1423 return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001424}
1425
Charles Davis8bdfafd2013-09-01 04:28:48 +00001426MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
Rafael Espindola6e040c02013-04-26 20:07:33 +00001427 unsigned Index) const {
1428 const char *Sec = getSectionPtr(this, L, Index);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001429 return getStruct<MachO::section>(this, Sec);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001430}
1431
Charles Davis8bdfafd2013-09-01 04:28:48 +00001432MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
1433 unsigned Index) const {
Rafael Espindola6e040c02013-04-26 20:07:33 +00001434 const char *Sec = getSectionPtr(this, L, Index);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001435 return getStruct<MachO::section_64>(this, Sec);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001436}
1437
Charles Davis8bdfafd2013-09-01 04:28:48 +00001438MachO::nlist
Rafael Espindola56f976f2013-04-18 18:08:55 +00001439MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
Rafael Espindola75c30362013-04-24 19:47:55 +00001440 const char *P = reinterpret_cast<const char *>(DRI.p);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001441 return getStruct<MachO::nlist>(this, P);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001442}
1443
Charles Davis8bdfafd2013-09-01 04:28:48 +00001444MachO::nlist_64
Rafael Espindola56f976f2013-04-18 18:08:55 +00001445MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
Rafael Espindola75c30362013-04-24 19:47:55 +00001446 const char *P = reinterpret_cast<const char *>(DRI.p);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001447 return getStruct<MachO::nlist_64>(this, P);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001448}
1449
Charles Davis8bdfafd2013-09-01 04:28:48 +00001450MachO::linkedit_data_command
1451MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
1452 return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001453}
1454
Charles Davis8bdfafd2013-09-01 04:28:48 +00001455MachO::segment_command
Rafael Espindola6e040c02013-04-26 20:07:33 +00001456MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001457 return getStruct<MachO::segment_command>(this, L.Ptr);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001458}
1459
Charles Davis8bdfafd2013-09-01 04:28:48 +00001460MachO::segment_command_64
Rafael Espindola6e040c02013-04-26 20:07:33 +00001461MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001462 return getStruct<MachO::segment_command_64>(this, L.Ptr);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001463}
1464
Charles Davis8bdfafd2013-09-01 04:28:48 +00001465MachO::linker_options_command
Rafael Espindola6e040c02013-04-26 20:07:33 +00001466MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001467 return getStruct<MachO::linker_options_command>(this, L.Ptr);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001468}
1469
Charles Davis8bdfafd2013-09-01 04:28:48 +00001470MachO::any_relocation_info
Rafael Espindola56f976f2013-04-18 18:08:55 +00001471MachOObjectFile::getRelocation(DataRefImpl Rel) const {
Rafael Espindola04d3f492013-04-25 12:45:46 +00001472 const char *P = reinterpret_cast<const char *>(Rel.p);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001473 return getStruct<MachO::any_relocation_info>(this, P);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001474}
1475
Charles Davis8bdfafd2013-09-01 04:28:48 +00001476MachO::data_in_code_entry
Kevin Enderby273ae012013-06-06 17:20:50 +00001477MachOObjectFile::getDice(DataRefImpl Rel) const {
1478 const char *P = reinterpret_cast<const char *>(Rel.p);
Charles Davis8bdfafd2013-09-01 04:28:48 +00001479 return getStruct<MachO::data_in_code_entry>(this, P);
Kevin Enderby273ae012013-06-06 17:20:50 +00001480}
1481
Charles Davis8bdfafd2013-09-01 04:28:48 +00001482MachO::mach_header MachOObjectFile::getHeader() const {
1483 return getStruct<MachO::mach_header>(this, getPtr(this, 0));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001484}
1485
Charles Davis8bdfafd2013-09-01 04:28:48 +00001486MachO::mach_header_64 MachOObjectFile::getHeader64() const {
1487 return getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
Rafael Espindola6e040c02013-04-26 20:07:33 +00001488}
1489
Charles Davis8bdfafd2013-09-01 04:28:48 +00001490uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
1491 const MachO::dysymtab_command &DLC,
1492 unsigned Index) const {
1493 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
1494 return getStruct<uint32_t>(this, getPtr(this, Offset));
Rafael Espindola6e040c02013-04-26 20:07:33 +00001495}
1496
Charles Davis8bdfafd2013-09-01 04:28:48 +00001497MachO::data_in_code_entry
Rafael Espindola6e040c02013-04-26 20:07:33 +00001498MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
1499 unsigned Index) const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001500 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
1501 return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
Rafael Espindola6e040c02013-04-26 20:07:33 +00001502}
1503
Charles Davis8bdfafd2013-09-01 04:28:48 +00001504MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
1505 return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
Rafael Espindola56f976f2013-04-18 18:08:55 +00001506}
1507
Charles Davis8bdfafd2013-09-01 04:28:48 +00001508MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
1509 return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001510}
1511
Charles Davis8bdfafd2013-09-01 04:28:48 +00001512MachO::linkedit_data_command
Kevin Enderby273ae012013-06-06 17:20:50 +00001513MachOObjectFile::getDataInCodeLoadCommand() const {
1514 if (DataInCodeLoadCmd)
Charles Davis8bdfafd2013-09-01 04:28:48 +00001515 return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
Kevin Enderby273ae012013-06-06 17:20:50 +00001516
1517 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
Charles Davis8bdfafd2013-09-01 04:28:48 +00001518 MachO::linkedit_data_command Cmd;
1519 Cmd.cmd = MachO::LC_DATA_IN_CODE;
1520 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
1521 Cmd.dataoff = 0;
1522 Cmd.datasize = 0;
Kevin Enderby273ae012013-06-06 17:20:50 +00001523 return Cmd;
1524}
1525
Rafael Espindola6e040c02013-04-26 20:07:33 +00001526StringRef MachOObjectFile::getStringTableData() const {
Charles Davis8bdfafd2013-09-01 04:28:48 +00001527 MachO::symtab_command S = getSymtabLoadCommand();
1528 return getData().substr(S.stroff, S.strsize);
Rafael Espindola6e040c02013-04-26 20:07:33 +00001529}
1530
Rafael Espindola56f976f2013-04-18 18:08:55 +00001531bool MachOObjectFile::is64Bit() const {
1532 return getType() == getMachOType(false, true) ||
1533 getType() == getMachOType(true, true);
1534}
1535
1536void MachOObjectFile::ReadULEB128s(uint64_t Index,
1537 SmallVectorImpl<uint64_t> &Out) const {
1538 DataExtractor extractor(ObjectFile::getData(), true, 0);
1539
1540 uint32_t offset = Index;
1541 uint64_t data = 0;
1542 while (uint64_t delta = extractor.getULEB128(&offset)) {
1543 data += delta;
1544 Out.push_back(data);
1545 }
1546}
1547
Rafael Espindolaafcc3df2014-01-24 21:32:21 +00001548ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
1549 bool BufferOwned) {
Rafael Espindola56f976f2013-04-18 18:08:55 +00001550 StringRef Magic = Buffer->getBuffer().slice(0, 4);
Rafael Espindola692410e2014-01-21 23:06:54 +00001551 error_code EC;
1552 OwningPtr<MachOObjectFile> Ret;
Rafael Espindola56f976f2013-04-18 18:08:55 +00001553 if (Magic == "\xFE\xED\xFA\xCE")
Rafael Espindolaafcc3df2014-01-24 21:32:21 +00001554 Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001555 else if (Magic == "\xCE\xFA\xED\xFE")
Rafael Espindolaafcc3df2014-01-24 21:32:21 +00001556 Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001557 else if (Magic == "\xFE\xED\xFA\xCF")
Rafael Espindolaafcc3df2014-01-24 21:32:21 +00001558 Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
Rafael Espindola56f976f2013-04-18 18:08:55 +00001559 else if (Magic == "\xCF\xFA\xED\xFE")
Rafael Espindolaafcc3df2014-01-24 21:32:21 +00001560 Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
Benjamin Kramer097e09a2013-08-03 22:16:37 +00001561 else {
1562 delete Buffer;
Rafael Espindola692410e2014-01-21 23:06:54 +00001563 return object_error::parse_failed;
Benjamin Kramer097e09a2013-08-03 22:16:37 +00001564 }
Rafael Espindola56f976f2013-04-18 18:08:55 +00001565
Rafael Espindola692410e2014-01-21 23:06:54 +00001566 if (EC)
1567 return EC;
Ahmed Charles96c9d952014-03-05 10:19:29 +00001568 return Ret.release();
Rafael Espindola56f976f2013-04-18 18:08:55 +00001569}
1570
Owen Anderson27c579d2011-10-11 17:32:27 +00001571} // end namespace object
Eric Christopher7b015c72011-04-22 03:19:48 +00001572} // end namespace llvm