1*9880d681SAndroid Build Coastguard Worker //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines the MachOObjectFile class, which binds the MachOObject
11*9880d681SAndroid Build Coastguard Worker // class to the generic ObjectFile wrapper.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachO.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataExtractor.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LEB128.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MachO.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
27*9880d681SAndroid Build Coastguard Worker #include <cctype>
28*9880d681SAndroid Build Coastguard Worker #include <cstring>
29*9880d681SAndroid Build Coastguard Worker #include <limits>
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker using namespace llvm;
32*9880d681SAndroid Build Coastguard Worker using namespace object;
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker struct section_base {
36*9880d681SAndroid Build Coastguard Worker char sectname[16];
37*9880d681SAndroid Build Coastguard Worker char segname[16];
38*9880d681SAndroid Build Coastguard Worker };
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker static Error
malformedError(Twine Msg)42*9880d681SAndroid Build Coastguard Worker malformedError(Twine Msg) {
43*9880d681SAndroid Build Coastguard Worker std::string StringMsg = "truncated or malformed object (" + Msg.str() + ")";
44*9880d681SAndroid Build Coastguard Worker return make_error<GenericBinaryError>(std::move(StringMsg),
45*9880d681SAndroid Build Coastguard Worker object_error::parse_failed);
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker // FIXME: Replace all uses of this function with getStructOrErr.
49*9880d681SAndroid Build Coastguard Worker template <typename T>
getStruct(const MachOObjectFile * O,const char * P)50*9880d681SAndroid Build Coastguard Worker static T getStruct(const MachOObjectFile *O, const char *P) {
51*9880d681SAndroid Build Coastguard Worker // Don't read before the beginning or past the end of the file
52*9880d681SAndroid Build Coastguard Worker if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
53*9880d681SAndroid Build Coastguard Worker report_fatal_error("Malformed MachO file.");
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker T Cmd;
56*9880d681SAndroid Build Coastguard Worker memcpy(&Cmd, P, sizeof(T));
57*9880d681SAndroid Build Coastguard Worker if (O->isLittleEndian() != sys::IsLittleEndianHost)
58*9880d681SAndroid Build Coastguard Worker MachO::swapStruct(Cmd);
59*9880d681SAndroid Build Coastguard Worker return Cmd;
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker template <typename T>
getStructOrErr(const MachOObjectFile * O,const char * P)63*9880d681SAndroid Build Coastguard Worker static Expected<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
64*9880d681SAndroid Build Coastguard Worker // Don't read before the beginning or past the end of the file
65*9880d681SAndroid Build Coastguard Worker if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
66*9880d681SAndroid Build Coastguard Worker return malformedError("Structure read out-of-range");
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker T Cmd;
69*9880d681SAndroid Build Coastguard Worker memcpy(&Cmd, P, sizeof(T));
70*9880d681SAndroid Build Coastguard Worker if (O->isLittleEndian() != sys::IsLittleEndianHost)
71*9880d681SAndroid Build Coastguard Worker MachO::swapStruct(Cmd);
72*9880d681SAndroid Build Coastguard Worker return Cmd;
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker static const char *
getSectionPtr(const MachOObjectFile * O,MachOObjectFile::LoadCommandInfo L,unsigned Sec)76*9880d681SAndroid Build Coastguard Worker getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
77*9880d681SAndroid Build Coastguard Worker unsigned Sec) {
78*9880d681SAndroid Build Coastguard Worker uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker bool Is64 = O->is64Bit();
81*9880d681SAndroid Build Coastguard Worker unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
82*9880d681SAndroid Build Coastguard Worker sizeof(MachO::segment_command);
83*9880d681SAndroid Build Coastguard Worker unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
84*9880d681SAndroid Build Coastguard Worker sizeof(MachO::section);
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
87*9880d681SAndroid Build Coastguard Worker return reinterpret_cast<const char*>(SectionAddr);
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker
getPtr(const MachOObjectFile * O,size_t Offset)90*9880d681SAndroid Build Coastguard Worker static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
91*9880d681SAndroid Build Coastguard Worker return O->getData().substr(Offset, 1).data();
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker static MachO::nlist_base
getSymbolTableEntryBase(const MachOObjectFile * O,DataRefImpl DRI)95*9880d681SAndroid Build Coastguard Worker getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
96*9880d681SAndroid Build Coastguard Worker const char *P = reinterpret_cast<const char *>(DRI.p);
97*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::nlist_base>(O, P);
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker
parseSegmentOrSectionName(const char * P)100*9880d681SAndroid Build Coastguard Worker static StringRef parseSegmentOrSectionName(const char *P) {
101*9880d681SAndroid Build Coastguard Worker if (P[15] == 0)
102*9880d681SAndroid Build Coastguard Worker // Null terminated.
103*9880d681SAndroid Build Coastguard Worker return P;
104*9880d681SAndroid Build Coastguard Worker // Not null terminated, so this is a 16 char string.
105*9880d681SAndroid Build Coastguard Worker return StringRef(P, 16);
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker // Helper to advance a section or symbol iterator multiple increments at a time.
109*9880d681SAndroid Build Coastguard Worker template<class T>
advance(T & it,size_t Val)110*9880d681SAndroid Build Coastguard Worker static void advance(T &it, size_t Val) {
111*9880d681SAndroid Build Coastguard Worker while (Val--)
112*9880d681SAndroid Build Coastguard Worker ++it;
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker
getCPUType(const MachOObjectFile * O)115*9880d681SAndroid Build Coastguard Worker static unsigned getCPUType(const MachOObjectFile *O) {
116*9880d681SAndroid Build Coastguard Worker return O->getHeader().cputype;
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker static uint32_t
getPlainRelocationAddress(const MachO::any_relocation_info & RE)120*9880d681SAndroid Build Coastguard Worker getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
121*9880d681SAndroid Build Coastguard Worker return RE.r_word0;
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker static unsigned
getScatteredRelocationAddress(const MachO::any_relocation_info & RE)125*9880d681SAndroid Build Coastguard Worker getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
126*9880d681SAndroid Build Coastguard Worker return RE.r_word0 & 0xffffff;
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker
getPlainRelocationPCRel(const MachOObjectFile * O,const MachO::any_relocation_info & RE)129*9880d681SAndroid Build Coastguard Worker static bool getPlainRelocationPCRel(const MachOObjectFile *O,
130*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) {
131*9880d681SAndroid Build Coastguard Worker if (O->isLittleEndian())
132*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 24) & 1;
133*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 7) & 1;
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker static bool
getScatteredRelocationPCRel(const MachOObjectFile * O,const MachO::any_relocation_info & RE)137*9880d681SAndroid Build Coastguard Worker getScatteredRelocationPCRel(const MachOObjectFile *O,
138*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) {
139*9880d681SAndroid Build Coastguard Worker return (RE.r_word0 >> 30) & 1;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
getPlainRelocationLength(const MachOObjectFile * O,const MachO::any_relocation_info & RE)142*9880d681SAndroid Build Coastguard Worker static unsigned getPlainRelocationLength(const MachOObjectFile *O,
143*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) {
144*9880d681SAndroid Build Coastguard Worker if (O->isLittleEndian())
145*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 25) & 3;
146*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 5) & 3;
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker static unsigned
getScatteredRelocationLength(const MachO::any_relocation_info & RE)150*9880d681SAndroid Build Coastguard Worker getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
151*9880d681SAndroid Build Coastguard Worker return (RE.r_word0 >> 28) & 3;
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker
getPlainRelocationType(const MachOObjectFile * O,const MachO::any_relocation_info & RE)154*9880d681SAndroid Build Coastguard Worker static unsigned getPlainRelocationType(const MachOObjectFile *O,
155*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) {
156*9880d681SAndroid Build Coastguard Worker if (O->isLittleEndian())
157*9880d681SAndroid Build Coastguard Worker return RE.r_word1 >> 28;
158*9880d681SAndroid Build Coastguard Worker return RE.r_word1 & 0xf;
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker
getSectionFlags(const MachOObjectFile * O,DataRefImpl Sec)161*9880d681SAndroid Build Coastguard Worker static uint32_t getSectionFlags(const MachOObjectFile *O,
162*9880d681SAndroid Build Coastguard Worker DataRefImpl Sec) {
163*9880d681SAndroid Build Coastguard Worker if (O->is64Bit()) {
164*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = O->getSection64(Sec);
165*9880d681SAndroid Build Coastguard Worker return Sect.flags;
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker MachO::section Sect = O->getSection(Sec);
168*9880d681SAndroid Build Coastguard Worker return Sect.flags;
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker static Expected<MachOObjectFile::LoadCommandInfo>
getLoadCommandInfo(const MachOObjectFile * Obj,const char * Ptr,uint32_t LoadCommandIndex)172*9880d681SAndroid Build Coastguard Worker getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr,
173*9880d681SAndroid Build Coastguard Worker uint32_t LoadCommandIndex) {
174*9880d681SAndroid Build Coastguard Worker if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
175*9880d681SAndroid Build Coastguard Worker if (CmdOrErr->cmdsize < 8)
176*9880d681SAndroid Build Coastguard Worker return malformedError("load command " + Twine(LoadCommandIndex) +
177*9880d681SAndroid Build Coastguard Worker " with size less than 8 bytes");
178*9880d681SAndroid Build Coastguard Worker return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
179*9880d681SAndroid Build Coastguard Worker } else
180*9880d681SAndroid Build Coastguard Worker return CmdOrErr.takeError();
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker static Expected<MachOObjectFile::LoadCommandInfo>
getFirstLoadCommandInfo(const MachOObjectFile * Obj)184*9880d681SAndroid Build Coastguard Worker getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
185*9880d681SAndroid Build Coastguard Worker unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
186*9880d681SAndroid Build Coastguard Worker : sizeof(MachO::mach_header);
187*9880d681SAndroid Build Coastguard Worker if (sizeof(MachOObjectFile::LoadCommandInfo) > Obj->getHeader().sizeofcmds)
188*9880d681SAndroid Build Coastguard Worker return malformedError("load command 0 extends past the end all load "
189*9880d681SAndroid Build Coastguard Worker "commands in the file");
190*9880d681SAndroid Build Coastguard Worker return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker static Expected<MachOObjectFile::LoadCommandInfo>
getNextLoadCommandInfo(const MachOObjectFile * Obj,uint32_t LoadCommandIndex,const MachOObjectFile::LoadCommandInfo & L)194*9880d681SAndroid Build Coastguard Worker getNextLoadCommandInfo(const MachOObjectFile *Obj, uint32_t LoadCommandIndex,
195*9880d681SAndroid Build Coastguard Worker const MachOObjectFile::LoadCommandInfo &L) {
196*9880d681SAndroid Build Coastguard Worker unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
197*9880d681SAndroid Build Coastguard Worker : sizeof(MachO::mach_header);
198*9880d681SAndroid Build Coastguard Worker if (L.Ptr + L.C.cmdsize + sizeof(MachOObjectFile::LoadCommandInfo) >
199*9880d681SAndroid Build Coastguard Worker Obj->getData().data() + HeaderSize + Obj->getHeader().sizeofcmds)
200*9880d681SAndroid Build Coastguard Worker return malformedError("load command " + Twine(LoadCommandIndex + 1) +
201*9880d681SAndroid Build Coastguard Worker " extends past the end all load commands in the file");
202*9880d681SAndroid Build Coastguard Worker return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker template <typename T>
parseHeader(const MachOObjectFile * Obj,T & Header,Error & Err)206*9880d681SAndroid Build Coastguard Worker static void parseHeader(const MachOObjectFile *Obj, T &Header,
207*9880d681SAndroid Build Coastguard Worker Error &Err) {
208*9880d681SAndroid Build Coastguard Worker if (sizeof(T) > Obj->getData().size()) {
209*9880d681SAndroid Build Coastguard Worker Err = malformedError("the mach header extends past the end of the "
210*9880d681SAndroid Build Coastguard Worker "file");
211*9880d681SAndroid Build Coastguard Worker return;
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
214*9880d681SAndroid Build Coastguard Worker Header = *HeaderOrErr;
215*9880d681SAndroid Build Coastguard Worker else
216*9880d681SAndroid Build Coastguard Worker Err = HeaderOrErr.takeError();
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
220*9880d681SAndroid Build Coastguard Worker // sections to \param Sections, and optionally sets
221*9880d681SAndroid Build Coastguard Worker // \param IsPageZeroSegment to true.
222*9880d681SAndroid Build Coastguard Worker template <typename SegmentCmd>
parseSegmentLoadCommand(const MachOObjectFile * Obj,const MachOObjectFile::LoadCommandInfo & Load,SmallVectorImpl<const char * > & Sections,bool & IsPageZeroSegment,uint32_t LoadCommandIndex,const char * CmdName)223*9880d681SAndroid Build Coastguard Worker static Error parseSegmentLoadCommand(
224*9880d681SAndroid Build Coastguard Worker const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
225*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
226*9880d681SAndroid Build Coastguard Worker uint32_t LoadCommandIndex, const char *CmdName) {
227*9880d681SAndroid Build Coastguard Worker const unsigned SegmentLoadSize = sizeof(SegmentCmd);
228*9880d681SAndroid Build Coastguard Worker if (Load.C.cmdsize < SegmentLoadSize)
229*9880d681SAndroid Build Coastguard Worker return malformedError("load command " + Twine(LoadCommandIndex) +
230*9880d681SAndroid Build Coastguard Worker " " + CmdName + " cmdsize too small");
231*9880d681SAndroid Build Coastguard Worker if (auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr)) {
232*9880d681SAndroid Build Coastguard Worker SegmentCmd S = SegOrErr.get();
233*9880d681SAndroid Build Coastguard Worker const unsigned SectionSize =
234*9880d681SAndroid Build Coastguard Worker Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section);
235*9880d681SAndroid Build Coastguard Worker if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
236*9880d681SAndroid Build Coastguard Worker S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
237*9880d681SAndroid Build Coastguard Worker return malformedError("load command " + Twine(LoadCommandIndex) +
238*9880d681SAndroid Build Coastguard Worker " inconsistent cmdsize in " + CmdName +
239*9880d681SAndroid Build Coastguard Worker " for the number of sections");
240*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0; J < S.nsects; ++J) {
241*9880d681SAndroid Build Coastguard Worker const char *Sec = getSectionPtr(Obj, Load, J);
242*9880d681SAndroid Build Coastguard Worker Sections.push_back(Sec);
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
245*9880d681SAndroid Build Coastguard Worker } else
246*9880d681SAndroid Build Coastguard Worker return SegOrErr.takeError();
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker return Error::success();
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<MachOObjectFile>>
create(MemoryBufferRef Object,bool IsLittleEndian,bool Is64Bits)252*9880d681SAndroid Build Coastguard Worker MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
253*9880d681SAndroid Build Coastguard Worker bool Is64Bits) {
254*9880d681SAndroid Build Coastguard Worker Error Err;
255*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MachOObjectFile> Obj(
256*9880d681SAndroid Build Coastguard Worker new MachOObjectFile(std::move(Object), IsLittleEndian,
257*9880d681SAndroid Build Coastguard Worker Is64Bits, Err));
258*9880d681SAndroid Build Coastguard Worker if (Err)
259*9880d681SAndroid Build Coastguard Worker return std::move(Err);
260*9880d681SAndroid Build Coastguard Worker return std::move(Obj);
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
MachOObjectFile(MemoryBufferRef Object,bool IsLittleEndian,bool Is64bits,Error & Err)263*9880d681SAndroid Build Coastguard Worker MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
264*9880d681SAndroid Build Coastguard Worker bool Is64bits, Error &Err)
265*9880d681SAndroid Build Coastguard Worker : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
266*9880d681SAndroid Build Coastguard Worker SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
267*9880d681SAndroid Build Coastguard Worker DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
268*9880d681SAndroid Build Coastguard Worker DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
269*9880d681SAndroid Build Coastguard Worker HasPageZeroSegment(false) {
270*9880d681SAndroid Build Coastguard Worker ErrorAsOutParameter ErrAsOutParam(Err);
271*9880d681SAndroid Build Coastguard Worker uint64_t BigSize;
272*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
273*9880d681SAndroid Build Coastguard Worker parseHeader(this, Header64, Err);
274*9880d681SAndroid Build Coastguard Worker BigSize = sizeof(MachO::mach_header_64);
275*9880d681SAndroid Build Coastguard Worker } else {
276*9880d681SAndroid Build Coastguard Worker parseHeader(this, Header, Err);
277*9880d681SAndroid Build Coastguard Worker BigSize = sizeof(MachO::mach_header);
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker if (Err)
280*9880d681SAndroid Build Coastguard Worker return;
281*9880d681SAndroid Build Coastguard Worker BigSize += getHeader().sizeofcmds;
282*9880d681SAndroid Build Coastguard Worker if (getData().data() + BigSize > getData().end()) {
283*9880d681SAndroid Build Coastguard Worker Err = malformedError("load commands extend past the end of the file");
284*9880d681SAndroid Build Coastguard Worker return;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker uint32_t LoadCommandCount = getHeader().ncmds;
288*9880d681SAndroid Build Coastguard Worker if (LoadCommandCount == 0)
289*9880d681SAndroid Build Coastguard Worker return;
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker LoadCommandInfo Load;
292*9880d681SAndroid Build Coastguard Worker if (auto LoadOrErr = getFirstLoadCommandInfo(this))
293*9880d681SAndroid Build Coastguard Worker Load = *LoadOrErr;
294*9880d681SAndroid Build Coastguard Worker else {
295*9880d681SAndroid Build Coastguard Worker Err = LoadOrErr.takeError();
296*9880d681SAndroid Build Coastguard Worker return;
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0; I < LoadCommandCount; ++I) {
300*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
301*9880d681SAndroid Build Coastguard Worker if (Load.C.cmdsize % 8 != 0) {
302*9880d681SAndroid Build Coastguard Worker // We have a hack here to allow 64-bit Mach-O core files to have
303*9880d681SAndroid Build Coastguard Worker // LC_THREAD commands that are only a multiple of 4 and not 8 to be
304*9880d681SAndroid Build Coastguard Worker // allowed since the macOS kernel produces them.
305*9880d681SAndroid Build Coastguard Worker if (getHeader().filetype != MachO::MH_CORE ||
306*9880d681SAndroid Build Coastguard Worker Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
307*9880d681SAndroid Build Coastguard Worker Err = malformedError("load command " + Twine(I) + " cmdsize not a "
308*9880d681SAndroid Build Coastguard Worker "multiple of 8");
309*9880d681SAndroid Build Coastguard Worker return;
310*9880d681SAndroid Build Coastguard Worker }
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker } else {
313*9880d681SAndroid Build Coastguard Worker if (Load.C.cmdsize % 4 != 0) {
314*9880d681SAndroid Build Coastguard Worker Err = malformedError("load command " + Twine(I) + " cmdsize not a "
315*9880d681SAndroid Build Coastguard Worker "multiple of 4");
316*9880d681SAndroid Build Coastguard Worker return;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker }
319*9880d681SAndroid Build Coastguard Worker LoadCommands.push_back(Load);
320*9880d681SAndroid Build Coastguard Worker if (Load.C.cmd == MachO::LC_SYMTAB) {
321*9880d681SAndroid Build Coastguard Worker // Multiple symbol tables
322*9880d681SAndroid Build Coastguard Worker if (SymtabLoadCmd) {
323*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple symbol tables");
324*9880d681SAndroid Build Coastguard Worker return;
325*9880d681SAndroid Build Coastguard Worker }
326*9880d681SAndroid Build Coastguard Worker SymtabLoadCmd = Load.Ptr;
327*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
328*9880d681SAndroid Build Coastguard Worker // Multiple dynamic symbol tables
329*9880d681SAndroid Build Coastguard Worker if (DysymtabLoadCmd) {
330*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple dynamic symbol tables");
331*9880d681SAndroid Build Coastguard Worker return;
332*9880d681SAndroid Build Coastguard Worker }
333*9880d681SAndroid Build Coastguard Worker DysymtabLoadCmd = Load.Ptr;
334*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
335*9880d681SAndroid Build Coastguard Worker // Multiple data in code tables
336*9880d681SAndroid Build Coastguard Worker if (DataInCodeLoadCmd) {
337*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple data-in-code tables");
338*9880d681SAndroid Build Coastguard Worker return;
339*9880d681SAndroid Build Coastguard Worker }
340*9880d681SAndroid Build Coastguard Worker DataInCodeLoadCmd = Load.Ptr;
341*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
342*9880d681SAndroid Build Coastguard Worker // Multiple linker optimization hint tables
343*9880d681SAndroid Build Coastguard Worker if (LinkOptHintsLoadCmd) {
344*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple linker optimization hint tables");
345*9880d681SAndroid Build Coastguard Worker return;
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker LinkOptHintsLoadCmd = Load.Ptr;
348*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
349*9880d681SAndroid Build Coastguard Worker Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
350*9880d681SAndroid Build Coastguard Worker // Multiple dyldinfo load commands
351*9880d681SAndroid Build Coastguard Worker if (DyldInfoLoadCmd) {
352*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple dyldinfo load commands");
353*9880d681SAndroid Build Coastguard Worker return;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker DyldInfoLoadCmd = Load.Ptr;
356*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_UUID) {
357*9880d681SAndroid Build Coastguard Worker // Multiple UUID load commands
358*9880d681SAndroid Build Coastguard Worker if (UuidLoadCmd) {
359*9880d681SAndroid Build Coastguard Worker Err = malformedError("Multiple UUID load commands");
360*9880d681SAndroid Build Coastguard Worker return;
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker UuidLoadCmd = Load.Ptr;
363*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
364*9880d681SAndroid Build Coastguard Worker if ((Err = parseSegmentLoadCommand<MachO::segment_command_64>(
365*9880d681SAndroid Build Coastguard Worker this, Load, Sections, HasPageZeroSegment, I,
366*9880d681SAndroid Build Coastguard Worker "LC_SEGMENT_64")))
367*9880d681SAndroid Build Coastguard Worker return;
368*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_SEGMENT) {
369*9880d681SAndroid Build Coastguard Worker if ((Err = parseSegmentLoadCommand<MachO::segment_command>(
370*9880d681SAndroid Build Coastguard Worker this, Load, Sections, HasPageZeroSegment, I, "LC_SEGMENT")))
371*9880d681SAndroid Build Coastguard Worker return;
372*9880d681SAndroid Build Coastguard Worker } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
373*9880d681SAndroid Build Coastguard Worker Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
374*9880d681SAndroid Build Coastguard Worker Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
375*9880d681SAndroid Build Coastguard Worker Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
376*9880d681SAndroid Build Coastguard Worker Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
377*9880d681SAndroid Build Coastguard Worker Libraries.push_back(Load.Ptr);
378*9880d681SAndroid Build Coastguard Worker }
379*9880d681SAndroid Build Coastguard Worker if (I < LoadCommandCount - 1) {
380*9880d681SAndroid Build Coastguard Worker if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
381*9880d681SAndroid Build Coastguard Worker Load = *LoadOrErr;
382*9880d681SAndroid Build Coastguard Worker else {
383*9880d681SAndroid Build Coastguard Worker Err = LoadOrErr.takeError();
384*9880d681SAndroid Build Coastguard Worker return;
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker }
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker if (!SymtabLoadCmd) {
389*9880d681SAndroid Build Coastguard Worker if (DysymtabLoadCmd) {
390*9880d681SAndroid Build Coastguard Worker Err = malformedError("contains LC_DYSYMTAB load command without a "
391*9880d681SAndroid Build Coastguard Worker "LC_SYMTAB load command");
392*9880d681SAndroid Build Coastguard Worker return;
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker } else if (DysymtabLoadCmd) {
395*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Symtab =
396*9880d681SAndroid Build Coastguard Worker getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
397*9880d681SAndroid Build Coastguard Worker MachO::dysymtab_command Dysymtab =
398*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
399*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
400*9880d681SAndroid Build Coastguard Worker Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
401*9880d681SAndroid Build Coastguard Worker "extends past the end of the symbol table");
402*9880d681SAndroid Build Coastguard Worker return;
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker uint64_t BigSize = Dysymtab.ilocalsym;
405*9880d681SAndroid Build Coastguard Worker BigSize += Dysymtab.nlocalsym;
406*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
407*9880d681SAndroid Build Coastguard Worker Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
408*9880d681SAndroid Build Coastguard Worker "command extends past the end of the symbol table");
409*9880d681SAndroid Build Coastguard Worker return;
410*9880d681SAndroid Build Coastguard Worker }
411*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
412*9880d681SAndroid Build Coastguard Worker Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
413*9880d681SAndroid Build Coastguard Worker "extends past the end of the symbol table");
414*9880d681SAndroid Build Coastguard Worker return;
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker BigSize = Dysymtab.iextdefsym;
417*9880d681SAndroid Build Coastguard Worker BigSize += Dysymtab.nextdefsym;
418*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
419*9880d681SAndroid Build Coastguard Worker Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
420*9880d681SAndroid Build Coastguard Worker "load command extends past the end of the symbol "
421*9880d681SAndroid Build Coastguard Worker "table");
422*9880d681SAndroid Build Coastguard Worker return;
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
425*9880d681SAndroid Build Coastguard Worker Err = malformedError("nundefsym in LC_DYSYMTAB load command "
426*9880d681SAndroid Build Coastguard Worker "extends past the end of the symbol table");
427*9880d681SAndroid Build Coastguard Worker return;
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker BigSize = Dysymtab.iundefsym;
430*9880d681SAndroid Build Coastguard Worker BigSize += Dysymtab.nundefsym;
431*9880d681SAndroid Build Coastguard Worker if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
432*9880d681SAndroid Build Coastguard Worker Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
433*9880d681SAndroid Build Coastguard Worker " command extends past the end of the symbol table");
434*9880d681SAndroid Build Coastguard Worker return;
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker assert(LoadCommands.size() == LoadCommandCount);
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker Err = Error::success();
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker
moveSymbolNext(DataRefImpl & Symb) const442*9880d681SAndroid Build Coastguard Worker void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
443*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableEntrySize = is64Bit() ?
444*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist_64) :
445*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist);
446*9880d681SAndroid Build Coastguard Worker Symb.p += SymbolTableEntrySize;
447*9880d681SAndroid Build Coastguard Worker }
448*9880d681SAndroid Build Coastguard Worker
getSymbolName(DataRefImpl Symb) const449*9880d681SAndroid Build Coastguard Worker Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
450*9880d681SAndroid Build Coastguard Worker StringRef StringTable = getStringTableData();
451*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
452*9880d681SAndroid Build Coastguard Worker const char *Start = &StringTable.data()[Entry.n_strx];
453*9880d681SAndroid Build Coastguard Worker if (Start < getData().begin() || Start >= getData().end()) {
454*9880d681SAndroid Build Coastguard Worker return malformedError("bad string index: " + Twine(Entry.n_strx) +
455*9880d681SAndroid Build Coastguard Worker " for symbol at index " + Twine(getSymbolIndex(Symb)));
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker return StringRef(Start);
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker
getSectionType(SectionRef Sec) const460*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
461*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI = Sec.getRawDataRefImpl();
462*9880d681SAndroid Build Coastguard Worker uint32_t Flags = getSectionFlags(this, DRI);
463*9880d681SAndroid Build Coastguard Worker return Flags & MachO::SECTION_TYPE;
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker
getNValue(DataRefImpl Sym) const466*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
467*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
468*9880d681SAndroid Build Coastguard Worker MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
469*9880d681SAndroid Build Coastguard Worker return Entry.n_value;
470*9880d681SAndroid Build Coastguard Worker }
471*9880d681SAndroid Build Coastguard Worker MachO::nlist Entry = getSymbolTableEntry(Sym);
472*9880d681SAndroid Build Coastguard Worker return Entry.n_value;
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Worker // getIndirectName() returns the name of the alias'ed symbol who's string table
476*9880d681SAndroid Build Coastguard Worker // index is in the n_value field.
getIndirectName(DataRefImpl Symb,StringRef & Res) const477*9880d681SAndroid Build Coastguard Worker std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
478*9880d681SAndroid Build Coastguard Worker StringRef &Res) const {
479*9880d681SAndroid Build Coastguard Worker StringRef StringTable = getStringTableData();
480*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
481*9880d681SAndroid Build Coastguard Worker if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
482*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
483*9880d681SAndroid Build Coastguard Worker uint64_t NValue = getNValue(Symb);
484*9880d681SAndroid Build Coastguard Worker if (NValue >= StringTable.size())
485*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
486*9880d681SAndroid Build Coastguard Worker const char *Start = &StringTable.data()[NValue];
487*9880d681SAndroid Build Coastguard Worker Res = StringRef(Start);
488*9880d681SAndroid Build Coastguard Worker return std::error_code();
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker
getSymbolValueImpl(DataRefImpl Sym) const491*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
492*9880d681SAndroid Build Coastguard Worker return getNValue(Sym);
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker
getSymbolAddress(DataRefImpl Sym) const495*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
496*9880d681SAndroid Build Coastguard Worker return getSymbolValue(Sym);
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker
getSymbolAlignment(DataRefImpl DRI) const499*9880d681SAndroid Build Coastguard Worker uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
500*9880d681SAndroid Build Coastguard Worker uint32_t flags = getSymbolFlags(DRI);
501*9880d681SAndroid Build Coastguard Worker if (flags & SymbolRef::SF_Common) {
502*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
503*9880d681SAndroid Build Coastguard Worker return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
504*9880d681SAndroid Build Coastguard Worker }
505*9880d681SAndroid Build Coastguard Worker return 0;
506*9880d681SAndroid Build Coastguard Worker }
507*9880d681SAndroid Build Coastguard Worker
getCommonSymbolSizeImpl(DataRefImpl DRI) const508*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
509*9880d681SAndroid Build Coastguard Worker return getNValue(DRI);
510*9880d681SAndroid Build Coastguard Worker }
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Worker Expected<SymbolRef::Type>
getSymbolType(DataRefImpl Symb) const513*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
514*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
515*9880d681SAndroid Build Coastguard Worker uint8_t n_type = Entry.n_type;
516*9880d681SAndroid Build Coastguard Worker
517*9880d681SAndroid Build Coastguard Worker // If this is a STAB debugging symbol, we can do nothing more.
518*9880d681SAndroid Build Coastguard Worker if (n_type & MachO::N_STAB)
519*9880d681SAndroid Build Coastguard Worker return SymbolRef::ST_Debug;
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker switch (n_type & MachO::N_TYPE) {
522*9880d681SAndroid Build Coastguard Worker case MachO::N_UNDF :
523*9880d681SAndroid Build Coastguard Worker return SymbolRef::ST_Unknown;
524*9880d681SAndroid Build Coastguard Worker case MachO::N_SECT :
525*9880d681SAndroid Build Coastguard Worker Expected<section_iterator> SecOrError = getSymbolSection(Symb);
526*9880d681SAndroid Build Coastguard Worker if (!SecOrError)
527*9880d681SAndroid Build Coastguard Worker return SecOrError.takeError();
528*9880d681SAndroid Build Coastguard Worker section_iterator Sec = *SecOrError;
529*9880d681SAndroid Build Coastguard Worker if (Sec->isData() || Sec->isBSS())
530*9880d681SAndroid Build Coastguard Worker return SymbolRef::ST_Data;
531*9880d681SAndroid Build Coastguard Worker return SymbolRef::ST_Function;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker return SymbolRef::ST_Other;
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker
getSymbolFlags(DataRefImpl DRI) const536*9880d681SAndroid Build Coastguard Worker uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
537*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker uint8_t MachOType = Entry.n_type;
540*9880d681SAndroid Build Coastguard Worker uint16_t MachOFlags = Entry.n_desc;
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker uint32_t Result = SymbolRef::SF_None;
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
545*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Indirect;
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker if (MachOType & MachO::N_STAB)
548*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_FormatSpecific;
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Worker if (MachOType & MachO::N_EXT) {
551*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Global;
552*9880d681SAndroid Build Coastguard Worker if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
553*9880d681SAndroid Build Coastguard Worker if (getNValue(DRI))
554*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Common;
555*9880d681SAndroid Build Coastguard Worker else
556*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Undefined;
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker if (!(MachOType & MachO::N_PEXT))
560*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Exported;
561*9880d681SAndroid Build Coastguard Worker }
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Worker if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
564*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Weak;
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
567*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Thumb;
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
570*9880d681SAndroid Build Coastguard Worker Result |= SymbolRef::SF_Absolute;
571*9880d681SAndroid Build Coastguard Worker
572*9880d681SAndroid Build Coastguard Worker return Result;
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker Expected<section_iterator>
getSymbolSection(DataRefImpl Symb) const576*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
577*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
578*9880d681SAndroid Build Coastguard Worker uint8_t index = Entry.n_sect;
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Worker if (index == 0)
581*9880d681SAndroid Build Coastguard Worker return section_end();
582*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
583*9880d681SAndroid Build Coastguard Worker DRI.d.a = index - 1;
584*9880d681SAndroid Build Coastguard Worker if (DRI.d.a >= Sections.size()){
585*9880d681SAndroid Build Coastguard Worker return malformedError("bad section index: " + Twine((int)index) +
586*9880d681SAndroid Build Coastguard Worker " for symbol at index " + Twine(getSymbolIndex(Symb)));
587*9880d681SAndroid Build Coastguard Worker }
588*9880d681SAndroid Build Coastguard Worker return section_iterator(SectionRef(DRI, this));
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker
getSymbolSectionID(SymbolRef Sym) const591*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
592*9880d681SAndroid Build Coastguard Worker MachO::nlist_base Entry =
593*9880d681SAndroid Build Coastguard Worker getSymbolTableEntryBase(this, Sym.getRawDataRefImpl());
594*9880d681SAndroid Build Coastguard Worker return Entry.n_sect - 1;
595*9880d681SAndroid Build Coastguard Worker }
596*9880d681SAndroid Build Coastguard Worker
moveSectionNext(DataRefImpl & Sec) const597*9880d681SAndroid Build Coastguard Worker void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
598*9880d681SAndroid Build Coastguard Worker Sec.d.a++;
599*9880d681SAndroid Build Coastguard Worker }
600*9880d681SAndroid Build Coastguard Worker
getSectionName(DataRefImpl Sec,StringRef & Result) const601*9880d681SAndroid Build Coastguard Worker std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
602*9880d681SAndroid Build Coastguard Worker StringRef &Result) const {
603*9880d681SAndroid Build Coastguard Worker ArrayRef<char> Raw = getSectionRawName(Sec);
604*9880d681SAndroid Build Coastguard Worker Result = parseSegmentOrSectionName(Raw.data());
605*9880d681SAndroid Build Coastguard Worker return std::error_code();
606*9880d681SAndroid Build Coastguard Worker }
607*9880d681SAndroid Build Coastguard Worker
getSectionAddress(DataRefImpl Sec) const608*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
609*9880d681SAndroid Build Coastguard Worker if (is64Bit())
610*9880d681SAndroid Build Coastguard Worker return getSection64(Sec).addr;
611*9880d681SAndroid Build Coastguard Worker return getSection(Sec).addr;
612*9880d681SAndroid Build Coastguard Worker }
613*9880d681SAndroid Build Coastguard Worker
getSectionSize(DataRefImpl Sec) const614*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
615*9880d681SAndroid Build Coastguard Worker // In the case if a malformed Mach-O file where the section offset is past
616*9880d681SAndroid Build Coastguard Worker // the end of the file or some part of the section size is past the end of
617*9880d681SAndroid Build Coastguard Worker // the file return a size of zero or a size that covers the rest of the file
618*9880d681SAndroid Build Coastguard Worker // but does not extend past the end of the file.
619*9880d681SAndroid Build Coastguard Worker uint32_t SectOffset, SectType;
620*9880d681SAndroid Build Coastguard Worker uint64_t SectSize;
621*9880d681SAndroid Build Coastguard Worker
622*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
623*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = getSection64(Sec);
624*9880d681SAndroid Build Coastguard Worker SectOffset = Sect.offset;
625*9880d681SAndroid Build Coastguard Worker SectSize = Sect.size;
626*9880d681SAndroid Build Coastguard Worker SectType = Sect.flags & MachO::SECTION_TYPE;
627*9880d681SAndroid Build Coastguard Worker } else {
628*9880d681SAndroid Build Coastguard Worker MachO::section Sect = getSection(Sec);
629*9880d681SAndroid Build Coastguard Worker SectOffset = Sect.offset;
630*9880d681SAndroid Build Coastguard Worker SectSize = Sect.size;
631*9880d681SAndroid Build Coastguard Worker SectType = Sect.flags & MachO::SECTION_TYPE;
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
634*9880d681SAndroid Build Coastguard Worker return SectSize;
635*9880d681SAndroid Build Coastguard Worker uint64_t FileSize = getData().size();
636*9880d681SAndroid Build Coastguard Worker if (SectOffset > FileSize)
637*9880d681SAndroid Build Coastguard Worker return 0;
638*9880d681SAndroid Build Coastguard Worker if (FileSize - SectOffset < SectSize)
639*9880d681SAndroid Build Coastguard Worker return FileSize - SectOffset;
640*9880d681SAndroid Build Coastguard Worker return SectSize;
641*9880d681SAndroid Build Coastguard Worker }
642*9880d681SAndroid Build Coastguard Worker
getSectionContents(DataRefImpl Sec,StringRef & Res) const643*9880d681SAndroid Build Coastguard Worker std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
644*9880d681SAndroid Build Coastguard Worker StringRef &Res) const {
645*9880d681SAndroid Build Coastguard Worker uint32_t Offset;
646*9880d681SAndroid Build Coastguard Worker uint64_t Size;
647*9880d681SAndroid Build Coastguard Worker
648*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
649*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = getSection64(Sec);
650*9880d681SAndroid Build Coastguard Worker Offset = Sect.offset;
651*9880d681SAndroid Build Coastguard Worker Size = Sect.size;
652*9880d681SAndroid Build Coastguard Worker } else {
653*9880d681SAndroid Build Coastguard Worker MachO::section Sect = getSection(Sec);
654*9880d681SAndroid Build Coastguard Worker Offset = Sect.offset;
655*9880d681SAndroid Build Coastguard Worker Size = Sect.size;
656*9880d681SAndroid Build Coastguard Worker }
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Worker Res = this->getData().substr(Offset, Size);
659*9880d681SAndroid Build Coastguard Worker return std::error_code();
660*9880d681SAndroid Build Coastguard Worker }
661*9880d681SAndroid Build Coastguard Worker
getSectionAlignment(DataRefImpl Sec) const662*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
663*9880d681SAndroid Build Coastguard Worker uint32_t Align;
664*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
665*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = getSection64(Sec);
666*9880d681SAndroid Build Coastguard Worker Align = Sect.align;
667*9880d681SAndroid Build Coastguard Worker } else {
668*9880d681SAndroid Build Coastguard Worker MachO::section Sect = getSection(Sec);
669*9880d681SAndroid Build Coastguard Worker Align = Sect.align;
670*9880d681SAndroid Build Coastguard Worker }
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Worker return uint64_t(1) << Align;
673*9880d681SAndroid Build Coastguard Worker }
674*9880d681SAndroid Build Coastguard Worker
isSectionCompressed(DataRefImpl Sec) const675*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
676*9880d681SAndroid Build Coastguard Worker return false;
677*9880d681SAndroid Build Coastguard Worker }
678*9880d681SAndroid Build Coastguard Worker
isSectionText(DataRefImpl Sec) const679*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
680*9880d681SAndroid Build Coastguard Worker uint32_t Flags = getSectionFlags(this, Sec);
681*9880d681SAndroid Build Coastguard Worker return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
isSectionData(DataRefImpl Sec) const684*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
685*9880d681SAndroid Build Coastguard Worker uint32_t Flags = getSectionFlags(this, Sec);
686*9880d681SAndroid Build Coastguard Worker unsigned SectionType = Flags & MachO::SECTION_TYPE;
687*9880d681SAndroid Build Coastguard Worker return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
688*9880d681SAndroid Build Coastguard Worker !(SectionType == MachO::S_ZEROFILL ||
689*9880d681SAndroid Build Coastguard Worker SectionType == MachO::S_GB_ZEROFILL);
690*9880d681SAndroid Build Coastguard Worker }
691*9880d681SAndroid Build Coastguard Worker
isSectionBSS(DataRefImpl Sec) const692*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
693*9880d681SAndroid Build Coastguard Worker uint32_t Flags = getSectionFlags(this, Sec);
694*9880d681SAndroid Build Coastguard Worker unsigned SectionType = Flags & MachO::SECTION_TYPE;
695*9880d681SAndroid Build Coastguard Worker return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
696*9880d681SAndroid Build Coastguard Worker (SectionType == MachO::S_ZEROFILL ||
697*9880d681SAndroid Build Coastguard Worker SectionType == MachO::S_GB_ZEROFILL);
698*9880d681SAndroid Build Coastguard Worker }
699*9880d681SAndroid Build Coastguard Worker
getSectionID(SectionRef Sec) const700*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
701*9880d681SAndroid Build Coastguard Worker return Sec.getRawDataRefImpl().d.a;
702*9880d681SAndroid Build Coastguard Worker }
703*9880d681SAndroid Build Coastguard Worker
isSectionVirtual(DataRefImpl Sec) const704*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
705*9880d681SAndroid Build Coastguard Worker // FIXME: Unimplemented.
706*9880d681SAndroid Build Coastguard Worker return false;
707*9880d681SAndroid Build Coastguard Worker }
708*9880d681SAndroid Build Coastguard Worker
isSectionBitcode(DataRefImpl Sec) const709*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
710*9880d681SAndroid Build Coastguard Worker StringRef SegmentName = getSectionFinalSegmentName(Sec);
711*9880d681SAndroid Build Coastguard Worker StringRef SectName;
712*9880d681SAndroid Build Coastguard Worker if (!getSectionName(Sec, SectName))
713*9880d681SAndroid Build Coastguard Worker return (SegmentName == "__LLVM" && SectName == "__bitcode");
714*9880d681SAndroid Build Coastguard Worker return false;
715*9880d681SAndroid Build Coastguard Worker }
716*9880d681SAndroid Build Coastguard Worker
section_rel_begin(DataRefImpl Sec) const717*9880d681SAndroid Build Coastguard Worker relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
718*9880d681SAndroid Build Coastguard Worker DataRefImpl Ret;
719*9880d681SAndroid Build Coastguard Worker Ret.d.a = Sec.d.a;
720*9880d681SAndroid Build Coastguard Worker Ret.d.b = 0;
721*9880d681SAndroid Build Coastguard Worker return relocation_iterator(RelocationRef(Ret, this));
722*9880d681SAndroid Build Coastguard Worker }
723*9880d681SAndroid Build Coastguard Worker
724*9880d681SAndroid Build Coastguard Worker relocation_iterator
section_rel_end(DataRefImpl Sec) const725*9880d681SAndroid Build Coastguard Worker MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
726*9880d681SAndroid Build Coastguard Worker uint32_t Num;
727*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
728*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = getSection64(Sec);
729*9880d681SAndroid Build Coastguard Worker Num = Sect.nreloc;
730*9880d681SAndroid Build Coastguard Worker } else {
731*9880d681SAndroid Build Coastguard Worker MachO::section Sect = getSection(Sec);
732*9880d681SAndroid Build Coastguard Worker Num = Sect.nreloc;
733*9880d681SAndroid Build Coastguard Worker }
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker DataRefImpl Ret;
736*9880d681SAndroid Build Coastguard Worker Ret.d.a = Sec.d.a;
737*9880d681SAndroid Build Coastguard Worker Ret.d.b = Num;
738*9880d681SAndroid Build Coastguard Worker return relocation_iterator(RelocationRef(Ret, this));
739*9880d681SAndroid Build Coastguard Worker }
740*9880d681SAndroid Build Coastguard Worker
moveRelocationNext(DataRefImpl & Rel) const741*9880d681SAndroid Build Coastguard Worker void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
742*9880d681SAndroid Build Coastguard Worker ++Rel.d.b;
743*9880d681SAndroid Build Coastguard Worker }
744*9880d681SAndroid Build Coastguard Worker
getRelocationOffset(DataRefImpl Rel) const745*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
746*9880d681SAndroid Build Coastguard Worker assert(getHeader().filetype == MachO::MH_OBJECT &&
747*9880d681SAndroid Build Coastguard Worker "Only implemented for MH_OBJECT");
748*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RE = getRelocation(Rel);
749*9880d681SAndroid Build Coastguard Worker return getAnyRelocationAddress(RE);
750*9880d681SAndroid Build Coastguard Worker }
751*9880d681SAndroid Build Coastguard Worker
752*9880d681SAndroid Build Coastguard Worker symbol_iterator
getRelocationSymbol(DataRefImpl Rel) const753*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
754*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RE = getRelocation(Rel);
755*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE))
756*9880d681SAndroid Build Coastguard Worker return symbol_end();
757*9880d681SAndroid Build Coastguard Worker
758*9880d681SAndroid Build Coastguard Worker uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
759*9880d681SAndroid Build Coastguard Worker bool isExtern = getPlainRelocationExternal(RE);
760*9880d681SAndroid Build Coastguard Worker if (!isExtern)
761*9880d681SAndroid Build Coastguard Worker return symbol_end();
762*9880d681SAndroid Build Coastguard Worker
763*9880d681SAndroid Build Coastguard Worker MachO::symtab_command S = getSymtabLoadCommand();
764*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableEntrySize = is64Bit() ?
765*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist_64) :
766*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist);
767*9880d681SAndroid Build Coastguard Worker uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
768*9880d681SAndroid Build Coastguard Worker DataRefImpl Sym;
769*9880d681SAndroid Build Coastguard Worker Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
770*9880d681SAndroid Build Coastguard Worker return symbol_iterator(SymbolRef(Sym, this));
771*9880d681SAndroid Build Coastguard Worker }
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker section_iterator
getRelocationSection(DataRefImpl Rel) const774*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
775*9880d681SAndroid Build Coastguard Worker return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
776*9880d681SAndroid Build Coastguard Worker }
777*9880d681SAndroid Build Coastguard Worker
getRelocationType(DataRefImpl Rel) const778*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
779*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RE = getRelocation(Rel);
780*9880d681SAndroid Build Coastguard Worker return getAnyRelocationType(RE);
781*9880d681SAndroid Build Coastguard Worker }
782*9880d681SAndroid Build Coastguard Worker
getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result) const783*9880d681SAndroid Build Coastguard Worker void MachOObjectFile::getRelocationTypeName(
784*9880d681SAndroid Build Coastguard Worker DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
785*9880d681SAndroid Build Coastguard Worker StringRef res;
786*9880d681SAndroid Build Coastguard Worker uint64_t RType = getRelocationType(Rel);
787*9880d681SAndroid Build Coastguard Worker
788*9880d681SAndroid Build Coastguard Worker unsigned Arch = this->getArch();
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker switch (Arch) {
791*9880d681SAndroid Build Coastguard Worker case Triple::x86: {
792*9880d681SAndroid Build Coastguard Worker static const char *const Table[] = {
793*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_VANILLA",
794*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_PAIR",
795*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_SECTDIFF",
796*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_PB_LA_PTR",
797*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_LOCAL_SECTDIFF",
798*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_TLV" };
799*9880d681SAndroid Build Coastguard Worker
800*9880d681SAndroid Build Coastguard Worker if (RType > 5)
801*9880d681SAndroid Build Coastguard Worker res = "Unknown";
802*9880d681SAndroid Build Coastguard Worker else
803*9880d681SAndroid Build Coastguard Worker res = Table[RType];
804*9880d681SAndroid Build Coastguard Worker break;
805*9880d681SAndroid Build Coastguard Worker }
806*9880d681SAndroid Build Coastguard Worker case Triple::x86_64: {
807*9880d681SAndroid Build Coastguard Worker static const char *const Table[] = {
808*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_UNSIGNED",
809*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SIGNED",
810*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_BRANCH",
811*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_GOT_LOAD",
812*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_GOT",
813*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SUBTRACTOR",
814*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SIGNED_1",
815*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SIGNED_2",
816*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SIGNED_4",
817*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_TLV" };
818*9880d681SAndroid Build Coastguard Worker
819*9880d681SAndroid Build Coastguard Worker if (RType > 9)
820*9880d681SAndroid Build Coastguard Worker res = "Unknown";
821*9880d681SAndroid Build Coastguard Worker else
822*9880d681SAndroid Build Coastguard Worker res = Table[RType];
823*9880d681SAndroid Build Coastguard Worker break;
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker case Triple::arm: {
826*9880d681SAndroid Build Coastguard Worker static const char *const Table[] = {
827*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_VANILLA",
828*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_PAIR",
829*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_SECTDIFF",
830*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_LOCAL_SECTDIFF",
831*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_PB_LA_PTR",
832*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_BR24",
833*9880d681SAndroid Build Coastguard Worker "ARM_THUMB_RELOC_BR22",
834*9880d681SAndroid Build Coastguard Worker "ARM_THUMB_32BIT_BRANCH",
835*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_HALF",
836*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_HALF_SECTDIFF" };
837*9880d681SAndroid Build Coastguard Worker
838*9880d681SAndroid Build Coastguard Worker if (RType > 9)
839*9880d681SAndroid Build Coastguard Worker res = "Unknown";
840*9880d681SAndroid Build Coastguard Worker else
841*9880d681SAndroid Build Coastguard Worker res = Table[RType];
842*9880d681SAndroid Build Coastguard Worker break;
843*9880d681SAndroid Build Coastguard Worker }
844*9880d681SAndroid Build Coastguard Worker case Triple::aarch64: {
845*9880d681SAndroid Build Coastguard Worker static const char *const Table[] = {
846*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
847*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
848*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
849*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
850*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
851*9880d681SAndroid Build Coastguard Worker "ARM64_RELOC_ADDEND"
852*9880d681SAndroid Build Coastguard Worker };
853*9880d681SAndroid Build Coastguard Worker
854*9880d681SAndroid Build Coastguard Worker if (RType >= array_lengthof(Table))
855*9880d681SAndroid Build Coastguard Worker res = "Unknown";
856*9880d681SAndroid Build Coastguard Worker else
857*9880d681SAndroid Build Coastguard Worker res = Table[RType];
858*9880d681SAndroid Build Coastguard Worker break;
859*9880d681SAndroid Build Coastguard Worker }
860*9880d681SAndroid Build Coastguard Worker case Triple::ppc: {
861*9880d681SAndroid Build Coastguard Worker static const char *const Table[] = {
862*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_VANILLA",
863*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_PAIR",
864*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_BR14",
865*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_BR24",
866*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_HI16",
867*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_LO16",
868*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_HA16",
869*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_LO14",
870*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_SECTDIFF",
871*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_PB_LA_PTR",
872*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_HI16_SECTDIFF",
873*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_LO16_SECTDIFF",
874*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_HA16_SECTDIFF",
875*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_JBSR",
876*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_LO14_SECTDIFF",
877*9880d681SAndroid Build Coastguard Worker "PPC_RELOC_LOCAL_SECTDIFF" };
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker if (RType > 15)
880*9880d681SAndroid Build Coastguard Worker res = "Unknown";
881*9880d681SAndroid Build Coastguard Worker else
882*9880d681SAndroid Build Coastguard Worker res = Table[RType];
883*9880d681SAndroid Build Coastguard Worker break;
884*9880d681SAndroid Build Coastguard Worker }
885*9880d681SAndroid Build Coastguard Worker case Triple::UnknownArch:
886*9880d681SAndroid Build Coastguard Worker res = "Unknown";
887*9880d681SAndroid Build Coastguard Worker break;
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker Result.append(res.begin(), res.end());
890*9880d681SAndroid Build Coastguard Worker }
891*9880d681SAndroid Build Coastguard Worker
getRelocationLength(DataRefImpl Rel) const892*9880d681SAndroid Build Coastguard Worker uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
893*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RE = getRelocation(Rel);
894*9880d681SAndroid Build Coastguard Worker return getAnyRelocationLength(RE);
895*9880d681SAndroid Build Coastguard Worker }
896*9880d681SAndroid Build Coastguard Worker
897*9880d681SAndroid Build Coastguard Worker //
898*9880d681SAndroid Build Coastguard Worker // guessLibraryShortName() is passed a name of a dynamic library and returns a
899*9880d681SAndroid Build Coastguard Worker // guess on what the short name is. Then name is returned as a substring of the
900*9880d681SAndroid Build Coastguard Worker // StringRef Name passed in. The name of the dynamic library is recognized as
901*9880d681SAndroid Build Coastguard Worker // a framework if it has one of the two following forms:
902*9880d681SAndroid Build Coastguard Worker // Foo.framework/Versions/A/Foo
903*9880d681SAndroid Build Coastguard Worker // Foo.framework/Foo
904*9880d681SAndroid Build Coastguard Worker // Where A and Foo can be any string. And may contain a trailing suffix
905*9880d681SAndroid Build Coastguard Worker // starting with an underbar. If the Name is recognized as a framework then
906*9880d681SAndroid Build Coastguard Worker // isFramework is set to true else it is set to false. If the Name has a
907*9880d681SAndroid Build Coastguard Worker // suffix then Suffix is set to the substring in Name that contains the suffix
908*9880d681SAndroid Build Coastguard Worker // else it is set to a NULL StringRef.
909*9880d681SAndroid Build Coastguard Worker //
910*9880d681SAndroid Build Coastguard Worker // The Name of the dynamic library is recognized as a library name if it has
911*9880d681SAndroid Build Coastguard Worker // one of the two following forms:
912*9880d681SAndroid Build Coastguard Worker // libFoo.A.dylib
913*9880d681SAndroid Build Coastguard Worker // libFoo.dylib
914*9880d681SAndroid Build Coastguard Worker // The library may have a suffix trailing the name Foo of the form:
915*9880d681SAndroid Build Coastguard Worker // libFoo_profile.A.dylib
916*9880d681SAndroid Build Coastguard Worker // libFoo_profile.dylib
917*9880d681SAndroid Build Coastguard Worker //
918*9880d681SAndroid Build Coastguard Worker // The Name of the dynamic library is also recognized as a library name if it
919*9880d681SAndroid Build Coastguard Worker // has the following form:
920*9880d681SAndroid Build Coastguard Worker // Foo.qtx
921*9880d681SAndroid Build Coastguard Worker //
922*9880d681SAndroid Build Coastguard Worker // If the Name of the dynamic library is none of the forms above then a NULL
923*9880d681SAndroid Build Coastguard Worker // StringRef is returned.
924*9880d681SAndroid Build Coastguard Worker //
guessLibraryShortName(StringRef Name,bool & isFramework,StringRef & Suffix)925*9880d681SAndroid Build Coastguard Worker StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
926*9880d681SAndroid Build Coastguard Worker bool &isFramework,
927*9880d681SAndroid Build Coastguard Worker StringRef &Suffix) {
928*9880d681SAndroid Build Coastguard Worker StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
929*9880d681SAndroid Build Coastguard Worker size_t a, b, c, d, Idx;
930*9880d681SAndroid Build Coastguard Worker
931*9880d681SAndroid Build Coastguard Worker isFramework = false;
932*9880d681SAndroid Build Coastguard Worker Suffix = StringRef();
933*9880d681SAndroid Build Coastguard Worker
934*9880d681SAndroid Build Coastguard Worker // Pull off the last component and make Foo point to it
935*9880d681SAndroid Build Coastguard Worker a = Name.rfind('/');
936*9880d681SAndroid Build Coastguard Worker if (a == Name.npos || a == 0)
937*9880d681SAndroid Build Coastguard Worker goto guess_library;
938*9880d681SAndroid Build Coastguard Worker Foo = Name.slice(a+1, Name.npos);
939*9880d681SAndroid Build Coastguard Worker
940*9880d681SAndroid Build Coastguard Worker // Look for a suffix starting with a '_'
941*9880d681SAndroid Build Coastguard Worker Idx = Foo.rfind('_');
942*9880d681SAndroid Build Coastguard Worker if (Idx != Foo.npos && Foo.size() >= 2) {
943*9880d681SAndroid Build Coastguard Worker Suffix = Foo.slice(Idx, Foo.npos);
944*9880d681SAndroid Build Coastguard Worker Foo = Foo.slice(0, Idx);
945*9880d681SAndroid Build Coastguard Worker }
946*9880d681SAndroid Build Coastguard Worker
947*9880d681SAndroid Build Coastguard Worker // First look for the form Foo.framework/Foo
948*9880d681SAndroid Build Coastguard Worker b = Name.rfind('/', a);
949*9880d681SAndroid Build Coastguard Worker if (b == Name.npos)
950*9880d681SAndroid Build Coastguard Worker Idx = 0;
951*9880d681SAndroid Build Coastguard Worker else
952*9880d681SAndroid Build Coastguard Worker Idx = b+1;
953*9880d681SAndroid Build Coastguard Worker F = Name.slice(Idx, Idx + Foo.size());
954*9880d681SAndroid Build Coastguard Worker DotFramework = Name.slice(Idx + Foo.size(),
955*9880d681SAndroid Build Coastguard Worker Idx + Foo.size() + sizeof(".framework/")-1);
956*9880d681SAndroid Build Coastguard Worker if (F == Foo && DotFramework == ".framework/") {
957*9880d681SAndroid Build Coastguard Worker isFramework = true;
958*9880d681SAndroid Build Coastguard Worker return Foo;
959*9880d681SAndroid Build Coastguard Worker }
960*9880d681SAndroid Build Coastguard Worker
961*9880d681SAndroid Build Coastguard Worker // Next look for the form Foo.framework/Versions/A/Foo
962*9880d681SAndroid Build Coastguard Worker if (b == Name.npos)
963*9880d681SAndroid Build Coastguard Worker goto guess_library;
964*9880d681SAndroid Build Coastguard Worker c = Name.rfind('/', b);
965*9880d681SAndroid Build Coastguard Worker if (c == Name.npos || c == 0)
966*9880d681SAndroid Build Coastguard Worker goto guess_library;
967*9880d681SAndroid Build Coastguard Worker V = Name.slice(c+1, Name.npos);
968*9880d681SAndroid Build Coastguard Worker if (!V.startswith("Versions/"))
969*9880d681SAndroid Build Coastguard Worker goto guess_library;
970*9880d681SAndroid Build Coastguard Worker d = Name.rfind('/', c);
971*9880d681SAndroid Build Coastguard Worker if (d == Name.npos)
972*9880d681SAndroid Build Coastguard Worker Idx = 0;
973*9880d681SAndroid Build Coastguard Worker else
974*9880d681SAndroid Build Coastguard Worker Idx = d+1;
975*9880d681SAndroid Build Coastguard Worker F = Name.slice(Idx, Idx + Foo.size());
976*9880d681SAndroid Build Coastguard Worker DotFramework = Name.slice(Idx + Foo.size(),
977*9880d681SAndroid Build Coastguard Worker Idx + Foo.size() + sizeof(".framework/")-1);
978*9880d681SAndroid Build Coastguard Worker if (F == Foo && DotFramework == ".framework/") {
979*9880d681SAndroid Build Coastguard Worker isFramework = true;
980*9880d681SAndroid Build Coastguard Worker return Foo;
981*9880d681SAndroid Build Coastguard Worker }
982*9880d681SAndroid Build Coastguard Worker
983*9880d681SAndroid Build Coastguard Worker guess_library:
984*9880d681SAndroid Build Coastguard Worker // pull off the suffix after the "." and make a point to it
985*9880d681SAndroid Build Coastguard Worker a = Name.rfind('.');
986*9880d681SAndroid Build Coastguard Worker if (a == Name.npos || a == 0)
987*9880d681SAndroid Build Coastguard Worker return StringRef();
988*9880d681SAndroid Build Coastguard Worker Dylib = Name.slice(a, Name.npos);
989*9880d681SAndroid Build Coastguard Worker if (Dylib != ".dylib")
990*9880d681SAndroid Build Coastguard Worker goto guess_qtx;
991*9880d681SAndroid Build Coastguard Worker
992*9880d681SAndroid Build Coastguard Worker // First pull off the version letter for the form Foo.A.dylib if any.
993*9880d681SAndroid Build Coastguard Worker if (a >= 3) {
994*9880d681SAndroid Build Coastguard Worker Dot = Name.slice(a-2, a-1);
995*9880d681SAndroid Build Coastguard Worker if (Dot == ".")
996*9880d681SAndroid Build Coastguard Worker a = a - 2;
997*9880d681SAndroid Build Coastguard Worker }
998*9880d681SAndroid Build Coastguard Worker
999*9880d681SAndroid Build Coastguard Worker b = Name.rfind('/', a);
1000*9880d681SAndroid Build Coastguard Worker if (b == Name.npos)
1001*9880d681SAndroid Build Coastguard Worker b = 0;
1002*9880d681SAndroid Build Coastguard Worker else
1003*9880d681SAndroid Build Coastguard Worker b = b+1;
1004*9880d681SAndroid Build Coastguard Worker // ignore any suffix after an underbar like Foo_profile.A.dylib
1005*9880d681SAndroid Build Coastguard Worker Idx = Name.find('_', b);
1006*9880d681SAndroid Build Coastguard Worker if (Idx != Name.npos && Idx != b) {
1007*9880d681SAndroid Build Coastguard Worker Lib = Name.slice(b, Idx);
1008*9880d681SAndroid Build Coastguard Worker Suffix = Name.slice(Idx, a);
1009*9880d681SAndroid Build Coastguard Worker }
1010*9880d681SAndroid Build Coastguard Worker else
1011*9880d681SAndroid Build Coastguard Worker Lib = Name.slice(b, a);
1012*9880d681SAndroid Build Coastguard Worker // There are incorrect library names of the form:
1013*9880d681SAndroid Build Coastguard Worker // libATS.A_profile.dylib so check for these.
1014*9880d681SAndroid Build Coastguard Worker if (Lib.size() >= 3) {
1015*9880d681SAndroid Build Coastguard Worker Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1016*9880d681SAndroid Build Coastguard Worker if (Dot == ".")
1017*9880d681SAndroid Build Coastguard Worker Lib = Lib.slice(0, Lib.size()-2);
1018*9880d681SAndroid Build Coastguard Worker }
1019*9880d681SAndroid Build Coastguard Worker return Lib;
1020*9880d681SAndroid Build Coastguard Worker
1021*9880d681SAndroid Build Coastguard Worker guess_qtx:
1022*9880d681SAndroid Build Coastguard Worker Qtx = Name.slice(a, Name.npos);
1023*9880d681SAndroid Build Coastguard Worker if (Qtx != ".qtx")
1024*9880d681SAndroid Build Coastguard Worker return StringRef();
1025*9880d681SAndroid Build Coastguard Worker b = Name.rfind('/', a);
1026*9880d681SAndroid Build Coastguard Worker if (b == Name.npos)
1027*9880d681SAndroid Build Coastguard Worker Lib = Name.slice(0, a);
1028*9880d681SAndroid Build Coastguard Worker else
1029*9880d681SAndroid Build Coastguard Worker Lib = Name.slice(b+1, a);
1030*9880d681SAndroid Build Coastguard Worker // There are library names of the form: QT.A.qtx so check for these.
1031*9880d681SAndroid Build Coastguard Worker if (Lib.size() >= 3) {
1032*9880d681SAndroid Build Coastguard Worker Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
1033*9880d681SAndroid Build Coastguard Worker if (Dot == ".")
1034*9880d681SAndroid Build Coastguard Worker Lib = Lib.slice(0, Lib.size()-2);
1035*9880d681SAndroid Build Coastguard Worker }
1036*9880d681SAndroid Build Coastguard Worker return Lib;
1037*9880d681SAndroid Build Coastguard Worker }
1038*9880d681SAndroid Build Coastguard Worker
1039*9880d681SAndroid Build Coastguard Worker // getLibraryShortNameByIndex() is used to get the short name of the library
1040*9880d681SAndroid Build Coastguard Worker // for an undefined symbol in a linked Mach-O binary that was linked with the
1041*9880d681SAndroid Build Coastguard Worker // normal two-level namespace default (that is MH_TWOLEVEL in the header).
1042*9880d681SAndroid Build Coastguard Worker // It is passed the index (0 - based) of the library as translated from
1043*9880d681SAndroid Build Coastguard Worker // GET_LIBRARY_ORDINAL (1 - based).
getLibraryShortNameByIndex(unsigned Index,StringRef & Res) const1044*9880d681SAndroid Build Coastguard Worker std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
1045*9880d681SAndroid Build Coastguard Worker StringRef &Res) const {
1046*9880d681SAndroid Build Coastguard Worker if (Index >= Libraries.size())
1047*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
1048*9880d681SAndroid Build Coastguard Worker
1049*9880d681SAndroid Build Coastguard Worker // If the cache of LibrariesShortNames is not built up do that first for
1050*9880d681SAndroid Build Coastguard Worker // all the Libraries.
1051*9880d681SAndroid Build Coastguard Worker if (LibrariesShortNames.size() == 0) {
1052*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < Libraries.size(); i++) {
1053*9880d681SAndroid Build Coastguard Worker MachO::dylib_command D =
1054*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dylib_command>(this, Libraries[i]);
1055*9880d681SAndroid Build Coastguard Worker if (D.dylib.name >= D.cmdsize)
1056*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
1057*9880d681SAndroid Build Coastguard Worker const char *P = (const char *)(Libraries[i]) + D.dylib.name;
1058*9880d681SAndroid Build Coastguard Worker StringRef Name = StringRef(P);
1059*9880d681SAndroid Build Coastguard Worker if (D.dylib.name+Name.size() >= D.cmdsize)
1060*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
1061*9880d681SAndroid Build Coastguard Worker StringRef Suffix;
1062*9880d681SAndroid Build Coastguard Worker bool isFramework;
1063*9880d681SAndroid Build Coastguard Worker StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
1064*9880d681SAndroid Build Coastguard Worker if (shortName.empty())
1065*9880d681SAndroid Build Coastguard Worker LibrariesShortNames.push_back(Name);
1066*9880d681SAndroid Build Coastguard Worker else
1067*9880d681SAndroid Build Coastguard Worker LibrariesShortNames.push_back(shortName);
1068*9880d681SAndroid Build Coastguard Worker }
1069*9880d681SAndroid Build Coastguard Worker }
1070*9880d681SAndroid Build Coastguard Worker
1071*9880d681SAndroid Build Coastguard Worker Res = LibrariesShortNames[Index];
1072*9880d681SAndroid Build Coastguard Worker return std::error_code();
1073*9880d681SAndroid Build Coastguard Worker }
1074*9880d681SAndroid Build Coastguard Worker
1075*9880d681SAndroid Build Coastguard Worker section_iterator
getRelocationRelocatedSection(relocation_iterator Rel) const1076*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
1077*9880d681SAndroid Build Coastguard Worker DataRefImpl Sec;
1078*9880d681SAndroid Build Coastguard Worker Sec.d.a = Rel->getRawDataRefImpl().d.a;
1079*9880d681SAndroid Build Coastguard Worker return section_iterator(SectionRef(Sec, this));
1080*9880d681SAndroid Build Coastguard Worker }
1081*9880d681SAndroid Build Coastguard Worker
symbol_begin_impl() const1082*9880d681SAndroid Build Coastguard Worker basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
1083*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1084*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Symtab = getSymtabLoadCommand();
1085*9880d681SAndroid Build Coastguard Worker if (!SymtabLoadCmd || Symtab.nsyms == 0)
1086*9880d681SAndroid Build Coastguard Worker return basic_symbol_iterator(SymbolRef(DRI, this));
1087*9880d681SAndroid Build Coastguard Worker
1088*9880d681SAndroid Build Coastguard Worker return getSymbolByIndex(0);
1089*9880d681SAndroid Build Coastguard Worker }
1090*9880d681SAndroid Build Coastguard Worker
symbol_end_impl() const1091*9880d681SAndroid Build Coastguard Worker basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
1092*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1093*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Symtab = getSymtabLoadCommand();
1094*9880d681SAndroid Build Coastguard Worker if (!SymtabLoadCmd || Symtab.nsyms == 0)
1095*9880d681SAndroid Build Coastguard Worker return basic_symbol_iterator(SymbolRef(DRI, this));
1096*9880d681SAndroid Build Coastguard Worker
1097*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableEntrySize = is64Bit() ?
1098*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist_64) :
1099*9880d681SAndroid Build Coastguard Worker sizeof(MachO::nlist);
1100*9880d681SAndroid Build Coastguard Worker unsigned Offset = Symtab.symoff +
1101*9880d681SAndroid Build Coastguard Worker Symtab.nsyms * SymbolTableEntrySize;
1102*9880d681SAndroid Build Coastguard Worker DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1103*9880d681SAndroid Build Coastguard Worker return basic_symbol_iterator(SymbolRef(DRI, this));
1104*9880d681SAndroid Build Coastguard Worker }
1105*9880d681SAndroid Build Coastguard Worker
getSymbolByIndex(unsigned Index) const1106*9880d681SAndroid Build Coastguard Worker basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
1107*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Symtab = getSymtabLoadCommand();
1108*9880d681SAndroid Build Coastguard Worker if (!SymtabLoadCmd || Index >= Symtab.nsyms)
1109*9880d681SAndroid Build Coastguard Worker report_fatal_error("Requested symbol index is out of range.");
1110*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableEntrySize =
1111*9880d681SAndroid Build Coastguard Worker is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1112*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1113*9880d681SAndroid Build Coastguard Worker DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1114*9880d681SAndroid Build Coastguard Worker DRI.p += Index * SymbolTableEntrySize;
1115*9880d681SAndroid Build Coastguard Worker return basic_symbol_iterator(SymbolRef(DRI, this));
1116*9880d681SAndroid Build Coastguard Worker }
1117*9880d681SAndroid Build Coastguard Worker
getSymbolIndex(DataRefImpl Symb) const1118*9880d681SAndroid Build Coastguard Worker uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
1119*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Symtab = getSymtabLoadCommand();
1120*9880d681SAndroid Build Coastguard Worker if (!SymtabLoadCmd)
1121*9880d681SAndroid Build Coastguard Worker report_fatal_error("getSymbolIndex() called with no symbol table symbol");
1122*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableEntrySize =
1123*9880d681SAndroid Build Coastguard Worker is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
1124*9880d681SAndroid Build Coastguard Worker DataRefImpl DRIstart;
1125*9880d681SAndroid Build Coastguard Worker DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
1126*9880d681SAndroid Build Coastguard Worker uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
1127*9880d681SAndroid Build Coastguard Worker return Index;
1128*9880d681SAndroid Build Coastguard Worker }
1129*9880d681SAndroid Build Coastguard Worker
section_begin() const1130*9880d681SAndroid Build Coastguard Worker section_iterator MachOObjectFile::section_begin() const {
1131*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1132*9880d681SAndroid Build Coastguard Worker return section_iterator(SectionRef(DRI, this));
1133*9880d681SAndroid Build Coastguard Worker }
1134*9880d681SAndroid Build Coastguard Worker
section_end() const1135*9880d681SAndroid Build Coastguard Worker section_iterator MachOObjectFile::section_end() const {
1136*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1137*9880d681SAndroid Build Coastguard Worker DRI.d.a = Sections.size();
1138*9880d681SAndroid Build Coastguard Worker return section_iterator(SectionRef(DRI, this));
1139*9880d681SAndroid Build Coastguard Worker }
1140*9880d681SAndroid Build Coastguard Worker
getBytesInAddress() const1141*9880d681SAndroid Build Coastguard Worker uint8_t MachOObjectFile::getBytesInAddress() const {
1142*9880d681SAndroid Build Coastguard Worker return is64Bit() ? 8 : 4;
1143*9880d681SAndroid Build Coastguard Worker }
1144*9880d681SAndroid Build Coastguard Worker
getFileFormatName() const1145*9880d681SAndroid Build Coastguard Worker StringRef MachOObjectFile::getFileFormatName() const {
1146*9880d681SAndroid Build Coastguard Worker unsigned CPUType = getCPUType(this);
1147*9880d681SAndroid Build Coastguard Worker if (!is64Bit()) {
1148*9880d681SAndroid Build Coastguard Worker switch (CPUType) {
1149*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_I386:
1150*9880d681SAndroid Build Coastguard Worker return "Mach-O 32-bit i386";
1151*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_ARM:
1152*9880d681SAndroid Build Coastguard Worker return "Mach-O arm";
1153*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_POWERPC:
1154*9880d681SAndroid Build Coastguard Worker return "Mach-O 32-bit ppc";
1155*9880d681SAndroid Build Coastguard Worker default:
1156*9880d681SAndroid Build Coastguard Worker return "Mach-O 32-bit unknown";
1157*9880d681SAndroid Build Coastguard Worker }
1158*9880d681SAndroid Build Coastguard Worker }
1159*9880d681SAndroid Build Coastguard Worker
1160*9880d681SAndroid Build Coastguard Worker switch (CPUType) {
1161*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_X86_64:
1162*9880d681SAndroid Build Coastguard Worker return "Mach-O 64-bit x86-64";
1163*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_ARM64:
1164*9880d681SAndroid Build Coastguard Worker return "Mach-O arm64";
1165*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_POWERPC64:
1166*9880d681SAndroid Build Coastguard Worker return "Mach-O 64-bit ppc64";
1167*9880d681SAndroid Build Coastguard Worker default:
1168*9880d681SAndroid Build Coastguard Worker return "Mach-O 64-bit unknown";
1169*9880d681SAndroid Build Coastguard Worker }
1170*9880d681SAndroid Build Coastguard Worker }
1171*9880d681SAndroid Build Coastguard Worker
getArch(uint32_t CPUType)1172*9880d681SAndroid Build Coastguard Worker Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
1173*9880d681SAndroid Build Coastguard Worker switch (CPUType) {
1174*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_I386:
1175*9880d681SAndroid Build Coastguard Worker return Triple::x86;
1176*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_X86_64:
1177*9880d681SAndroid Build Coastguard Worker return Triple::x86_64;
1178*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_ARM:
1179*9880d681SAndroid Build Coastguard Worker return Triple::arm;
1180*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_ARM64:
1181*9880d681SAndroid Build Coastguard Worker return Triple::aarch64;
1182*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_POWERPC:
1183*9880d681SAndroid Build Coastguard Worker return Triple::ppc;
1184*9880d681SAndroid Build Coastguard Worker case llvm::MachO::CPU_TYPE_POWERPC64:
1185*9880d681SAndroid Build Coastguard Worker return Triple::ppc64;
1186*9880d681SAndroid Build Coastguard Worker default:
1187*9880d681SAndroid Build Coastguard Worker return Triple::UnknownArch;
1188*9880d681SAndroid Build Coastguard Worker }
1189*9880d681SAndroid Build Coastguard Worker }
1190*9880d681SAndroid Build Coastguard Worker
getArchTriple(uint32_t CPUType,uint32_t CPUSubType,const char ** McpuDefault)1191*9880d681SAndroid Build Coastguard Worker Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
1192*9880d681SAndroid Build Coastguard Worker const char **McpuDefault) {
1193*9880d681SAndroid Build Coastguard Worker if (McpuDefault)
1194*9880d681SAndroid Build Coastguard Worker *McpuDefault = nullptr;
1195*9880d681SAndroid Build Coastguard Worker
1196*9880d681SAndroid Build Coastguard Worker switch (CPUType) {
1197*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_I386:
1198*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1199*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_I386_ALL:
1200*9880d681SAndroid Build Coastguard Worker return Triple("i386-apple-darwin");
1201*9880d681SAndroid Build Coastguard Worker default:
1202*9880d681SAndroid Build Coastguard Worker return Triple();
1203*9880d681SAndroid Build Coastguard Worker }
1204*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_X86_64:
1205*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1206*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_X86_64_ALL:
1207*9880d681SAndroid Build Coastguard Worker return Triple("x86_64-apple-darwin");
1208*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_X86_64_H:
1209*9880d681SAndroid Build Coastguard Worker return Triple("x86_64h-apple-darwin");
1210*9880d681SAndroid Build Coastguard Worker default:
1211*9880d681SAndroid Build Coastguard Worker return Triple();
1212*9880d681SAndroid Build Coastguard Worker }
1213*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_ARM:
1214*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1215*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V4T:
1216*9880d681SAndroid Build Coastguard Worker return Triple("armv4t-apple-darwin");
1217*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1218*9880d681SAndroid Build Coastguard Worker return Triple("armv5e-apple-darwin");
1219*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_XSCALE:
1220*9880d681SAndroid Build Coastguard Worker return Triple("xscale-apple-darwin");
1221*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V6:
1222*9880d681SAndroid Build Coastguard Worker return Triple("armv6-apple-darwin");
1223*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V6M:
1224*9880d681SAndroid Build Coastguard Worker if (McpuDefault)
1225*9880d681SAndroid Build Coastguard Worker *McpuDefault = "cortex-m0";
1226*9880d681SAndroid Build Coastguard Worker return Triple("armv6m-apple-darwin");
1227*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V7:
1228*9880d681SAndroid Build Coastguard Worker return Triple("armv7-apple-darwin");
1229*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V7EM:
1230*9880d681SAndroid Build Coastguard Worker if (McpuDefault)
1231*9880d681SAndroid Build Coastguard Worker *McpuDefault = "cortex-m4";
1232*9880d681SAndroid Build Coastguard Worker return Triple("thumbv7em-apple-darwin");
1233*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V7K:
1234*9880d681SAndroid Build Coastguard Worker return Triple("armv7k-apple-darwin");
1235*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V7M:
1236*9880d681SAndroid Build Coastguard Worker if (McpuDefault)
1237*9880d681SAndroid Build Coastguard Worker *McpuDefault = "cortex-m3";
1238*9880d681SAndroid Build Coastguard Worker return Triple("thumbv7m-apple-darwin");
1239*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM_V7S:
1240*9880d681SAndroid Build Coastguard Worker return Triple("armv7s-apple-darwin");
1241*9880d681SAndroid Build Coastguard Worker default:
1242*9880d681SAndroid Build Coastguard Worker return Triple();
1243*9880d681SAndroid Build Coastguard Worker }
1244*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_ARM64:
1245*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1246*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_ARM64_ALL:
1247*9880d681SAndroid Build Coastguard Worker return Triple("arm64-apple-darwin");
1248*9880d681SAndroid Build Coastguard Worker default:
1249*9880d681SAndroid Build Coastguard Worker return Triple();
1250*9880d681SAndroid Build Coastguard Worker }
1251*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_POWERPC:
1252*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1253*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_POWERPC_ALL:
1254*9880d681SAndroid Build Coastguard Worker return Triple("ppc-apple-darwin");
1255*9880d681SAndroid Build Coastguard Worker default:
1256*9880d681SAndroid Build Coastguard Worker return Triple();
1257*9880d681SAndroid Build Coastguard Worker }
1258*9880d681SAndroid Build Coastguard Worker case MachO::CPU_TYPE_POWERPC64:
1259*9880d681SAndroid Build Coastguard Worker switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
1260*9880d681SAndroid Build Coastguard Worker case MachO::CPU_SUBTYPE_POWERPC_ALL:
1261*9880d681SAndroid Build Coastguard Worker return Triple("ppc64-apple-darwin");
1262*9880d681SAndroid Build Coastguard Worker default:
1263*9880d681SAndroid Build Coastguard Worker return Triple();
1264*9880d681SAndroid Build Coastguard Worker }
1265*9880d681SAndroid Build Coastguard Worker default:
1266*9880d681SAndroid Build Coastguard Worker return Triple();
1267*9880d681SAndroid Build Coastguard Worker }
1268*9880d681SAndroid Build Coastguard Worker }
1269*9880d681SAndroid Build Coastguard Worker
getHostArch()1270*9880d681SAndroid Build Coastguard Worker Triple MachOObjectFile::getHostArch() {
1271*9880d681SAndroid Build Coastguard Worker return Triple(sys::getDefaultTargetTriple());
1272*9880d681SAndroid Build Coastguard Worker }
1273*9880d681SAndroid Build Coastguard Worker
isValidArch(StringRef ArchFlag)1274*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
1275*9880d681SAndroid Build Coastguard Worker return StringSwitch<bool>(ArchFlag)
1276*9880d681SAndroid Build Coastguard Worker .Case("i386", true)
1277*9880d681SAndroid Build Coastguard Worker .Case("x86_64", true)
1278*9880d681SAndroid Build Coastguard Worker .Case("x86_64h", true)
1279*9880d681SAndroid Build Coastguard Worker .Case("armv4t", true)
1280*9880d681SAndroid Build Coastguard Worker .Case("arm", true)
1281*9880d681SAndroid Build Coastguard Worker .Case("armv5e", true)
1282*9880d681SAndroid Build Coastguard Worker .Case("armv6", true)
1283*9880d681SAndroid Build Coastguard Worker .Case("armv6m", true)
1284*9880d681SAndroid Build Coastguard Worker .Case("armv7", true)
1285*9880d681SAndroid Build Coastguard Worker .Case("armv7em", true)
1286*9880d681SAndroid Build Coastguard Worker .Case("armv7k", true)
1287*9880d681SAndroid Build Coastguard Worker .Case("armv7m", true)
1288*9880d681SAndroid Build Coastguard Worker .Case("armv7s", true)
1289*9880d681SAndroid Build Coastguard Worker .Case("arm64", true)
1290*9880d681SAndroid Build Coastguard Worker .Case("ppc", true)
1291*9880d681SAndroid Build Coastguard Worker .Case("ppc64", true)
1292*9880d681SAndroid Build Coastguard Worker .Default(false);
1293*9880d681SAndroid Build Coastguard Worker }
1294*9880d681SAndroid Build Coastguard Worker
getArch() const1295*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getArch() const {
1296*9880d681SAndroid Build Coastguard Worker return getArch(getCPUType(this));
1297*9880d681SAndroid Build Coastguard Worker }
1298*9880d681SAndroid Build Coastguard Worker
getArchTriple(const char ** McpuDefault) const1299*9880d681SAndroid Build Coastguard Worker Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
1300*9880d681SAndroid Build Coastguard Worker return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
1301*9880d681SAndroid Build Coastguard Worker }
1302*9880d681SAndroid Build Coastguard Worker
section_rel_begin(unsigned Index) const1303*9880d681SAndroid Build Coastguard Worker relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
1304*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1305*9880d681SAndroid Build Coastguard Worker DRI.d.a = Index;
1306*9880d681SAndroid Build Coastguard Worker return section_rel_begin(DRI);
1307*9880d681SAndroid Build Coastguard Worker }
1308*9880d681SAndroid Build Coastguard Worker
section_rel_end(unsigned Index) const1309*9880d681SAndroid Build Coastguard Worker relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
1310*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1311*9880d681SAndroid Build Coastguard Worker DRI.d.a = Index;
1312*9880d681SAndroid Build Coastguard Worker return section_rel_end(DRI);
1313*9880d681SAndroid Build Coastguard Worker }
1314*9880d681SAndroid Build Coastguard Worker
begin_dices() const1315*9880d681SAndroid Build Coastguard Worker dice_iterator MachOObjectFile::begin_dices() const {
1316*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1317*9880d681SAndroid Build Coastguard Worker if (!DataInCodeLoadCmd)
1318*9880d681SAndroid Build Coastguard Worker return dice_iterator(DiceRef(DRI, this));
1319*9880d681SAndroid Build Coastguard Worker
1320*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1321*9880d681SAndroid Build Coastguard Worker DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.dataoff));
1322*9880d681SAndroid Build Coastguard Worker return dice_iterator(DiceRef(DRI, this));
1323*9880d681SAndroid Build Coastguard Worker }
1324*9880d681SAndroid Build Coastguard Worker
end_dices() const1325*9880d681SAndroid Build Coastguard Worker dice_iterator MachOObjectFile::end_dices() const {
1326*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
1327*9880d681SAndroid Build Coastguard Worker if (!DataInCodeLoadCmd)
1328*9880d681SAndroid Build Coastguard Worker return dice_iterator(DiceRef(DRI, this));
1329*9880d681SAndroid Build Coastguard Worker
1330*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
1331*9880d681SAndroid Build Coastguard Worker unsigned Offset = DicLC.dataoff + DicLC.datasize;
1332*9880d681SAndroid Build Coastguard Worker DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
1333*9880d681SAndroid Build Coastguard Worker return dice_iterator(DiceRef(DRI, this));
1334*9880d681SAndroid Build Coastguard Worker }
1335*9880d681SAndroid Build Coastguard Worker
ExportEntry(ArrayRef<uint8_t> T)1336*9880d681SAndroid Build Coastguard Worker ExportEntry::ExportEntry(ArrayRef<uint8_t> T)
1337*9880d681SAndroid Build Coastguard Worker : Trie(T), Malformed(false), Done(false) {}
1338*9880d681SAndroid Build Coastguard Worker
moveToFirst()1339*9880d681SAndroid Build Coastguard Worker void ExportEntry::moveToFirst() {
1340*9880d681SAndroid Build Coastguard Worker pushNode(0);
1341*9880d681SAndroid Build Coastguard Worker pushDownUntilBottom();
1342*9880d681SAndroid Build Coastguard Worker }
1343*9880d681SAndroid Build Coastguard Worker
moveToEnd()1344*9880d681SAndroid Build Coastguard Worker void ExportEntry::moveToEnd() {
1345*9880d681SAndroid Build Coastguard Worker Stack.clear();
1346*9880d681SAndroid Build Coastguard Worker Done = true;
1347*9880d681SAndroid Build Coastguard Worker }
1348*9880d681SAndroid Build Coastguard Worker
operator ==(const ExportEntry & Other) const1349*9880d681SAndroid Build Coastguard Worker bool ExportEntry::operator==(const ExportEntry &Other) const {
1350*9880d681SAndroid Build Coastguard Worker // Common case, one at end, other iterating from begin.
1351*9880d681SAndroid Build Coastguard Worker if (Done || Other.Done)
1352*9880d681SAndroid Build Coastguard Worker return (Done == Other.Done);
1353*9880d681SAndroid Build Coastguard Worker // Not equal if different stack sizes.
1354*9880d681SAndroid Build Coastguard Worker if (Stack.size() != Other.Stack.size())
1355*9880d681SAndroid Build Coastguard Worker return false;
1356*9880d681SAndroid Build Coastguard Worker // Not equal if different cumulative strings.
1357*9880d681SAndroid Build Coastguard Worker if (!CumulativeString.equals(Other.CumulativeString))
1358*9880d681SAndroid Build Coastguard Worker return false;
1359*9880d681SAndroid Build Coastguard Worker // Equal if all nodes in both stacks match.
1360*9880d681SAndroid Build Coastguard Worker for (unsigned i=0; i < Stack.size(); ++i) {
1361*9880d681SAndroid Build Coastguard Worker if (Stack[i].Start != Other.Stack[i].Start)
1362*9880d681SAndroid Build Coastguard Worker return false;
1363*9880d681SAndroid Build Coastguard Worker }
1364*9880d681SAndroid Build Coastguard Worker return true;
1365*9880d681SAndroid Build Coastguard Worker }
1366*9880d681SAndroid Build Coastguard Worker
readULEB128(const uint8_t * & Ptr)1367*9880d681SAndroid Build Coastguard Worker uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
1368*9880d681SAndroid Build Coastguard Worker unsigned Count;
1369*9880d681SAndroid Build Coastguard Worker uint64_t Result = decodeULEB128(Ptr, &Count);
1370*9880d681SAndroid Build Coastguard Worker Ptr += Count;
1371*9880d681SAndroid Build Coastguard Worker if (Ptr > Trie.end()) {
1372*9880d681SAndroid Build Coastguard Worker Ptr = Trie.end();
1373*9880d681SAndroid Build Coastguard Worker Malformed = true;
1374*9880d681SAndroid Build Coastguard Worker }
1375*9880d681SAndroid Build Coastguard Worker return Result;
1376*9880d681SAndroid Build Coastguard Worker }
1377*9880d681SAndroid Build Coastguard Worker
name() const1378*9880d681SAndroid Build Coastguard Worker StringRef ExportEntry::name() const {
1379*9880d681SAndroid Build Coastguard Worker return CumulativeString;
1380*9880d681SAndroid Build Coastguard Worker }
1381*9880d681SAndroid Build Coastguard Worker
flags() const1382*9880d681SAndroid Build Coastguard Worker uint64_t ExportEntry::flags() const {
1383*9880d681SAndroid Build Coastguard Worker return Stack.back().Flags;
1384*9880d681SAndroid Build Coastguard Worker }
1385*9880d681SAndroid Build Coastguard Worker
address() const1386*9880d681SAndroid Build Coastguard Worker uint64_t ExportEntry::address() const {
1387*9880d681SAndroid Build Coastguard Worker return Stack.back().Address;
1388*9880d681SAndroid Build Coastguard Worker }
1389*9880d681SAndroid Build Coastguard Worker
other() const1390*9880d681SAndroid Build Coastguard Worker uint64_t ExportEntry::other() const {
1391*9880d681SAndroid Build Coastguard Worker return Stack.back().Other;
1392*9880d681SAndroid Build Coastguard Worker }
1393*9880d681SAndroid Build Coastguard Worker
otherName() const1394*9880d681SAndroid Build Coastguard Worker StringRef ExportEntry::otherName() const {
1395*9880d681SAndroid Build Coastguard Worker const char* ImportName = Stack.back().ImportName;
1396*9880d681SAndroid Build Coastguard Worker if (ImportName)
1397*9880d681SAndroid Build Coastguard Worker return StringRef(ImportName);
1398*9880d681SAndroid Build Coastguard Worker return StringRef();
1399*9880d681SAndroid Build Coastguard Worker }
1400*9880d681SAndroid Build Coastguard Worker
nodeOffset() const1401*9880d681SAndroid Build Coastguard Worker uint32_t ExportEntry::nodeOffset() const {
1402*9880d681SAndroid Build Coastguard Worker return Stack.back().Start - Trie.begin();
1403*9880d681SAndroid Build Coastguard Worker }
1404*9880d681SAndroid Build Coastguard Worker
NodeState(const uint8_t * Ptr)1405*9880d681SAndroid Build Coastguard Worker ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
1406*9880d681SAndroid Build Coastguard Worker : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0),
1407*9880d681SAndroid Build Coastguard Worker ImportName(nullptr), ChildCount(0), NextChildIndex(0),
1408*9880d681SAndroid Build Coastguard Worker ParentStringLength(0), IsExportNode(false) {}
1409*9880d681SAndroid Build Coastguard Worker
pushNode(uint64_t offset)1410*9880d681SAndroid Build Coastguard Worker void ExportEntry::pushNode(uint64_t offset) {
1411*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr = Trie.begin() + offset;
1412*9880d681SAndroid Build Coastguard Worker NodeState State(Ptr);
1413*9880d681SAndroid Build Coastguard Worker uint64_t ExportInfoSize = readULEB128(State.Current);
1414*9880d681SAndroid Build Coastguard Worker State.IsExportNode = (ExportInfoSize != 0);
1415*9880d681SAndroid Build Coastguard Worker const uint8_t* Children = State.Current + ExportInfoSize;
1416*9880d681SAndroid Build Coastguard Worker if (State.IsExportNode) {
1417*9880d681SAndroid Build Coastguard Worker State.Flags = readULEB128(State.Current);
1418*9880d681SAndroid Build Coastguard Worker if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
1419*9880d681SAndroid Build Coastguard Worker State.Address = 0;
1420*9880d681SAndroid Build Coastguard Worker State.Other = readULEB128(State.Current); // dylib ordinal
1421*9880d681SAndroid Build Coastguard Worker State.ImportName = reinterpret_cast<const char*>(State.Current);
1422*9880d681SAndroid Build Coastguard Worker } else {
1423*9880d681SAndroid Build Coastguard Worker State.Address = readULEB128(State.Current);
1424*9880d681SAndroid Build Coastguard Worker if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1425*9880d681SAndroid Build Coastguard Worker State.Other = readULEB128(State.Current);
1426*9880d681SAndroid Build Coastguard Worker }
1427*9880d681SAndroid Build Coastguard Worker }
1428*9880d681SAndroid Build Coastguard Worker State.ChildCount = *Children;
1429*9880d681SAndroid Build Coastguard Worker State.Current = Children + 1;
1430*9880d681SAndroid Build Coastguard Worker State.NextChildIndex = 0;
1431*9880d681SAndroid Build Coastguard Worker State.ParentStringLength = CumulativeString.size();
1432*9880d681SAndroid Build Coastguard Worker Stack.push_back(State);
1433*9880d681SAndroid Build Coastguard Worker }
1434*9880d681SAndroid Build Coastguard Worker
pushDownUntilBottom()1435*9880d681SAndroid Build Coastguard Worker void ExportEntry::pushDownUntilBottom() {
1436*9880d681SAndroid Build Coastguard Worker while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
1437*9880d681SAndroid Build Coastguard Worker NodeState &Top = Stack.back();
1438*9880d681SAndroid Build Coastguard Worker CumulativeString.resize(Top.ParentStringLength);
1439*9880d681SAndroid Build Coastguard Worker for (;*Top.Current != 0; Top.Current++) {
1440*9880d681SAndroid Build Coastguard Worker char C = *Top.Current;
1441*9880d681SAndroid Build Coastguard Worker CumulativeString.push_back(C);
1442*9880d681SAndroid Build Coastguard Worker }
1443*9880d681SAndroid Build Coastguard Worker Top.Current += 1;
1444*9880d681SAndroid Build Coastguard Worker uint64_t childNodeIndex = readULEB128(Top.Current);
1445*9880d681SAndroid Build Coastguard Worker Top.NextChildIndex += 1;
1446*9880d681SAndroid Build Coastguard Worker pushNode(childNodeIndex);
1447*9880d681SAndroid Build Coastguard Worker }
1448*9880d681SAndroid Build Coastguard Worker if (!Stack.back().IsExportNode) {
1449*9880d681SAndroid Build Coastguard Worker Malformed = true;
1450*9880d681SAndroid Build Coastguard Worker moveToEnd();
1451*9880d681SAndroid Build Coastguard Worker }
1452*9880d681SAndroid Build Coastguard Worker }
1453*9880d681SAndroid Build Coastguard Worker
1454*9880d681SAndroid Build Coastguard Worker // We have a trie data structure and need a way to walk it that is compatible
1455*9880d681SAndroid Build Coastguard Worker // with the C++ iterator model. The solution is a non-recursive depth first
1456*9880d681SAndroid Build Coastguard Worker // traversal where the iterator contains a stack of parent nodes along with a
1457*9880d681SAndroid Build Coastguard Worker // string that is the accumulation of all edge strings along the parent chain
1458*9880d681SAndroid Build Coastguard Worker // to this point.
1459*9880d681SAndroid Build Coastguard Worker //
1460*9880d681SAndroid Build Coastguard Worker // There is one "export" node for each exported symbol. But because some
1461*9880d681SAndroid Build Coastguard Worker // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
1462*9880d681SAndroid Build Coastguard Worker // node may have child nodes too.
1463*9880d681SAndroid Build Coastguard Worker //
1464*9880d681SAndroid Build Coastguard Worker // The algorithm for moveNext() is to keep moving down the leftmost unvisited
1465*9880d681SAndroid Build Coastguard Worker // child until hitting a node with no children (which is an export node or
1466*9880d681SAndroid Build Coastguard Worker // else the trie is malformed). On the way down, each node is pushed on the
1467*9880d681SAndroid Build Coastguard Worker // stack ivar. If there is no more ways down, it pops up one and tries to go
1468*9880d681SAndroid Build Coastguard Worker // down a sibling path until a childless node is reached.
moveNext()1469*9880d681SAndroid Build Coastguard Worker void ExportEntry::moveNext() {
1470*9880d681SAndroid Build Coastguard Worker if (Stack.empty() || !Stack.back().IsExportNode) {
1471*9880d681SAndroid Build Coastguard Worker Malformed = true;
1472*9880d681SAndroid Build Coastguard Worker moveToEnd();
1473*9880d681SAndroid Build Coastguard Worker return;
1474*9880d681SAndroid Build Coastguard Worker }
1475*9880d681SAndroid Build Coastguard Worker
1476*9880d681SAndroid Build Coastguard Worker Stack.pop_back();
1477*9880d681SAndroid Build Coastguard Worker while (!Stack.empty()) {
1478*9880d681SAndroid Build Coastguard Worker NodeState &Top = Stack.back();
1479*9880d681SAndroid Build Coastguard Worker if (Top.NextChildIndex < Top.ChildCount) {
1480*9880d681SAndroid Build Coastguard Worker pushDownUntilBottom();
1481*9880d681SAndroid Build Coastguard Worker // Now at the next export node.
1482*9880d681SAndroid Build Coastguard Worker return;
1483*9880d681SAndroid Build Coastguard Worker } else {
1484*9880d681SAndroid Build Coastguard Worker if (Top.IsExportNode) {
1485*9880d681SAndroid Build Coastguard Worker // This node has no children but is itself an export node.
1486*9880d681SAndroid Build Coastguard Worker CumulativeString.resize(Top.ParentStringLength);
1487*9880d681SAndroid Build Coastguard Worker return;
1488*9880d681SAndroid Build Coastguard Worker }
1489*9880d681SAndroid Build Coastguard Worker Stack.pop_back();
1490*9880d681SAndroid Build Coastguard Worker }
1491*9880d681SAndroid Build Coastguard Worker }
1492*9880d681SAndroid Build Coastguard Worker Done = true;
1493*9880d681SAndroid Build Coastguard Worker }
1494*9880d681SAndroid Build Coastguard Worker
1495*9880d681SAndroid Build Coastguard Worker iterator_range<export_iterator>
exports(ArrayRef<uint8_t> Trie)1496*9880d681SAndroid Build Coastguard Worker MachOObjectFile::exports(ArrayRef<uint8_t> Trie) {
1497*9880d681SAndroid Build Coastguard Worker ExportEntry Start(Trie);
1498*9880d681SAndroid Build Coastguard Worker if (Trie.size() == 0)
1499*9880d681SAndroid Build Coastguard Worker Start.moveToEnd();
1500*9880d681SAndroid Build Coastguard Worker else
1501*9880d681SAndroid Build Coastguard Worker Start.moveToFirst();
1502*9880d681SAndroid Build Coastguard Worker
1503*9880d681SAndroid Build Coastguard Worker ExportEntry Finish(Trie);
1504*9880d681SAndroid Build Coastguard Worker Finish.moveToEnd();
1505*9880d681SAndroid Build Coastguard Worker
1506*9880d681SAndroid Build Coastguard Worker return make_range(export_iterator(Start), export_iterator(Finish));
1507*9880d681SAndroid Build Coastguard Worker }
1508*9880d681SAndroid Build Coastguard Worker
exports() const1509*9880d681SAndroid Build Coastguard Worker iterator_range<export_iterator> MachOObjectFile::exports() const {
1510*9880d681SAndroid Build Coastguard Worker return exports(getDyldInfoExportsTrie());
1511*9880d681SAndroid Build Coastguard Worker }
1512*9880d681SAndroid Build Coastguard Worker
MachORebaseEntry(ArrayRef<uint8_t> Bytes,bool is64Bit)1513*9880d681SAndroid Build Coastguard Worker MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit)
1514*9880d681SAndroid Build Coastguard Worker : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1515*9880d681SAndroid Build Coastguard Worker RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0),
1516*9880d681SAndroid Build Coastguard Worker PointerSize(is64Bit ? 8 : 4), Malformed(false), Done(false) {}
1517*9880d681SAndroid Build Coastguard Worker
moveToFirst()1518*9880d681SAndroid Build Coastguard Worker void MachORebaseEntry::moveToFirst() {
1519*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.begin();
1520*9880d681SAndroid Build Coastguard Worker moveNext();
1521*9880d681SAndroid Build Coastguard Worker }
1522*9880d681SAndroid Build Coastguard Worker
moveToEnd()1523*9880d681SAndroid Build Coastguard Worker void MachORebaseEntry::moveToEnd() {
1524*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.end();
1525*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1526*9880d681SAndroid Build Coastguard Worker Done = true;
1527*9880d681SAndroid Build Coastguard Worker }
1528*9880d681SAndroid Build Coastguard Worker
moveNext()1529*9880d681SAndroid Build Coastguard Worker void MachORebaseEntry::moveNext() {
1530*9880d681SAndroid Build Coastguard Worker // If in the middle of some loop, move to next rebasing in loop.
1531*9880d681SAndroid Build Coastguard Worker SegmentOffset += AdvanceAmount;
1532*9880d681SAndroid Build Coastguard Worker if (RemainingLoopCount) {
1533*9880d681SAndroid Build Coastguard Worker --RemainingLoopCount;
1534*9880d681SAndroid Build Coastguard Worker return;
1535*9880d681SAndroid Build Coastguard Worker }
1536*9880d681SAndroid Build Coastguard Worker if (Ptr == Opcodes.end()) {
1537*9880d681SAndroid Build Coastguard Worker Done = true;
1538*9880d681SAndroid Build Coastguard Worker return;
1539*9880d681SAndroid Build Coastguard Worker }
1540*9880d681SAndroid Build Coastguard Worker bool More = true;
1541*9880d681SAndroid Build Coastguard Worker while (More && !Malformed) {
1542*9880d681SAndroid Build Coastguard Worker // Parse next opcode and set up next loop.
1543*9880d681SAndroid Build Coastguard Worker uint8_t Byte = *Ptr++;
1544*9880d681SAndroid Build Coastguard Worker uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
1545*9880d681SAndroid Build Coastguard Worker uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
1546*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1547*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_DONE:
1548*9880d681SAndroid Build Coastguard Worker More = false;
1549*9880d681SAndroid Build Coastguard Worker Done = true;
1550*9880d681SAndroid Build Coastguard Worker moveToEnd();
1551*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-rebase", llvm::dbgs() << "REBASE_OPCODE_DONE\n");
1552*9880d681SAndroid Build Coastguard Worker break;
1553*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_SET_TYPE_IMM:
1554*9880d681SAndroid Build Coastguard Worker RebaseType = ImmValue;
1555*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1556*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1557*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
1558*9880d681SAndroid Build Coastguard Worker << "RebaseType=" << (int) RebaseType << "\n");
1559*9880d681SAndroid Build Coastguard Worker break;
1560*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1561*9880d681SAndroid Build Coastguard Worker SegmentIndex = ImmValue;
1562*9880d681SAndroid Build Coastguard Worker SegmentOffset = readULEB128();
1563*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1564*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1565*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1566*9880d681SAndroid Build Coastguard Worker << "SegmentIndex=" << SegmentIndex << ", "
1567*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1568*9880d681SAndroid Build Coastguard Worker << "\n");
1569*9880d681SAndroid Build Coastguard Worker break;
1570*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
1571*9880d681SAndroid Build Coastguard Worker SegmentOffset += readULEB128();
1572*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-rebase",
1573*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
1574*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X",
1575*9880d681SAndroid Build Coastguard Worker SegmentOffset) << "\n");
1576*9880d681SAndroid Build Coastguard Worker break;
1577*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
1578*9880d681SAndroid Build Coastguard Worker SegmentOffset += ImmValue * PointerSize;
1579*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-rebase",
1580*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
1581*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X",
1582*9880d681SAndroid Build Coastguard Worker SegmentOffset) << "\n");
1583*9880d681SAndroid Build Coastguard Worker break;
1584*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
1585*9880d681SAndroid Build Coastguard Worker AdvanceAmount = PointerSize;
1586*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = ImmValue - 1;
1587*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1588*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1589*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
1590*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1591*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1592*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1593*9880d681SAndroid Build Coastguard Worker << "\n");
1594*9880d681SAndroid Build Coastguard Worker return;
1595*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
1596*9880d681SAndroid Build Coastguard Worker AdvanceAmount = PointerSize;
1597*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = readULEB128() - 1;
1598*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1599*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1600*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
1601*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1602*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1603*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1604*9880d681SAndroid Build Coastguard Worker << "\n");
1605*9880d681SAndroid Build Coastguard Worker return;
1606*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
1607*9880d681SAndroid Build Coastguard Worker AdvanceAmount = readULEB128() + PointerSize;
1608*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1609*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1610*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1611*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
1612*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1613*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1614*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1615*9880d681SAndroid Build Coastguard Worker << "\n");
1616*9880d681SAndroid Build Coastguard Worker return;
1617*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
1618*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = readULEB128() - 1;
1619*9880d681SAndroid Build Coastguard Worker AdvanceAmount = readULEB128() + PointerSize;
1620*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1621*9880d681SAndroid Build Coastguard Worker "mach-o-rebase",
1622*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
1623*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1624*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1625*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1626*9880d681SAndroid Build Coastguard Worker << "\n");
1627*9880d681SAndroid Build Coastguard Worker return;
1628*9880d681SAndroid Build Coastguard Worker default:
1629*9880d681SAndroid Build Coastguard Worker Malformed = true;
1630*9880d681SAndroid Build Coastguard Worker }
1631*9880d681SAndroid Build Coastguard Worker }
1632*9880d681SAndroid Build Coastguard Worker }
1633*9880d681SAndroid Build Coastguard Worker
readULEB128()1634*9880d681SAndroid Build Coastguard Worker uint64_t MachORebaseEntry::readULEB128() {
1635*9880d681SAndroid Build Coastguard Worker unsigned Count;
1636*9880d681SAndroid Build Coastguard Worker uint64_t Result = decodeULEB128(Ptr, &Count);
1637*9880d681SAndroid Build Coastguard Worker Ptr += Count;
1638*9880d681SAndroid Build Coastguard Worker if (Ptr > Opcodes.end()) {
1639*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.end();
1640*9880d681SAndroid Build Coastguard Worker Malformed = true;
1641*9880d681SAndroid Build Coastguard Worker }
1642*9880d681SAndroid Build Coastguard Worker return Result;
1643*9880d681SAndroid Build Coastguard Worker }
1644*9880d681SAndroid Build Coastguard Worker
segmentIndex() const1645*9880d681SAndroid Build Coastguard Worker uint32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
1646*9880d681SAndroid Build Coastguard Worker
segmentOffset() const1647*9880d681SAndroid Build Coastguard Worker uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
1648*9880d681SAndroid Build Coastguard Worker
typeName() const1649*9880d681SAndroid Build Coastguard Worker StringRef MachORebaseEntry::typeName() const {
1650*9880d681SAndroid Build Coastguard Worker switch (RebaseType) {
1651*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_TYPE_POINTER:
1652*9880d681SAndroid Build Coastguard Worker return "pointer";
1653*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
1654*9880d681SAndroid Build Coastguard Worker return "text abs32";
1655*9880d681SAndroid Build Coastguard Worker case MachO::REBASE_TYPE_TEXT_PCREL32:
1656*9880d681SAndroid Build Coastguard Worker return "text rel32";
1657*9880d681SAndroid Build Coastguard Worker }
1658*9880d681SAndroid Build Coastguard Worker return "unknown";
1659*9880d681SAndroid Build Coastguard Worker }
1660*9880d681SAndroid Build Coastguard Worker
operator ==(const MachORebaseEntry & Other) const1661*9880d681SAndroid Build Coastguard Worker bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
1662*9880d681SAndroid Build Coastguard Worker assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1663*9880d681SAndroid Build Coastguard Worker return (Ptr == Other.Ptr) &&
1664*9880d681SAndroid Build Coastguard Worker (RemainingLoopCount == Other.RemainingLoopCount) &&
1665*9880d681SAndroid Build Coastguard Worker (Done == Other.Done);
1666*9880d681SAndroid Build Coastguard Worker }
1667*9880d681SAndroid Build Coastguard Worker
1668*9880d681SAndroid Build Coastguard Worker iterator_range<rebase_iterator>
rebaseTable(ArrayRef<uint8_t> Opcodes,bool is64)1669*9880d681SAndroid Build Coastguard Worker MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) {
1670*9880d681SAndroid Build Coastguard Worker MachORebaseEntry Start(Opcodes, is64);
1671*9880d681SAndroid Build Coastguard Worker Start.moveToFirst();
1672*9880d681SAndroid Build Coastguard Worker
1673*9880d681SAndroid Build Coastguard Worker MachORebaseEntry Finish(Opcodes, is64);
1674*9880d681SAndroid Build Coastguard Worker Finish.moveToEnd();
1675*9880d681SAndroid Build Coastguard Worker
1676*9880d681SAndroid Build Coastguard Worker return make_range(rebase_iterator(Start), rebase_iterator(Finish));
1677*9880d681SAndroid Build Coastguard Worker }
1678*9880d681SAndroid Build Coastguard Worker
rebaseTable() const1679*9880d681SAndroid Build Coastguard Worker iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const {
1680*9880d681SAndroid Build Coastguard Worker return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
1681*9880d681SAndroid Build Coastguard Worker }
1682*9880d681SAndroid Build Coastguard Worker
MachOBindEntry(ArrayRef<uint8_t> Bytes,bool is64Bit,Kind BK)1683*9880d681SAndroid Build Coastguard Worker MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
1684*9880d681SAndroid Build Coastguard Worker : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
1685*9880d681SAndroid Build Coastguard Worker Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
1686*9880d681SAndroid Build Coastguard Worker BindType(0), PointerSize(is64Bit ? 8 : 4),
1687*9880d681SAndroid Build Coastguard Worker TableKind(BK), Malformed(false), Done(false) {}
1688*9880d681SAndroid Build Coastguard Worker
moveToFirst()1689*9880d681SAndroid Build Coastguard Worker void MachOBindEntry::moveToFirst() {
1690*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.begin();
1691*9880d681SAndroid Build Coastguard Worker moveNext();
1692*9880d681SAndroid Build Coastguard Worker }
1693*9880d681SAndroid Build Coastguard Worker
moveToEnd()1694*9880d681SAndroid Build Coastguard Worker void MachOBindEntry::moveToEnd() {
1695*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.end();
1696*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1697*9880d681SAndroid Build Coastguard Worker Done = true;
1698*9880d681SAndroid Build Coastguard Worker }
1699*9880d681SAndroid Build Coastguard Worker
moveNext()1700*9880d681SAndroid Build Coastguard Worker void MachOBindEntry::moveNext() {
1701*9880d681SAndroid Build Coastguard Worker // If in the middle of some loop, move to next binding in loop.
1702*9880d681SAndroid Build Coastguard Worker SegmentOffset += AdvanceAmount;
1703*9880d681SAndroid Build Coastguard Worker if (RemainingLoopCount) {
1704*9880d681SAndroid Build Coastguard Worker --RemainingLoopCount;
1705*9880d681SAndroid Build Coastguard Worker return;
1706*9880d681SAndroid Build Coastguard Worker }
1707*9880d681SAndroid Build Coastguard Worker if (Ptr == Opcodes.end()) {
1708*9880d681SAndroid Build Coastguard Worker Done = true;
1709*9880d681SAndroid Build Coastguard Worker return;
1710*9880d681SAndroid Build Coastguard Worker }
1711*9880d681SAndroid Build Coastguard Worker bool More = true;
1712*9880d681SAndroid Build Coastguard Worker while (More && !Malformed) {
1713*9880d681SAndroid Build Coastguard Worker // Parse next opcode and set up next loop.
1714*9880d681SAndroid Build Coastguard Worker uint8_t Byte = *Ptr++;
1715*9880d681SAndroid Build Coastguard Worker uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
1716*9880d681SAndroid Build Coastguard Worker uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
1717*9880d681SAndroid Build Coastguard Worker int8_t SignExtended;
1718*9880d681SAndroid Build Coastguard Worker const uint8_t *SymStart;
1719*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1720*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_DONE:
1721*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Lazy) {
1722*9880d681SAndroid Build Coastguard Worker // Lazying bindings have a DONE opcode between entries. Need to ignore
1723*9880d681SAndroid Build Coastguard Worker // it to advance to next entry. But need not if this is last entry.
1724*9880d681SAndroid Build Coastguard Worker bool NotLastEntry = false;
1725*9880d681SAndroid Build Coastguard Worker for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
1726*9880d681SAndroid Build Coastguard Worker if (*P) {
1727*9880d681SAndroid Build Coastguard Worker NotLastEntry = true;
1728*9880d681SAndroid Build Coastguard Worker }
1729*9880d681SAndroid Build Coastguard Worker }
1730*9880d681SAndroid Build Coastguard Worker if (NotLastEntry)
1731*9880d681SAndroid Build Coastguard Worker break;
1732*9880d681SAndroid Build Coastguard Worker }
1733*9880d681SAndroid Build Coastguard Worker More = false;
1734*9880d681SAndroid Build Coastguard Worker Done = true;
1735*9880d681SAndroid Build Coastguard Worker moveToEnd();
1736*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
1737*9880d681SAndroid Build Coastguard Worker break;
1738*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
1739*9880d681SAndroid Build Coastguard Worker Ordinal = ImmValue;
1740*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1741*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1742*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
1743*9880d681SAndroid Build Coastguard Worker << "Ordinal=" << Ordinal << "\n");
1744*9880d681SAndroid Build Coastguard Worker break;
1745*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
1746*9880d681SAndroid Build Coastguard Worker Ordinal = readULEB128();
1747*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1748*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1749*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
1750*9880d681SAndroid Build Coastguard Worker << "Ordinal=" << Ordinal << "\n");
1751*9880d681SAndroid Build Coastguard Worker break;
1752*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
1753*9880d681SAndroid Build Coastguard Worker if (ImmValue) {
1754*9880d681SAndroid Build Coastguard Worker SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
1755*9880d681SAndroid Build Coastguard Worker Ordinal = SignExtended;
1756*9880d681SAndroid Build Coastguard Worker } else
1757*9880d681SAndroid Build Coastguard Worker Ordinal = 0;
1758*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1759*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1760*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
1761*9880d681SAndroid Build Coastguard Worker << "Ordinal=" << Ordinal << "\n");
1762*9880d681SAndroid Build Coastguard Worker break;
1763*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
1764*9880d681SAndroid Build Coastguard Worker Flags = ImmValue;
1765*9880d681SAndroid Build Coastguard Worker SymStart = Ptr;
1766*9880d681SAndroid Build Coastguard Worker while (*Ptr) {
1767*9880d681SAndroid Build Coastguard Worker ++Ptr;
1768*9880d681SAndroid Build Coastguard Worker }
1769*9880d681SAndroid Build Coastguard Worker SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
1770*9880d681SAndroid Build Coastguard Worker Ptr-SymStart);
1771*9880d681SAndroid Build Coastguard Worker ++Ptr;
1772*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1773*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1774*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
1775*9880d681SAndroid Build Coastguard Worker << "SymbolName=" << SymbolName << "\n");
1776*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Weak) {
1777*9880d681SAndroid Build Coastguard Worker if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
1778*9880d681SAndroid Build Coastguard Worker return;
1779*9880d681SAndroid Build Coastguard Worker }
1780*9880d681SAndroid Build Coastguard Worker break;
1781*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_TYPE_IMM:
1782*9880d681SAndroid Build Coastguard Worker BindType = ImmValue;
1783*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1784*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1785*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
1786*9880d681SAndroid Build Coastguard Worker << "BindType=" << (int)BindType << "\n");
1787*9880d681SAndroid Build Coastguard Worker break;
1788*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
1789*9880d681SAndroid Build Coastguard Worker Addend = readSLEB128();
1790*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Lazy)
1791*9880d681SAndroid Build Coastguard Worker Malformed = true;
1792*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1793*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1794*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
1795*9880d681SAndroid Build Coastguard Worker << "Addend=" << Addend << "\n");
1796*9880d681SAndroid Build Coastguard Worker break;
1797*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
1798*9880d681SAndroid Build Coastguard Worker SegmentIndex = ImmValue;
1799*9880d681SAndroid Build Coastguard Worker SegmentOffset = readULEB128();
1800*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1801*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1802*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
1803*9880d681SAndroid Build Coastguard Worker << "SegmentIndex=" << SegmentIndex << ", "
1804*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1805*9880d681SAndroid Build Coastguard Worker << "\n");
1806*9880d681SAndroid Build Coastguard Worker break;
1807*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
1808*9880d681SAndroid Build Coastguard Worker SegmentOffset += readULEB128();
1809*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-bind",
1810*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
1811*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X",
1812*9880d681SAndroid Build Coastguard Worker SegmentOffset) << "\n");
1813*9880d681SAndroid Build Coastguard Worker break;
1814*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_DO_BIND:
1815*9880d681SAndroid Build Coastguard Worker AdvanceAmount = PointerSize;
1816*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1817*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-bind",
1818*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
1819*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X",
1820*9880d681SAndroid Build Coastguard Worker SegmentOffset) << "\n");
1821*9880d681SAndroid Build Coastguard Worker return;
1822*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
1823*9880d681SAndroid Build Coastguard Worker AdvanceAmount = readULEB128() + PointerSize;
1824*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1825*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Lazy)
1826*9880d681SAndroid Build Coastguard Worker Malformed = true;
1827*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1828*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1829*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
1830*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1831*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1832*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1833*9880d681SAndroid Build Coastguard Worker << "\n");
1834*9880d681SAndroid Build Coastguard Worker return;
1835*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
1836*9880d681SAndroid Build Coastguard Worker AdvanceAmount = ImmValue * PointerSize + PointerSize;
1837*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = 0;
1838*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Lazy)
1839*9880d681SAndroid Build Coastguard Worker Malformed = true;
1840*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE("mach-o-bind",
1841*9880d681SAndroid Build Coastguard Worker llvm::dbgs()
1842*9880d681SAndroid Build Coastguard Worker << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
1843*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X",
1844*9880d681SAndroid Build Coastguard Worker SegmentOffset) << "\n");
1845*9880d681SAndroid Build Coastguard Worker return;
1846*9880d681SAndroid Build Coastguard Worker case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
1847*9880d681SAndroid Build Coastguard Worker RemainingLoopCount = readULEB128() - 1;
1848*9880d681SAndroid Build Coastguard Worker AdvanceAmount = readULEB128() + PointerSize;
1849*9880d681SAndroid Build Coastguard Worker if (TableKind == Kind::Lazy)
1850*9880d681SAndroid Build Coastguard Worker Malformed = true;
1851*9880d681SAndroid Build Coastguard Worker DEBUG_WITH_TYPE(
1852*9880d681SAndroid Build Coastguard Worker "mach-o-bind",
1853*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
1854*9880d681SAndroid Build Coastguard Worker << format("SegmentOffset=0x%06X", SegmentOffset)
1855*9880d681SAndroid Build Coastguard Worker << ", AdvanceAmount=" << AdvanceAmount
1856*9880d681SAndroid Build Coastguard Worker << ", RemainingLoopCount=" << RemainingLoopCount
1857*9880d681SAndroid Build Coastguard Worker << "\n");
1858*9880d681SAndroid Build Coastguard Worker return;
1859*9880d681SAndroid Build Coastguard Worker default:
1860*9880d681SAndroid Build Coastguard Worker Malformed = true;
1861*9880d681SAndroid Build Coastguard Worker }
1862*9880d681SAndroid Build Coastguard Worker }
1863*9880d681SAndroid Build Coastguard Worker }
1864*9880d681SAndroid Build Coastguard Worker
readULEB128()1865*9880d681SAndroid Build Coastguard Worker uint64_t MachOBindEntry::readULEB128() {
1866*9880d681SAndroid Build Coastguard Worker unsigned Count;
1867*9880d681SAndroid Build Coastguard Worker uint64_t Result = decodeULEB128(Ptr, &Count);
1868*9880d681SAndroid Build Coastguard Worker Ptr += Count;
1869*9880d681SAndroid Build Coastguard Worker if (Ptr > Opcodes.end()) {
1870*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.end();
1871*9880d681SAndroid Build Coastguard Worker Malformed = true;
1872*9880d681SAndroid Build Coastguard Worker }
1873*9880d681SAndroid Build Coastguard Worker return Result;
1874*9880d681SAndroid Build Coastguard Worker }
1875*9880d681SAndroid Build Coastguard Worker
readSLEB128()1876*9880d681SAndroid Build Coastguard Worker int64_t MachOBindEntry::readSLEB128() {
1877*9880d681SAndroid Build Coastguard Worker unsigned Count;
1878*9880d681SAndroid Build Coastguard Worker int64_t Result = decodeSLEB128(Ptr, &Count);
1879*9880d681SAndroid Build Coastguard Worker Ptr += Count;
1880*9880d681SAndroid Build Coastguard Worker if (Ptr > Opcodes.end()) {
1881*9880d681SAndroid Build Coastguard Worker Ptr = Opcodes.end();
1882*9880d681SAndroid Build Coastguard Worker Malformed = true;
1883*9880d681SAndroid Build Coastguard Worker }
1884*9880d681SAndroid Build Coastguard Worker return Result;
1885*9880d681SAndroid Build Coastguard Worker }
1886*9880d681SAndroid Build Coastguard Worker
segmentIndex() const1887*9880d681SAndroid Build Coastguard Worker uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
1888*9880d681SAndroid Build Coastguard Worker
segmentOffset() const1889*9880d681SAndroid Build Coastguard Worker uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
1890*9880d681SAndroid Build Coastguard Worker
typeName() const1891*9880d681SAndroid Build Coastguard Worker StringRef MachOBindEntry::typeName() const {
1892*9880d681SAndroid Build Coastguard Worker switch (BindType) {
1893*9880d681SAndroid Build Coastguard Worker case MachO::BIND_TYPE_POINTER:
1894*9880d681SAndroid Build Coastguard Worker return "pointer";
1895*9880d681SAndroid Build Coastguard Worker case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
1896*9880d681SAndroid Build Coastguard Worker return "text abs32";
1897*9880d681SAndroid Build Coastguard Worker case MachO::BIND_TYPE_TEXT_PCREL32:
1898*9880d681SAndroid Build Coastguard Worker return "text rel32";
1899*9880d681SAndroid Build Coastguard Worker }
1900*9880d681SAndroid Build Coastguard Worker return "unknown";
1901*9880d681SAndroid Build Coastguard Worker }
1902*9880d681SAndroid Build Coastguard Worker
symbolName() const1903*9880d681SAndroid Build Coastguard Worker StringRef MachOBindEntry::symbolName() const { return SymbolName; }
1904*9880d681SAndroid Build Coastguard Worker
addend() const1905*9880d681SAndroid Build Coastguard Worker int64_t MachOBindEntry::addend() const { return Addend; }
1906*9880d681SAndroid Build Coastguard Worker
flags() const1907*9880d681SAndroid Build Coastguard Worker uint32_t MachOBindEntry::flags() const { return Flags; }
1908*9880d681SAndroid Build Coastguard Worker
ordinal() const1909*9880d681SAndroid Build Coastguard Worker int MachOBindEntry::ordinal() const { return Ordinal; }
1910*9880d681SAndroid Build Coastguard Worker
operator ==(const MachOBindEntry & Other) const1911*9880d681SAndroid Build Coastguard Worker bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
1912*9880d681SAndroid Build Coastguard Worker assert(Opcodes == Other.Opcodes && "compare iterators of different files");
1913*9880d681SAndroid Build Coastguard Worker return (Ptr == Other.Ptr) &&
1914*9880d681SAndroid Build Coastguard Worker (RemainingLoopCount == Other.RemainingLoopCount) &&
1915*9880d681SAndroid Build Coastguard Worker (Done == Other.Done);
1916*9880d681SAndroid Build Coastguard Worker }
1917*9880d681SAndroid Build Coastguard Worker
1918*9880d681SAndroid Build Coastguard Worker iterator_range<bind_iterator>
bindTable(ArrayRef<uint8_t> Opcodes,bool is64,MachOBindEntry::Kind BKind)1919*9880d681SAndroid Build Coastguard Worker MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
1920*9880d681SAndroid Build Coastguard Worker MachOBindEntry::Kind BKind) {
1921*9880d681SAndroid Build Coastguard Worker MachOBindEntry Start(Opcodes, is64, BKind);
1922*9880d681SAndroid Build Coastguard Worker Start.moveToFirst();
1923*9880d681SAndroid Build Coastguard Worker
1924*9880d681SAndroid Build Coastguard Worker MachOBindEntry Finish(Opcodes, is64, BKind);
1925*9880d681SAndroid Build Coastguard Worker Finish.moveToEnd();
1926*9880d681SAndroid Build Coastguard Worker
1927*9880d681SAndroid Build Coastguard Worker return make_range(bind_iterator(Start), bind_iterator(Finish));
1928*9880d681SAndroid Build Coastguard Worker }
1929*9880d681SAndroid Build Coastguard Worker
bindTable() const1930*9880d681SAndroid Build Coastguard Worker iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
1931*9880d681SAndroid Build Coastguard Worker return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
1932*9880d681SAndroid Build Coastguard Worker MachOBindEntry::Kind::Regular);
1933*9880d681SAndroid Build Coastguard Worker }
1934*9880d681SAndroid Build Coastguard Worker
lazyBindTable() const1935*9880d681SAndroid Build Coastguard Worker iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
1936*9880d681SAndroid Build Coastguard Worker return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
1937*9880d681SAndroid Build Coastguard Worker MachOBindEntry::Kind::Lazy);
1938*9880d681SAndroid Build Coastguard Worker }
1939*9880d681SAndroid Build Coastguard Worker
weakBindTable() const1940*9880d681SAndroid Build Coastguard Worker iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
1941*9880d681SAndroid Build Coastguard Worker return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
1942*9880d681SAndroid Build Coastguard Worker MachOBindEntry::Kind::Weak);
1943*9880d681SAndroid Build Coastguard Worker }
1944*9880d681SAndroid Build Coastguard Worker
1945*9880d681SAndroid Build Coastguard Worker MachOObjectFile::load_command_iterator
begin_load_commands() const1946*9880d681SAndroid Build Coastguard Worker MachOObjectFile::begin_load_commands() const {
1947*9880d681SAndroid Build Coastguard Worker return LoadCommands.begin();
1948*9880d681SAndroid Build Coastguard Worker }
1949*9880d681SAndroid Build Coastguard Worker
1950*9880d681SAndroid Build Coastguard Worker MachOObjectFile::load_command_iterator
end_load_commands() const1951*9880d681SAndroid Build Coastguard Worker MachOObjectFile::end_load_commands() const {
1952*9880d681SAndroid Build Coastguard Worker return LoadCommands.end();
1953*9880d681SAndroid Build Coastguard Worker }
1954*9880d681SAndroid Build Coastguard Worker
1955*9880d681SAndroid Build Coastguard Worker iterator_range<MachOObjectFile::load_command_iterator>
load_commands() const1956*9880d681SAndroid Build Coastguard Worker MachOObjectFile::load_commands() const {
1957*9880d681SAndroid Build Coastguard Worker return make_range(begin_load_commands(), end_load_commands());
1958*9880d681SAndroid Build Coastguard Worker }
1959*9880d681SAndroid Build Coastguard Worker
1960*9880d681SAndroid Build Coastguard Worker StringRef
getSectionFinalSegmentName(DataRefImpl Sec) const1961*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
1962*9880d681SAndroid Build Coastguard Worker ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
1963*9880d681SAndroid Build Coastguard Worker return parseSegmentOrSectionName(Raw.data());
1964*9880d681SAndroid Build Coastguard Worker }
1965*9880d681SAndroid Build Coastguard Worker
1966*9880d681SAndroid Build Coastguard Worker ArrayRef<char>
getSectionRawName(DataRefImpl Sec) const1967*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
1968*9880d681SAndroid Build Coastguard Worker assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1969*9880d681SAndroid Build Coastguard Worker const section_base *Base =
1970*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1971*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Base->sectname);
1972*9880d681SAndroid Build Coastguard Worker }
1973*9880d681SAndroid Build Coastguard Worker
1974*9880d681SAndroid Build Coastguard Worker ArrayRef<char>
getSectionRawFinalSegmentName(DataRefImpl Sec) const1975*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
1976*9880d681SAndroid Build Coastguard Worker assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
1977*9880d681SAndroid Build Coastguard Worker const section_base *Base =
1978*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
1979*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Base->segname);
1980*9880d681SAndroid Build Coastguard Worker }
1981*9880d681SAndroid Build Coastguard Worker
1982*9880d681SAndroid Build Coastguard Worker bool
isRelocationScattered(const MachO::any_relocation_info & RE) const1983*9880d681SAndroid Build Coastguard Worker MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
1984*9880d681SAndroid Build Coastguard Worker const {
1985*9880d681SAndroid Build Coastguard Worker if (getCPUType(this) == MachO::CPU_TYPE_X86_64)
1986*9880d681SAndroid Build Coastguard Worker return false;
1987*9880d681SAndroid Build Coastguard Worker return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
1988*9880d681SAndroid Build Coastguard Worker }
1989*9880d681SAndroid Build Coastguard Worker
getPlainRelocationSymbolNum(const MachO::any_relocation_info & RE) const1990*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getPlainRelocationSymbolNum(
1991*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
1992*9880d681SAndroid Build Coastguard Worker if (isLittleEndian())
1993*9880d681SAndroid Build Coastguard Worker return RE.r_word1 & 0xffffff;
1994*9880d681SAndroid Build Coastguard Worker return RE.r_word1 >> 8;
1995*9880d681SAndroid Build Coastguard Worker }
1996*9880d681SAndroid Build Coastguard Worker
getPlainRelocationExternal(const MachO::any_relocation_info & RE) const1997*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::getPlainRelocationExternal(
1998*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
1999*9880d681SAndroid Build Coastguard Worker if (isLittleEndian())
2000*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 27) & 1;
2001*9880d681SAndroid Build Coastguard Worker return (RE.r_word1 >> 4) & 1;
2002*9880d681SAndroid Build Coastguard Worker }
2003*9880d681SAndroid Build Coastguard Worker
getScatteredRelocationScattered(const MachO::any_relocation_info & RE) const2004*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::getScatteredRelocationScattered(
2005*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2006*9880d681SAndroid Build Coastguard Worker return RE.r_word0 >> 31;
2007*9880d681SAndroid Build Coastguard Worker }
2008*9880d681SAndroid Build Coastguard Worker
getScatteredRelocationValue(const MachO::any_relocation_info & RE) const2009*9880d681SAndroid Build Coastguard Worker uint32_t MachOObjectFile::getScatteredRelocationValue(
2010*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2011*9880d681SAndroid Build Coastguard Worker return RE.r_word1;
2012*9880d681SAndroid Build Coastguard Worker }
2013*9880d681SAndroid Build Coastguard Worker
getScatteredRelocationType(const MachO::any_relocation_info & RE) const2014*9880d681SAndroid Build Coastguard Worker uint32_t MachOObjectFile::getScatteredRelocationType(
2015*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2016*9880d681SAndroid Build Coastguard Worker return (RE.r_word0 >> 24) & 0xf;
2017*9880d681SAndroid Build Coastguard Worker }
2018*9880d681SAndroid Build Coastguard Worker
getAnyRelocationAddress(const MachO::any_relocation_info & RE) const2019*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getAnyRelocationAddress(
2020*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2021*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE))
2022*9880d681SAndroid Build Coastguard Worker return getScatteredRelocationAddress(RE);
2023*9880d681SAndroid Build Coastguard Worker return getPlainRelocationAddress(RE);
2024*9880d681SAndroid Build Coastguard Worker }
2025*9880d681SAndroid Build Coastguard Worker
getAnyRelocationPCRel(const MachO::any_relocation_info & RE) const2026*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getAnyRelocationPCRel(
2027*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2028*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE))
2029*9880d681SAndroid Build Coastguard Worker return getScatteredRelocationPCRel(this, RE);
2030*9880d681SAndroid Build Coastguard Worker return getPlainRelocationPCRel(this, RE);
2031*9880d681SAndroid Build Coastguard Worker }
2032*9880d681SAndroid Build Coastguard Worker
getAnyRelocationLength(const MachO::any_relocation_info & RE) const2033*9880d681SAndroid Build Coastguard Worker unsigned MachOObjectFile::getAnyRelocationLength(
2034*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2035*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE))
2036*9880d681SAndroid Build Coastguard Worker return getScatteredRelocationLength(RE);
2037*9880d681SAndroid Build Coastguard Worker return getPlainRelocationLength(this, RE);
2038*9880d681SAndroid Build Coastguard Worker }
2039*9880d681SAndroid Build Coastguard Worker
2040*9880d681SAndroid Build Coastguard Worker unsigned
getAnyRelocationType(const MachO::any_relocation_info & RE) const2041*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getAnyRelocationType(
2042*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2043*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE))
2044*9880d681SAndroid Build Coastguard Worker return getScatteredRelocationType(RE);
2045*9880d681SAndroid Build Coastguard Worker return getPlainRelocationType(this, RE);
2046*9880d681SAndroid Build Coastguard Worker }
2047*9880d681SAndroid Build Coastguard Worker
2048*9880d681SAndroid Build Coastguard Worker SectionRef
getAnyRelocationSection(const MachO::any_relocation_info & RE) const2049*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getAnyRelocationSection(
2050*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE) const {
2051*9880d681SAndroid Build Coastguard Worker if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
2052*9880d681SAndroid Build Coastguard Worker return *section_end();
2053*9880d681SAndroid Build Coastguard Worker unsigned SecNum = getPlainRelocationSymbolNum(RE);
2054*9880d681SAndroid Build Coastguard Worker if (SecNum == MachO::R_ABS || SecNum > Sections.size())
2055*9880d681SAndroid Build Coastguard Worker return *section_end();
2056*9880d681SAndroid Build Coastguard Worker DataRefImpl DRI;
2057*9880d681SAndroid Build Coastguard Worker DRI.d.a = SecNum - 1;
2058*9880d681SAndroid Build Coastguard Worker return SectionRef(DRI, this);
2059*9880d681SAndroid Build Coastguard Worker }
2060*9880d681SAndroid Build Coastguard Worker
getSection(DataRefImpl DRI) const2061*9880d681SAndroid Build Coastguard Worker MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
2062*9880d681SAndroid Build Coastguard Worker assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2063*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::section>(this, Sections[DRI.d.a]);
2064*9880d681SAndroid Build Coastguard Worker }
2065*9880d681SAndroid Build Coastguard Worker
getSection64(DataRefImpl DRI) const2066*9880d681SAndroid Build Coastguard Worker MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
2067*9880d681SAndroid Build Coastguard Worker assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
2068*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
2069*9880d681SAndroid Build Coastguard Worker }
2070*9880d681SAndroid Build Coastguard Worker
getSection(const LoadCommandInfo & L,unsigned Index) const2071*9880d681SAndroid Build Coastguard Worker MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
2072*9880d681SAndroid Build Coastguard Worker unsigned Index) const {
2073*9880d681SAndroid Build Coastguard Worker const char *Sec = getSectionPtr(this, L, Index);
2074*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::section>(this, Sec);
2075*9880d681SAndroid Build Coastguard Worker }
2076*9880d681SAndroid Build Coastguard Worker
getSection64(const LoadCommandInfo & L,unsigned Index) const2077*9880d681SAndroid Build Coastguard Worker MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
2078*9880d681SAndroid Build Coastguard Worker unsigned Index) const {
2079*9880d681SAndroid Build Coastguard Worker const char *Sec = getSectionPtr(this, L, Index);
2080*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::section_64>(this, Sec);
2081*9880d681SAndroid Build Coastguard Worker }
2082*9880d681SAndroid Build Coastguard Worker
2083*9880d681SAndroid Build Coastguard Worker MachO::nlist
getSymbolTableEntry(DataRefImpl DRI) const2084*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
2085*9880d681SAndroid Build Coastguard Worker const char *P = reinterpret_cast<const char *>(DRI.p);
2086*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::nlist>(this, P);
2087*9880d681SAndroid Build Coastguard Worker }
2088*9880d681SAndroid Build Coastguard Worker
2089*9880d681SAndroid Build Coastguard Worker MachO::nlist_64
getSymbol64TableEntry(DataRefImpl DRI) const2090*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
2091*9880d681SAndroid Build Coastguard Worker const char *P = reinterpret_cast<const char *>(DRI.p);
2092*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::nlist_64>(this, P);
2093*9880d681SAndroid Build Coastguard Worker }
2094*9880d681SAndroid Build Coastguard Worker
2095*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command
getLinkeditDataLoadCommand(const LoadCommandInfo & L) const2096*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
2097*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::linkedit_data_command>(this, L.Ptr);
2098*9880d681SAndroid Build Coastguard Worker }
2099*9880d681SAndroid Build Coastguard Worker
2100*9880d681SAndroid Build Coastguard Worker MachO::segment_command
getSegmentLoadCommand(const LoadCommandInfo & L) const2101*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
2102*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::segment_command>(this, L.Ptr);
2103*9880d681SAndroid Build Coastguard Worker }
2104*9880d681SAndroid Build Coastguard Worker
2105*9880d681SAndroid Build Coastguard Worker MachO::segment_command_64
getSegment64LoadCommand(const LoadCommandInfo & L) const2106*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
2107*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::segment_command_64>(this, L.Ptr);
2108*9880d681SAndroid Build Coastguard Worker }
2109*9880d681SAndroid Build Coastguard Worker
2110*9880d681SAndroid Build Coastguard Worker MachO::linker_option_command
getLinkerOptionLoadCommand(const LoadCommandInfo & L) const2111*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
2112*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::linker_option_command>(this, L.Ptr);
2113*9880d681SAndroid Build Coastguard Worker }
2114*9880d681SAndroid Build Coastguard Worker
2115*9880d681SAndroid Build Coastguard Worker MachO::version_min_command
getVersionMinLoadCommand(const LoadCommandInfo & L) const2116*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
2117*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::version_min_command>(this, L.Ptr);
2118*9880d681SAndroid Build Coastguard Worker }
2119*9880d681SAndroid Build Coastguard Worker
2120*9880d681SAndroid Build Coastguard Worker MachO::dylib_command
getDylibIDLoadCommand(const LoadCommandInfo & L) const2121*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
2122*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::dylib_command>(this, L.Ptr);
2123*9880d681SAndroid Build Coastguard Worker }
2124*9880d681SAndroid Build Coastguard Worker
2125*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command
getDyldInfoLoadCommand(const LoadCommandInfo & L) const2126*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
2127*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::dyld_info_command>(this, L.Ptr);
2128*9880d681SAndroid Build Coastguard Worker }
2129*9880d681SAndroid Build Coastguard Worker
2130*9880d681SAndroid Build Coastguard Worker MachO::dylinker_command
getDylinkerCommand(const LoadCommandInfo & L) const2131*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
2132*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::dylinker_command>(this, L.Ptr);
2133*9880d681SAndroid Build Coastguard Worker }
2134*9880d681SAndroid Build Coastguard Worker
2135*9880d681SAndroid Build Coastguard Worker MachO::uuid_command
getUuidCommand(const LoadCommandInfo & L) const2136*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
2137*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::uuid_command>(this, L.Ptr);
2138*9880d681SAndroid Build Coastguard Worker }
2139*9880d681SAndroid Build Coastguard Worker
2140*9880d681SAndroid Build Coastguard Worker MachO::rpath_command
getRpathCommand(const LoadCommandInfo & L) const2141*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
2142*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::rpath_command>(this, L.Ptr);
2143*9880d681SAndroid Build Coastguard Worker }
2144*9880d681SAndroid Build Coastguard Worker
2145*9880d681SAndroid Build Coastguard Worker MachO::source_version_command
getSourceVersionCommand(const LoadCommandInfo & L) const2146*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
2147*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::source_version_command>(this, L.Ptr);
2148*9880d681SAndroid Build Coastguard Worker }
2149*9880d681SAndroid Build Coastguard Worker
2150*9880d681SAndroid Build Coastguard Worker MachO::entry_point_command
getEntryPointCommand(const LoadCommandInfo & L) const2151*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
2152*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::entry_point_command>(this, L.Ptr);
2153*9880d681SAndroid Build Coastguard Worker }
2154*9880d681SAndroid Build Coastguard Worker
2155*9880d681SAndroid Build Coastguard Worker MachO::encryption_info_command
getEncryptionInfoCommand(const LoadCommandInfo & L) const2156*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
2157*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::encryption_info_command>(this, L.Ptr);
2158*9880d681SAndroid Build Coastguard Worker }
2159*9880d681SAndroid Build Coastguard Worker
2160*9880d681SAndroid Build Coastguard Worker MachO::encryption_info_command_64
getEncryptionInfoCommand64(const LoadCommandInfo & L) const2161*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
2162*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::encryption_info_command_64>(this, L.Ptr);
2163*9880d681SAndroid Build Coastguard Worker }
2164*9880d681SAndroid Build Coastguard Worker
2165*9880d681SAndroid Build Coastguard Worker MachO::sub_framework_command
getSubFrameworkCommand(const LoadCommandInfo & L) const2166*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
2167*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::sub_framework_command>(this, L.Ptr);
2168*9880d681SAndroid Build Coastguard Worker }
2169*9880d681SAndroid Build Coastguard Worker
2170*9880d681SAndroid Build Coastguard Worker MachO::sub_umbrella_command
getSubUmbrellaCommand(const LoadCommandInfo & L) const2171*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
2172*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::sub_umbrella_command>(this, L.Ptr);
2173*9880d681SAndroid Build Coastguard Worker }
2174*9880d681SAndroid Build Coastguard Worker
2175*9880d681SAndroid Build Coastguard Worker MachO::sub_library_command
getSubLibraryCommand(const LoadCommandInfo & L) const2176*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
2177*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::sub_library_command>(this, L.Ptr);
2178*9880d681SAndroid Build Coastguard Worker }
2179*9880d681SAndroid Build Coastguard Worker
2180*9880d681SAndroid Build Coastguard Worker MachO::sub_client_command
getSubClientCommand(const LoadCommandInfo & L) const2181*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
2182*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::sub_client_command>(this, L.Ptr);
2183*9880d681SAndroid Build Coastguard Worker }
2184*9880d681SAndroid Build Coastguard Worker
2185*9880d681SAndroid Build Coastguard Worker MachO::routines_command
getRoutinesCommand(const LoadCommandInfo & L) const2186*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
2187*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::routines_command>(this, L.Ptr);
2188*9880d681SAndroid Build Coastguard Worker }
2189*9880d681SAndroid Build Coastguard Worker
2190*9880d681SAndroid Build Coastguard Worker MachO::routines_command_64
getRoutinesCommand64(const LoadCommandInfo & L) const2191*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
2192*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::routines_command_64>(this, L.Ptr);
2193*9880d681SAndroid Build Coastguard Worker }
2194*9880d681SAndroid Build Coastguard Worker
2195*9880d681SAndroid Build Coastguard Worker MachO::thread_command
getThreadCommand(const LoadCommandInfo & L) const2196*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
2197*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::thread_command>(this, L.Ptr);
2198*9880d681SAndroid Build Coastguard Worker }
2199*9880d681SAndroid Build Coastguard Worker
2200*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info
getRelocation(DataRefImpl Rel) const2201*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getRelocation(DataRefImpl Rel) const {
2202*9880d681SAndroid Build Coastguard Worker DataRefImpl Sec;
2203*9880d681SAndroid Build Coastguard Worker Sec.d.a = Rel.d.a;
2204*9880d681SAndroid Build Coastguard Worker uint32_t Offset;
2205*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
2206*9880d681SAndroid Build Coastguard Worker MachO::section_64 Sect = getSection64(Sec);
2207*9880d681SAndroid Build Coastguard Worker Offset = Sect.reloff;
2208*9880d681SAndroid Build Coastguard Worker } else {
2209*9880d681SAndroid Build Coastguard Worker MachO::section Sect = getSection(Sec);
2210*9880d681SAndroid Build Coastguard Worker Offset = Sect.reloff;
2211*9880d681SAndroid Build Coastguard Worker }
2212*9880d681SAndroid Build Coastguard Worker
2213*9880d681SAndroid Build Coastguard Worker auto P = reinterpret_cast<const MachO::any_relocation_info *>(
2214*9880d681SAndroid Build Coastguard Worker getPtr(this, Offset)) + Rel.d.b;
2215*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::any_relocation_info>(
2216*9880d681SAndroid Build Coastguard Worker this, reinterpret_cast<const char *>(P));
2217*9880d681SAndroid Build Coastguard Worker }
2218*9880d681SAndroid Build Coastguard Worker
2219*9880d681SAndroid Build Coastguard Worker MachO::data_in_code_entry
getDice(DataRefImpl Rel) const2220*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDice(DataRefImpl Rel) const {
2221*9880d681SAndroid Build Coastguard Worker const char *P = reinterpret_cast<const char *>(Rel.p);
2222*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::data_in_code_entry>(this, P);
2223*9880d681SAndroid Build Coastguard Worker }
2224*9880d681SAndroid Build Coastguard Worker
getHeader() const2225*9880d681SAndroid Build Coastguard Worker const MachO::mach_header &MachOObjectFile::getHeader() const {
2226*9880d681SAndroid Build Coastguard Worker return Header;
2227*9880d681SAndroid Build Coastguard Worker }
2228*9880d681SAndroid Build Coastguard Worker
getHeader64() const2229*9880d681SAndroid Build Coastguard Worker const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
2230*9880d681SAndroid Build Coastguard Worker assert(is64Bit());
2231*9880d681SAndroid Build Coastguard Worker return Header64;
2232*9880d681SAndroid Build Coastguard Worker }
2233*9880d681SAndroid Build Coastguard Worker
getIndirectSymbolTableEntry(const MachO::dysymtab_command & DLC,unsigned Index) const2234*9880d681SAndroid Build Coastguard Worker uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
2235*9880d681SAndroid Build Coastguard Worker const MachO::dysymtab_command &DLC,
2236*9880d681SAndroid Build Coastguard Worker unsigned Index) const {
2237*9880d681SAndroid Build Coastguard Worker uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
2238*9880d681SAndroid Build Coastguard Worker return getStruct<uint32_t>(this, getPtr(this, Offset));
2239*9880d681SAndroid Build Coastguard Worker }
2240*9880d681SAndroid Build Coastguard Worker
2241*9880d681SAndroid Build Coastguard Worker MachO::data_in_code_entry
getDataInCodeTableEntry(uint32_t DataOffset,unsigned Index) const2242*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
2243*9880d681SAndroid Build Coastguard Worker unsigned Index) const {
2244*9880d681SAndroid Build Coastguard Worker uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
2245*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::data_in_code_entry>(this, getPtr(this, Offset));
2246*9880d681SAndroid Build Coastguard Worker }
2247*9880d681SAndroid Build Coastguard Worker
getSymtabLoadCommand() const2248*9880d681SAndroid Build Coastguard Worker MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
2249*9880d681SAndroid Build Coastguard Worker if (SymtabLoadCmd)
2250*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
2251*9880d681SAndroid Build Coastguard Worker
2252*9880d681SAndroid Build Coastguard Worker // If there is no SymtabLoadCmd return a load command with zero'ed fields.
2253*9880d681SAndroid Build Coastguard Worker MachO::symtab_command Cmd;
2254*9880d681SAndroid Build Coastguard Worker Cmd.cmd = MachO::LC_SYMTAB;
2255*9880d681SAndroid Build Coastguard Worker Cmd.cmdsize = sizeof(MachO::symtab_command);
2256*9880d681SAndroid Build Coastguard Worker Cmd.symoff = 0;
2257*9880d681SAndroid Build Coastguard Worker Cmd.nsyms = 0;
2258*9880d681SAndroid Build Coastguard Worker Cmd.stroff = 0;
2259*9880d681SAndroid Build Coastguard Worker Cmd.strsize = 0;
2260*9880d681SAndroid Build Coastguard Worker return Cmd;
2261*9880d681SAndroid Build Coastguard Worker }
2262*9880d681SAndroid Build Coastguard Worker
getDysymtabLoadCommand() const2263*9880d681SAndroid Build Coastguard Worker MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
2264*9880d681SAndroid Build Coastguard Worker if (DysymtabLoadCmd)
2265*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
2266*9880d681SAndroid Build Coastguard Worker
2267*9880d681SAndroid Build Coastguard Worker // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
2268*9880d681SAndroid Build Coastguard Worker MachO::dysymtab_command Cmd;
2269*9880d681SAndroid Build Coastguard Worker Cmd.cmd = MachO::LC_DYSYMTAB;
2270*9880d681SAndroid Build Coastguard Worker Cmd.cmdsize = sizeof(MachO::dysymtab_command);
2271*9880d681SAndroid Build Coastguard Worker Cmd.ilocalsym = 0;
2272*9880d681SAndroid Build Coastguard Worker Cmd.nlocalsym = 0;
2273*9880d681SAndroid Build Coastguard Worker Cmd.iextdefsym = 0;
2274*9880d681SAndroid Build Coastguard Worker Cmd.nextdefsym = 0;
2275*9880d681SAndroid Build Coastguard Worker Cmd.iundefsym = 0;
2276*9880d681SAndroid Build Coastguard Worker Cmd.nundefsym = 0;
2277*9880d681SAndroid Build Coastguard Worker Cmd.tocoff = 0;
2278*9880d681SAndroid Build Coastguard Worker Cmd.ntoc = 0;
2279*9880d681SAndroid Build Coastguard Worker Cmd.modtaboff = 0;
2280*9880d681SAndroid Build Coastguard Worker Cmd.nmodtab = 0;
2281*9880d681SAndroid Build Coastguard Worker Cmd.extrefsymoff = 0;
2282*9880d681SAndroid Build Coastguard Worker Cmd.nextrefsyms = 0;
2283*9880d681SAndroid Build Coastguard Worker Cmd.indirectsymoff = 0;
2284*9880d681SAndroid Build Coastguard Worker Cmd.nindirectsyms = 0;
2285*9880d681SAndroid Build Coastguard Worker Cmd.extreloff = 0;
2286*9880d681SAndroid Build Coastguard Worker Cmd.nextrel = 0;
2287*9880d681SAndroid Build Coastguard Worker Cmd.locreloff = 0;
2288*9880d681SAndroid Build Coastguard Worker Cmd.nlocrel = 0;
2289*9880d681SAndroid Build Coastguard Worker return Cmd;
2290*9880d681SAndroid Build Coastguard Worker }
2291*9880d681SAndroid Build Coastguard Worker
2292*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command
getDataInCodeLoadCommand() const2293*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getDataInCodeLoadCommand() const {
2294*9880d681SAndroid Build Coastguard Worker if (DataInCodeLoadCmd)
2295*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::linkedit_data_command>(this, DataInCodeLoadCmd);
2296*9880d681SAndroid Build Coastguard Worker
2297*9880d681SAndroid Build Coastguard Worker // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
2298*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command Cmd;
2299*9880d681SAndroid Build Coastguard Worker Cmd.cmd = MachO::LC_DATA_IN_CODE;
2300*9880d681SAndroid Build Coastguard Worker Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2301*9880d681SAndroid Build Coastguard Worker Cmd.dataoff = 0;
2302*9880d681SAndroid Build Coastguard Worker Cmd.datasize = 0;
2303*9880d681SAndroid Build Coastguard Worker return Cmd;
2304*9880d681SAndroid Build Coastguard Worker }
2305*9880d681SAndroid Build Coastguard Worker
2306*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command
getLinkOptHintsLoadCommand() const2307*9880d681SAndroid Build Coastguard Worker MachOObjectFile::getLinkOptHintsLoadCommand() const {
2308*9880d681SAndroid Build Coastguard Worker if (LinkOptHintsLoadCmd)
2309*9880d681SAndroid Build Coastguard Worker return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
2310*9880d681SAndroid Build Coastguard Worker
2311*9880d681SAndroid Build Coastguard Worker // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
2312*9880d681SAndroid Build Coastguard Worker // fields.
2313*9880d681SAndroid Build Coastguard Worker MachO::linkedit_data_command Cmd;
2314*9880d681SAndroid Build Coastguard Worker Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
2315*9880d681SAndroid Build Coastguard Worker Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
2316*9880d681SAndroid Build Coastguard Worker Cmd.dataoff = 0;
2317*9880d681SAndroid Build Coastguard Worker Cmd.datasize = 0;
2318*9880d681SAndroid Build Coastguard Worker return Cmd;
2319*9880d681SAndroid Build Coastguard Worker }
2320*9880d681SAndroid Build Coastguard Worker
getDyldInfoRebaseOpcodes() const2321*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
2322*9880d681SAndroid Build Coastguard Worker if (!DyldInfoLoadCmd)
2323*9880d681SAndroid Build Coastguard Worker return None;
2324*9880d681SAndroid Build Coastguard Worker
2325*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command DyldInfo =
2326*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2327*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr =
2328*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off));
2329*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Ptr, DyldInfo.rebase_size);
2330*9880d681SAndroid Build Coastguard Worker }
2331*9880d681SAndroid Build Coastguard Worker
getDyldInfoBindOpcodes() const2332*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
2333*9880d681SAndroid Build Coastguard Worker if (!DyldInfoLoadCmd)
2334*9880d681SAndroid Build Coastguard Worker return None;
2335*9880d681SAndroid Build Coastguard Worker
2336*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command DyldInfo =
2337*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2338*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr =
2339*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off));
2340*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Ptr, DyldInfo.bind_size);
2341*9880d681SAndroid Build Coastguard Worker }
2342*9880d681SAndroid Build Coastguard Worker
getDyldInfoWeakBindOpcodes() const2343*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
2344*9880d681SAndroid Build Coastguard Worker if (!DyldInfoLoadCmd)
2345*9880d681SAndroid Build Coastguard Worker return None;
2346*9880d681SAndroid Build Coastguard Worker
2347*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command DyldInfo =
2348*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2349*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr =
2350*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off));
2351*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
2352*9880d681SAndroid Build Coastguard Worker }
2353*9880d681SAndroid Build Coastguard Worker
getDyldInfoLazyBindOpcodes() const2354*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
2355*9880d681SAndroid Build Coastguard Worker if (!DyldInfoLoadCmd)
2356*9880d681SAndroid Build Coastguard Worker return None;
2357*9880d681SAndroid Build Coastguard Worker
2358*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command DyldInfo =
2359*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2360*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr =
2361*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off));
2362*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
2363*9880d681SAndroid Build Coastguard Worker }
2364*9880d681SAndroid Build Coastguard Worker
getDyldInfoExportsTrie() const2365*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
2366*9880d681SAndroid Build Coastguard Worker if (!DyldInfoLoadCmd)
2367*9880d681SAndroid Build Coastguard Worker return None;
2368*9880d681SAndroid Build Coastguard Worker
2369*9880d681SAndroid Build Coastguard Worker MachO::dyld_info_command DyldInfo =
2370*9880d681SAndroid Build Coastguard Worker getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd);
2371*9880d681SAndroid Build Coastguard Worker const uint8_t *Ptr =
2372*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off));
2373*9880d681SAndroid Build Coastguard Worker return makeArrayRef(Ptr, DyldInfo.export_size);
2374*9880d681SAndroid Build Coastguard Worker }
2375*9880d681SAndroid Build Coastguard Worker
getUuid() const2376*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
2377*9880d681SAndroid Build Coastguard Worker if (!UuidLoadCmd)
2378*9880d681SAndroid Build Coastguard Worker return None;
2379*9880d681SAndroid Build Coastguard Worker // Returning a pointer is fine as uuid doesn't need endian swapping.
2380*9880d681SAndroid Build Coastguard Worker const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid);
2381*9880d681SAndroid Build Coastguard Worker return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
2382*9880d681SAndroid Build Coastguard Worker }
2383*9880d681SAndroid Build Coastguard Worker
getStringTableData() const2384*9880d681SAndroid Build Coastguard Worker StringRef MachOObjectFile::getStringTableData() const {
2385*9880d681SAndroid Build Coastguard Worker MachO::symtab_command S = getSymtabLoadCommand();
2386*9880d681SAndroid Build Coastguard Worker return getData().substr(S.stroff, S.strsize);
2387*9880d681SAndroid Build Coastguard Worker }
2388*9880d681SAndroid Build Coastguard Worker
is64Bit() const2389*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::is64Bit() const {
2390*9880d681SAndroid Build Coastguard Worker return getType() == getMachOType(false, true) ||
2391*9880d681SAndroid Build Coastguard Worker getType() == getMachOType(true, true);
2392*9880d681SAndroid Build Coastguard Worker }
2393*9880d681SAndroid Build Coastguard Worker
ReadULEB128s(uint64_t Index,SmallVectorImpl<uint64_t> & Out) const2394*9880d681SAndroid Build Coastguard Worker void MachOObjectFile::ReadULEB128s(uint64_t Index,
2395*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<uint64_t> &Out) const {
2396*9880d681SAndroid Build Coastguard Worker DataExtractor extractor(ObjectFile::getData(), true, 0);
2397*9880d681SAndroid Build Coastguard Worker
2398*9880d681SAndroid Build Coastguard Worker uint32_t offset = Index;
2399*9880d681SAndroid Build Coastguard Worker uint64_t data = 0;
2400*9880d681SAndroid Build Coastguard Worker while (uint64_t delta = extractor.getULEB128(&offset)) {
2401*9880d681SAndroid Build Coastguard Worker data += delta;
2402*9880d681SAndroid Build Coastguard Worker Out.push_back(data);
2403*9880d681SAndroid Build Coastguard Worker }
2404*9880d681SAndroid Build Coastguard Worker }
2405*9880d681SAndroid Build Coastguard Worker
isRelocatableObject() const2406*9880d681SAndroid Build Coastguard Worker bool MachOObjectFile::isRelocatableObject() const {
2407*9880d681SAndroid Build Coastguard Worker return getHeader().filetype == MachO::MH_OBJECT;
2408*9880d681SAndroid Build Coastguard Worker }
2409*9880d681SAndroid Build Coastguard Worker
2410*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<MachOObjectFile>>
createMachOObjectFile(MemoryBufferRef Buffer)2411*9880d681SAndroid Build Coastguard Worker ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
2412*9880d681SAndroid Build Coastguard Worker StringRef Magic = Buffer.getBuffer().slice(0, 4);
2413*9880d681SAndroid Build Coastguard Worker if (Magic == "\xFE\xED\xFA\xCE")
2414*9880d681SAndroid Build Coastguard Worker return MachOObjectFile::create(Buffer, false, false);
2415*9880d681SAndroid Build Coastguard Worker if (Magic == "\xCE\xFA\xED\xFE")
2416*9880d681SAndroid Build Coastguard Worker return MachOObjectFile::create(Buffer, true, false);
2417*9880d681SAndroid Build Coastguard Worker if (Magic == "\xFE\xED\xFA\xCF")
2418*9880d681SAndroid Build Coastguard Worker return MachOObjectFile::create(Buffer, false, true);
2419*9880d681SAndroid Build Coastguard Worker if (Magic == "\xCF\xFA\xED\xFE")
2420*9880d681SAndroid Build Coastguard Worker return MachOObjectFile::create(Buffer, true, true);
2421*9880d681SAndroid Build Coastguard Worker return make_error<GenericBinaryError>("Unrecognized MachO magic number",
2422*9880d681SAndroid Build Coastguard Worker object_error::invalid_file_type);
2423*9880d681SAndroid Build Coastguard Worker }
2424