xref: /aosp_15_r20/external/llvm/lib/Object/MachOObjectFile.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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