Bug Summary

File:lib/Object/MachOObjectFile.cpp
Warning:line 3986, column 41
The right operand of '-' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MachOObjectFile.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/lib/Object -I /build/llvm-toolchain-snapshot-7~svn338205/lib/Object -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/lib/Object -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp -faddrsig

/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp

1//===- MachOObjectFile.cpp - Mach-O object file binding -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the MachOObjectFile class, which binds the MachOObject
11// class to the generic ObjectFile wrapper.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/None.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/ADT/Triple.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/BinaryFormat/MachO.h"
24#include "llvm/Object/Error.h"
25#include "llvm/Object/MachO.h"
26#include "llvm/Object/ObjectFile.h"
27#include "llvm/Object/SymbolicFile.h"
28#include "llvm/Support/DataExtractor.h"
29#include "llvm/Support/Debug.h"
30#include "llvm/Support/Error.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/Format.h"
33#include "llvm/Support/Host.h"
34#include "llvm/Support/LEB128.h"
35#include "llvm/Support/MemoryBuffer.h"
36#include "llvm/Support/SwapByteOrder.h"
37#include "llvm/Support/raw_ostream.h"
38#include <algorithm>
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42#include <cstring>
43#include <limits>
44#include <list>
45#include <memory>
46#include <string>
47#include <system_error>
48
49using namespace llvm;
50using namespace object;
51
52namespace {
53
54 struct section_base {
55 char sectname[16];
56 char segname[16];
57 };
58
59} // end anonymous namespace
60
61static Error malformedError(const Twine &Msg) {
62 return make_error<GenericBinaryError>("truncated or malformed object (" +
63 Msg + ")",
64 object_error::parse_failed);
65}
66
67// FIXME: Replace all uses of this function with getStructOrErr.
68template <typename T>
69static T getStruct(const MachOObjectFile &O, const char *P) {
70 // Don't read before the beginning or past the end of the file
71 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
72 report_fatal_error("Malformed MachO file.");
73
74 T Cmd;
75 memcpy(&Cmd, P, sizeof(T));
76 if (O.isLittleEndian() != sys::IsLittleEndianHost)
77 MachO::swapStruct(Cmd);
78 return Cmd;
79}
80
81template <typename T>
82static Expected<T> getStructOrErr(const MachOObjectFile &O, const char *P) {
83 // Don't read before the beginning or past the end of the file
84 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
85 return malformedError("Structure read out-of-range");
86
87 T Cmd;
88 memcpy(&Cmd, P, sizeof(T));
89 if (O.isLittleEndian() != sys::IsLittleEndianHost)
90 MachO::swapStruct(Cmd);
91 return Cmd;
92}
93
94static const char *
95getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L,
96 unsigned Sec) {
97 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
98
99 bool Is64 = O.is64Bit();
100 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) :
101 sizeof(MachO::segment_command);
102 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) :
103 sizeof(MachO::section);
104
105 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
106 return reinterpret_cast<const char*>(SectionAddr);
107}
108
109static const char *getPtr(const MachOObjectFile &O, size_t Offset) {
110 assert(Offset <= O.getData().size())(static_cast <bool> (Offset <= O.getData().size()) ?
void (0) : __assert_fail ("Offset <= O.getData().size()",
"/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 return O.getData().data() + Offset;
112}
113
114static MachO::nlist_base
115getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI) {
116 const char *P = reinterpret_cast<const char *>(DRI.p);
117 return getStruct<MachO::nlist_base>(O, P);
118}
119
120static StringRef parseSegmentOrSectionName(const char *P) {
121 if (P[15] == 0)
122 // Null terminated.
123 return P;
124 // Not null terminated, so this is a 16 char string.
125 return StringRef(P, 16);
126}
127
128static unsigned getCPUType(const MachOObjectFile &O) {
129 return O.getHeader().cputype;
130}
131
132static uint32_t
133getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
134 return RE.r_word0;
135}
136
137static unsigned
138getScatteredRelocationAddress(const MachO::any_relocation_info &RE) {
139 return RE.r_word0 & 0xffffff;
140}
141
142static bool getPlainRelocationPCRel(const MachOObjectFile &O,
143 const MachO::any_relocation_info &RE) {
144 if (O.isLittleEndian())
145 return (RE.r_word1 >> 24) & 1;
146 return (RE.r_word1 >> 7) & 1;
147}
148
149static bool
150getScatteredRelocationPCRel(const MachO::any_relocation_info &RE) {
151 return (RE.r_word0 >> 30) & 1;
152}
153
154static unsigned getPlainRelocationLength(const MachOObjectFile &O,
155 const MachO::any_relocation_info &RE) {
156 if (O.isLittleEndian())
157 return (RE.r_word1 >> 25) & 3;
158 return (RE.r_word1 >> 5) & 3;
159}
160
161static unsigned
162getScatteredRelocationLength(const MachO::any_relocation_info &RE) {
163 return (RE.r_word0 >> 28) & 3;
164}
165
166static unsigned getPlainRelocationType(const MachOObjectFile &O,
167 const MachO::any_relocation_info &RE) {
168 if (O.isLittleEndian())
169 return RE.r_word1 >> 28;
170 return RE.r_word1 & 0xf;
171}
172
173static uint32_t getSectionFlags(const MachOObjectFile &O,
174 DataRefImpl Sec) {
175 if (O.is64Bit()) {
176 MachO::section_64 Sect = O.getSection64(Sec);
177 return Sect.flags;
178 }
179 MachO::section Sect = O.getSection(Sec);
180 return Sect.flags;
181}
182
183static Expected<MachOObjectFile::LoadCommandInfo>
184getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr,
185 uint32_t LoadCommandIndex) {
186 if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
187 if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())
188 return malformedError("load command " + Twine(LoadCommandIndex) +
189 " extends past end of file");
190 if (CmdOrErr->cmdsize < 8)
191 return malformedError("load command " + Twine(LoadCommandIndex) +
192 " with size less than 8 bytes");
193 return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
194 } else
195 return CmdOrErr.takeError();
196}
197
198static Expected<MachOObjectFile::LoadCommandInfo>
199getFirstLoadCommandInfo(const MachOObjectFile &Obj) {
200 unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
201 : sizeof(MachO::mach_header);
202 if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds)
203 return malformedError("load command 0 extends past the end all load "
204 "commands in the file");
205 return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
206}
207
208static Expected<MachOObjectFile::LoadCommandInfo>
209getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex,
210 const MachOObjectFile::LoadCommandInfo &L) {
211 unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
212 : sizeof(MachO::mach_header);
213 if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
214 Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
215 return malformedError("load command " + Twine(LoadCommandIndex + 1) +
216 " extends past the end all load commands in the file");
217 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
218}
219
220template <typename T>
221static void parseHeader(const MachOObjectFile &Obj, T &Header,
222 Error &Err) {
223 if (sizeof(T) > Obj.getData().size()) {
224 Err = malformedError("the mach header extends past the end of the "
225 "file");
226 return;
227 }
228 if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
229 Header = *HeaderOrErr;
230 else
231 Err = HeaderOrErr.takeError();
232}
233
234// This is used to check for overlapping of Mach-O elements.
235struct MachOElement {
236 uint64_t Offset;
237 uint64_t Size;
238 const char *Name;
239};
240
241static Error checkOverlappingElement(std::list<MachOElement> &Elements,
242 uint64_t Offset, uint64_t Size,
243 const char *Name) {
244 if (Size == 0)
245 return Error::success();
246
247 for (auto it=Elements.begin() ; it != Elements.end(); ++it) {
248 auto E = *it;
249 if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
250 (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) ||
251 (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
252 return malformedError(Twine(Name) + " at offset " + Twine(Offset) +
253 " with a size of " + Twine(Size) + ", overlaps " +
254 E.Name + " at offset " + Twine(E.Offset) + " with "
255 "a size of " + Twine(E.Size));
256 auto nt = it;
257 nt++;
258 if (nt != Elements.end()) {
259 auto N = *nt;
260 if (Offset + Size <= N.Offset) {
261 Elements.insert(nt, {Offset, Size, Name});
262 return Error::success();
263 }
264 }
265 }
266 Elements.push_back({Offset, Size, Name});
267 return Error::success();
268}
269
270// Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
271// sections to \param Sections, and optionally sets
272// \param IsPageZeroSegment to true.
273template <typename Segment, typename Section>
274static Error parseSegmentLoadCommand(
275 const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load,
276 SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
277 uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
278 std::list<MachOElement> &Elements) {
279 const unsigned SegmentLoadSize = sizeof(Segment);
280 if (Load.C.cmdsize < SegmentLoadSize)
281 return malformedError("load command " + Twine(LoadCommandIndex) +
282 " " + CmdName + " cmdsize too small");
283 if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
284 Segment S = SegOrErr.get();
285 const unsigned SectionSize = sizeof(Section);
286 uint64_t FileSize = Obj.getData().size();
287 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
288 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
289 return malformedError("load command " + Twine(LoadCommandIndex) +
290 " inconsistent cmdsize in " + CmdName +
291 " for the number of sections");
292 for (unsigned J = 0; J < S.nsects; ++J) {
293 const char *Sec = getSectionPtr(Obj, Load, J);
294 Sections.push_back(Sec);
295 Section s = getStruct<Section>(Obj, Sec);
296 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
297 Obj.getHeader().filetype != MachO::MH_DSYM &&
298 s.flags != MachO::S_ZEROFILL &&
299 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
300 s.offset > FileSize)
301 return malformedError("offset field of section " + Twine(J) + " in " +
302 CmdName + " command " + Twine(LoadCommandIndex) +
303 " extends past the end of the file");
304 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
305 Obj.getHeader().filetype != MachO::MH_DSYM &&
306 s.flags != MachO::S_ZEROFILL &&
307 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 &&
308 s.offset < SizeOfHeaders && s.size != 0)
309 return malformedError("offset field of section " + Twine(J) + " in " +
310 CmdName + " command " + Twine(LoadCommandIndex) +
311 " not past the headers of the file");
312 uint64_t BigSize = s.offset;
313 BigSize += s.size;
314 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
315 Obj.getHeader().filetype != MachO::MH_DSYM &&
316 s.flags != MachO::S_ZEROFILL &&
317 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
318 BigSize > FileSize)
319 return malformedError("offset field plus size field of section " +
320 Twine(J) + " in " + CmdName + " command " +
321 Twine(LoadCommandIndex) +
322 " extends past the end of the file");
323 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
324 Obj.getHeader().filetype != MachO::MH_DSYM &&
325 s.flags != MachO::S_ZEROFILL &&
326 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL &&
327 s.size > S.filesize)
328 return malformedError("size field of section " +
329 Twine(J) + " in " + CmdName + " command " +
330 Twine(LoadCommandIndex) +
331 " greater than the segment");
332 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
333 Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
334 s.addr < S.vmaddr)
335 return malformedError("addr field of section " + Twine(J) + " in " +
336 CmdName + " command " + Twine(LoadCommandIndex) +
337 " less than the segment's vmaddr");
338 BigSize = s.addr;
339 BigSize += s.size;
340 uint64_t BigEnd = S.vmaddr;
341 BigEnd += S.vmsize;
342 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
343 return malformedError("addr field plus size of section " + Twine(J) +
344 " in " + CmdName + " command " +
345 Twine(LoadCommandIndex) +
346 " greater than than "
347 "the segment's vmaddr plus vmsize");
348 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB &&
349 Obj.getHeader().filetype != MachO::MH_DSYM &&
350 s.flags != MachO::S_ZEROFILL &&
351 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL)
352 if (Error Err = checkOverlappingElement(Elements, s.offset, s.size,
353 "section contents"))
354 return Err;
355 if (s.reloff > FileSize)
356 return malformedError("reloff field of section " + Twine(J) + " in " +
357 CmdName + " command " + Twine(LoadCommandIndex) +
358 " extends past the end of the file");
359 BigSize = s.nreloc;
360 BigSize *= sizeof(struct MachO::relocation_info);
361 BigSize += s.reloff;
362 if (BigSize > FileSize)
363 return malformedError("reloff field plus nreloc field times sizeof("
364 "struct relocation_info) of section " +
365 Twine(J) + " in " + CmdName + " command " +
366 Twine(LoadCommandIndex) +
367 " extends past the end of the file");
368 if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc *
369 sizeof(struct
370 MachO::relocation_info),
371 "section relocation entries"))
372 return Err;
373 }
374 if (S.fileoff > FileSize)
375 return malformedError("load command " + Twine(LoadCommandIndex) +
376 " fileoff field in " + CmdName +
377 " extends past the end of the file");
378 uint64_t BigSize = S.fileoff;
379 BigSize += S.filesize;
380 if (BigSize > FileSize)
381 return malformedError("load command " + Twine(LoadCommandIndex) +
382 " fileoff field plus filesize field in " +
383 CmdName + " extends past the end of the file");
384 if (S.vmsize != 0 && S.filesize > S.vmsize)
385 return malformedError("load command " + Twine(LoadCommandIndex) +
386 " filesize field in " + CmdName +
387 " greater than vmsize field");
388 IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
389 } else
390 return SegOrErr.takeError();
391
392 return Error::success();
393}
394
395static Error checkSymtabCommand(const MachOObjectFile &Obj,
396 const MachOObjectFile::LoadCommandInfo &Load,
397 uint32_t LoadCommandIndex,
398 const char **SymtabLoadCmd,
399 std::list<MachOElement> &Elements) {
400 if (Load.C.cmdsize < sizeof(MachO::symtab_command))
401 return malformedError("load command " + Twine(LoadCommandIndex) +
402 " LC_SYMTAB cmdsize too small");
403 if (*SymtabLoadCmd != nullptr)
404 return malformedError("more than one LC_SYMTAB command");
405 MachO::symtab_command Symtab =
406 getStruct<MachO::symtab_command>(Obj, Load.Ptr);
407 if (Symtab.cmdsize != sizeof(MachO::symtab_command))
408 return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) +
409 " has incorrect cmdsize");
410 uint64_t FileSize = Obj.getData().size();
411 if (Symtab.symoff > FileSize)
412 return malformedError("symoff field of LC_SYMTAB command " +
413 Twine(LoadCommandIndex) + " extends past the end "
414 "of the file");
415 uint64_t SymtabSize = Symtab.nsyms;
416 const char *struct_nlist_name;
417 if (Obj.is64Bit()) {
418 SymtabSize *= sizeof(MachO::nlist_64);
419 struct_nlist_name = "struct nlist_64";
420 } else {
421 SymtabSize *= sizeof(MachO::nlist);
422 struct_nlist_name = "struct nlist";
423 }
424 uint64_t BigSize = SymtabSize;
425 BigSize += Symtab.symoff;
426 if (BigSize > FileSize)
427 return malformedError("symoff field plus nsyms field times sizeof(" +
428 Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
429 Twine(LoadCommandIndex) + " extends past the end "
430 "of the file");
431 if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize,
432 "symbol table"))
433 return Err;
434 if (Symtab.stroff > FileSize)
435 return malformedError("stroff field of LC_SYMTAB command " +
436 Twine(LoadCommandIndex) + " extends past the end "
437 "of the file");
438 BigSize = Symtab.stroff;
439 BigSize += Symtab.strsize;
440 if (BigSize > FileSize)
441 return malformedError("stroff field plus strsize field of LC_SYMTAB "
442 "command " + Twine(LoadCommandIndex) + " extends "
443 "past the end of the file");
444 if (Error Err = checkOverlappingElement(Elements, Symtab.stroff,
445 Symtab.strsize, "string table"))
446 return Err;
447 *SymtabLoadCmd = Load.Ptr;
448 return Error::success();
449}
450
451static Error checkDysymtabCommand(const MachOObjectFile &Obj,
452 const MachOObjectFile::LoadCommandInfo &Load,
453 uint32_t LoadCommandIndex,
454 const char **DysymtabLoadCmd,
455 std::list<MachOElement> &Elements) {
456 if (Load.C.cmdsize < sizeof(MachO::dysymtab_command))
457 return malformedError("load command " + Twine(LoadCommandIndex) +
458 " LC_DYSYMTAB cmdsize too small");
459 if (*DysymtabLoadCmd != nullptr)
460 return malformedError("more than one LC_DYSYMTAB command");
461 MachO::dysymtab_command Dysymtab =
462 getStruct<MachO::dysymtab_command>(Obj, Load.Ptr);
463 if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command))
464 return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) +
465 " has incorrect cmdsize");
466 uint64_t FileSize = Obj.getData().size();
467 if (Dysymtab.tocoff > FileSize)
468 return malformedError("tocoff field of LC_DYSYMTAB command " +
469 Twine(LoadCommandIndex) + " extends past the end of "
470 "the file");
471 uint64_t BigSize = Dysymtab.ntoc;
472 BigSize *= sizeof(MachO::dylib_table_of_contents);
473 BigSize += Dysymtab.tocoff;
474 if (BigSize > FileSize)
475 return malformedError("tocoff field plus ntoc field times sizeof(struct "
476 "dylib_table_of_contents) of LC_DYSYMTAB command " +
477 Twine(LoadCommandIndex) + " extends past the end of "
478 "the file");
479 if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff,
480 Dysymtab.ntoc * sizeof(struct
481 MachO::dylib_table_of_contents),
482 "table of contents"))
483 return Err;
484 if (Dysymtab.modtaboff > FileSize)
485 return malformedError("modtaboff field of LC_DYSYMTAB command " +
486 Twine(LoadCommandIndex) + " extends past the end of "
487 "the file");
488 BigSize = Dysymtab.nmodtab;
489 const char *struct_dylib_module_name;
490 uint64_t sizeof_modtab;
491 if (Obj.is64Bit()) {
492 sizeof_modtab = sizeof(MachO::dylib_module_64);
493 struct_dylib_module_name = "struct dylib_module_64";
494 } else {
495 sizeof_modtab = sizeof(MachO::dylib_module);
496 struct_dylib_module_name = "struct dylib_module";
497 }
498 BigSize *= sizeof_modtab;
499 BigSize += Dysymtab.modtaboff;
500 if (BigSize > FileSize)
501 return malformedError("modtaboff field plus nmodtab field times sizeof(" +
502 Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
503 "command " + Twine(LoadCommandIndex) + " extends "
504 "past the end of the file");
505 if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff,
506 Dysymtab.nmodtab * sizeof_modtab,
507 "module table"))
508 return Err;
509 if (Dysymtab.extrefsymoff > FileSize)
510 return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
511 Twine(LoadCommandIndex) + " extends past the end of "
512 "the file");
513 BigSize = Dysymtab.nextrefsyms;
514 BigSize *= sizeof(MachO::dylib_reference);
515 BigSize += Dysymtab.extrefsymoff;
516 if (BigSize > FileSize)
517 return malformedError("extrefsymoff field plus nextrefsyms field times "
518 "sizeof(struct dylib_reference) of LC_DYSYMTAB "
519 "command " + Twine(LoadCommandIndex) + " extends "
520 "past the end of the file");
521 if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff,
522 Dysymtab.nextrefsyms *
523 sizeof(MachO::dylib_reference),
524 "reference table"))
525 return Err;
526 if (Dysymtab.indirectsymoff > FileSize)
527 return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
528 Twine(LoadCommandIndex) + " extends past the end of "
529 "the file");
530 BigSize = Dysymtab.nindirectsyms;
531 BigSize *= sizeof(uint32_t);
532 BigSize += Dysymtab.indirectsymoff;
533 if (BigSize > FileSize)
534 return malformedError("indirectsymoff field plus nindirectsyms field times "
535 "sizeof(uint32_t) of LC_DYSYMTAB command " +
536 Twine(LoadCommandIndex) + " extends past the end of "
537 "the file");
538 if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff,
539 Dysymtab.nindirectsyms *
540 sizeof(uint32_t),
541 "indirect table"))
542 return Err;
543 if (Dysymtab.extreloff > FileSize)
544 return malformedError("extreloff field of LC_DYSYMTAB command " +
545 Twine(LoadCommandIndex) + " extends past the end of "
546 "the file");
547 BigSize = Dysymtab.nextrel;
548 BigSize *= sizeof(MachO::relocation_info);
549 BigSize += Dysymtab.extreloff;
550 if (BigSize > FileSize)
551 return malformedError("extreloff field plus nextrel field times sizeof"
552 "(struct relocation_info) of LC_DYSYMTAB command " +
553 Twine(LoadCommandIndex) + " extends past the end of "
554 "the file");
555 if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff,
556 Dysymtab.nextrel *
557 sizeof(MachO::relocation_info),
558 "external relocation table"))
559 return Err;
560 if (Dysymtab.locreloff > FileSize)
561 return malformedError("locreloff field of LC_DYSYMTAB command " +
562 Twine(LoadCommandIndex) + " extends past the end of "
563 "the file");
564 BigSize = Dysymtab.nlocrel;
565 BigSize *= sizeof(MachO::relocation_info);
566 BigSize += Dysymtab.locreloff;
567 if (BigSize > FileSize)
568 return malformedError("locreloff field plus nlocrel field times sizeof"
569 "(struct relocation_info) of LC_DYSYMTAB command " +
570 Twine(LoadCommandIndex) + " extends past the end of "
571 "the file");
572 if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff,
573 Dysymtab.nlocrel *
574 sizeof(MachO::relocation_info),
575 "local relocation table"))
576 return Err;
577 *DysymtabLoadCmd = Load.Ptr;
578 return Error::success();
579}
580
581static Error checkLinkeditDataCommand(const MachOObjectFile &Obj,
582 const MachOObjectFile::LoadCommandInfo &Load,
583 uint32_t LoadCommandIndex,
584 const char **LoadCmd, const char *CmdName,
585 std::list<MachOElement> &Elements,
586 const char *ElementName) {
587 if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command))
588 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
589 CmdName + " cmdsize too small");
590 if (*LoadCmd != nullptr)
591 return malformedError("more than one " + Twine(CmdName) + " command");
592 MachO::linkedit_data_command LinkData =
593 getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr);
594 if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command))
595 return malformedError(Twine(CmdName) + " command " +
596 Twine(LoadCommandIndex) + " has incorrect cmdsize");
597 uint64_t FileSize = Obj.getData().size();
598 if (LinkData.dataoff > FileSize)
599 return malformedError("dataoff field of " + Twine(CmdName) + " command " +
600 Twine(LoadCommandIndex) + " extends past the end of "
601 "the file");
602 uint64_t BigSize = LinkData.dataoff;
603 BigSize += LinkData.datasize;
604 if (BigSize > FileSize)
605 return malformedError("dataoff field plus datasize field of " +
606 Twine(CmdName) + " command " +
607 Twine(LoadCommandIndex) + " extends past the end of "
608 "the file");
609 if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff,
610 LinkData.datasize, ElementName))
611 return Err;
612 *LoadCmd = Load.Ptr;
613 return Error::success();
614}
615
616static Error checkDyldInfoCommand(const MachOObjectFile &Obj,
617 const MachOObjectFile::LoadCommandInfo &Load,
618 uint32_t LoadCommandIndex,
619 const char **LoadCmd, const char *CmdName,
620 std::list<MachOElement> &Elements) {
621 if (Load.C.cmdsize < sizeof(MachO::dyld_info_command))
622 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
623 CmdName + " cmdsize too small");
624 if (*LoadCmd != nullptr)
625 return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
626 "command");
627 MachO::dyld_info_command DyldInfo =
628 getStruct<MachO::dyld_info_command>(Obj, Load.Ptr);
629 if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command))
630 return malformedError(Twine(CmdName) + " command " +
631 Twine(LoadCommandIndex) + " has incorrect cmdsize");
632 uint64_t FileSize = Obj.getData().size();
633 if (DyldInfo.rebase_off > FileSize)
634 return malformedError("rebase_off field of " + Twine(CmdName) +
635 " command " + Twine(LoadCommandIndex) + " extends "
636 "past the end of the file");
637 uint64_t BigSize = DyldInfo.rebase_off;
638 BigSize += DyldInfo.rebase_size;
639 if (BigSize > FileSize)
640 return malformedError("rebase_off field plus rebase_size field of " +
641 Twine(CmdName) + " command " +
642 Twine(LoadCommandIndex) + " extends past the end of "
643 "the file");
644 if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off,
645 DyldInfo.rebase_size,
646 "dyld rebase info"))
647 return Err;
648 if (DyldInfo.bind_off > FileSize)
649 return malformedError("bind_off field of " + Twine(CmdName) +
650 " command " + Twine(LoadCommandIndex) + " extends "
651 "past the end of the file");
652 BigSize = DyldInfo.bind_off;
653 BigSize += DyldInfo.bind_size;
654 if (BigSize > FileSize)
655 return malformedError("bind_off field plus bind_size field of " +
656 Twine(CmdName) + " command " +
657 Twine(LoadCommandIndex) + " extends past the end of "
658 "the file");
659 if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off,
660 DyldInfo.bind_size,
661 "dyld bind info"))
662 return Err;
663 if (DyldInfo.weak_bind_off > FileSize)
664 return malformedError("weak_bind_off field of " + Twine(CmdName) +
665 " command " + Twine(LoadCommandIndex) + " extends "
666 "past the end of the file");
667 BigSize = DyldInfo.weak_bind_off;
668 BigSize += DyldInfo.weak_bind_size;
669 if (BigSize > FileSize)
670 return malformedError("weak_bind_off field plus weak_bind_size field of " +
671 Twine(CmdName) + " command " +
672 Twine(LoadCommandIndex) + " extends past the end of "
673 "the file");
674 if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off,
675 DyldInfo.weak_bind_size,
676 "dyld weak bind info"))
677 return Err;
678 if (DyldInfo.lazy_bind_off > FileSize)
679 return malformedError("lazy_bind_off field of " + Twine(CmdName) +
680 " command " + Twine(LoadCommandIndex) + " extends "
681 "past the end of the file");
682 BigSize = DyldInfo.lazy_bind_off;
683 BigSize += DyldInfo.lazy_bind_size;
684 if (BigSize > FileSize)
685 return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
686 Twine(CmdName) + " command " +
687 Twine(LoadCommandIndex) + " extends past the end of "
688 "the file");
689 if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off,
690 DyldInfo.lazy_bind_size,
691 "dyld lazy bind info"))
692 return Err;
693 if (DyldInfo.export_off > FileSize)
694 return malformedError("export_off field of " + Twine(CmdName) +
695 " command " + Twine(LoadCommandIndex) + " extends "
696 "past the end of the file");
697 BigSize = DyldInfo.export_off;
698 BigSize += DyldInfo.export_size;
699 if (BigSize > FileSize)
700 return malformedError("export_off field plus export_size field of " +
701 Twine(CmdName) + " command " +
702 Twine(LoadCommandIndex) + " extends past the end of "
703 "the file");
704 if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off,
705 DyldInfo.export_size,
706 "dyld export info"))
707 return Err;
708 *LoadCmd = Load.Ptr;
709 return Error::success();
710}
711
712static Error checkDylibCommand(const MachOObjectFile &Obj,
713 const MachOObjectFile::LoadCommandInfo &Load,
714 uint32_t LoadCommandIndex, const char *CmdName) {
715 if (Load.C.cmdsize < sizeof(MachO::dylib_command))
716 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
717 CmdName + " cmdsize too small");
718 MachO::dylib_command D = getStruct<MachO::dylib_command>(Obj, Load.Ptr);
719 if (D.dylib.name < sizeof(MachO::dylib_command))
720 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
721 CmdName + " name.offset field too small, not past "
722 "the end of the dylib_command struct");
723 if (D.dylib.name >= D.cmdsize)
724 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
725 CmdName + " name.offset field extends past the end "
726 "of the load command");
727 // Make sure there is a null between the starting offset of the name and
728 // the end of the load command.
729 uint32_t i;
730 const char *P = (const char *)Load.Ptr;
731 for (i = D.dylib.name; i < D.cmdsize; i++)
732 if (P[i] == '\0')
733 break;
734 if (i >= D.cmdsize)
735 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
736 CmdName + " library name extends past the end of the "
737 "load command");
738 return Error::success();
739}
740
741static Error checkDylibIdCommand(const MachOObjectFile &Obj,
742 const MachOObjectFile::LoadCommandInfo &Load,
743 uint32_t LoadCommandIndex,
744 const char **LoadCmd) {
745 if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex,
746 "LC_ID_DYLIB"))
747 return Err;
748 if (*LoadCmd != nullptr)
749 return malformedError("more than one LC_ID_DYLIB command");
750 if (Obj.getHeader().filetype != MachO::MH_DYLIB &&
751 Obj.getHeader().filetype != MachO::MH_DYLIB_STUB)
752 return malformedError("LC_ID_DYLIB load command in non-dynamic library "
753 "file type");
754 *LoadCmd = Load.Ptr;
755 return Error::success();
756}
757
758static Error checkDyldCommand(const MachOObjectFile &Obj,
759 const MachOObjectFile::LoadCommandInfo &Load,
760 uint32_t LoadCommandIndex, const char *CmdName) {
761 if (Load.C.cmdsize < sizeof(MachO::dylinker_command))
762 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
763 CmdName + " cmdsize too small");
764 MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr);
765 if (D.name < sizeof(MachO::dylinker_command))
766 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
767 CmdName + " name.offset field too small, not past "
768 "the end of the dylinker_command struct");
769 if (D.name >= D.cmdsize)
770 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
771 CmdName + " name.offset field extends past the end "
772 "of the load command");
773 // Make sure there is a null between the starting offset of the name and
774 // the end of the load command.
775 uint32_t i;
776 const char *P = (const char *)Load.Ptr;
777 for (i = D.name; i < D.cmdsize; i++)
778 if (P[i] == '\0')
779 break;
780 if (i >= D.cmdsize)
781 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
782 CmdName + " dyld name extends past the end of the "
783 "load command");
784 return Error::success();
785}
786
787static Error checkVersCommand(const MachOObjectFile &Obj,
788 const MachOObjectFile::LoadCommandInfo &Load,
789 uint32_t LoadCommandIndex,
790 const char **LoadCmd, const char *CmdName) {
791 if (Load.C.cmdsize != sizeof(MachO::version_min_command))
792 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
793 CmdName + " has incorrect cmdsize");
794 if (*LoadCmd != nullptr)
795 return malformedError("more than one LC_VERSION_MIN_MACOSX, "
796 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
797 "LC_VERSION_MIN_WATCHOS command");
798 *LoadCmd = Load.Ptr;
799 return Error::success();
800}
801
802static Error checkNoteCommand(const MachOObjectFile &Obj,
803 const MachOObjectFile::LoadCommandInfo &Load,
804 uint32_t LoadCommandIndex,
805 std::list<MachOElement> &Elements) {
806 if (Load.C.cmdsize != sizeof(MachO::note_command))
807 return malformedError("load command " + Twine(LoadCommandIndex) +
808 " LC_NOTE has incorrect cmdsize");
809 MachO::note_command Nt = getStruct<MachO::note_command>(Obj, Load.Ptr);
810 uint64_t FileSize = Obj.getData().size();
811 if (Nt.offset > FileSize)
812 return malformedError("offset field of LC_NOTE command " +
813 Twine(LoadCommandIndex) + " extends "
814 "past the end of the file");
815 uint64_t BigSize = Nt.offset;
816 BigSize += Nt.size;
817 if (BigSize > FileSize)
818 return malformedError("size field plus offset field of LC_NOTE command " +
819 Twine(LoadCommandIndex) + " extends past the end of "
820 "the file");
821 if (Error Err = checkOverlappingElement(Elements, Nt.offset, Nt.size,
822 "LC_NOTE data"))
823 return Err;
824 return Error::success();
825}
826
827static Error
828parseBuildVersionCommand(const MachOObjectFile &Obj,
829 const MachOObjectFile::LoadCommandInfo &Load,
830 SmallVectorImpl<const char*> &BuildTools,
831 uint32_t LoadCommandIndex) {
832 MachO::build_version_command BVC =
833 getStruct<MachO::build_version_command>(Obj, Load.Ptr);
834 if (Load.C.cmdsize !=
835 sizeof(MachO::build_version_command) +
836 BVC.ntools * sizeof(MachO::build_tool_version))
837 return malformedError("load command " + Twine(LoadCommandIndex) +
838 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
839
840 auto Start = Load.Ptr + sizeof(MachO::build_version_command);
841 BuildTools.resize(BVC.ntools);
842 for (unsigned i = 0; i < BVC.ntools; ++i)
843 BuildTools[i] = Start + i * sizeof(MachO::build_tool_version);
844
845 return Error::success();
846}
847
848static Error checkRpathCommand(const MachOObjectFile &Obj,
849 const MachOObjectFile::LoadCommandInfo &Load,
850 uint32_t LoadCommandIndex) {
851 if (Load.C.cmdsize < sizeof(MachO::rpath_command))
852 return malformedError("load command " + Twine(LoadCommandIndex) +
853 " LC_RPATH cmdsize too small");
854 MachO::rpath_command R = getStruct<MachO::rpath_command>(Obj, Load.Ptr);
855 if (R.path < sizeof(MachO::rpath_command))
856 return malformedError("load command " + Twine(LoadCommandIndex) +
857 " LC_RPATH path.offset field too small, not past "
858 "the end of the rpath_command struct");
859 if (R.path >= R.cmdsize)
860 return malformedError("load command " + Twine(LoadCommandIndex) +
861 " LC_RPATH path.offset field extends past the end "
862 "of the load command");
863 // Make sure there is a null between the starting offset of the path and
864 // the end of the load command.
865 uint32_t i;
866 const char *P = (const char *)Load.Ptr;
867 for (i = R.path; i < R.cmdsize; i++)
868 if (P[i] == '\0')
869 break;
870 if (i >= R.cmdsize)
871 return malformedError("load command " + Twine(LoadCommandIndex) +
872 " LC_RPATH library name extends past the end of the "
873 "load command");
874 return Error::success();
875}
876
877static Error checkEncryptCommand(const MachOObjectFile &Obj,
878 const MachOObjectFile::LoadCommandInfo &Load,
879 uint32_t LoadCommandIndex,
880 uint64_t cryptoff, uint64_t cryptsize,
881 const char **LoadCmd, const char *CmdName) {
882 if (*LoadCmd != nullptr)
883 return malformedError("more than one LC_ENCRYPTION_INFO and or "
884 "LC_ENCRYPTION_INFO_64 command");
885 uint64_t FileSize = Obj.getData().size();
886 if (cryptoff > FileSize)
887 return malformedError("cryptoff field of " + Twine(CmdName) +
888 " command " + Twine(LoadCommandIndex) + " extends "
889 "past the end of the file");
890 uint64_t BigSize = cryptoff;
891 BigSize += cryptsize;
892 if (BigSize > FileSize)
893 return malformedError("cryptoff field plus cryptsize field of " +
894 Twine(CmdName) + " command " +
895 Twine(LoadCommandIndex) + " extends past the end of "
896 "the file");
897 *LoadCmd = Load.Ptr;
898 return Error::success();
899}
900
901static Error checkLinkerOptCommand(const MachOObjectFile &Obj,
902 const MachOObjectFile::LoadCommandInfo &Load,
903 uint32_t LoadCommandIndex) {
904 if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
905 return malformedError("load command " + Twine(LoadCommandIndex) +
906 " LC_LINKER_OPTION cmdsize too small");
907 MachO::linker_option_command L =
908 getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
909 // Make sure the count of strings is correct.
910 const char *string = (const char *)Load.Ptr +
911 sizeof(struct MachO::linker_option_command);
912 uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
913 uint32_t i = 0;
914 while (left > 0) {
915 while (*string == '\0' && left > 0) {
916 string++;
917 left--;
918 }
919 if (left > 0) {
920 i++;
921 uint32_t NullPos = StringRef(string, left).find('\0');
922 uint32_t len = std::min(NullPos, left) + 1;
923 string += len;
924 left -= len;
925 }
926 }
927 if (L.count != i)
928 return malformedError("load command " + Twine(LoadCommandIndex) +
929 " LC_LINKER_OPTION string count " + Twine(L.count) +
930 " does not match number of strings");
931 return Error::success();
932}
933
934static Error checkSubCommand(const MachOObjectFile &Obj,
935 const MachOObjectFile::LoadCommandInfo &Load,
936 uint32_t LoadCommandIndex, const char *CmdName,
937 size_t SizeOfCmd, const char *CmdStructName,
938 uint32_t PathOffset, const char *PathFieldName) {
939 if (PathOffset < SizeOfCmd)
940 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
941 CmdName + " " + PathFieldName + ".offset field too "
942 "small, not past the end of the " + CmdStructName);
943 if (PathOffset >= Load.C.cmdsize)
944 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
945 CmdName + " " + PathFieldName + ".offset field "
946 "extends past the end of the load command");
947 // Make sure there is a null between the starting offset of the path and
948 // the end of the load command.
949 uint32_t i;
950 const char *P = (const char *)Load.Ptr;
951 for (i = PathOffset; i < Load.C.cmdsize; i++)
952 if (P[i] == '\0')
953 break;
954 if (i >= Load.C.cmdsize)
955 return malformedError("load command " + Twine(LoadCommandIndex) + " " +
956 CmdName + " " + PathFieldName + " name extends past "
957 "the end of the load command");
958 return Error::success();
959}
960
961static Error checkThreadCommand(const MachOObjectFile &Obj,
962 const MachOObjectFile::LoadCommandInfo &Load,
963 uint32_t LoadCommandIndex,
964 const char *CmdName) {
965 if (Load.C.cmdsize < sizeof(MachO::thread_command))
966 return malformedError("load command " + Twine(LoadCommandIndex) +
967 CmdName + " cmdsize too small");
968 MachO::thread_command T =
969 getStruct<MachO::thread_command>(Obj, Load.Ptr);
970 const char *state = Load.Ptr + sizeof(MachO::thread_command);
971 const char *end = Load.Ptr + T.cmdsize;
972 uint32_t nflavor = 0;
973 uint32_t cputype = getCPUType(Obj);
974 while (state < end) {
975 if(state + sizeof(uint32_t) > end)
976 return malformedError("load command " + Twine(LoadCommandIndex) +
977 "flavor in " + CmdName + " extends past end of "
978 "command");
979 uint32_t flavor;
980 memcpy(&flavor, state, sizeof(uint32_t));
981 if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
982 sys::swapByteOrder(flavor);
983 state += sizeof(uint32_t);
984
985 if(state + sizeof(uint32_t) > end)
986 return malformedError("load command " + Twine(LoadCommandIndex) +
987 " count in " + CmdName + " extends past end of "
988 "command");
989 uint32_t count;
990 memcpy(&count, state, sizeof(uint32_t));
991 if (Obj.isLittleEndian() != sys::IsLittleEndianHost)
992 sys::swapByteOrder(count);
993 state += sizeof(uint32_t);
994
995 if (cputype == MachO::CPU_TYPE_I386) {
996 if (flavor == MachO::x86_THREAD_STATE32) {
997 if (count != MachO::x86_THREAD_STATE32_COUNT)
998 return malformedError("load command " + Twine(LoadCommandIndex) +
999 " count not x86_THREAD_STATE32_COUNT for "
1000 "flavor number " + Twine(nflavor) + " which is "
1001 "a x86_THREAD_STATE32 flavor in " + CmdName +
1002 " command");
1003 if (state + sizeof(MachO::x86_thread_state32_t) > end)
1004 return malformedError("load command " + Twine(LoadCommandIndex) +
1005 " x86_THREAD_STATE32 extends past end of "
1006 "command in " + CmdName + " command");
1007 state += sizeof(MachO::x86_thread_state32_t);
1008 } else {
1009 return malformedError("load command " + Twine(LoadCommandIndex) +
1010 " unknown flavor (" + Twine(flavor) + ") for "
1011 "flavor number " + Twine(nflavor) + " in " +
1012 CmdName + " command");
1013 }
1014 } else if (cputype == MachO::CPU_TYPE_X86_64) {
1015 if (flavor == MachO::x86_THREAD_STATE) {
1016 if (count != MachO::x86_THREAD_STATE_COUNT)
1017 return malformedError("load command " + Twine(LoadCommandIndex) +
1018 " count not x86_THREAD_STATE_COUNT for "
1019 "flavor number " + Twine(nflavor) + " which is "
1020 "a x86_THREAD_STATE flavor in " + CmdName +
1021 " command");
1022 if (state + sizeof(MachO::x86_thread_state_t) > end)
1023 return malformedError("load command " + Twine(LoadCommandIndex) +
1024 " x86_THREAD_STATE extends past end of "
1025 "command in " + CmdName + " command");
1026 state += sizeof(MachO::x86_thread_state_t);
1027 } else if (flavor == MachO::x86_FLOAT_STATE) {
1028 if (count != MachO::x86_FLOAT_STATE_COUNT)
1029 return malformedError("load command " + Twine(LoadCommandIndex) +
1030 " count not x86_FLOAT_STATE_COUNT for "
1031 "flavor number " + Twine(nflavor) + " which is "
1032 "a x86_FLOAT_STATE flavor in " + CmdName +
1033 " command");
1034 if (state + sizeof(MachO::x86_float_state_t) > end)
1035 return malformedError("load command " + Twine(LoadCommandIndex) +
1036 " x86_FLOAT_STATE extends past end of "
1037 "command in " + CmdName + " command");
1038 state += sizeof(MachO::x86_float_state_t);
1039 } else if (flavor == MachO::x86_EXCEPTION_STATE) {
1040 if (count != MachO::x86_EXCEPTION_STATE_COUNT)
1041 return malformedError("load command " + Twine(LoadCommandIndex) +
1042 " count not x86_EXCEPTION_STATE_COUNT for "
1043 "flavor number " + Twine(nflavor) + " which is "
1044 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1045 " command");
1046 if (state + sizeof(MachO::x86_exception_state_t) > end)
1047 return malformedError("load command " + Twine(LoadCommandIndex) +
1048 " x86_EXCEPTION_STATE extends past end of "
1049 "command in " + CmdName + " command");
1050 state += sizeof(MachO::x86_exception_state_t);
1051 } else if (flavor == MachO::x86_THREAD_STATE64) {
1052 if (count != MachO::x86_THREAD_STATE64_COUNT)
1053 return malformedError("load command " + Twine(LoadCommandIndex) +
1054 " count not x86_THREAD_STATE64_COUNT for "
1055 "flavor number " + Twine(nflavor) + " which is "
1056 "a x86_THREAD_STATE64 flavor in " + CmdName +
1057 " command");
1058 if (state + sizeof(MachO::x86_thread_state64_t) > end)
1059 return malformedError("load command " + Twine(LoadCommandIndex) +
1060 " x86_THREAD_STATE64 extends past end of "
1061 "command in " + CmdName + " command");
1062 state += sizeof(MachO::x86_thread_state64_t);
1063 } else if (flavor == MachO::x86_EXCEPTION_STATE64) {
1064 if (count != MachO::x86_EXCEPTION_STATE64_COUNT)
1065 return malformedError("load command " + Twine(LoadCommandIndex) +
1066 " count not x86_EXCEPTION_STATE64_COUNT for "
1067 "flavor number " + Twine(nflavor) + " which is "
1068 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1069 " command");
1070 if (state + sizeof(MachO::x86_exception_state64_t) > end)
1071 return malformedError("load command " + Twine(LoadCommandIndex) +
1072 " x86_EXCEPTION_STATE64 extends past end of "
1073 "command in " + CmdName + " command");
1074 state += sizeof(MachO::x86_exception_state64_t);
1075 } else {
1076 return malformedError("load command " + Twine(LoadCommandIndex) +
1077 " unknown flavor (" + Twine(flavor) + ") for "
1078 "flavor number " + Twine(nflavor) + " in " +
1079 CmdName + " command");
1080 }
1081 } else if (cputype == MachO::CPU_TYPE_ARM) {
1082 if (flavor == MachO::ARM_THREAD_STATE) {
1083 if (count != MachO::ARM_THREAD_STATE_COUNT)
1084 return malformedError("load command " + Twine(LoadCommandIndex) +
1085 " count not ARM_THREAD_STATE_COUNT for "
1086 "flavor number " + Twine(nflavor) + " which is "
1087 "a ARM_THREAD_STATE flavor in " + CmdName +
1088 " command");
1089 if (state + sizeof(MachO::arm_thread_state32_t) > end)
1090 return malformedError("load command " + Twine(LoadCommandIndex) +
1091 " ARM_THREAD_STATE extends past end of "
1092 "command in " + CmdName + " command");
1093 state += sizeof(MachO::arm_thread_state32_t);
1094 } else {
1095 return malformedError("load command " + Twine(LoadCommandIndex) +
1096 " unknown flavor (" + Twine(flavor) + ") for "
1097 "flavor number " + Twine(nflavor) + " in " +
1098 CmdName + " command");
1099 }
1100 } else if (cputype == MachO::CPU_TYPE_ARM64) {
1101 if (flavor == MachO::ARM_THREAD_STATE64) {
1102 if (count != MachO::ARM_THREAD_STATE64_COUNT)
1103 return malformedError("load command " + Twine(LoadCommandIndex) +
1104 " count not ARM_THREAD_STATE64_COUNT for "
1105 "flavor number " + Twine(nflavor) + " which is "
1106 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1107 " command");
1108 if (state + sizeof(MachO::arm_thread_state64_t) > end)
1109 return malformedError("load command " + Twine(LoadCommandIndex) +
1110 " ARM_THREAD_STATE64 extends past end of "
1111 "command in " + CmdName + " command");
1112 state += sizeof(MachO::arm_thread_state64_t);
1113 } else {
1114 return malformedError("load command " + Twine(LoadCommandIndex) +
1115 " unknown flavor (" + Twine(flavor) + ") for "
1116 "flavor number " + Twine(nflavor) + " in " +
1117 CmdName + " command");
1118 }
1119 } else if (cputype == MachO::CPU_TYPE_POWERPC) {
1120 if (flavor == MachO::PPC_THREAD_STATE) {
1121 if (count != MachO::PPC_THREAD_STATE_COUNT)
1122 return malformedError("load command " + Twine(LoadCommandIndex) +
1123 " count not PPC_THREAD_STATE_COUNT for "
1124 "flavor number " + Twine(nflavor) + " which is "
1125 "a PPC_THREAD_STATE flavor in " + CmdName +
1126 " command");
1127 if (state + sizeof(MachO::ppc_thread_state32_t) > end)
1128 return malformedError("load command " + Twine(LoadCommandIndex) +
1129 " PPC_THREAD_STATE extends past end of "
1130 "command in " + CmdName + " command");
1131 state += sizeof(MachO::ppc_thread_state32_t);
1132 } else {
1133 return malformedError("load command " + Twine(LoadCommandIndex) +
1134 " unknown flavor (" + Twine(flavor) + ") for "
1135 "flavor number " + Twine(nflavor) + " in " +
1136 CmdName + " command");
1137 }
1138 } else {
1139 return malformedError("unknown cputype (" + Twine(cputype) + ") load "
1140 "command " + Twine(LoadCommandIndex) + " for " +
1141 CmdName + " command can't be checked");
1142 }
1143 nflavor++;
1144 }
1145 return Error::success();
1146}
1147
1148static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj,
1149 const MachOObjectFile::LoadCommandInfo
1150 &Load,
1151 uint32_t LoadCommandIndex,
1152 const char **LoadCmd,
1153 std::list<MachOElement> &Elements) {
1154 if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
1155 return malformedError("load command " + Twine(LoadCommandIndex) +
1156 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1157 if (*LoadCmd != nullptr)
1158 return malformedError("more than one LC_TWOLEVEL_HINTS command");
1159 MachO::twolevel_hints_command Hints =
1160 getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1161 uint64_t FileSize = Obj.getData().size();
1162 if (Hints.offset > FileSize)
1163 return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1164 Twine(LoadCommandIndex) + " extends past the end of "
1165 "the file");
1166 uint64_t BigSize = Hints.nhints;
1167 BigSize *= sizeof(MachO::twolevel_hint);
1168 BigSize += Hints.offset;
1169 if (BigSize > FileSize)
1170 return malformedError("offset field plus nhints times sizeof(struct "
1171 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1172 Twine(LoadCommandIndex) + " extends past the end of "
1173 "the file");
1174 if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints *
1175 sizeof(MachO::twolevel_hint),
1176 "two level hints"))
1177 return Err;
1178 *LoadCmd = Load.Ptr;
1179 return Error::success();
1180}
1181
1182// Returns true if the libObject code does not support the load command and its
1183// contents. The cmd value it is treated as an unknown load command but with
1184// an error message that says the cmd value is obsolete.
1185static bool isLoadCommandObsolete(uint32_t cmd) {
1186 if (cmd == MachO::LC_SYMSEG ||
1187 cmd == MachO::LC_LOADFVMLIB ||
1188 cmd == MachO::LC_IDFVMLIB ||
1189 cmd == MachO::LC_IDENT ||
1190 cmd == MachO::LC_FVMFILE ||
1191 cmd == MachO::LC_PREPAGE ||
1192 cmd == MachO::LC_PREBOUND_DYLIB ||
1193 cmd == MachO::LC_TWOLEVEL_HINTS ||
1194 cmd == MachO::LC_PREBIND_CKSUM)
1195 return true;
1196 return false;
1197}
1198
1199Expected<std::unique_ptr<MachOObjectFile>>
1200MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
1201 bool Is64Bits, uint32_t UniversalCputype,
1202 uint32_t UniversalIndex) {
1203 Error Err = Error::success();
1204 std::unique_ptr<MachOObjectFile> Obj(
1205 new MachOObjectFile(std::move(Object), IsLittleEndian,
1206 Is64Bits, Err, UniversalCputype,
1207 UniversalIndex));
1208 if (Err)
1209 return std::move(Err);
1210 return std::move(Obj);
1211}
1212
1213MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1214 bool Is64bits, Error &Err,
1215 uint32_t UniversalCputype,
1216 uint32_t UniversalIndex)
1217 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
1218 ErrorAsOutParameter ErrAsOutParam(&Err);
1219 uint64_t SizeOfHeaders;
1220 uint32_t cputype;
1221 if (is64Bit()) {
1222 parseHeader(*this, Header64, Err);
1223 SizeOfHeaders = sizeof(MachO::mach_header_64);
1224 cputype = Header64.cputype;
1225 } else {
1226 parseHeader(*this, Header, Err);
1227 SizeOfHeaders = sizeof(MachO::mach_header);
1228 cputype = Header.cputype;
1229 }
1230 if (Err)
1231 return;
1232 SizeOfHeaders += getHeader().sizeofcmds;
1233 if (getData().data() + SizeOfHeaders > getData().end()) {
1234 Err = malformedError("load commands extend past the end of the file");
1235 return;
1236 }
1237 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1238 Err = malformedError("universal header architecture: " +
1239 Twine(UniversalIndex) + "'s cputype does not match "
1240 "object file's mach header");
1241 return;
1242 }
1243 std::list<MachOElement> Elements;
1244 Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1245
1246 uint32_t LoadCommandCount = getHeader().ncmds;
1247 LoadCommandInfo Load;
1248 if (LoadCommandCount != 0) {
1249 if (auto LoadOrErr = getFirstLoadCommandInfo(*this))
1250 Load = *LoadOrErr;
1251 else {
1252 Err = LoadOrErr.takeError();
1253 return;
1254 }
1255 }
1256
1257 const char *DyldIdLoadCmd = nullptr;
1258 const char *FuncStartsLoadCmd = nullptr;
1259 const char *SplitInfoLoadCmd = nullptr;
1260 const char *CodeSignDrsLoadCmd = nullptr;
1261 const char *CodeSignLoadCmd = nullptr;
1262 const char *VersLoadCmd = nullptr;
1263 const char *SourceLoadCmd = nullptr;
1264 const char *EntryPointLoadCmd = nullptr;
1265 const char *EncryptLoadCmd = nullptr;
1266 const char *RoutinesLoadCmd = nullptr;
1267 const char *UnixThreadLoadCmd = nullptr;
1268 const char *TwoLevelHintsLoadCmd = nullptr;
1269 for (unsigned I = 0; I < LoadCommandCount; ++I) {
1270 if (is64Bit()) {
1271 if (Load.C.cmdsize % 8 != 0) {
1272 // We have a hack here to allow 64-bit Mach-O core files to have
1273 // LC_THREAD commands that are only a multiple of 4 and not 8 to be
1274 // allowed since the macOS kernel produces them.
1275 if (getHeader().filetype != MachO::MH_CORE ||
1276 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1277 Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1278 "multiple of 8");
1279 return;
1280 }
1281 }
1282 } else {
1283 if (Load.C.cmdsize % 4 != 0) {
1284 Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1285 "multiple of 4");
1286 return;
1287 }
1288 }
1289 LoadCommands.push_back(Load);
1290 if (Load.C.cmd == MachO::LC_SYMTAB) {
1291 if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1292 return;
1293 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1294 if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd,
1295 Elements)))
1296 return;
1297 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1298 if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd,
1299 "LC_DATA_IN_CODE", Elements,
1300 "data in code info")))
1301 return;
1302 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1303 if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd,
1304 "LC_LINKER_OPTIMIZATION_HINT",
1305 Elements, "linker optimization "
1306 "hints")))
1307 return;
1308 } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1309 if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd,
1310 "LC_FUNCTION_STARTS", Elements,
1311 "function starts data")))
1312 return;
1313 } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1314 if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd,
1315 "LC_SEGMENT_SPLIT_INFO", Elements,
1316 "split info data")))
1317 return;
1318 } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1319 if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd,
1320 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1321 "code signing RDs data")))
1322 return;
1323 } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1324 if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd,
1325 "LC_CODE_SIGNATURE", Elements,
1326 "code signature data")))
1327 return;
1328 } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1329 if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1330 "LC_DYLD_INFO", Elements)))
1331 return;
1332 } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1333 if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
1334 "LC_DYLD_INFO_ONLY", Elements)))
1335 return;
1336 } else if (Load.C.cmd == MachO::LC_UUID) {
1337 if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1338 Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1339 "cmdsize");
1340 return;
1341 }
1342 if (UuidLoadCmd) {
1343 Err = malformedError("more than one LC_UUID command");
1344 return;
1345 }
1346 UuidLoadCmd = Load.Ptr;
1347 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1348 if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
1349 MachO::section_64>(
1350 *this, Load, Sections, HasPageZeroSegment, I,
1351 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1352 return;
1353 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1354 if ((Err = parseSegmentLoadCommand<MachO::segment_command,
1355 MachO::section>(
1356 *this, Load, Sections, HasPageZeroSegment, I,
1357 "LC_SEGMENT", SizeOfHeaders, Elements)))
1358 return;
1359 } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1360 if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
1361 return;
1362 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1363 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB")))
1364 return;
1365 Libraries.push_back(Load.Ptr);
1366 } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1367 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1368 return;
1369 Libraries.push_back(Load.Ptr);
1370 } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1371 if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1372 return;
1373 Libraries.push_back(Load.Ptr);
1374 } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1375 if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB")))
1376 return;
1377 Libraries.push_back(Load.Ptr);
1378 } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1379 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1380 return;
1381 Libraries.push_back(Load.Ptr);
1382 } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1383 if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER")))
1384 return;
1385 } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1386 if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1387 return;
1388 } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1389 if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1390 return;
1391 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1392 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1393 "LC_VERSION_MIN_MACOSX")))
1394 return;
1395 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1396 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1397 "LC_VERSION_MIN_IPHONEOS")))
1398 return;
1399 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1400 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1401 "LC_VERSION_MIN_TVOS")))
1402 return;
1403 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1404 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
1405 "LC_VERSION_MIN_WATCHOS")))
1406 return;
1407 } else if (Load.C.cmd == MachO::LC_NOTE) {
1408 if ((Err = checkNoteCommand(*this, Load, I, Elements)))
1409 return;
1410 } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1411 if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
1412 return;
1413 } else if (Load.C.cmd == MachO::LC_RPATH) {
1414 if ((Err = checkRpathCommand(*this, Load, I)))
1415 return;
1416 } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1417 if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1418 Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1419 " has incorrect cmdsize");
1420 return;
1421 }
1422 if (SourceLoadCmd) {
1423 Err = malformedError("more than one LC_SOURCE_VERSION command");
1424 return;
1425 }
1426 SourceLoadCmd = Load.Ptr;
1427 } else if (Load.C.cmd == MachO::LC_MAIN) {
1428 if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1429 Err = malformedError("LC_MAIN command " + Twine(I) +
1430 " has incorrect cmdsize");
1431 return;
1432 }
1433 if (EntryPointLoadCmd) {
1434 Err = malformedError("more than one LC_MAIN command");
1435 return;
1436 }
1437 EntryPointLoadCmd = Load.Ptr;
1438 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1439 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1440 Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1441 " has incorrect cmdsize");
1442 return;
1443 }
1444 MachO::encryption_info_command E =
1445 getStruct<MachO::encryption_info_command>(*this, Load.Ptr);
1446 if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1447 &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1448 return;
1449 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1450 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1451 Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1452 " has incorrect cmdsize");
1453 return;
1454 }
1455 MachO::encryption_info_command_64 E =
1456 getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr);
1457 if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize,
1458 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1459 return;
1460 } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1461 if ((Err = checkLinkerOptCommand(*this, Load, I)))
1462 return;
1463 } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1464 if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1465 Err = malformedError("load command " + Twine(I) +
1466 " LC_SUB_FRAMEWORK cmdsize too small");
1467 return;
1468 }
1469 MachO::sub_framework_command S =
1470 getStruct<MachO::sub_framework_command>(*this, Load.Ptr);
1471 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1472 sizeof(MachO::sub_framework_command),
1473 "sub_framework_command", S.umbrella,
1474 "umbrella")))
1475 return;
1476 } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1477 if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1478 Err = malformedError("load command " + Twine(I) +
1479 " LC_SUB_UMBRELLA cmdsize too small");
1480 return;
1481 }
1482 MachO::sub_umbrella_command S =
1483 getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr);
1484 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1485 sizeof(MachO::sub_umbrella_command),
1486 "sub_umbrella_command", S.sub_umbrella,
1487 "sub_umbrella")))
1488 return;
1489 } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1490 if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1491 Err = malformedError("load command " + Twine(I) +
1492 " LC_SUB_LIBRARY cmdsize too small");
1493 return;
1494 }
1495 MachO::sub_library_command S =
1496 getStruct<MachO::sub_library_command>(*this, Load.Ptr);
1497 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1498 sizeof(MachO::sub_library_command),
1499 "sub_library_command", S.sub_library,
1500 "sub_library")))
1501 return;
1502 } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1503 if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1504 Err = malformedError("load command " + Twine(I) +
1505 " LC_SUB_CLIENT cmdsize too small");
1506 return;
1507 }
1508 MachO::sub_client_command S =
1509 getStruct<MachO::sub_client_command>(*this, Load.Ptr);
1510 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT",
1511 sizeof(MachO::sub_client_command),
1512 "sub_client_command", S.client, "client")))
1513 return;
1514 } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1515 if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1516 Err = malformedError("LC_ROUTINES command " + Twine(I) +
1517 " has incorrect cmdsize");
1518 return;
1519 }
1520 if (RoutinesLoadCmd) {
1521 Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1522 "command");
1523 return;
1524 }
1525 RoutinesLoadCmd = Load.Ptr;
1526 } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1527 if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1528 Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1529 " has incorrect cmdsize");
1530 return;
1531 }
1532 if (RoutinesLoadCmd) {
1533 Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1534 "command");
1535 return;
1536 }
1537 RoutinesLoadCmd = Load.Ptr;
1538 } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1539 if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD")))
1540 return;
1541 if (UnixThreadLoadCmd) {
1542 Err = malformedError("more than one LC_UNIXTHREAD command");
1543 return;
1544 }
1545 UnixThreadLoadCmd = Load.Ptr;
1546 } else if (Load.C.cmd == MachO::LC_THREAD) {
1547 if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD")))
1548 return;
1549 // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
1550 } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1551 if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
1552 &TwoLevelHintsLoadCmd, Elements)))
1553 return;
1554 } else if (isLoadCommandObsolete(Load.C.cmd)) {
1555 Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1556 Twine(Load.C.cmd) + " is obsolete and not "
1557 "supported");
1558 return;
1559 }
1560 // TODO: generate a error for unknown load commands by default. But still
1561 // need work out an approach to allow or not allow unknown values like this
1562 // as an option for some uses like lldb.
1563 if (I < LoadCommandCount - 1) {
1564 if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load))
1565 Load = *LoadOrErr;
1566 else {
1567 Err = LoadOrErr.takeError();
1568 return;
1569 }
1570 }
1571 }
1572 if (!SymtabLoadCmd) {
1573 if (DysymtabLoadCmd) {
1574 Err = malformedError("contains LC_DYSYMTAB load command without a "
1575 "LC_SYMTAB load command");
1576 return;
1577 }
1578 } else if (DysymtabLoadCmd) {
1579 MachO::symtab_command Symtab =
1580 getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
1581 MachO::dysymtab_command Dysymtab =
1582 getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
1583 if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1584 Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1585 "extends past the end of the symbol table");
1586 return;
1587 }
1588 uint64_t BigSize = Dysymtab.ilocalsym;
1589 BigSize += Dysymtab.nlocalsym;
1590 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1591 Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1592 "command extends past the end of the symbol table");
1593 return;
1594 }
1595 if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
1596 Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
1597 "extends past the end of the symbol table");
1598 return;
1599 }
1600 BigSize = Dysymtab.iextdefsym;
1601 BigSize += Dysymtab.nextdefsym;
1602 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1603 Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1604 "load command extends past the end of the symbol "
1605 "table");
1606 return;
1607 }
1608 if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
1609 Err = malformedError("nundefsym in LC_DYSYMTAB load command "
1610 "extends past the end of the symbol table");
1611 return;
1612 }
1613 BigSize = Dysymtab.iundefsym;
1614 BigSize += Dysymtab.nundefsym;
1615 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1616 Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1617 " command extends past the end of the symbol table");
1618 return;
1619 }
1620 }
1621 if ((getHeader().filetype == MachO::MH_DYLIB ||
1622 getHeader().filetype == MachO::MH_DYLIB_STUB) &&
1623 DyldIdLoadCmd == nullptr) {
1624 Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1625 "filetype");
1626 return;
1627 }
1628 assert(LoadCommands.size() == LoadCommandCount)(static_cast <bool> (LoadCommands.size() == LoadCommandCount
) ? void (0) : __assert_fail ("LoadCommands.size() == LoadCommandCount"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 1628, __extension__ __PRETTY_FUNCTION__))
;
1629
1630 Err = Error::success();
1631}
1632
1633Error MachOObjectFile::checkSymbolTable() const {
1634 uint32_t Flags = 0;
1635 if (is64Bit()) {
1636 MachO::mach_header_64 H_64 = MachOObjectFile::getHeader64();
1637 Flags = H_64.flags;
1638 } else {
1639 MachO::mach_header H = MachOObjectFile::getHeader();
1640 Flags = H.flags;
1641 }
1642 uint8_t NType = 0;
1643 uint8_t NSect = 0;
1644 uint16_t NDesc = 0;
1645 uint32_t NStrx = 0;
1646 uint64_t NValue = 0;
1647 uint32_t SymbolIndex = 0;
1648 MachO::symtab_command S = getSymtabLoadCommand();
1649 for (const SymbolRef &Symbol : symbols()) {
1650 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1651 if (is64Bit()) {
1652 MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI);
1653 NType = STE_64.n_type;
1654 NSect = STE_64.n_sect;
1655 NDesc = STE_64.n_desc;
1656 NStrx = STE_64.n_strx;
1657 NValue = STE_64.n_value;
1658 } else {
1659 MachO::nlist STE = getSymbolTableEntry(SymDRI);
1660 NType = STE.n_type;
1661 NType = STE.n_type;
1662 NSect = STE.n_sect;
1663 NDesc = STE.n_desc;
1664 NStrx = STE.n_strx;
1665 NValue = STE.n_value;
1666 }
1667 if ((NType & MachO::N_STAB) == 0 &&
1668 (NType & MachO::N_TYPE) == MachO::N_SECT) {
1669 if (NSect == 0 || NSect > Sections.size())
1670 return malformedError("bad section index: " + Twine((int)NSect) +
1671 " for symbol at index " + Twine(SymbolIndex));
1672 }
1673 if ((NType & MachO::N_STAB) == 0 &&
1674 (NType & MachO::N_TYPE) == MachO::N_INDR) {
1675 if (NValue >= S.strsize)
1676 return malformedError("bad n_value: " + Twine((int)NValue) + " past "
1677 "the end of string table, for N_INDR symbol at "
1678 "index " + Twine(SymbolIndex));
1679 }
1680 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
1681 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
1682 (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
1683 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
1684 if (LibraryOrdinal != 0 &&
1685 LibraryOrdinal != MachO::EXECUTABLE_ORDINAL &&
1686 LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL &&
1687 LibraryOrdinal - 1 >= Libraries.size() ) {
1688 return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) +
1689 " for symbol at index " + Twine(SymbolIndex));
1690 }
1691 }
1692 if (NStrx >= S.strsize)
1693 return malformedError("bad string table index: " + Twine((int)NStrx) +
1694 " past the end of string table, for symbol at "
1695 "index " + Twine(SymbolIndex));
1696 SymbolIndex++;
1697 }
1698 return Error::success();
1699}
1700
1701void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
1702 unsigned SymbolTableEntrySize = is64Bit() ?
1703 sizeof(MachO::nlist_64) :
1704 sizeof(MachO::nlist);
1705 Symb.p += SymbolTableEntrySize;
1706}
1707
1708Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
1709 StringRef StringTable = getStringTableData();
1710 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1711 if (Entry.n_strx == 0)
1712 // A n_strx value of 0 indicates that no name is associated with a
1713 // particular symbol table entry.
1714 return StringRef();
1715 const char *Start = &StringTable.data()[Entry.n_strx];
1716 if (Start < getData().begin() || Start >= getData().end()) {
1717 return malformedError("bad string index: " + Twine(Entry.n_strx) +
1718 " for symbol at index " + Twine(getSymbolIndex(Symb)));
1719 }
1720 return StringRef(Start);
1721}
1722
1723unsigned MachOObjectFile::getSectionType(SectionRef Sec) const {
1724 DataRefImpl DRI = Sec.getRawDataRefImpl();
1725 uint32_t Flags = getSectionFlags(*this, DRI);
1726 return Flags & MachO::SECTION_TYPE;
1727}
1728
1729uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const {
1730 if (is64Bit()) {
1731 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym);
1732 return Entry.n_value;
1733 }
1734 MachO::nlist Entry = getSymbolTableEntry(Sym);
1735 return Entry.n_value;
1736}
1737
1738// getIndirectName() returns the name of the alias'ed symbol who's string table
1739// index is in the n_value field.
1740std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
1741 StringRef &Res) const {
1742 StringRef StringTable = getStringTableData();
1743 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1744 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
1745 return object_error::parse_failed;
1746 uint64_t NValue = getNValue(Symb);
1747 if (NValue >= StringTable.size())
1748 return object_error::parse_failed;
1749 const char *Start = &StringTable.data()[NValue];
1750 Res = StringRef(Start);
1751 return std::error_code();
1752}
1753
1754uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
1755 return getNValue(Sym);
1756}
1757
1758Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
1759 return getSymbolValue(Sym);
1760}
1761
1762uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
1763 uint32_t flags = getSymbolFlags(DRI);
1764 if (flags & SymbolRef::SF_Common) {
1765 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1766 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
1767 }
1768 return 0;
1769}
1770
1771uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
1772 return getNValue(DRI);
1773}
1774
1775Expected<SymbolRef::Type>
1776MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
1777 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1778 uint8_t n_type = Entry.n_type;
1779
1780 // If this is a STAB debugging symbol, we can do nothing more.
1781 if (n_type & MachO::N_STAB)
1782 return SymbolRef::ST_Debug;
1783
1784 switch (n_type & MachO::N_TYPE) {
1785 case MachO::N_UNDF :
1786 return SymbolRef::ST_Unknown;
1787 case MachO::N_SECT :
1788 Expected<section_iterator> SecOrError = getSymbolSection(Symb);
1789 if (!SecOrError)
1790 return SecOrError.takeError();
1791 section_iterator Sec = *SecOrError;
1792 if (Sec->isData() || Sec->isBSS())
1793 return SymbolRef::ST_Data;
1794 return SymbolRef::ST_Function;
1795 }
1796 return SymbolRef::ST_Other;
1797}
1798
1799uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
1800 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
1801
1802 uint8_t MachOType = Entry.n_type;
1803 uint16_t MachOFlags = Entry.n_desc;
1804
1805 uint32_t Result = SymbolRef::SF_None;
1806
1807 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
1808 Result |= SymbolRef::SF_Indirect;
1809
1810 if (MachOType & MachO::N_STAB)
1811 Result |= SymbolRef::SF_FormatSpecific;
1812
1813 if (MachOType & MachO::N_EXT) {
1814 Result |= SymbolRef::SF_Global;
1815 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
1816 if (getNValue(DRI))
1817 Result |= SymbolRef::SF_Common;
1818 else
1819 Result |= SymbolRef::SF_Undefined;
1820 }
1821
1822 if (!(MachOType & MachO::N_PEXT))
1823 Result |= SymbolRef::SF_Exported;
1824 }
1825
1826 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
1827 Result |= SymbolRef::SF_Weak;
1828
1829 if (MachOFlags & (MachO::N_ARM_THUMB_DEF))
1830 Result |= SymbolRef::SF_Thumb;
1831
1832 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
1833 Result |= SymbolRef::SF_Absolute;
1834
1835 return Result;
1836}
1837
1838Expected<section_iterator>
1839MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
1840 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb);
1841 uint8_t index = Entry.n_sect;
1842
1843 if (index == 0)
1844 return section_end();
1845 DataRefImpl DRI;
1846 DRI.d.a = index - 1;
1847 if (DRI.d.a >= Sections.size()){
1848 return malformedError("bad section index: " + Twine((int)index) +
1849 " for symbol at index " + Twine(getSymbolIndex(Symb)));
1850 }
1851 return section_iterator(SectionRef(DRI, this));
1852}
1853
1854unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const {
1855 MachO::nlist_base Entry =
1856 getSymbolTableEntryBase(*this, Sym.getRawDataRefImpl());
1857 return Entry.n_sect - 1;
1858}
1859
1860void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
1861 Sec.d.a++;
1862}
1863
1864std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
1865 StringRef &Result) const {
1866 ArrayRef<char> Raw = getSectionRawName(Sec);
1867 Result = parseSegmentOrSectionName(Raw.data());
1868 return std::error_code();
1869}
1870
1871uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
1872 if (is64Bit())
1873 return getSection64(Sec).addr;
1874 return getSection(Sec).addr;
1875}
1876
1877uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
1878 return Sec.d.a;
1879}
1880
1881uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
1882 // In the case if a malformed Mach-O file where the section offset is past
1883 // the end of the file or some part of the section size is past the end of
1884 // the file return a size of zero or a size that covers the rest of the file
1885 // but does not extend past the end of the file.
1886 uint32_t SectOffset, SectType;
1887 uint64_t SectSize;
1888
1889 if (is64Bit()) {
1890 MachO::section_64 Sect = getSection64(Sec);
1891 SectOffset = Sect.offset;
1892 SectSize = Sect.size;
1893 SectType = Sect.flags & MachO::SECTION_TYPE;
1894 } else {
1895 MachO::section Sect = getSection(Sec);
1896 SectOffset = Sect.offset;
1897 SectSize = Sect.size;
1898 SectType = Sect.flags & MachO::SECTION_TYPE;
1899 }
1900 if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
1901 return SectSize;
1902 uint64_t FileSize = getData().size();
1903 if (SectOffset > FileSize)
1904 return 0;
1905 if (FileSize - SectOffset < SectSize)
1906 return FileSize - SectOffset;
1907 return SectSize;
1908}
1909
1910std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
1911 StringRef &Res) const {
1912 uint32_t Offset;
1913 uint64_t Size;
1914
1915 if (is64Bit()) {
1916 MachO::section_64 Sect = getSection64(Sec);
1917 Offset = Sect.offset;
1918 Size = Sect.size;
1919 } else {
1920 MachO::section Sect = getSection(Sec);
1921 Offset = Sect.offset;
1922 Size = Sect.size;
1923 }
1924
1925 Res = this->getData().substr(Offset, Size);
1926 return std::error_code();
1927}
1928
1929uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
1930 uint32_t Align;
1931 if (is64Bit()) {
1932 MachO::section_64 Sect = getSection64(Sec);
1933 Align = Sect.align;
1934 } else {
1935 MachO::section Sect = getSection(Sec);
1936 Align = Sect.align;
1937 }
1938
1939 return uint64_t(1) << Align;
1940}
1941
1942Expected<SectionRef> MachOObjectFile::getSection(unsigned SectionIndex) const {
1943 if (SectionIndex < 1 || SectionIndex > Sections.size())
1944 return malformedError("bad section index: " + Twine((int)SectionIndex));
1945
1946 DataRefImpl DRI;
1947 DRI.d.a = SectionIndex - 1;
1948 return SectionRef(DRI, this);
1949}
1950
1951Expected<SectionRef> MachOObjectFile::getSection(StringRef SectionName) const {
1952 StringRef SecName;
1953 for (const SectionRef &Section : sections()) {
1954 if (std::error_code E = Section.getName(SecName))
1955 return errorCodeToError(E);
1956 if (SecName == SectionName) {
1957 return Section;
1958 }
1959 }
1960 return errorCodeToError(object_error::parse_failed);
1961}
1962
1963bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
1964 return false;
1965}
1966
1967bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
1968 uint32_t Flags = getSectionFlags(*this, Sec);
1969 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
1970}
1971
1972bool MachOObjectFile::isSectionData(DataRefImpl Sec) const {
1973 uint32_t Flags = getSectionFlags(*this, Sec);
1974 unsigned SectionType = Flags & MachO::SECTION_TYPE;
1975 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1976 !(SectionType == MachO::S_ZEROFILL ||
1977 SectionType == MachO::S_GB_ZEROFILL);
1978}
1979
1980bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
1981 uint32_t Flags = getSectionFlags(*this, Sec);
1982 unsigned SectionType = Flags & MachO::SECTION_TYPE;
1983 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
1984 (SectionType == MachO::S_ZEROFILL ||
1985 SectionType == MachO::S_GB_ZEROFILL);
1986}
1987
1988unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
1989 return Sec.getRawDataRefImpl().d.a;
1990}
1991
1992bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
1993 uint32_t Flags = getSectionFlags(*this, Sec);
1994 unsigned SectionType = Flags & MachO::SECTION_TYPE;
1995 return SectionType == MachO::S_ZEROFILL ||
1996 SectionType == MachO::S_GB_ZEROFILL;
1997}
1998
1999bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
2000 StringRef SegmentName = getSectionFinalSegmentName(Sec);
2001 StringRef SectName;
2002 if (!getSectionName(Sec, SectName))
2003 return (SegmentName == "__LLVM" && SectName == "__bitcode");
2004 return false;
2005}
2006
2007bool MachOObjectFile::isSectionStripped(DataRefImpl Sec) const {
2008 if (is64Bit())
2009 return getSection64(Sec).offset == 0;
2010 return getSection(Sec).offset == 0;
2011}
2012
2013relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
2014 DataRefImpl Ret;
2015 Ret.d.a = Sec.d.a;
2016 Ret.d.b = 0;
2017 return relocation_iterator(RelocationRef(Ret, this));
2018}
2019
2020relocation_iterator
2021MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
2022 uint32_t Num;
2023 if (is64Bit()) {
2024 MachO::section_64 Sect = getSection64(Sec);
2025 Num = Sect.nreloc;
2026 } else {
2027 MachO::section Sect = getSection(Sec);
2028 Num = Sect.nreloc;
2029 }
2030
2031 DataRefImpl Ret;
2032 Ret.d.a = Sec.d.a;
2033 Ret.d.b = Num;
2034 return relocation_iterator(RelocationRef(Ret, this));
2035}
2036
2037relocation_iterator MachOObjectFile::extrel_begin() const {
2038 DataRefImpl Ret;
2039 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2040 Ret.d.a = 0; // Would normally be a section index.
2041 Ret.d.b = 0; // Index into the external relocations
2042 return relocation_iterator(RelocationRef(Ret, this));
2043}
2044
2045relocation_iterator MachOObjectFile::extrel_end() const {
2046 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2047 DataRefImpl Ret;
2048 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations
2049 Ret.d.a = 0; // Would normally be a section index.
2050 Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
2051 return relocation_iterator(RelocationRef(Ret, this));
2052}
2053
2054relocation_iterator MachOObjectFile::locrel_begin() const {
2055 DataRefImpl Ret;
2056 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2057 Ret.d.a = 1; // Would normally be a section index.
2058 Ret.d.b = 0; // Index into the local relocations
2059 return relocation_iterator(RelocationRef(Ret, this));
2060}
2061
2062relocation_iterator MachOObjectFile::locrel_end() const {
2063 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
2064 DataRefImpl Ret;
2065 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations
2066 Ret.d.a = 1; // Would normally be a section index.
2067 Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations
2068 return relocation_iterator(RelocationRef(Ret, this));
2069}
2070
2071void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
2072 ++Rel.d.b;
2073}
2074
2075uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
2076 assert((getHeader().filetype == MachO::MH_OBJECT ||(static_cast <bool> ((getHeader().filetype == MachO::MH_OBJECT
|| getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE") ?
void (0) : __assert_fail ("(getHeader().filetype == MachO::MH_OBJECT || getHeader().filetype == MachO::MH_KEXT_BUNDLE) && \"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 2078, __extension__ __PRETTY_FUNCTION__))
2077 getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&(static_cast <bool> ((getHeader().filetype == MachO::MH_OBJECT
|| getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE") ?
void (0) : __assert_fail ("(getHeader().filetype == MachO::MH_OBJECT || getHeader().filetype == MachO::MH_KEXT_BUNDLE) && \"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 2078, __extension__ __PRETTY_FUNCTION__))
2078 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE")(static_cast <bool> ((getHeader().filetype == MachO::MH_OBJECT
|| getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE") ?
void (0) : __assert_fail ("(getHeader().filetype == MachO::MH_OBJECT || getHeader().filetype == MachO::MH_KEXT_BUNDLE) && \"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 2078, __extension__ __PRETTY_FUNCTION__))
;
2079 MachO::any_relocation_info RE = getRelocation(Rel);
2080 return getAnyRelocationAddress(RE);
2081}
2082
2083symbol_iterator
2084MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
2085 MachO::any_relocation_info RE = getRelocation(Rel);
2086 if (isRelocationScattered(RE))
2087 return symbol_end();
2088
2089 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2090 bool isExtern = getPlainRelocationExternal(RE);
2091 if (!isExtern)
2092 return symbol_end();
2093
2094 MachO::symtab_command S = getSymtabLoadCommand();
2095 unsigned SymbolTableEntrySize = is64Bit() ?
2096 sizeof(MachO::nlist_64) :
2097 sizeof(MachO::nlist);
2098 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize;
2099 DataRefImpl Sym;
2100 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2101 return symbol_iterator(SymbolRef(Sym, this));
2102}
2103
2104section_iterator
2105MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
2106 return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
2107}
2108
2109uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const {
2110 MachO::any_relocation_info RE = getRelocation(Rel);
2111 return getAnyRelocationType(RE);
2112}
2113
2114void MachOObjectFile::getRelocationTypeName(
2115 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2116 StringRef res;
2117 uint64_t RType = getRelocationType(Rel);
2118
2119 unsigned Arch = this->getArch();
2120
2121 switch (Arch) {
2122 case Triple::x86: {
2123 static const char *const Table[] = {
2124 "GENERIC_RELOC_VANILLA",
2125 "GENERIC_RELOC_PAIR",
2126 "GENERIC_RELOC_SECTDIFF",
2127 "GENERIC_RELOC_PB_LA_PTR",
2128 "GENERIC_RELOC_LOCAL_SECTDIFF",
2129 "GENERIC_RELOC_TLV" };
2130
2131 if (RType > 5)
2132 res = "Unknown";
2133 else
2134 res = Table[RType];
2135 break;
2136 }
2137 case Triple::x86_64: {
2138 static const char *const Table[] = {
2139 "X86_64_RELOC_UNSIGNED",
2140 "X86_64_RELOC_SIGNED",
2141 "X86_64_RELOC_BRANCH",
2142 "X86_64_RELOC_GOT_LOAD",
2143 "X86_64_RELOC_GOT",
2144 "X86_64_RELOC_SUBTRACTOR",
2145 "X86_64_RELOC_SIGNED_1",
2146 "X86_64_RELOC_SIGNED_2",
2147 "X86_64_RELOC_SIGNED_4",
2148 "X86_64_RELOC_TLV" };
2149
2150 if (RType > 9)
2151 res = "Unknown";
2152 else
2153 res = Table[RType];
2154 break;
2155 }
2156 case Triple::arm: {
2157 static const char *const Table[] = {
2158 "ARM_RELOC_VANILLA",
2159 "ARM_RELOC_PAIR",
2160 "ARM_RELOC_SECTDIFF",
2161 "ARM_RELOC_LOCAL_SECTDIFF",
2162 "ARM_RELOC_PB_LA_PTR",
2163 "ARM_RELOC_BR24",
2164 "ARM_THUMB_RELOC_BR22",
2165 "ARM_THUMB_32BIT_BRANCH",
2166 "ARM_RELOC_HALF",
2167 "ARM_RELOC_HALF_SECTDIFF" };
2168
2169 if (RType > 9)
2170 res = "Unknown";
2171 else
2172 res = Table[RType];
2173 break;
2174 }
2175 case Triple::aarch64: {
2176 static const char *const Table[] = {
2177 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
2178 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
2179 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
2180 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2181 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2182 "ARM64_RELOC_ADDEND"
2183 };
2184
2185 if (RType >= array_lengthof(Table))
2186 res = "Unknown";
2187 else
2188 res = Table[RType];
2189 break;
2190 }
2191 case Triple::ppc: {
2192 static const char *const Table[] = {
2193 "PPC_RELOC_VANILLA",
2194 "PPC_RELOC_PAIR",
2195 "PPC_RELOC_BR14",
2196 "PPC_RELOC_BR24",
2197 "PPC_RELOC_HI16",
2198 "PPC_RELOC_LO16",
2199 "PPC_RELOC_HA16",
2200 "PPC_RELOC_LO14",
2201 "PPC_RELOC_SECTDIFF",
2202 "PPC_RELOC_PB_LA_PTR",
2203 "PPC_RELOC_HI16_SECTDIFF",
2204 "PPC_RELOC_LO16_SECTDIFF",
2205 "PPC_RELOC_HA16_SECTDIFF",
2206 "PPC_RELOC_JBSR",
2207 "PPC_RELOC_LO14_SECTDIFF",
2208 "PPC_RELOC_LOCAL_SECTDIFF" };
2209
2210 if (RType > 15)
2211 res = "Unknown";
2212 else
2213 res = Table[RType];
2214 break;
2215 }
2216 case Triple::UnknownArch:
2217 res = "Unknown";
2218 break;
2219 }
2220 Result.append(res.begin(), res.end());
2221}
2222
2223uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
2224 MachO::any_relocation_info RE = getRelocation(Rel);
2225 return getAnyRelocationLength(RE);
2226}
2227
2228//
2229// guessLibraryShortName() is passed a name of a dynamic library and returns a
2230// guess on what the short name is. Then name is returned as a substring of the
2231// StringRef Name passed in. The name of the dynamic library is recognized as
2232// a framework if it has one of the two following forms:
2233// Foo.framework/Versions/A/Foo
2234// Foo.framework/Foo
2235// Where A and Foo can be any string. And may contain a trailing suffix
2236// starting with an underbar. If the Name is recognized as a framework then
2237// isFramework is set to true else it is set to false. If the Name has a
2238// suffix then Suffix is set to the substring in Name that contains the suffix
2239// else it is set to a NULL StringRef.
2240//
2241// The Name of the dynamic library is recognized as a library name if it has
2242// one of the two following forms:
2243// libFoo.A.dylib
2244// libFoo.dylib
2245// The library may have a suffix trailing the name Foo of the form:
2246// libFoo_profile.A.dylib
2247// libFoo_profile.dylib
2248//
2249// The Name of the dynamic library is also recognized as a library name if it
2250// has the following form:
2251// Foo.qtx
2252//
2253// If the Name of the dynamic library is none of the forms above then a NULL
2254// StringRef is returned.
2255//
2256StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
2257 bool &isFramework,
2258 StringRef &Suffix) {
2259 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2260 size_t a, b, c, d, Idx;
2261
2262 isFramework = false;
2263 Suffix = StringRef();
2264
2265 // Pull off the last component and make Foo point to it
2266 a = Name.rfind('/');
2267 if (a == Name.npos || a == 0)
2268 goto guess_library;
2269 Foo = Name.slice(a+1, Name.npos);
2270
2271 // Look for a suffix starting with a '_'
2272 Idx = Foo.rfind('_');
2273 if (Idx != Foo.npos && Foo.size() >= 2) {
2274 Suffix = Foo.slice(Idx, Foo.npos);
2275 Foo = Foo.slice(0, Idx);
2276 }
2277
2278 // First look for the form Foo.framework/Foo
2279 b = Name.rfind('/', a);
2280 if (b == Name.npos)
2281 Idx = 0;
2282 else
2283 Idx = b+1;
2284 F = Name.slice(Idx, Idx + Foo.size());
2285 DotFramework = Name.slice(Idx + Foo.size(),
2286 Idx + Foo.size() + sizeof(".framework/")-1);
2287 if (F == Foo && DotFramework == ".framework/") {
2288 isFramework = true;
2289 return Foo;
2290 }
2291
2292 // Next look for the form Foo.framework/Versions/A/Foo
2293 if (b == Name.npos)
2294 goto guess_library;
2295 c = Name.rfind('/', b);
2296 if (c == Name.npos || c == 0)
2297 goto guess_library;
2298 V = Name.slice(c+1, Name.npos);
2299 if (!V.startswith("Versions/"))
2300 goto guess_library;
2301 d = Name.rfind('/', c);
2302 if (d == Name.npos)
2303 Idx = 0;
2304 else
2305 Idx = d+1;
2306 F = Name.slice(Idx, Idx + Foo.size());
2307 DotFramework = Name.slice(Idx + Foo.size(),
2308 Idx + Foo.size() + sizeof(".framework/")-1);
2309 if (F == Foo && DotFramework == ".framework/") {
2310 isFramework = true;
2311 return Foo;
2312 }
2313
2314guess_library:
2315 // pull off the suffix after the "." and make a point to it
2316 a = Name.rfind('.');
2317 if (a == Name.npos || a == 0)
2318 return StringRef();
2319 Dylib = Name.slice(a, Name.npos);
2320 if (Dylib != ".dylib")
2321 goto guess_qtx;
2322
2323 // First pull off the version letter for the form Foo.A.dylib if any.
2324 if (a >= 3) {
2325 Dot = Name.slice(a-2, a-1);
2326 if (Dot == ".")
2327 a = a - 2;
2328 }
2329
2330 b = Name.rfind('/', a);
2331 if (b == Name.npos)
2332 b = 0;
2333 else
2334 b = b+1;
2335 // ignore any suffix after an underbar like Foo_profile.A.dylib
2336 Idx = Name.find('_', b);
2337 if (Idx != Name.npos && Idx != b) {
2338 Lib = Name.slice(b, Idx);
2339 Suffix = Name.slice(Idx, a);
2340 }
2341 else
2342 Lib = Name.slice(b, a);
2343 // There are incorrect library names of the form:
2344 // libATS.A_profile.dylib so check for these.
2345 if (Lib.size() >= 3) {
2346 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2347 if (Dot == ".")
2348 Lib = Lib.slice(0, Lib.size()-2);
2349 }
2350 return Lib;
2351
2352guess_qtx:
2353 Qtx = Name.slice(a, Name.npos);
2354 if (Qtx != ".qtx")
2355 return StringRef();
2356 b = Name.rfind('/', a);
2357 if (b == Name.npos)
2358 Lib = Name.slice(0, a);
2359 else
2360 Lib = Name.slice(b+1, a);
2361 // There are library names of the form: QT.A.qtx so check for these.
2362 if (Lib.size() >= 3) {
2363 Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
2364 if (Dot == ".")
2365 Lib = Lib.slice(0, Lib.size()-2);
2366 }
2367 return Lib;
2368}
2369
2370// getLibraryShortNameByIndex() is used to get the short name of the library
2371// for an undefined symbol in a linked Mach-O binary that was linked with the
2372// normal two-level namespace default (that is MH_TWOLEVEL in the header).
2373// It is passed the index (0 - based) of the library as translated from
2374// GET_LIBRARY_ORDINAL (1 - based).
2375std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
2376 StringRef &Res) const {
2377 if (Index >= Libraries.size())
2378 return object_error::parse_failed;
2379
2380 // If the cache of LibrariesShortNames is not built up do that first for
2381 // all the Libraries.
2382 if (LibrariesShortNames.size() == 0) {
2383 for (unsigned i = 0; i < Libraries.size(); i++) {
2384 MachO::dylib_command D =
2385 getStruct<MachO::dylib_command>(*this, Libraries[i]);
2386 if (D.dylib.name >= D.cmdsize)
2387 return object_error::parse_failed;
2388 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2389 StringRef Name = StringRef(P);
2390 if (D.dylib.name+Name.size() >= D.cmdsize)
2391 return object_error::parse_failed;
2392 StringRef Suffix;
2393 bool isFramework;
2394 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2395 if (shortName.empty())
2396 LibrariesShortNames.push_back(Name);
2397 else
2398 LibrariesShortNames.push_back(shortName);
2399 }
2400 }
2401
2402 Res = LibrariesShortNames[Index];
2403 return std::error_code();
2404}
2405
2406uint32_t MachOObjectFile::getLibraryCount() const {
2407 return Libraries.size();
2408}
2409
2410section_iterator
2411MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
2412 DataRefImpl Sec;
2413 Sec.d.a = Rel->getRawDataRefImpl().d.a;
2414 return section_iterator(SectionRef(Sec, this));
2415}
2416
2417basic_symbol_iterator MachOObjectFile::symbol_begin() const {
2418 DataRefImpl DRI;
2419 MachO::symtab_command Symtab = getSymtabLoadCommand();
2420 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2421 return basic_symbol_iterator(SymbolRef(DRI, this));
2422
2423 return getSymbolByIndex(0);
2424}
2425
2426basic_symbol_iterator MachOObjectFile::symbol_end() const {
2427 DataRefImpl DRI;
2428 MachO::symtab_command Symtab = getSymtabLoadCommand();
2429 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2430 return basic_symbol_iterator(SymbolRef(DRI, this));
2431
2432 unsigned SymbolTableEntrySize = is64Bit() ?
2433 sizeof(MachO::nlist_64) :
2434 sizeof(MachO::nlist);
2435 unsigned Offset = Symtab.symoff +
2436 Symtab.nsyms * SymbolTableEntrySize;
2437 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2438 return basic_symbol_iterator(SymbolRef(DRI, this));
2439}
2440
2441basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
2442 MachO::symtab_command Symtab = getSymtabLoadCommand();
2443 if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2444 report_fatal_error("Requested symbol index is out of range.");
2445 unsigned SymbolTableEntrySize =
2446 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2447 DataRefImpl DRI;
2448 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2449 DRI.p += Index * SymbolTableEntrySize;
2450 return basic_symbol_iterator(SymbolRef(DRI, this));
2451}
2452
2453uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
2454 MachO::symtab_command Symtab = getSymtabLoadCommand();
2455 if (!SymtabLoadCmd)
2456 report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2457 unsigned SymbolTableEntrySize =
2458 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
2459 DataRefImpl DRIstart;
2460 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2461 uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
2462 return Index;
2463}
2464
2465section_iterator MachOObjectFile::section_begin() const {
2466 DataRefImpl DRI;
2467 return section_iterator(SectionRef(DRI, this));
2468}
2469
2470section_iterator MachOObjectFile::section_end() const {
2471 DataRefImpl DRI;
2472 DRI.d.a = Sections.size();
2473 return section_iterator(SectionRef(DRI, this));
2474}
2475
2476uint8_t MachOObjectFile::getBytesInAddress() const {
2477 return is64Bit() ? 8 : 4;
2478}
2479
2480StringRef MachOObjectFile::getFileFormatName() const {
2481 unsigned CPUType = getCPUType(*this);
2482 if (!is64Bit()) {
2483 switch (CPUType) {
2484 case MachO::CPU_TYPE_I386:
2485 return "Mach-O 32-bit i386";
2486 case MachO::CPU_TYPE_ARM:
2487 return "Mach-O arm";
2488 case MachO::CPU_TYPE_POWERPC:
2489 return "Mach-O 32-bit ppc";
2490 default:
2491 return "Mach-O 32-bit unknown";
2492 }
2493 }
2494
2495 switch (CPUType) {
2496 case MachO::CPU_TYPE_X86_64:
2497 return "Mach-O 64-bit x86-64";
2498 case MachO::CPU_TYPE_ARM64:
2499 return "Mach-O arm64";
2500 case MachO::CPU_TYPE_POWERPC64:
2501 return "Mach-O 64-bit ppc64";
2502 default:
2503 return "Mach-O 64-bit unknown";
2504 }
2505}
2506
2507Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
2508 switch (CPUType) {
2509 case MachO::CPU_TYPE_I386:
2510 return Triple::x86;
2511 case MachO::CPU_TYPE_X86_64:
2512 return Triple::x86_64;
2513 case MachO::CPU_TYPE_ARM:
2514 return Triple::arm;
2515 case MachO::CPU_TYPE_ARM64:
2516 return Triple::aarch64;
2517 case MachO::CPU_TYPE_POWERPC:
2518 return Triple::ppc;
2519 case MachO::CPU_TYPE_POWERPC64:
2520 return Triple::ppc64;
2521 default:
2522 return Triple::UnknownArch;
2523 }
2524}
2525
2526Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
2527 const char **McpuDefault,
2528 const char **ArchFlag) {
2529 if (McpuDefault)
2530 *McpuDefault = nullptr;
2531 if (ArchFlag)
2532 *ArchFlag = nullptr;
2533
2534 switch (CPUType) {
2535 case MachO::CPU_TYPE_I386:
2536 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2537 case MachO::CPU_SUBTYPE_I386_ALL:
2538 if (ArchFlag)
2539 *ArchFlag = "i386";
2540 return Triple("i386-apple-darwin");
2541 default:
2542 return Triple();
2543 }
2544 case MachO::CPU_TYPE_X86_64:
2545 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2546 case MachO::CPU_SUBTYPE_X86_64_ALL:
2547 if (ArchFlag)
2548 *ArchFlag = "x86_64";
2549 return Triple("x86_64-apple-darwin");
2550 case MachO::CPU_SUBTYPE_X86_64_H:
2551 if (ArchFlag)
2552 *ArchFlag = "x86_64h";
2553 return Triple("x86_64h-apple-darwin");
2554 default:
2555 return Triple();
2556 }
2557 case MachO::CPU_TYPE_ARM:
2558 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2559 case MachO::CPU_SUBTYPE_ARM_V4T:
2560 if (ArchFlag)
2561 *ArchFlag = "armv4t";
2562 return Triple("armv4t-apple-darwin");
2563 case MachO::CPU_SUBTYPE_ARM_V5TEJ:
2564 if (ArchFlag)
2565 *ArchFlag = "armv5e";
2566 return Triple("armv5e-apple-darwin");
2567 case MachO::CPU_SUBTYPE_ARM_XSCALE:
2568 if (ArchFlag)
2569 *ArchFlag = "xscale";
2570 return Triple("xscale-apple-darwin");
2571 case MachO::CPU_SUBTYPE_ARM_V6:
2572 if (ArchFlag)
2573 *ArchFlag = "armv6";
2574 return Triple("armv6-apple-darwin");
2575 case MachO::CPU_SUBTYPE_ARM_V6M:
2576 if (McpuDefault)
2577 *McpuDefault = "cortex-m0";
2578 if (ArchFlag)
2579 *ArchFlag = "armv6m";
2580 return Triple("armv6m-apple-darwin");
2581 case MachO::CPU_SUBTYPE_ARM_V7:
2582 if (ArchFlag)
2583 *ArchFlag = "armv7";
2584 return Triple("armv7-apple-darwin");
2585 case MachO::CPU_SUBTYPE_ARM_V7EM:
2586 if (McpuDefault)
2587 *McpuDefault = "cortex-m4";
2588 if (ArchFlag)
2589 *ArchFlag = "armv7em";
2590 return Triple("thumbv7em-apple-darwin");
2591 case MachO::CPU_SUBTYPE_ARM_V7K:
2592 if (McpuDefault)
2593 *McpuDefault = "cortex-a7";
2594 if (ArchFlag)
2595 *ArchFlag = "armv7k";
2596 return Triple("armv7k-apple-darwin");
2597 case MachO::CPU_SUBTYPE_ARM_V7M:
2598 if (McpuDefault)
2599 *McpuDefault = "cortex-m3";
2600 if (ArchFlag)
2601 *ArchFlag = "armv7m";
2602 return Triple("thumbv7m-apple-darwin");
2603 case MachO::CPU_SUBTYPE_ARM_V7S:
2604 if (McpuDefault)
2605 *McpuDefault = "cortex-a7";
2606 if (ArchFlag)
2607 *ArchFlag = "armv7s";
2608 return Triple("armv7s-apple-darwin");
2609 default:
2610 return Triple();
2611 }
2612 case MachO::CPU_TYPE_ARM64:
2613 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2614 case MachO::CPU_SUBTYPE_ARM64_ALL:
2615 if (McpuDefault)
2616 *McpuDefault = "cyclone";
2617 if (ArchFlag)
2618 *ArchFlag = "arm64";
2619 return Triple("arm64-apple-darwin");
2620 default:
2621 return Triple();
2622 }
2623 case MachO::CPU_TYPE_POWERPC:
2624 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2625 case MachO::CPU_SUBTYPE_POWERPC_ALL:
2626 if (ArchFlag)
2627 *ArchFlag = "ppc";
2628 return Triple("ppc-apple-darwin");
2629 default:
2630 return Triple();
2631 }
2632 case MachO::CPU_TYPE_POWERPC64:
2633 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
2634 case MachO::CPU_SUBTYPE_POWERPC_ALL:
2635 if (ArchFlag)
2636 *ArchFlag = "ppc64";
2637 return Triple("ppc64-apple-darwin");
2638 default:
2639 return Triple();
2640 }
2641 default:
2642 return Triple();
2643 }
2644}
2645
2646Triple MachOObjectFile::getHostArch() {
2647 return Triple(sys::getDefaultTargetTriple());
2648}
2649
2650bool MachOObjectFile::isValidArch(StringRef ArchFlag) {
2651 return StringSwitch<bool>(ArchFlag)
2652 .Case("i386", true)
2653 .Case("x86_64", true)
2654 .Case("x86_64h", true)
2655 .Case("armv4t", true)
2656 .Case("arm", true)
2657 .Case("armv5e", true)
2658 .Case("armv6", true)
2659 .Case("armv6m", true)
2660 .Case("armv7", true)
2661 .Case("armv7em", true)
2662 .Case("armv7k", true)
2663 .Case("armv7m", true)
2664 .Case("armv7s", true)
2665 .Case("arm64", true)
2666 .Case("ppc", true)
2667 .Case("ppc64", true)
2668 .Default(false);
2669}
2670
2671Triple::ArchType MachOObjectFile::getArch() const {
2672 return getArch(getCPUType(*this));
2673}
2674
2675Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
2676 return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2677}
2678
2679relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
2680 DataRefImpl DRI;
2681 DRI.d.a = Index;
2682 return section_rel_begin(DRI);
2683}
2684
2685relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const {
2686 DataRefImpl DRI;
2687 DRI.d.a = Index;
2688 return section_rel_end(DRI);
2689}
2690
2691dice_iterator MachOObjectFile::begin_dices() const {
2692 DataRefImpl DRI;
2693 if (!DataInCodeLoadCmd)
2694 return dice_iterator(DiceRef(DRI, this));
2695
2696 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2697 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2698 return dice_iterator(DiceRef(DRI, this));
2699}
2700
2701dice_iterator MachOObjectFile::end_dices() const {
2702 DataRefImpl DRI;
2703 if (!DataInCodeLoadCmd)
2704 return dice_iterator(DiceRef(DRI, this));
2705
2706 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand();
2707 unsigned Offset = DicLC.dataoff + DicLC.datasize;
2708 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2709 return dice_iterator(DiceRef(DRI, this));
2710}
2711
2712ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O,
2713 ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {}
2714
2715void ExportEntry::moveToFirst() {
2716 ErrorAsOutParameter ErrAsOutParam(E);
2717 pushNode(0);
2718 if (*E)
2719 return;
2720 pushDownUntilBottom();
2721}
2722
2723void ExportEntry::moveToEnd() {
2724 Stack.clear();
2725 Done = true;
2726}
2727
2728bool ExportEntry::operator==(const ExportEntry &Other) const {
2729 // Common case, one at end, other iterating from begin.
2730 if (Done || Other.Done)
2731 return (Done == Other.Done);
2732 // Not equal if different stack sizes.
2733 if (Stack.size() != Other.Stack.size())
2734 return false;
2735 // Not equal if different cumulative strings.
2736 if (!CumulativeString.equals(Other.CumulativeString))
2737 return false;
2738 // Equal if all nodes in both stacks match.
2739 for (unsigned i=0; i < Stack.size(); ++i) {
2740 if (Stack[i].Start != Other.Stack[i].Start)
2741 return false;
2742 }
2743 return true;
2744}
2745
2746uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) {
2747 unsigned Count;
2748 uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error);
2749 Ptr += Count;
2750 if (Ptr > Trie.end())
2751 Ptr = Trie.end();
2752 return Result;
2753}
2754
2755StringRef ExportEntry::name() const {
2756 return CumulativeString;
2757}
2758
2759uint64_t ExportEntry::flags() const {
2760 return Stack.back().Flags;
2761}
2762
2763uint64_t ExportEntry::address() const {
2764 return Stack.back().Address;
2765}
2766
2767uint64_t ExportEntry::other() const {
2768 return Stack.back().Other;
2769}
2770
2771StringRef ExportEntry::otherName() const {
2772 const char* ImportName = Stack.back().ImportName;
2773 if (ImportName)
2774 return StringRef(ImportName);
2775 return StringRef();
2776}
2777
2778uint32_t ExportEntry::nodeOffset() const {
2779 return Stack.back().Start - Trie.begin();
2780}
2781
2782ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2783 : Start(Ptr), Current(Ptr) {}
2784
2785void ExportEntry::pushNode(uint64_t offset) {
2786 ErrorAsOutParameter ErrAsOutParam(E);
2787 const uint8_t *Ptr = Trie.begin() + offset;
2788 NodeState State(Ptr);
2789 const char *error;
2790 uint64_t ExportInfoSize = readULEB128(State.Current, &error);
2791 if (error) {
2792 *E = malformedError("export info size " + Twine(error) +
2793 " in export trie data at node: 0x" +
2794 Twine::utohexstr(offset));
2795 moveToEnd();
2796 return;
2797 }
2798 State.IsExportNode = (ExportInfoSize != 0);
2799 const uint8_t* Children = State.Current + ExportInfoSize;
2800 if (Children > Trie.end()) {
2801 *E = malformedError(
2802 "export info size: 0x" + Twine::utohexstr(ExportInfoSize) +
2803 " in export trie data at node: 0x" + Twine::utohexstr(offset) +
2804 " too big and extends past end of trie data");
2805 moveToEnd();
2806 return;
2807 }
2808 if (State.IsExportNode) {
2809 const uint8_t *ExportStart = State.Current;
2810 State.Flags = readULEB128(State.Current, &error);
2811 if (error) {
2812 *E = malformedError("flags " + Twine(error) +
2813 " in export trie data at node: 0x" +
2814 Twine::utohexstr(offset));
2815 moveToEnd();
2816 return;
2817 }
2818 uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK;
2819 if (State.Flags != 0 &&
2820 (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR &&
2821 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE &&
2822 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) {
2823 *E = malformedError(
2824 "unsupported exported symbol kind: " + Twine((int)Kind) +
2825 " in flags: 0x" + Twine::utohexstr(State.Flags) +
2826 " in export trie data at node: 0x" + Twine::utohexstr(offset));
2827 moveToEnd();
2828 return;
2829 }
2830 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
2831 State.Address = 0;
2832 State.Other = readULEB128(State.Current, &error); // dylib ordinal
2833 if (error) {
2834 *E = malformedError("dylib ordinal of re-export " + Twine(error) +
2835 " in export trie data at node: 0x" +
2836 Twine::utohexstr(offset));
2837 moveToEnd();
2838 return;
2839 }
2840 if (O != nullptr) {
2841 if (State.Other > O->getLibraryCount()) {
2842 *E = malformedError(
2843 "bad library ordinal: " + Twine((int)State.Other) + " (max " +
2844 Twine((int)O->getLibraryCount()) +
2845 ") in export trie data at node: 0x" + Twine::utohexstr(offset));
2846 moveToEnd();
2847 return;
2848 }
2849 }
2850 State.ImportName = reinterpret_cast<const char*>(State.Current);
2851 if (*State.ImportName == '\0') {
2852 State.Current++;
2853 } else {
2854 const uint8_t *End = State.Current + 1;
2855 if (End >= Trie.end()) {
2856 *E = malformedError("import name of re-export in export trie data at "
2857 "node: 0x" +
2858 Twine::utohexstr(offset) +
2859 " starts past end of trie data");
2860 moveToEnd();
2861 return;
2862 }
2863 while(*End != '\0' && End < Trie.end())
2864 End++;
2865 if (*End != '\0') {
2866 *E = malformedError("import name of re-export in export trie data at "
2867 "node: 0x" +
2868 Twine::utohexstr(offset) +
2869 " extends past end of trie data");
2870 moveToEnd();
2871 return;
2872 }
2873 State.Current = End + 1;
2874 }
2875 } else {
2876 State.Address = readULEB128(State.Current, &error);
2877 if (error) {
2878 *E = malformedError("address " + Twine(error) +
2879 " in export trie data at node: 0x" +
2880 Twine::utohexstr(offset));
2881 moveToEnd();
2882 return;
2883 }
2884 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2885 State.Other = readULEB128(State.Current, &error);
2886 if (error) {
2887 *E = malformedError("resolver of stub and resolver " + Twine(error) +
2888 " in export trie data at node: 0x" +
2889 Twine::utohexstr(offset));
2890 moveToEnd();
2891 return;
2892 }
2893 }
2894 }
2895 if(ExportStart + ExportInfoSize != State.Current) {
2896 *E = malformedError(
2897 "inconsistant export info size: 0x" +
2898 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
2899 Twine::utohexstr(State.Current - ExportStart) +
2900 " in export trie data at node: 0x" + Twine::utohexstr(offset));
2901 moveToEnd();
2902 return;
2903 }
2904 }
2905 State.ChildCount = *Children;
2906 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
2907 *E = malformedError("byte for count of childern in export trie data at "
2908 "node: 0x" +
2909 Twine::utohexstr(offset) +
2910 " extends past end of trie data");
2911 moveToEnd();
2912 return;
2913 }
2914 State.Current = Children + 1;
2915 State.NextChildIndex = 0;
2916 State.ParentStringLength = CumulativeString.size();
2917 Stack.push_back(State);
2918}
2919
2920void ExportEntry::pushDownUntilBottom() {
2921 ErrorAsOutParameter ErrAsOutParam(E);
2922 const char *error;
2923 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
2924 NodeState &Top = Stack.back();
2925 CumulativeString.resize(Top.ParentStringLength);
2926 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
2927 char C = *Top.Current;
2928 CumulativeString.push_back(C);
2929 }
2930 if (Top.Current >= Trie.end()) {
2931 *E = malformedError("edge sub-string in export trie data at node: 0x" +
2932 Twine::utohexstr(Top.Start - Trie.begin()) +
2933 " for child #" + Twine((int)Top.NextChildIndex) +
2934 " extends past end of trie data");
2935 moveToEnd();
2936 return;
2937 }
2938 Top.Current += 1;
2939 uint64_t childNodeIndex = readULEB128(Top.Current, &error);
2940 if (error) {
2941 *E = malformedError("child node offset " + Twine(error) +
2942 " in export trie data at node: 0x" +
2943 Twine::utohexstr(Top.Start - Trie.begin()));
2944 moveToEnd();
2945 return;
2946 }
2947 for (const NodeState &node : nodes()) {
2948 if (node.Start == Trie.begin() + childNodeIndex){
2949 *E = malformedError("loop in childern in export trie data at node: 0x" +
2950 Twine::utohexstr(Top.Start - Trie.begin()) +
2951 " back to node: 0x" +
2952 Twine::utohexstr(childNodeIndex));
2953 moveToEnd();
2954 return;
2955 }
2956 }
2957 Top.NextChildIndex += 1;
2958 pushNode(childNodeIndex);
2959 if (*E)
2960 return;
2961 }
2962 if (!Stack.back().IsExportNode) {
2963 *E = malformedError("node is not an export node in export trie data at "
2964 "node: 0x" +
2965 Twine::utohexstr(Stack.back().Start - Trie.begin()));
2966 moveToEnd();
2967 return;
2968 }
2969}
2970
2971// We have a trie data structure and need a way to walk it that is compatible
2972// with the C++ iterator model. The solution is a non-recursive depth first
2973// traversal where the iterator contains a stack of parent nodes along with a
2974// string that is the accumulation of all edge strings along the parent chain
2975// to this point.
2976//
2977// There is one "export" node for each exported symbol. But because some
2978// symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export
2979// node may have child nodes too.
2980//
2981// The algorithm for moveNext() is to keep moving down the leftmost unvisited
2982// child until hitting a node with no children (which is an export node or
2983// else the trie is malformed). On the way down, each node is pushed on the
2984// stack ivar. If there is no more ways down, it pops up one and tries to go
2985// down a sibling path until a childless node is reached.
2986void ExportEntry::moveNext() {
2987 assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack")(static_cast <bool> (!Stack.empty() && "ExportEntry::moveNext() with empty node stack"
) ? void (0) : __assert_fail ("!Stack.empty() && \"ExportEntry::moveNext() with empty node stack\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 2987, __extension__ __PRETTY_FUNCTION__))
;
2988 if (!Stack.back().IsExportNode) {
2989 *E = malformedError("node is not an export node in export trie data at "
2990 "node: 0x" +
2991 Twine::utohexstr(Stack.back().Start - Trie.begin()));
2992 moveToEnd();
2993 return;
2994 }
2995
2996 Stack.pop_back();
2997 while (!Stack.empty()) {
2998 NodeState &Top = Stack.back();
2999 if (Top.NextChildIndex < Top.ChildCount) {
3000 pushDownUntilBottom();
3001 // Now at the next export node.
3002 return;
3003 } else {
3004 if (Top.IsExportNode) {
3005 // This node has no children but is itself an export node.
3006 CumulativeString.resize(Top.ParentStringLength);
3007 return;
3008 }
3009 Stack.pop_back();
3010 }
3011 }
3012 Done = true;
3013}
3014
3015iterator_range<export_iterator>
3016MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie,
3017 const MachOObjectFile *O) {
3018 ExportEntry Start(&E, O, Trie);
3019 if (Trie.empty())
3020 Start.moveToEnd();
3021 else
3022 Start.moveToFirst();
3023
3024 ExportEntry Finish(&E, O, Trie);
3025 Finish.moveToEnd();
3026
3027 return make_range(export_iterator(Start), export_iterator(Finish));
3028}
3029
3030iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const {
3031 return exports(Err, getDyldInfoExportsTrie(), this);
3032}
3033
3034MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
3035 ArrayRef<uint8_t> Bytes, bool is64Bit)
3036 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3037 PointerSize(is64Bit ? 8 : 4) {}
3038
3039void MachORebaseEntry::moveToFirst() {
3040 Ptr = Opcodes.begin();
3041 moveNext();
3042}
3043
3044void MachORebaseEntry::moveToEnd() {
3045 Ptr = Opcodes.end();
3046 RemainingLoopCount = 0;
3047 Done = true;
3048}
3049
3050void MachORebaseEntry::moveNext() {
3051 ErrorAsOutParameter ErrAsOutParam(E);
3052 // If in the middle of some loop, move to next rebasing in loop.
3053 SegmentOffset += AdvanceAmount;
3054 if (RemainingLoopCount) {
3055 --RemainingLoopCount;
3056 return;
3057 }
3058 // REBASE_OPCODE_DONE is only used for padding if we are not aligned to
3059 // pointer size. Therefore it is possible to reach the end without ever having
3060 // seen REBASE_OPCODE_DONE.
3061 if (Ptr == Opcodes.end()) {
3062 Done = true;
3063 return;
3064 }
3065 bool More = true;
3066 while (More) {
3067 // Parse next opcode and set up next loop.
3068 const uint8_t *OpcodeStart = Ptr;
3069 uint8_t Byte = *Ptr++;
3070 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
3071 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
3072 uint32_t Count, Skip;
3073 const char *error = nullptr;
3074 switch (Opcode) {
3075 case MachO::REBASE_OPCODE_DONE:
3076 More = false;
3077 Done = true;
3078 moveToEnd();
3079 DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DONE\n"; }
} while (false)
;
3080 break;
3081 case MachO::REBASE_OPCODE_SET_TYPE_IMM:
3082 RebaseType = ImmValue;
3083 if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) {
3084 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3085 Twine((int)RebaseType) + " for opcode at: 0x" +
3086 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3087 moveToEnd();
3088 return;
3089 }
3090 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
<< "RebaseType=" << (int) RebaseType << "\n"
; } } while (false)
3091 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
<< "RebaseType=" << (int) RebaseType << "\n"
; } } while (false)
3092 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
<< "RebaseType=" << (int) RebaseType << "\n"
; } } while (false)
3093 << "RebaseType=" << (int) RebaseType << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
<< "RebaseType=" << (int) RebaseType << "\n"
; } } while (false)
;
3094 break;
3095 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3096 SegmentIndex = ImmValue;
3097 SegmentOffset = readULEB128(&error);
3098 if (error) {
3099 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3100 Twine(error) + " for opcode at: 0x" +
3101 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3102 moveToEnd();
3103 return;
3104 }
3105 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3106 true);
3107 if (error) {
3108 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3109 Twine(error) + " for opcode at: 0x" +
3110 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3111 moveToEnd();
3112 return;
3113 }
3114 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3115 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3116 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3117 << "SegmentIndex=" << SegmentIndex << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3118 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3119 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3120 break;
3121 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB:
3122 SegmentOffset += readULEB128(&error);
3123 if (error) {
3124 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3125 " for opcode at: 0x" +
3126 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3127 moveToEnd();
3128 return;
3129 }
3130 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3131 true);
3132 if (error) {
3133 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3134 " for opcode at: 0x" +
3135 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3136 moveToEnd();
3137 return;
3138 }
3139 DEBUG_WITH_TYPE("mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3140 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3141 << format("SegmentOffset=0x%06X",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3142 SegmentOffset) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3143 break;
3144 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
3145 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3146 true);
3147 if (error) {
3148 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3149 Twine(error) + " for opcode at: 0x" +
3150 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3151 moveToEnd();
3152 return;
3153 }
3154 SegmentOffset += ImmValue * PointerSize;
3155 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3156 false);
3157 if (error) {
3158 *E =
3159 malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED "
3160 " (after adding immediate times the pointer size) " +
3161 Twine(error) + " for opcode at: 0x" +
3162 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3163 moveToEnd();
3164 return;
3165 }
3166 DEBUG_WITH_TYPE("mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3167 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3168 << format("SegmentOffset=0x%06X",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3169 SegmentOffset) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3170 break;
3171 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES:
3172 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3173 true);
3174 if (error) {
3175 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3176 Twine(error) + " for opcode at: 0x" +
3177 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3178 moveToEnd();
3179 return;
3180 }
3181 AdvanceAmount = PointerSize;
3182 Skip = 0;
3183 Count = ImmValue;
3184 if (ImmValue != 0)
3185 RemainingLoopCount = ImmValue - 1;
3186 else
3187 RemainingLoopCount = 0;
3188 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3189 SegmentIndex, SegmentOffset);
3190 if (error) {
3191 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3192 Twine(error) + " for opcode at: 0x" +
3193 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3194 moveToEnd();
3195 return;
3196 }
3197 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3198 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3199 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3200 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3201 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3202 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3203 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3204 return;
3205 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
3206 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3207 true);
3208 if (error) {
3209 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3210 Twine(error) + " for opcode at: 0x" +
3211 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3212 moveToEnd();
3213 return;
3214 }
3215 AdvanceAmount = PointerSize;
3216 Skip = 0;
3217 Count = readULEB128(&error);
3218 if (error) {
3219 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3220 Twine(error) + " for opcode at: 0x" +
3221 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3222 moveToEnd();
3223 return;
3224 }
3225 if (Count != 0)
3226 RemainingLoopCount = Count - 1;
3227 else
3228 RemainingLoopCount = 0;
3229 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3230 SegmentIndex, SegmentOffset);
3231 if (error) {
3232 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3233 Twine(error) + " for opcode at: 0x" +
3234 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3235 moveToEnd();
3236 return;
3237 }
3238 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3239 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3240 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3241 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3242 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3243 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3244 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3245 return;
3246 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
3247 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3248 true);
3249 if (error) {
3250 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3251 Twine(error) + " for opcode at: 0x" +
3252 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3253 moveToEnd();
3254 return;
3255 }
3256 Skip = readULEB128(&error);
3257 if (error) {
3258 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3259 Twine(error) + " for opcode at: 0x" +
3260 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3261 moveToEnd();
3262 return;
3263 }
3264 AdvanceAmount = Skip + PointerSize;
3265 Count = 1;
3266 RemainingLoopCount = 0;
3267 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3268 SegmentIndex, SegmentOffset);
3269 if (error) {
3270 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3271 Twine(error) + " for opcode at: 0x" +
3272 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3273 moveToEnd();
3274 return;
3275 }
3276 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3277 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3278 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3279 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3280 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3281 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3282 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3283 return;
3284 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
3285 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset,
3286 true);
3287 if (error) {
3288 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3289 "ULEB " +
3290 Twine(error) + " for opcode at: 0x" +
3291 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3292 moveToEnd();
3293 return;
3294 }
3295 Count = readULEB128(&error);
3296 if (error) {
3297 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3298 "ULEB " +
3299 Twine(error) + " for opcode at: 0x" +
3300 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3301 moveToEnd();
3302 return;
3303 }
3304 if (Count != 0)
3305 RemainingLoopCount = Count - 1;
3306 else
3307 RemainingLoopCount = 0;
3308 Skip = readULEB128(&error);
3309 if (error) {
3310 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3311 "ULEB " +
3312 Twine(error) + " for opcode at: 0x" +
3313 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3314 moveToEnd();
3315 return;
3316 }
3317 AdvanceAmount = Skip + PointerSize;
3318
3319 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize,
3320 SegmentIndex, SegmentOffset);
3321 if (error) {
3322 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3323 "ULEB " +
3324 Twine(error) + " for opcode at: 0x" +
3325 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3326 moveToEnd();
3327 return;
3328 }
3329 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3330 "mach-o-rebase",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3331 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3332 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3333 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3334 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3335 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-rebase")) { dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3336 return;
3337 default:
3338 *E = malformedError("bad rebase info (bad opcode value 0x" +
3339 Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3340 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3341 moveToEnd();
3342 return;
3343 }
3344 }
3345}
3346
3347uint64_t MachORebaseEntry::readULEB128(const char **error) {
3348 unsigned Count;
3349 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3350 Ptr += Count;
3351 if (Ptr > Opcodes.end())
3352 Ptr = Opcodes.end();
3353 return Result;
3354}
3355
3356int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; }
3357
3358uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; }
3359
3360StringRef MachORebaseEntry::typeName() const {
3361 switch (RebaseType) {
3362 case MachO::REBASE_TYPE_POINTER:
3363 return "pointer";
3364 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32:
3365 return "text abs32";
3366 case MachO::REBASE_TYPE_TEXT_PCREL32:
3367 return "text rel32";
3368 }
3369 return "unknown";
3370}
3371
3372// For use with the SegIndex of a checked Mach-O Rebase entry
3373// to get the segment name.
3374StringRef MachORebaseEntry::segmentName() const {
3375 return O->BindRebaseSegmentName(SegmentIndex);
3376}
3377
3378// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3379// to get the section name.
3380StringRef MachORebaseEntry::sectionName() const {
3381 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3382}
3383
3384// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry
3385// to get the address.
3386uint64_t MachORebaseEntry::address() const {
3387 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3388}
3389
3390bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const {
3391#ifdef EXPENSIVE_CHECKS
3392 assert(Opcodes == Other.Opcodes && "compare iterators of different files")(static_cast <bool> (Opcodes == Other.Opcodes &&
"compare iterators of different files") ? void (0) : __assert_fail
("Opcodes == Other.Opcodes && \"compare iterators of different files\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 3392, __extension__ __PRETTY_FUNCTION__))
;
3393#else
3394 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files")(static_cast <bool> (Opcodes.data() == Other.Opcodes.data
() && "compare iterators of different files") ? void (
0) : __assert_fail ("Opcodes.data() == Other.Opcodes.data() && \"compare iterators of different files\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 3394, __extension__ __PRETTY_FUNCTION__))
;
3395#endif
3396 return (Ptr == Other.Ptr) &&
3397 (RemainingLoopCount == Other.RemainingLoopCount) &&
3398 (Done == Other.Done);
3399}
3400
3401iterator_range<rebase_iterator>
3402MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O,
3403 ArrayRef<uint8_t> Opcodes, bool is64) {
3404 if (O->BindRebaseSectionTable == nullptr)
3405 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
3406 MachORebaseEntry Start(&Err, O, Opcodes, is64);
3407 Start.moveToFirst();
3408
3409 MachORebaseEntry Finish(&Err, O, Opcodes, is64);
3410 Finish.moveToEnd();
3411
3412 return make_range(rebase_iterator(Start), rebase_iterator(Finish));
3413}
3414
3415iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) {
3416 return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit());
3417}
3418
3419MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O,
3420 ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK)
3421 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3422 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3423
3424void MachOBindEntry::moveToFirst() {
3425 Ptr = Opcodes.begin();
3426 moveNext();
3427}
3428
3429void MachOBindEntry::moveToEnd() {
3430 Ptr = Opcodes.end();
3431 RemainingLoopCount = 0;
3432 Done = true;
3433}
3434
3435void MachOBindEntry::moveNext() {
3436 ErrorAsOutParameter ErrAsOutParam(E);
3437 // If in the middle of some loop, move to next binding in loop.
3438 SegmentOffset += AdvanceAmount;
3439 if (RemainingLoopCount) {
3440 --RemainingLoopCount;
3441 return;
3442 }
3443 // BIND_OPCODE_DONE is only used for padding if we are not aligned to
3444 // pointer size. Therefore it is possible to reach the end without ever having
3445 // seen BIND_OPCODE_DONE.
3446 if (Ptr == Opcodes.end()) {
3447 Done = true;
3448 return;
3449 }
3450 bool More = true;
3451 while (More) {
3452 // Parse next opcode and set up next loop.
3453 const uint8_t *OpcodeStart = Ptr;
3454 uint8_t Byte = *Ptr++;
3455 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
3456 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
3457 int8_t SignExtended;
3458 const uint8_t *SymStart;
3459 uint32_t Count, Skip;
3460 const char *error = nullptr;
3461 switch (Opcode) {
3462 case MachO::BIND_OPCODE_DONE:
3463 if (TableKind == Kind::Lazy) {
3464 // Lazying bindings have a DONE opcode between entries. Need to ignore
3465 // it to advance to next entry. But need not if this is last entry.
3466 bool NotLastEntry = false;
3467 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3468 if (*P) {
3469 NotLastEntry = true;
3470 }
3471 }
3472 if (NotLastEntry)
3473 break;
3474 }
3475 More = false;
3476 moveToEnd();
3477 DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DONE\n"; } } while
(false)
;
3478 break;
3479 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
3480 if (TableKind == Kind::Weak) {
3481 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3482 "weak bind table for opcode at: 0x" +
3483 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3484 moveToEnd();
3485 return;
3486 }
3487 Ordinal = ImmValue;
3488 LibraryOrdinalSet = true;
3489 if (ImmValue > O->getLibraryCount()) {
3490 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3491 "library ordinal: " +
3492 Twine((int)ImmValue) + " (max " +
3493 Twine((int)O->getLibraryCount()) +
3494 ") for opcode at: 0x" +
3495 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3496 moveToEnd();
3497 return;
3498 }
3499 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3500 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3501 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3502 << "Ordinal=" << Ordinal << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
;
3503 break;
3504 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
3505 if (TableKind == Kind::Weak) {
3506 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3507 "weak bind table for opcode at: 0x" +
3508 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3509 moveToEnd();
3510 return;
3511 }
3512 Ordinal = readULEB128(&error);
3513 LibraryOrdinalSet = true;
3514 if (error) {
3515 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3516 Twine(error) + " for opcode at: 0x" +
3517 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3518 moveToEnd();
3519 return;
3520 }
3521 if (Ordinal > (int)O->getLibraryCount()) {
3522 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3523 "library ordinal: " +
3524 Twine((int)Ordinal) + " (max " +
3525 Twine((int)O->getLibraryCount()) +
3526 ") for opcode at: 0x" +
3527 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3528 moveToEnd();
3529 return;
3530 }
3531 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3532 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3533 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3534 << "Ordinal=" << Ordinal << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
;
3535 break;
3536 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
3537 if (TableKind == Kind::Weak) {
3538 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3539 "weak bind table for opcode at: 0x" +
3540 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3541 moveToEnd();
3542 return;
3543 }
3544 if (ImmValue) {
3545 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3546 Ordinal = SignExtended;
3547 if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
3548 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3549 "special ordinal: " +
3550 Twine((int)Ordinal) + " for opcode at: 0x" +
3551 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3552 moveToEnd();
3553 return;
3554 }
3555 } else
3556 Ordinal = 0;
3557 LibraryOrdinalSet = true;
3558 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3559 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3560 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
3561 << "Ordinal=" << Ordinal << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
<< "Ordinal=" << Ordinal << "\n"; } } while
(false)
;
3562 break;
3563 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
3564 Flags = ImmValue;
3565 SymStart = Ptr;
3566 while (*Ptr && (Ptr < Opcodes.end())) {
3567 ++Ptr;
3568 }
3569 if (Ptr == Opcodes.end()) {
3570 *E = malformedError(
3571 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3572 "symbol name extends past opcodes for opcode at: 0x" +
3573 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3574 moveToEnd();
3575 return;
3576 }
3577 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3578 Ptr-SymStart);
3579 ++Ptr;
3580 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
<< "SymbolName=" << SymbolName << "\n"; } }
while (false)
3581 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
<< "SymbolName=" << SymbolName << "\n"; } }
while (false)
3582 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
<< "SymbolName=" << SymbolName << "\n"; } }
while (false)
3583 << "SymbolName=" << SymbolName << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
<< "SymbolName=" << SymbolName << "\n"; } }
while (false)
;
3584 if (TableKind == Kind::Weak) {
3585 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
3586 return;
3587 }
3588 break;
3589 case MachO::BIND_OPCODE_SET_TYPE_IMM:
3590 BindType = ImmValue;
3591 if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) {
3592 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3593 Twine((int)ImmValue) + " for opcode at: 0x" +
3594 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3595 moveToEnd();
3596 return;
3597 }
3598 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
<< "BindType=" << (int)BindType << "\n"; }
} while (false)
3599 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
<< "BindType=" << (int)BindType << "\n"; }
} while (false)
3600 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
<< "BindType=" << (int)BindType << "\n"; }
} while (false)
3601 << "BindType=" << (int)BindType << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
<< "BindType=" << (int)BindType << "\n"; }
} while (false)
;
3602 break;
3603 case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
3604 Addend = readSLEB128(&error);
3605 if (error) {
3606 *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) +
3607 " for opcode at: 0x" +
3608 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3609 moveToEnd();
3610 return;
3611 }
3612 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
<< "Addend=" << Addend << "\n"; } } while (
false)
3613 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
<< "Addend=" << Addend << "\n"; } } while (
false)
3614 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
<< "Addend=" << Addend << "\n"; } } while (
false)
3615 << "Addend=" << Addend << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
<< "Addend=" << Addend << "\n"; } } while (
false)
;
3616 break;
3617 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
3618 SegmentIndex = ImmValue;
3619 SegmentOffset = readULEB128(&error);
3620 if (error) {
3621 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3622 Twine(error) + " for opcode at: 0x" +
3623 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3624 moveToEnd();
3625 return;
3626 }
3627 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3628 if (error) {
3629 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3630 Twine(error) + " for opcode at: 0x" +
3631 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3632 moveToEnd();
3633 return;
3634 }
3635 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3636 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3637 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3638 << "SegmentIndex=" << SegmentIndex << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3639 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3640 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
<< "SegmentIndex=" << SegmentIndex << ", "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3641 break;
3642 case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
3643 SegmentOffset += readULEB128(&error);
3644 if (error) {
3645 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3646 " for opcode at: 0x" +
3647 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3648 moveToEnd();
3649 return;
3650 }
3651 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3652 if (error) {
3653 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) +
3654 " for opcode at: 0x" +
3655 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3656 moveToEnd();
3657 return;
3658 }
3659 DEBUG_WITH_TYPE("mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3660 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3661 << format("SegmentOffset=0x%06X",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3662 SegmentOffset) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3663 break;
3664 case MachO::BIND_OPCODE_DO_BIND:
3665 AdvanceAmount = PointerSize;
3666 RemainingLoopCount = 0;
3667 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3668 if (error) {
3669 *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) +
3670 " for opcode at: 0x" +
3671 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3672 moveToEnd();
3673 return;
3674 }
3675 if (SymbolName == StringRef()) {
3676 *E = malformedError(
3677 "for BIND_OPCODE_DO_BIND missing preceding "
3678 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3679 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3680 moveToEnd();
3681 return;
3682 }
3683 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3684 *E =
3685 malformedError("for BIND_OPCODE_DO_BIND missing preceding "
3686 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3687 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3688 moveToEnd();
3689 return;
3690 }
3691 DEBUG_WITH_TYPE("mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND: " <<
format("SegmentOffset=0x%06X", SegmentOffset) << "\n";
} } while (false)
3692 dbgs() << "BIND_OPCODE_DO_BIND: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND: " <<
format("SegmentOffset=0x%06X", SegmentOffset) << "\n";
} } while (false)
3693 << format("SegmentOffset=0x%06X",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND: " <<
format("SegmentOffset=0x%06X", SegmentOffset) << "\n";
} } while (false)
3694 SegmentOffset) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND: " <<
format("SegmentOffset=0x%06X", SegmentOffset) << "\n";
} } while (false)
;
3695 return;
3696 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
3697 if (TableKind == Kind::Lazy) {
3698 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
3699 "lazy bind table for opcode at: 0x" +
3700 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3701 moveToEnd();
3702 return;
3703 }
3704 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3705 if (error) {
3706 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3707 Twine(error) + " for opcode at: 0x" +
3708 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3709 moveToEnd();
3710 return;
3711 }
3712 if (SymbolName == StringRef()) {
3713 *E = malformedError(
3714 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3715 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
3716 "at: 0x" +
3717 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3718 moveToEnd();
3719 return;
3720 }
3721 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3722 *E = malformedError(
3723 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
3724 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3725 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3726 moveToEnd();
3727 return;
3728 }
3729 AdvanceAmount = readULEB128(&error) + PointerSize;
3730 if (error) {
3731 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
3732 Twine(error) + " for opcode at: 0x" +
3733 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3734 moveToEnd();
3735 return;
3736 }
3737 // Note, this is not really an error until the next bind but make no sense
3738 // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another
3739 // bind operation.
3740 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
3741 AdvanceAmount, false);
3742 if (error) {
3743 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
3744 "ULEB) " +
3745 Twine(error) + " for opcode at: 0x" +
3746 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3747 moveToEnd();
3748 return;
3749 }
3750 RemainingLoopCount = 0;
3751 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3752 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3753 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3754 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3755 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3756 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3757 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3758 return;
3759 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
3760 if (TableKind == Kind::Lazy) {
3761 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
3762 "allowed in lazy bind table for opcode at: 0x" +
3763 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3764 moveToEnd();
3765 return;
3766 }
3767 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3768 if (error) {
3769 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
3770 Twine(error) + " for opcode at: 0x" +
3771 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3772 moveToEnd();
3773 return;
3774 }
3775 if (SymbolName == StringRef()) {
3776 *E = malformedError(
3777 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3778 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3779 "opcode at: 0x" +
3780 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3781 moveToEnd();
3782 return;
3783 }
3784 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3785 *E = malformedError(
3786 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3787 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3788 "at: 0x" +
3789 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3790 moveToEnd();
3791 return;
3792 }
3793 AdvanceAmount = ImmValue * PointerSize + PointerSize;
3794 RemainingLoopCount = 0;
3795 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset +
3796 AdvanceAmount, false);
3797 if (error) {
3798 *E =
3799 malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
3800 " (after adding immediate times the pointer size) " +
3801 Twine(error) + " for opcode at: 0x" +
3802 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3803 moveToEnd();
3804 return;
3805 }
3806 DEBUG_WITH_TYPE("mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3807 dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3808 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
3809 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
"\n"; } } while (false)
;
3810 return;
3811 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
3812 if (TableKind == Kind::Lazy) {
3813 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
3814 "allowed in lazy bind table for opcode at: 0x" +
3815 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3816 moveToEnd();
3817 return;
3818 }
3819 Count = readULEB128(&error);
3820 if (Count != 0)
3821 RemainingLoopCount = Count - 1;
3822 else
3823 RemainingLoopCount = 0;
3824 if (error) {
3825 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3826 " (count value) " +
3827 Twine(error) + " for opcode at: 0x" +
3828 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3829 moveToEnd();
3830 return;
3831 }
3832 Skip = readULEB128(&error);
3833 AdvanceAmount = Skip + PointerSize;
3834 if (error) {
3835 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3836 " (skip value) " +
3837 Twine(error) + " for opcode at: 0x" +
3838 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3839 moveToEnd();
3840 return;
3841 }
3842 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true);
3843 if (error) {
3844 *E =
3845 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3846 Twine(error) + " for opcode at: 0x" +
3847 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3848 moveToEnd();
3849 return;
3850 }
3851 if (SymbolName == StringRef()) {
3852 *E = malformedError(
3853 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3854 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
3855 "opcode at: 0x" +
3856 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3857 moveToEnd();
3858 return;
3859 }
3860 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
3861 *E = malformedError(
3862 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
3863 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
3864 "at: 0x" +
3865 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3866 moveToEnd();
3867 return;
3868 }
3869 error = O->BindEntryCheckCountAndSkip(Count, Skip, PointerSize,
3870 SegmentIndex, SegmentOffset);
3871 if (error) {
3872 *E =
3873 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3874 Twine(error) + " for opcode at: 0x" +
3875 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3876 moveToEnd();
3877 return;
3878 }
3879 DEBUG_WITH_TYPE(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3880 "mach-o-bind",do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3881 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3882 << format("SegmentOffset=0x%06X", SegmentOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3883 << ", AdvanceAmount=" << AdvanceAmountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3884 << ", RemainingLoopCount=" << RemainingLoopCountdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
3885 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mach-o-bind")) { dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
<< format("SegmentOffset=0x%06X", SegmentOffset) <<
", AdvanceAmount=" << AdvanceAmount << ", RemainingLoopCount="
<< RemainingLoopCount << "\n"; } } while (false)
;
3886 return;
3887 default:
3888 *E = malformedError("bad bind info (bad opcode value 0x" +
3889 Twine::utohexstr(Opcode) + " for opcode at: 0x" +
3890 Twine::utohexstr(OpcodeStart - Opcodes.begin()));
3891 moveToEnd();
3892 return;
3893 }
3894 }
3895}
3896
3897uint64_t MachOBindEntry::readULEB128(const char **error) {
3898 unsigned Count;
3899 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error);
3900 Ptr += Count;
3901 if (Ptr > Opcodes.end())
3902 Ptr = Opcodes.end();
3903 return Result;
3904}
3905
3906int64_t MachOBindEntry::readSLEB128(const char **error) {
3907 unsigned Count;
3908 int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error);
3909 Ptr += Count;
3910 if (Ptr > Opcodes.end())
3911 Ptr = Opcodes.end();
3912 return Result;
3913}
3914
3915int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
3916
3917uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
3918
3919StringRef MachOBindEntry::typeName() const {
3920 switch (BindType) {
3921 case MachO::BIND_TYPE_POINTER:
3922 return "pointer";
3923 case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
3924 return "text abs32";
3925 case MachO::BIND_TYPE_TEXT_PCREL32:
3926 return "text rel32";
3927 }
3928 return "unknown";
3929}
3930
3931StringRef MachOBindEntry::symbolName() const { return SymbolName; }
3932
3933int64_t MachOBindEntry::addend() const { return Addend; }
3934
3935uint32_t MachOBindEntry::flags() const { return Flags; }
3936
3937int MachOBindEntry::ordinal() const { return Ordinal; }
3938
3939// For use with the SegIndex of a checked Mach-O Bind entry
3940// to get the segment name.
3941StringRef MachOBindEntry::segmentName() const {
3942 return O->BindRebaseSegmentName(SegmentIndex);
3943}
3944
3945// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3946// to get the section name.
3947StringRef MachOBindEntry::sectionName() const {
3948 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3949}
3950
3951// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry
3952// to get the address.
3953uint64_t MachOBindEntry::address() const {
3954 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3955}
3956
3957bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
3958#ifdef EXPENSIVE_CHECKS
3959 assert(Opcodes == Other.Opcodes && "compare iterators of different files")(static_cast <bool> (Opcodes == Other.Opcodes &&
"compare iterators of different files") ? void (0) : __assert_fail
("Opcodes == Other.Opcodes && \"compare iterators of different files\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 3959, __extension__ __PRETTY_FUNCTION__))
;
3960#else
3961 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files")(static_cast <bool> (Opcodes.data() == Other.Opcodes.data
() && "compare iterators of different files") ? void (
0) : __assert_fail ("Opcodes.data() == Other.Opcodes.data() && \"compare iterators of different files\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 3961, __extension__ __PRETTY_FUNCTION__))
;
3962#endif
3963 return (Ptr == Other.Ptr) &&
3964 (RemainingLoopCount == Other.RemainingLoopCount) &&
3965 (Done == Other.Done);
3966}
3967
3968// Build table of sections so SegIndex/SegOffset pairs can be translated.
3969BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
3970 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
5
Assuming the condition is false
6
'?' condition is false
3971 StringRef CurSegName;
3972 uint64_t CurSegAddress;
7
'CurSegAddress' declared without an initial value
3973 for (const SectionRef &Section : Obj->sections()) {
3974 SectionInfo Info;
3975 Section.getName(Info.SectionName);
3976 Info.Address = Section.getAddress();
3977 Info.Size = Section.getSize();
3978 Info.SegmentName =
3979 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
3980 if (!Info.SegmentName.equals(CurSegName)) {
8
Assuming the condition is false
9
Taking false branch
3981 ++CurSegIndex;
3982 CurSegName = Info.SegmentName;
3983 CurSegAddress = Info.Address;
3984 }
3985 Info.SegmentIndex = CurSegIndex - 1;
3986 Info.OffsetInSegment = Info.Address - CurSegAddress;
10
The right operand of '-' is a garbage value
3987 Info.SegmentStartAddress = CurSegAddress;
3988 Sections.push_back(Info);
3989 }
3990 MaxSegIndex = CurSegIndex;
3991}
3992
3993// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
3994// validate a MachOBindEntry or MachORebaseEntry.
3995const char * BindRebaseSegInfo::checkSegAndOffset(int32_t SegIndex,
3996 uint64_t SegOffset,
3997 bool endInvalid) {
3998 if (SegIndex == -1)
3999 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4000 if (SegIndex >= MaxSegIndex)
4001 return "bad segIndex (too large)";
4002 for (const SectionInfo &SI : Sections) {
4003 if (SI.SegmentIndex != SegIndex)
4004 continue;
4005 if (SI.OffsetInSegment > SegOffset)
4006 continue;
4007 if (SegOffset > (SI.OffsetInSegment + SI.Size))
4008 continue;
4009 if (endInvalid && SegOffset >= (SI.OffsetInSegment + SI.Size))
4010 continue;
4011 return nullptr;
4012 }
4013 return "bad segOffset, too large";
4014}
4015
4016// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
4017// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode and for use in
4018// MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
4019// REBASE_OPCODE_DO_*_TIMES* opcodes. The SegIndex and SegOffset must have
4020// been already checked.
4021const char * BindRebaseSegInfo::checkCountAndSkip(uint32_t Count, uint32_t Skip,
4022 uint8_t PointerSize,
4023 int32_t SegIndex,
4024 uint64_t SegOffset) {
4025 const SectionInfo &SI = findSection(SegIndex, SegOffset);
4026 uint64_t addr = SI.SegmentStartAddress + SegOffset;
4027 if (addr >= SI.Address + SI.Size)
4028 return "bad segOffset, too large";
4029 uint64_t i = 0;
4030 if (Count > 1)
4031 i = (Skip + PointerSize) * (Count - 1);
4032 else if (Count == 1)
4033 i = Skip + PointerSize;
4034 if (addr + i >= SI.Address + SI.Size) {
4035 // For rebase opcodes they can step from one section to another.
4036 uint64_t TrailingSegOffset = (addr + i) - SI.SegmentStartAddress;
4037 const char *error = checkSegAndOffset(SegIndex, TrailingSegOffset, false);
4038 if (error)
4039 return "bad count and skip, too large";
4040 }
4041 return nullptr;
4042}
4043
4044// For use with the SegIndex of a checked Mach-O Bind or Rebase entry
4045// to get the segment name.
4046StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) {
4047 for (const SectionInfo &SI : Sections) {
4048 if (SI.SegmentIndex == SegIndex)
4049 return SI.SegmentName;
4050 }
4051 llvm_unreachable("invalid SegIndex")::llvm::llvm_unreachable_internal("invalid SegIndex", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4051)
;
4052}
4053
4054// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4055// to get the SectionInfo.
4056const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4057 int32_t SegIndex, uint64_t SegOffset) {
4058 for (const SectionInfo &SI : Sections) {
4059 if (SI.SegmentIndex != SegIndex)
4060 continue;
4061 if (SI.OffsetInSegment > SegOffset)
4062 continue;
4063 if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4064 continue;
4065 return SI;
4066 }
4067 llvm_unreachable("SegIndex and SegOffset not in any section")::llvm::llvm_unreachable_internal("SegIndex and SegOffset not in any section"
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4067)
;
4068}
4069
4070// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4071// entry to get the section name.
4072StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex,
4073 uint64_t SegOffset) {
4074 return findSection(SegIndex, SegOffset).SectionName;
4075}
4076
4077// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase
4078// entry to get the address.
4079uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
4080 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4081 return SI.SegmentStartAddress + OffsetInSeg;
4082}
4083
4084iterator_range<bind_iterator>
4085MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O,
4086 ArrayRef<uint8_t> Opcodes, bool is64,
4087 MachOBindEntry::Kind BKind) {
4088 if (O->BindRebaseSectionTable == nullptr)
2
Taking true branch
4089 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O);
3
Calling 'make_unique<llvm::object::BindRebaseSegInfo, llvm::object::MachOObjectFile *&>'
4090 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4091 Start.moveToFirst();
4092
4093 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4094 Finish.moveToEnd();
4095
4096 return make_range(bind_iterator(Start), bind_iterator(Finish));
4097}
4098
4099iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) {
4100 return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(),
4101 MachOBindEntry::Kind::Regular);
4102}
4103
4104iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) {
4105 return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(),
4106 MachOBindEntry::Kind::Lazy);
4107}
4108
4109iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
4110 return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(),
1
Calling 'MachOObjectFile::bindTable'
4111 MachOBindEntry::Kind::Weak);
4112}
4113
4114MachOObjectFile::load_command_iterator
4115MachOObjectFile::begin_load_commands() const {
4116 return LoadCommands.begin();
4117}
4118
4119MachOObjectFile::load_command_iterator
4120MachOObjectFile::end_load_commands() const {
4121 return LoadCommands.end();
4122}
4123
4124iterator_range<MachOObjectFile::load_command_iterator>
4125MachOObjectFile::load_commands() const {
4126 return make_range(begin_load_commands(), end_load_commands());
4127}
4128
4129StringRef
4130MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
4131 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
4132 return parseSegmentOrSectionName(Raw.data());
4133}
4134
4135ArrayRef<char>
4136MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
4137 assert(Sec.d.a < Sections.size() && "Should have detected this earlier")(static_cast <bool> (Sec.d.a < Sections.size() &&
"Should have detected this earlier") ? void (0) : __assert_fail
("Sec.d.a < Sections.size() && \"Should have detected this earlier\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4137, __extension__ __PRETTY_FUNCTION__))
;
4138 const section_base *Base =
4139 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4140 return makeArrayRef(Base->sectname);
4141}
4142
4143ArrayRef<char>
4144MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
4145 assert(Sec.d.a < Sections.size() && "Should have detected this earlier")(static_cast <bool> (Sec.d.a < Sections.size() &&
"Should have detected this earlier") ? void (0) : __assert_fail
("Sec.d.a < Sections.size() && \"Should have detected this earlier\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4145, __extension__ __PRETTY_FUNCTION__))
;
4146 const section_base *Base =
4147 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4148 return makeArrayRef(Base->segname);
4149}
4150
4151bool
4152MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE)
4153 const {
4154 if (getCPUType(*this) == MachO::CPU_TYPE_X86_64)
4155 return false;
4156 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED;
4157}
4158
4159unsigned MachOObjectFile::getPlainRelocationSymbolNum(
4160 const MachO::any_relocation_info &RE) const {
4161 if (isLittleEndian())
4162 return RE.r_word1 & 0xffffff;
4163 return RE.r_word1 >> 8;
4164}
4165
4166bool MachOObjectFile::getPlainRelocationExternal(
4167 const MachO::any_relocation_info &RE) const {
4168 if (isLittleEndian())
4169 return (RE.r_word1 >> 27) & 1;
4170 return (RE.r_word1 >> 4) & 1;
4171}
4172
4173bool MachOObjectFile::getScatteredRelocationScattered(
4174 const MachO::any_relocation_info &RE) const {
4175 return RE.r_word0 >> 31;
4176}
4177
4178uint32_t MachOObjectFile::getScatteredRelocationValue(
4179 const MachO::any_relocation_info &RE) const {
4180 return RE.r_word1;
4181}
4182
4183uint32_t MachOObjectFile::getScatteredRelocationType(
4184 const MachO::any_relocation_info &RE) const {
4185 return (RE.r_word0 >> 24) & 0xf;
4186}
4187
4188unsigned MachOObjectFile::getAnyRelocationAddress(
4189 const MachO::any_relocation_info &RE) const {
4190 if (isRelocationScattered(RE))
4191 return getScatteredRelocationAddress(RE);
4192 return getPlainRelocationAddress(RE);
4193}
4194
4195unsigned MachOObjectFile::getAnyRelocationPCRel(
4196 const MachO::any_relocation_info &RE) const {
4197 if (isRelocationScattered(RE))
4198 return getScatteredRelocationPCRel(RE);
4199 return getPlainRelocationPCRel(*this, RE);
4200}
4201
4202unsigned MachOObjectFile::getAnyRelocationLength(
4203 const MachO::any_relocation_info &RE) const {
4204 if (isRelocationScattered(RE))
4205 return getScatteredRelocationLength(RE);
4206 return getPlainRelocationLength(*this, RE);
4207}
4208
4209unsigned
4210MachOObjectFile::getAnyRelocationType(
4211 const MachO::any_relocation_info &RE) const {
4212 if (isRelocationScattered(RE))
4213 return getScatteredRelocationType(RE);
4214 return getPlainRelocationType(*this, RE);
4215}
4216
4217SectionRef
4218MachOObjectFile::getAnyRelocationSection(
4219 const MachO::any_relocation_info &RE) const {
4220 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4221 return *section_end();
4222 unsigned SecNum = getPlainRelocationSymbolNum(RE);
4223 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4224 return *section_end();
4225 DataRefImpl DRI;
4226 DRI.d.a = SecNum - 1;
4227 return SectionRef(DRI, this);
4228}
4229
4230MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
4231 assert(DRI.d.a < Sections.size() && "Should have detected this earlier")(static_cast <bool> (DRI.d.a < Sections.size() &&
"Should have detected this earlier") ? void (0) : __assert_fail
("DRI.d.a < Sections.size() && \"Should have detected this earlier\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4231, __extension__ __PRETTY_FUNCTION__))
;
4232 return getStruct<MachO::section>(*this, Sections[DRI.d.a]);
4233}
4234
4235MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
4236 assert(DRI.d.a < Sections.size() && "Should have detected this earlier")(static_cast <bool> (DRI.d.a < Sections.size() &&
"Should have detected this earlier") ? void (0) : __assert_fail
("DRI.d.a < Sections.size() && \"Should have detected this earlier\""
, "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4236, __extension__ __PRETTY_FUNCTION__))
;
4237 return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]);
4238}
4239
4240MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L,
4241 unsigned Index) const {
4242 const char *Sec = getSectionPtr(*this, L, Index);
4243 return getStruct<MachO::section>(*this, Sec);
4244}
4245
4246MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
4247 unsigned Index) const {
4248 const char *Sec = getSectionPtr(*this, L, Index);
4249 return getStruct<MachO::section_64>(*this, Sec);
4250}
4251
4252MachO::nlist
4253MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
4254 const char *P = reinterpret_cast<const char *>(DRI.p);
4255 return getStruct<MachO::nlist>(*this, P);
4256}
4257
4258MachO::nlist_64
4259MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
4260 const char *P = reinterpret_cast<const char *>(DRI.p);
4261 return getStruct<MachO::nlist_64>(*this, P);
4262}
4263
4264MachO::linkedit_data_command
4265MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const {
4266 return getStruct<MachO::linkedit_data_command>(*this, L.Ptr);
4267}
4268
4269MachO::segment_command
4270MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
4271 return getStruct<MachO::segment_command>(*this, L.Ptr);
4272}
4273
4274MachO::segment_command_64
4275MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
4276 return getStruct<MachO::segment_command_64>(*this, L.Ptr);
4277}
4278
4279MachO::linker_option_command
4280MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const {
4281 return getStruct<MachO::linker_option_command>(*this, L.Ptr);
4282}
4283
4284MachO::version_min_command
4285MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
4286 return getStruct<MachO::version_min_command>(*this, L.Ptr);
4287}
4288
4289MachO::note_command
4290MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
4291 return getStruct<MachO::note_command>(*this, L.Ptr);
4292}
4293
4294MachO::build_version_command
4295MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
4296 return getStruct<MachO::build_version_command>(*this, L.Ptr);
4297}
4298
4299MachO::build_tool_version
4300MachOObjectFile::getBuildToolVersion(unsigned index) const {
4301 return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
4302}
4303
4304MachO::dylib_command
4305MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
4306 return getStruct<MachO::dylib_command>(*this, L.Ptr);
4307}
4308
4309MachO::dyld_info_command
4310MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
4311 return getStruct<MachO::dyld_info_command>(*this, L.Ptr);
4312}
4313
4314MachO::dylinker_command
4315MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
4316 return getStruct<MachO::dylinker_command>(*this, L.Ptr);
4317}
4318
4319MachO::uuid_command
4320MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
4321 return getStruct<MachO::uuid_command>(*this, L.Ptr);
4322}
4323
4324MachO::rpath_command
4325MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const {
4326 return getStruct<MachO::rpath_command>(*this, L.Ptr);
4327}
4328
4329MachO::source_version_command
4330MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
4331 return getStruct<MachO::source_version_command>(*this, L.Ptr);
4332}
4333
4334MachO::entry_point_command
4335MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
4336 return getStruct<MachO::entry_point_command>(*this, L.Ptr);
4337}
4338
4339MachO::encryption_info_command
4340MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const {
4341 return getStruct<MachO::encryption_info_command>(*this, L.Ptr);
4342}
4343
4344MachO::encryption_info_command_64
4345MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const {
4346 return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr);
4347}
4348
4349MachO::sub_framework_command
4350MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const {
4351 return getStruct<MachO::sub_framework_command>(*this, L.Ptr);
4352}
4353
4354MachO::sub_umbrella_command
4355MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const {
4356 return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr);
4357}
4358
4359MachO::sub_library_command
4360MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const {
4361 return getStruct<MachO::sub_library_command>(*this, L.Ptr);
4362}
4363
4364MachO::sub_client_command
4365MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const {
4366 return getStruct<MachO::sub_client_command>(*this, L.Ptr);
4367}
4368
4369MachO::routines_command
4370MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const {
4371 return getStruct<MachO::routines_command>(*this, L.Ptr);
4372}
4373
4374MachO::routines_command_64
4375MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const {
4376 return getStruct<MachO::routines_command_64>(*this, L.Ptr);
4377}
4378
4379MachO::thread_command
4380MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
4381 return getStruct<MachO::thread_command>(*this, L.Ptr);
4382}
4383
4384MachO::any_relocation_info
4385MachOObjectFile::getRelocation(DataRefImpl Rel) const {
4386 uint32_t Offset;
4387 if (getHeader().filetype == MachO::MH_OBJECT) {
4388 DataRefImpl Sec;
4389 Sec.d.a = Rel.d.a;
4390 if (is64Bit()) {
4391 MachO::section_64 Sect = getSection64(Sec);
4392 Offset = Sect.reloff;
4393 } else {
4394 MachO::section Sect = getSection(Sec);
4395 Offset = Sect.reloff;
4396 }
4397 } else {
4398 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
4399 if (Rel.d.a == 0)
4400 Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
4401 else
4402 Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations
4403 }
4404
4405 auto P = reinterpret_cast<const MachO::any_relocation_info *>(
4406 getPtr(*this, Offset)) + Rel.d.b;
4407 return getStruct<MachO::any_relocation_info>(
4408 *this, reinterpret_cast<const char *>(P));
4409}
4410
4411MachO::data_in_code_entry
4412MachOObjectFile::getDice(DataRefImpl Rel) const {
4413 const char *P = reinterpret_cast<const char *>(Rel.p);
4414 return getStruct<MachO::data_in_code_entry>(*this, P);
4415}
4416
4417const MachO::mach_header &MachOObjectFile::getHeader() const {
4418 return Header;
4419}
4420
4421const MachO::mach_header_64 &MachOObjectFile::getHeader64() const {
4422 assert(is64Bit())(static_cast <bool> (is64Bit()) ? void (0) : __assert_fail
("is64Bit()", "/build/llvm-toolchain-snapshot-7~svn338205/lib/Object/MachOObjectFile.cpp"
, 4422, __extension__ __PRETTY_FUNCTION__))
;
4423 return Header64;
4424}
4425
4426uint32_t MachOObjectFile::getIndirectSymbolTableEntry(
4427 const MachO::dysymtab_command &DLC,
4428 unsigned Index) const {
4429 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t);
4430 return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4431}
4432
4433MachO::data_in_code_entry
4434MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
4435 unsigned Index) const {
4436 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry);
4437 return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset));
4438}
4439
4440MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const {
4441 if (SymtabLoadCmd)
4442 return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd);
4443
4444 // If there is no SymtabLoadCmd return a load command with zero'ed fields.
4445 MachO::symtab_command Cmd;
4446 Cmd.cmd = MachO::LC_SYMTAB;
4447 Cmd.cmdsize = sizeof(MachO::symtab_command);
4448 Cmd.symoff = 0;
4449 Cmd.nsyms = 0;
4450 Cmd.stroff = 0;
4451 Cmd.strsize = 0;
4452 return Cmd;
4453}
4454
4455MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const {
4456 if (DysymtabLoadCmd)
4457 return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd);
4458
4459 // If there is no DysymtabLoadCmd return a load command with zero'ed fields.
4460 MachO::dysymtab_command Cmd;
4461 Cmd.cmd = MachO::LC_DYSYMTAB;
4462 Cmd.cmdsize = sizeof(MachO::dysymtab_command);
4463 Cmd.ilocalsym = 0;
4464 Cmd.nlocalsym = 0;
4465 Cmd.iextdefsym = 0;
4466 Cmd.nextdefsym = 0;
4467 Cmd.iundefsym = 0;
4468 Cmd.nundefsym = 0;
4469 Cmd.tocoff = 0;
4470 Cmd.ntoc = 0;
4471 Cmd.modtaboff = 0;
4472 Cmd.nmodtab = 0;
4473 Cmd.extrefsymoff = 0;
4474 Cmd.nextrefsyms = 0;
4475 Cmd.indirectsymoff = 0;
4476 Cmd.nindirectsyms = 0;
4477 Cmd.extreloff = 0;
4478 Cmd.nextrel = 0;
4479 Cmd.locreloff = 0;
4480 Cmd.nlocrel = 0;
4481 return Cmd;
4482}
4483
4484MachO::linkedit_data_command
4485MachOObjectFile::getDataInCodeLoadCommand() const {
4486 if (DataInCodeLoadCmd)
4487 return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd);
4488
4489 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields.
4490 MachO::linkedit_data_command Cmd;
4491 Cmd.cmd = MachO::LC_DATA_IN_CODE;
4492 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4493 Cmd.dataoff = 0;
4494 Cmd.datasize = 0;
4495 return Cmd;
4496}
4497
4498MachO::linkedit_data_command
4499MachOObjectFile::getLinkOptHintsLoadCommand() const {
4500 if (LinkOptHintsLoadCmd)
4501 return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd);
4502
4503 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
4504 // fields.
4505 MachO::linkedit_data_command Cmd;
4506 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4507 Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
4508 Cmd.dataoff = 0;
4509 Cmd.datasize = 0;
4510 return Cmd;
4511}
4512
4513ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
4514 if (!DyldInfoLoadCmd)
4515 return None;
4516
4517 MachO::dyld_info_command DyldInfo =
4518 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4519 const uint8_t *Ptr =
4520 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off));
4521 return makeArrayRef(Ptr, DyldInfo.rebase_size);
4522}
4523
4524ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const {
4525 if (!DyldInfoLoadCmd)
4526 return None;
4527
4528 MachO::dyld_info_command DyldInfo =
4529 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4530 const uint8_t *Ptr =
4531 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off));
4532 return makeArrayRef(Ptr, DyldInfo.bind_size);
4533}
4534
4535ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const {
4536 if (!DyldInfoLoadCmd)
4537 return None;
4538
4539 MachO::dyld_info_command DyldInfo =
4540 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4541 const uint8_t *Ptr =
4542 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off));
4543 return makeArrayRef(Ptr, DyldInfo.weak_bind_size);
4544}
4545
4546ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
4547 if (!DyldInfoLoadCmd)
4548 return None;
4549
4550 MachO::dyld_info_command DyldInfo =
4551 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4552 const uint8_t *Ptr =
4553 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off));
4554 return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
4555}
4556
4557ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
4558 if (!DyldInfoLoadCmd)
4559 return None;
4560
4561 MachO::dyld_info_command DyldInfo =
4562 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd);
4563 const uint8_t *Ptr =
4564 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off));
4565 return makeArrayRef(Ptr, DyldInfo.export_size);
4566}
4567
4568ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
4569 if (!UuidLoadCmd)
4570 return None;
4571 // Returning a pointer is fine as uuid doesn't need endian swapping.
4572 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid)__builtin_offsetof(MachO::uuid_command, uuid);
4573 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4574}
4575
4576StringRef MachOObjectFile::getStringTableData() const {
4577 MachO::symtab_command S = getSymtabLoadCommand();
4578 return getData().substr(S.stroff, S.strsize);
4579}
4580
4581bool MachOObjectFile::is64Bit() const {
4582 return getType() == getMachOType(false, true) ||
4583 getType() == getMachOType(true, true);
4584}
4585
4586void MachOObjectFile::ReadULEB128s(uint64_t Index,
4587 SmallVectorImpl<uint64_t> &Out) const {
4588 DataExtractor extractor(ObjectFile::getData(), true, 0);
4589
4590 uint32_t offset = Index;
4591 uint64_t data = 0;
4592 while (uint64_t delta = extractor.getULEB128(&offset)) {
4593 data += delta;
4594 Out.push_back(data);
4595 }
4596}
4597
4598bool MachOObjectFile::isRelocatableObject() const {
4599 return getHeader().filetype == MachO::MH_OBJECT;
4600}
4601
4602Expected<std::unique_ptr<MachOObjectFile>>
4603ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
4604 uint32_t UniversalCputype,
4605 uint32_t UniversalIndex) {
4606 StringRef Magic = Buffer.getBuffer().slice(0, 4);
4607 if (Magic == "\xFE\xED\xFA\xCE")
4608 return MachOObjectFile::create(Buffer, false, false,
4609 UniversalCputype, UniversalIndex);
4610 if (Magic == "\xCE\xFA\xED\xFE")
4611 return MachOObjectFile::create(Buffer, true, false,
4612 UniversalCputype, UniversalIndex);
4613 if (Magic == "\xFE\xED\xFA\xCF")
4614 return MachOObjectFile::create(Buffer, false, true,
4615 UniversalCputype, UniversalIndex);
4616 if (Magic == "\xCF\xFA\xED\xFE")
4617 return MachOObjectFile::create(Buffer, true, true,
4618 UniversalCputype, UniversalIndex);
4619 return make_error<GenericBinaryError>("Unrecognized MachO magic number",
4620 object_error::invalid_file_type);
4621}
4622
4623StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
4624 return StringSwitch<StringRef>(Name)
4625 .Case("debug_str_offs", "debug_str_offsets")
4626 .Default(Name);
4627}

/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/ADT/STLExtras.h

1//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains some templates that are useful if you are working with the
11// STL at all.
12//
13// No library is required when using these functions.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ADT_STLEXTRAS_H
18#define LLVM_ADT_STLEXTRAS_H
19
20#include "llvm/ADT/Optional.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/iterator.h"
23#include "llvm/ADT/iterator_range.h"
24#include "llvm/Support/ErrorHandling.h"
25#include <algorithm>
26#include <cassert>
27#include <cstddef>
28#include <cstdint>
29#include <cstdlib>
30#include <functional>
31#include <initializer_list>
32#include <iterator>
33#include <limits>
34#include <memory>
35#include <tuple>
36#include <type_traits>
37#include <utility>
38
39#ifdef EXPENSIVE_CHECKS
40#include <random> // for std::mt19937
41#endif
42
43namespace llvm {
44
45// Only used by compiler if both template types are the same. Useful when
46// using SFINAE to test for the existence of member functions.
47template <typename T, T> struct SameType;
48
49namespace detail {
50
51template <typename RangeT>
52using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
53
54template <typename RangeT>
55using ValueOfRange = typename std::remove_reference<decltype(
56 *std::begin(std::declval<RangeT &>()))>::type;
57
58} // end namespace detail
59
60//===----------------------------------------------------------------------===//
61// Extra additions to <type_traits>
62//===----------------------------------------------------------------------===//
63
64template <typename T>
65struct negation : std::integral_constant<bool, !bool(T::value)> {};
66
67template <typename...> struct conjunction : std::true_type {};
68template <typename B1> struct conjunction<B1> : B1 {};
69template <typename B1, typename... Bn>
70struct conjunction<B1, Bn...>
71 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
72
73//===----------------------------------------------------------------------===//
74// Extra additions to <functional>
75//===----------------------------------------------------------------------===//
76
77template <class Ty> struct identity {
78 using argument_type = Ty;
79
80 Ty &operator()(Ty &self) const {
81 return self;
82 }
83 const Ty &operator()(const Ty &self) const {
84 return self;
85 }
86};
87
88template <class Ty> struct less_ptr {
89 bool operator()(const Ty* left, const Ty* right) const {
90 return *left < *right;
91 }
92};
93
94template <class Ty> struct greater_ptr {
95 bool operator()(const Ty* left, const Ty* right) const {
96 return *right < *left;
97 }
98};
99
100/// An efficient, type-erasing, non-owning reference to a callable. This is
101/// intended for use as the type of a function parameter that is not used
102/// after the function in question returns.
103///
104/// This class does not own the callable, so it is not in general safe to store
105/// a function_ref.
106template<typename Fn> class function_ref;
107
108template<typename Ret, typename ...Params>
109class function_ref<Ret(Params...)> {
110 Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
111 intptr_t callable;
112
113 template<typename Callable>
114 static Ret callback_fn(intptr_t callable, Params ...params) {
115 return (*reinterpret_cast<Callable*>(callable))(
116 std::forward<Params>(params)...);
117 }
118
119public:
120 function_ref() = default;
121 function_ref(std::nullptr_t) {}
122
123 template <typename Callable>
124 function_ref(Callable &&callable,
125 typename std::enable_if<
126 !std::is_same<typename std::remove_reference<Callable>::type,
127 function_ref>::value>::type * = nullptr)
128 : callback(callback_fn<typename std::remove_reference<Callable>::type>),
129 callable(reinterpret_cast<intptr_t>(&callable)) {}
130
131 Ret operator()(Params ...params) const {
132 return callback(callable, std::forward<Params>(params)...);
133 }
134
135 operator bool() const { return callback; }
136};
137
138// deleter - Very very very simple method that is used to invoke operator
139// delete on something. It is used like this:
140//
141// for_each(V.begin(), B.end(), deleter<Interval>);
142template <class T>
143inline void deleter(T *Ptr) {
144 delete Ptr;
145}
146
147//===----------------------------------------------------------------------===//
148// Extra additions to <iterator>
149//===----------------------------------------------------------------------===//
150
151namespace adl_detail {
152
153using std::begin;
154
155template <typename ContainerTy>
156auto adl_begin(ContainerTy &&container)
157 -> decltype(begin(std::forward<ContainerTy>(container))) {
158 return begin(std::forward<ContainerTy>(container));
159}
160
161using std::end;
162
163template <typename ContainerTy>
164auto adl_end(ContainerTy &&container)
165 -> decltype(end(std::forward<ContainerTy>(container))) {
166 return end(std::forward<ContainerTy>(container));
167}
168
169using std::swap;
170
171template <typename T>
172void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
173 std::declval<T>()))) {
174 swap(std::forward<T>(lhs), std::forward<T>(rhs));
175}
176
177} // end namespace adl_detail
178
179template <typename ContainerTy>
180auto adl_begin(ContainerTy &&container)
181 -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
182 return adl_detail::adl_begin(std::forward<ContainerTy>(container));
183}
184
185template <typename ContainerTy>
186auto adl_end(ContainerTy &&container)
187 -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
188 return adl_detail::adl_end(std::forward<ContainerTy>(container));
189}
190
191template <typename T>
192void adl_swap(T &&lhs, T &&rhs) noexcept(
193 noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
194 adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
195}
196
197// mapped_iterator - This is a simple iterator adapter that causes a function to
198// be applied whenever operator* is invoked on the iterator.
199
200template <typename ItTy, typename FuncTy,
201 typename FuncReturnTy =
202 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
203class mapped_iterator
204 : public iterator_adaptor_base<
205 mapped_iterator<ItTy, FuncTy>, ItTy,
206 typename std::iterator_traits<ItTy>::iterator_category,
207 typename std::remove_reference<FuncReturnTy>::type> {
208public:
209 mapped_iterator(ItTy U, FuncTy F)
210 : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
211
212 ItTy getCurrent() { return this->I; }
213
214 FuncReturnTy operator*() { return F(*this->I); }
215
216private:
217 FuncTy F;
218};
219
220// map_iterator - Provide a convenient way to create mapped_iterators, just like
221// make_pair is useful for creating pairs...
222template <class ItTy, class FuncTy>
223inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
224 return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
225}
226
227/// Helper to determine if type T has a member called rbegin().
228template <typename Ty> class has_rbegin_impl {
229 using yes = char[1];
230 using no = char[2];
231
232 template <typename Inner>
233 static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
234
235 template <typename>
236 static no& test(...);
237
238public:
239 static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
240};
241
242/// Metafunction to determine if T& or T has a member called rbegin().
243template <typename Ty>
244struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
245};
246
247// Returns an iterator_range over the given container which iterates in reverse.
248// Note that the container must have rbegin()/rend() methods for this to work.
249template <typename ContainerTy>
250auto reverse(ContainerTy &&C,
251 typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
252 nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
253 return make_range(C.rbegin(), C.rend());
254}
255
256// Returns a std::reverse_iterator wrapped around the given iterator.
257template <typename IteratorTy>
258std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
259 return std::reverse_iterator<IteratorTy>(It);
260}
261
262// Returns an iterator_range over the given container which iterates in reverse.
263// Note that the container must have begin()/end() methods which return
264// bidirectional iterators for this to work.
265template <typename ContainerTy>
266auto reverse(
267 ContainerTy &&C,
268 typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
269 -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
270 llvm::make_reverse_iterator(std::begin(C)))) {
271 return make_range(llvm::make_reverse_iterator(std::end(C)),
272 llvm::make_reverse_iterator(std::begin(C)));
273}
274
275/// An iterator adaptor that filters the elements of given inner iterators.
276///
277/// The predicate parameter should be a callable object that accepts the wrapped
278/// iterator's reference type and returns a bool. When incrementing or
279/// decrementing the iterator, it will call the predicate on each element and
280/// skip any where it returns false.
281///
282/// \code
283/// int A[] = { 1, 2, 3, 4 };
284/// auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
285/// // R contains { 1, 3 }.
286/// \endcode
287///
288/// Note: filter_iterator_base implements support for forward iteration.
289/// filter_iterator_impl exists to provide support for bidirectional iteration,
290/// conditional on whether the wrapped iterator supports it.
291template <typename WrappedIteratorT, typename PredicateT, typename IterTag>
292class filter_iterator_base
293 : public iterator_adaptor_base<
294 filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
295 WrappedIteratorT,
296 typename std::common_type<
297 IterTag, typename std::iterator_traits<
298 WrappedIteratorT>::iterator_category>::type> {
299 using BaseT = iterator_adaptor_base<
300 filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
301 WrappedIteratorT,
302 typename std::common_type<
303 IterTag, typename std::iterator_traits<
304 WrappedIteratorT>::iterator_category>::type>;
305
306protected:
307 WrappedIteratorT End;
308 PredicateT Pred;
309
310 void findNextValid() {
311 while (this->I != End && !Pred(*this->I))
312 BaseT::operator++();
313 }
314
315 // Construct the iterator. The begin iterator needs to know where the end
316 // is, so that it can properly stop when it gets there. The end iterator only
317 // needs the predicate to support bidirectional iteration.
318 filter_iterator_base(WrappedIteratorT Begin, WrappedIteratorT End,
319 PredicateT Pred)
320 : BaseT(Begin), End(End), Pred(Pred) {
321 findNextValid();
322 }
323
324public:
325 using BaseT::operator++;
326
327 filter_iterator_base &operator++() {
328 BaseT::operator++();
329 findNextValid();
330 return *this;
331 }
332};
333
334/// Specialization of filter_iterator_base for forward iteration only.
335template <typename WrappedIteratorT, typename PredicateT,
336 typename IterTag = std::forward_iterator_tag>
337class filter_iterator_impl
338 : public filter_iterator_base<WrappedIteratorT, PredicateT, IterTag> {
339 using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>;
340
341public:
342 filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
343 PredicateT Pred)
344 : BaseT(Begin, End, Pred) {}
345};
346
347/// Specialization of filter_iterator_base for bidirectional iteration.
348template <typename WrappedIteratorT, typename PredicateT>
349class filter_iterator_impl<WrappedIteratorT, PredicateT,
350 std::bidirectional_iterator_tag>
351 : public filter_iterator_base<WrappedIteratorT, PredicateT,
352 std::bidirectional_iterator_tag> {
353 using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT,
354 std::bidirectional_iterator_tag>;
355 void findPrevValid() {
356 while (!this->Pred(*this->I))
357 BaseT::operator--();
358 }
359
360public:
361 using BaseT::operator--;
362
363 filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
364 PredicateT Pred)
365 : BaseT(Begin, End, Pred) {}
366
367 filter_iterator_impl &operator--() {
368 BaseT::operator--();
369 findPrevValid();
370 return *this;
371 }
372};
373
374namespace detail {
375
376template <bool is_bidirectional> struct fwd_or_bidi_tag_impl {
377 using type = std::forward_iterator_tag;
378};
379
380template <> struct fwd_or_bidi_tag_impl<true> {
381 using type = std::bidirectional_iterator_tag;
382};
383
384/// Helper which sets its type member to forward_iterator_tag if the category
385/// of \p IterT does not derive from bidirectional_iterator_tag, and to
386/// bidirectional_iterator_tag otherwise.
387template <typename IterT> struct fwd_or_bidi_tag {
388 using type = typename fwd_or_bidi_tag_impl<std::is_base_of<
389 std::bidirectional_iterator_tag,
390 typename std::iterator_traits<IterT>::iterator_category>::value>::type;
391};
392
393} // namespace detail
394
395/// Defines filter_iterator to a suitable specialization of
396/// filter_iterator_impl, based on the underlying iterator's category.
397template <typename WrappedIteratorT, typename PredicateT>
398using filter_iterator = filter_iterator_impl<
399 WrappedIteratorT, PredicateT,
400 typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
401
402/// Convenience function that takes a range of elements and a predicate,
403/// and return a new filter_iterator range.
404///
405/// FIXME: Currently if RangeT && is a rvalue reference to a temporary, the
406/// lifetime of that temporary is not kept by the returned range object, and the
407/// temporary is going to be dropped on the floor after the make_iterator_range
408/// full expression that contains this function call.
409template <typename RangeT, typename PredicateT>
410iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
411make_filter_range(RangeT &&Range, PredicateT Pred) {
412 using FilterIteratorT =
413 filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
414 return make_range(
415 FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
416 std::end(std::forward<RangeT>(Range)), Pred),
417 FilterIteratorT(std::end(std::forward<RangeT>(Range)),
418 std::end(std::forward<RangeT>(Range)), Pred));
419}
420
421// forward declarations required by zip_shortest/zip_first
422template <typename R, typename UnaryPredicate>
423bool all_of(R &&range, UnaryPredicate P);
424
425template <size_t... I> struct index_sequence;
426
427template <class... Ts> struct index_sequence_for;
428
429namespace detail {
430
431using std::declval;
432
433// We have to alias this since inlining the actual type at the usage site
434// in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
435template<typename... Iters> struct ZipTupleType {
436 using type = std::tuple<decltype(*declval<Iters>())...>;
437};
438
439template <typename ZipType, typename... Iters>
440using zip_traits = iterator_facade_base<
441 ZipType, typename std::common_type<std::bidirectional_iterator_tag,
442 typename std::iterator_traits<
443 Iters>::iterator_category...>::type,
444 // ^ TODO: Implement random access methods.
445 typename ZipTupleType<Iters...>::type,
446 typename std::iterator_traits<typename std::tuple_element<
447 0, std::tuple<Iters...>>::type>::difference_type,
448 // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
449 // inner iterators have the same difference_type. It would fail if, for
450 // instance, the second field's difference_type were non-numeric while the
451 // first is.
452 typename ZipTupleType<Iters...>::type *,
453 typename ZipTupleType<Iters...>::type>;
454
455template <typename ZipType, typename... Iters>
456struct zip_common : public zip_traits<ZipType, Iters...> {
457 using Base = zip_traits<ZipType, Iters...>;
458 using value_type = typename Base::value_type;
459
460 std::tuple<Iters...> iterators;
461
462protected:
463 template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
464 return value_type(*std::get<Ns>(iterators)...);
465 }
466
467 template <size_t... Ns>
468 decltype(iterators) tup_inc(index_sequence<Ns...>) const {
469 return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
470 }
471
472 template <size_t... Ns>
473 decltype(iterators) tup_dec(index_sequence<Ns...>) const {
474 return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
475 }
476
477public:
478 zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
479
480 value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
481
482 const value_type operator*() const {
483 return deref(index_sequence_for<Iters...>{});
484 }
485
486 ZipType &operator++() {
487 iterators = tup_inc(index_sequence_for<Iters...>{});
488 return *reinterpret_cast<ZipType *>(this);
489 }
490
491 ZipType &operator--() {
492 static_assert(Base::IsBidirectional,
493 "All inner iterators must be at least bidirectional.");
494 iterators = tup_dec(index_sequence_for<Iters...>{});
495 return *reinterpret_cast<ZipType *>(this);
496 }
497};
498
499template <typename... Iters>
500struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
501 using Base = zip_common<zip_first<Iters...>, Iters...>;
502
503 bool operator==(const zip_first<Iters...> &other) const {
504 return std::get<0>(this->iterators) == std::get<0>(other.iterators);
505 }
506
507 zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
508};
509
510template <typename... Iters>
511class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
512 template <size_t... Ns>
513 bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const {
514 return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
515 std::get<Ns>(other.iterators)...},
516 identity<bool>{});
517 }
518
519public:
520 using Base = zip_common<zip_shortest<Iters...>, Iters...>;
521
522 zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
523
524 bool operator==(const zip_shortest<Iters...> &other) const {
525 return !test(other, index_sequence_for<Iters...>{});
526 }
527};
528
529template <template <typename...> class ItType, typename... Args> class zippy {
530public:
531 using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
532 using iterator_category = typename iterator::iterator_category;
533 using value_type = typename iterator::value_type;
534 using difference_type = typename iterator::difference_type;
535 using pointer = typename iterator::pointer;
536 using reference = typename iterator::reference;
537
538private:
539 std::tuple<Args...> ts;
540
541 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
542 return iterator(std::begin(std::get<Ns>(ts))...);
543 }
544 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
545 return iterator(std::end(std::get<Ns>(ts))...);
546 }
547
548public:
549 zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
550
551 iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
552 iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
553};
554
555} // end namespace detail
556
557/// zip iterator for two or more iteratable types.
558template <typename T, typename U, typename... Args>
559detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
560 Args &&... args) {
561 return detail::zippy<detail::zip_shortest, T, U, Args...>(
562 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
563}
564
565/// zip iterator that, for the sake of efficiency, assumes the first iteratee to
566/// be the shortest.
567template <typename T, typename U, typename... Args>
568detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
569 Args &&... args) {
570 return detail::zippy<detail::zip_first, T, U, Args...>(
571 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
572}
573
574/// Iterator wrapper that concatenates sequences together.
575///
576/// This can concatenate different iterators, even with different types, into
577/// a single iterator provided the value types of all the concatenated
578/// iterators expose `reference` and `pointer` types that can be converted to
579/// `ValueT &` and `ValueT *` respectively. It doesn't support more
580/// interesting/customized pointer or reference types.
581///
582/// Currently this only supports forward or higher iterator categories as
583/// inputs and always exposes a forward iterator interface.
584template <typename ValueT, typename... IterTs>
585class concat_iterator
586 : public iterator_facade_base<concat_iterator<ValueT, IterTs...>,
587 std::forward_iterator_tag, ValueT> {
588 using BaseT = typename concat_iterator::iterator_facade_base;
589
590 /// We store both the current and end iterators for each concatenated
591 /// sequence in a tuple of pairs.
592 ///
593 /// Note that something like iterator_range seems nice at first here, but the
594 /// range properties are of little benefit and end up getting in the way
595 /// because we need to do mutation on the current iterators.
596 std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
597
598 /// Attempts to increment a specific iterator.
599 ///
600 /// Returns true if it was able to increment the iterator. Returns false if
601 /// the iterator is already at the end iterator.
602 template <size_t Index> bool incrementHelper() {
603 auto &IterPair = std::get<Index>(IterPairs);
604 if (IterPair.first == IterPair.second)
605 return false;
606
607 ++IterPair.first;
608 return true;
609 }
610
611 /// Increments the first non-end iterator.
612 ///
613 /// It is an error to call this with all iterators at the end.
614 template <size_t... Ns> void increment(index_sequence<Ns...>) {
615 // Build a sequence of functions to increment each iterator if possible.
616 bool (concat_iterator::*IncrementHelperFns[])() = {
617 &concat_iterator::incrementHelper<Ns>...};
618
619 // Loop over them, and stop as soon as we succeed at incrementing one.
620 for (auto &IncrementHelperFn : IncrementHelperFns)
621 if ((this->*IncrementHelperFn)())
622 return;
623
624 llvm_unreachable("Attempted to increment an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to increment an end concat iterator!"
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/ADT/STLExtras.h"
, 624)
;
625 }
626
627 /// Returns null if the specified iterator is at the end. Otherwise,
628 /// dereferences the iterator and returns the address of the resulting
629 /// reference.
630 template <size_t Index> ValueT *getHelper() const {
631 auto &IterPair = std::get<Index>(IterPairs);
632 if (IterPair.first == IterPair.second)
633 return nullptr;
634
635 return &*IterPair.first;
636 }
637
638 /// Finds the first non-end iterator, dereferences, and returns the resulting
639 /// reference.
640 ///
641 /// It is an error to call this with all iterators at the end.
642 template <size_t... Ns> ValueT &get(index_sequence<Ns...>) const {
643 // Build a sequence of functions to get from iterator if possible.
644 ValueT *(concat_iterator::*GetHelperFns[])() const = {
645 &concat_iterator::getHelper<Ns>...};
646
647 // Loop over them, and return the first result we find.
648 for (auto &GetHelperFn : GetHelperFns)
649 if (ValueT *P = (this->*GetHelperFn)())
650 return *P;
651
652 llvm_unreachable("Attempted to get a pointer from an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to get a pointer from an end concat iterator!"
, "/build/llvm-toolchain-snapshot-7~svn338205/include/llvm/ADT/STLExtras.h"
, 652)
;
653 }
654
655public:
656 /// Constructs an iterator from a squence of ranges.
657 ///
658 /// We need the full range to know how to switch between each of the
659 /// iterators.
660 template <typename... RangeTs>
661 explicit concat_iterator(RangeTs &&... Ranges)
662 : IterPairs({std::begin(Ranges), std::end(Ranges)}...) {}
663
664 using BaseT::operator++;
665
666 concat_iterator &operator++() {
667 increment(index_sequence_for<IterTs...>());
668 return *this;
669 }
670
671 ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); }
672
673 bool operator==(const concat_iterator &RHS) const {
674 return IterPairs == RHS.IterPairs;
675 }
676};
677
678namespace detail {
679
680/// Helper to store a sequence of ranges being concatenated and access them.
681///
682/// This is designed to facilitate providing actual storage when temporaries
683/// are passed into the constructor such that we can use it as part of range
684/// based for loops.
685template <typename ValueT, typename... RangeTs> class concat_range {
686public:
687 using iterator =
688 concat_iterator<ValueT,
689 decltype(std::begin(std::declval<RangeTs &>()))...>;
690
691private:
692 std::tuple<RangeTs...> Ranges;
693
694 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
695 return iterator(std::get<Ns>(Ranges)...);
696 }
697 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
698 return iterator(make_range(std::end(std::get<Ns>(Ranges)),
699 std::end(std::get<Ns>(Ranges)))...);
700 }
701
702public:
703 concat_range(RangeTs &&... Ranges)
704 : Ranges(std::forward<RangeTs>(Ranges)...) {}
705
706 iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); }
707 iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); }
708};
709
710} // end namespace detail
711
712/// Concatenated range across two or more ranges.
713///
714/// The desired value type must be explicitly specified.
715template <typename ValueT, typename... RangeTs>
716detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
717 static_assert(sizeof...(RangeTs) > 1,
718 "Need more than one range to concatenate!");
719 return detail::concat_range<ValueT, RangeTs...>(
720 std::forward<RangeTs>(Ranges)...);
721}
722
723//===----------------------------------------------------------------------===//
724// Extra additions to <utility>
725//===----------------------------------------------------------------------===//
726
727/// Function object to check whether the first component of a std::pair
728/// compares less than the first component of another std::pair.
729struct less_first {
730 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
731 return lhs.first < rhs.first;
732 }
733};
734
735/// Function object to check whether the second component of a std::pair
736/// compares less than the second component of another std::pair.
737struct less_second {
738 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
739 return lhs.second < rhs.second;
740 }
741};
742
743// A subset of N3658. More stuff can be added as-needed.
744
745/// Represents a compile-time sequence of integers.
746template <class T, T... I> struct integer_sequence {
747 using value_type = T;
748
749 static constexpr size_t size() { return sizeof...(I); }
750};
751
752/// Alias for the common case of a sequence of size_ts.
753template <size_t... I>
754struct index_sequence : integer_sequence<std::size_t, I...> {};
755
756template <std::size_t N, std::size_t... I>
757struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
758template <std::size_t... I>
759struct build_index_impl<0, I...> : index_sequence<I...> {};
760
761/// Creates a compile-time integer sequence for a parameter pack.
762template <class... Ts>
763struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
764
765/// Utility type to build an inheritance chain that makes it easy to rank
766/// overload candidates.
767template <int N> struct rank : rank<N - 1> {};
768template <> struct rank<0> {};
769
770/// traits class for checking whether type T is one of any of the given
771/// types in the variadic list.
772template <typename T, typename... Ts> struct is_one_of {
773 static const bool value = false;
774};
775
776template <typename T, typename U, typename... Ts>
777struct is_one_of<T, U, Ts...> {
778 static const bool value =
779 std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
780};
781
782/// traits class for checking whether type T is a base class for all
783/// the given types in the variadic list.
784template <typename T, typename... Ts> struct are_base_of {
785 static const bool value = true;
786};
787
788template <typename T, typename U, typename... Ts>
789struct are_base_of<T, U, Ts...> {
790 static const bool value =
791 std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
792};
793
794//===----------------------------------------------------------------------===//
795// Extra additions for arrays
796//===----------------------------------------------------------------------===//
797
798/// Find the length of an array.
799template <class T, std::size_t N>
800constexpr inline size_t array_lengthof(T (&)[N]) {
801 return N;
802}
803
804/// Adapt std::less<T> for array_pod_sort.
805template<typename T>
806inline int array_pod_sort_comparator(const void *P1, const void *P2) {
807 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
808 *reinterpret_cast<const T*>(P2)))
809 return -1;
810 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
811 *reinterpret_cast<const T*>(P1)))
812 return 1;
813 return 0;
814}
815
816/// get_array_pod_sort_comparator - This is an internal helper function used to
817/// get type deduction of T right.
818template<typename T>
819inline int (*get_array_pod_sort_comparator(const T &))
820 (const void*, const void*) {
821 return array_pod_sort_comparator<T>;
822}
823
824/// array_pod_sort - This sorts an array with the specified start and end
825/// extent. This is just like std::sort, except that it calls qsort instead of
826/// using an inlined template. qsort is slightly slower than std::sort, but
827/// most sorts are not performance critical in LLVM and std::sort has to be
828/// template instantiated for each type, leading to significant measured code
829/// bloat. This function should generally be used instead of std::sort where
830/// possible.
831///
832/// This function assumes that you have simple POD-like types that can be
833/// compared with std::less and can be moved with memcpy. If this isn't true,
834/// you should use std::sort.
835///
836/// NOTE: If qsort_r were portable, we could allow a custom comparator and
837/// default to std::less.
838template<class IteratorTy>
839inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
840 // Don't inefficiently call qsort with one element or trigger undefined
841 // behavior with an empty sequence.
842 auto NElts = End - Start;
843 if (NElts <= 1) return;
844#ifdef EXPENSIVE_CHECKS
845 std::mt19937 Generator(std::random_device{}());
846 std::shuffle(Start, End, Generator);
847#endif
848 qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
849}
850
851template <class IteratorTy>
852inline void array_pod_sort(
853 IteratorTy Start, IteratorTy End,
854 int (*Compare)(
855 const typename std::iterator_traits<IteratorTy>::value_type *,
856 const typename std::iterator_traits<IteratorTy>::value_type *)) {
857 // Don't inefficiently call qsort with one element or trigger undefined
858 // behavior with an empty sequence.
859 auto NElts = End - Start;
860 if (NElts <= 1) return;
861#ifdef EXPENSIVE_CHECKS
862 std::mt19937 Generator(std::random_device{}());
863 std::shuffle(Start, End, Generator);
864#endif
865 qsort(&*Start, NElts, sizeof(*Start),
866 reinterpret_cast<int (*)(const void *, const void *)>(Compare));
867}
868
869// Provide wrappers to std::sort which shuffle the elements before sorting
870// to help uncover non-deterministic behavior (PR35135).
871template <typename IteratorTy>
872inline void sort(IteratorTy Start, IteratorTy End) {
873#ifdef EXPENSIVE_CHECKS
874 std::mt19937 Generator(std::random_device{}());
875 std::shuffle(Start, End, Generator);
876#endif
877 std::sort(Start, End);
878}
879
880template <typename IteratorTy, typename Compare>
881inline void sort(IteratorTy Start, IteratorTy End, Compare Comp) {
882#ifdef EXPENSIVE_CHECKS
883 std::mt19937 Generator(std::random_device{}());
884 std::shuffle(Start, End, Generator);
885#endif
886 std::sort(Start, End, Comp);
887}
888
889//===----------------------------------------------------------------------===//
890// Extra additions to <algorithm>
891//===----------------------------------------------------------------------===//
892
893/// For a container of pointers, deletes the pointers and then clears the
894/// container.
895template<typename Container>
896void DeleteContainerPointers(Container &C) {
897 for (auto V : C)
898 delete V;
899 C.clear();
900}
901
902/// In a container of pairs (usually a map) whose second element is a pointer,
903/// deletes the second elements and then clears the container.
904template<typename Container>
905void DeleteContainerSeconds(Container &C) {
906 for (auto &V : C)
907 delete V.second;
908 C.clear();
909}
910
911/// Provide wrappers to std::for_each which take ranges instead of having to
912/// pass begin/end explicitly.
913template <typename R, typename UnaryPredicate>
914UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
915 return std::for_each(adl_begin(Range), adl_end(Range), P);
916}
917
918/// Provide wrappers to std::all_of which take ranges instead of having to pass
919/// begin/end explicitly.
920template <typename R, typename UnaryPredicate>
921bool all_of(R &&Range, UnaryPredicate P) {
922 return std::all_of(adl_begin(Range), adl_end(Range), P);
923}
924
925/// Provide wrappers to std::any_of which take ranges instead of having to pass
926/// begin/end explicitly.
927template <typename R, typename UnaryPredicate>
928bool any_of(R &&Range, UnaryPredicate P) {
929 return std::any_of(adl_begin(Range), adl_end(Range), P);
930}
931
932/// Provide wrappers to std::none_of which take ranges instead of having to pass
933/// begin/end explicitly.
934template <typename R, typename UnaryPredicate>
935bool none_of(R &&Range, UnaryPredicate P) {
936 return std::none_of(adl_begin(Range), adl_end(Range), P);
937}
938
939/// Provide wrappers to std::find which take ranges instead of having to pass
940/// begin/end explicitly.
941template <typename R, typename T>
942auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
943 return std::find(adl_begin(Range), adl_end(Range), Val);
944}
945
946/// Provide wrappers to std::find_if which take ranges instead of having to pass
947/// begin/end explicitly.
948template <typename R, typename UnaryPredicate>
949auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
950 return std::find_if(adl_begin(Range), adl_end(Range), P);
951}
952
953template <typename R, typename UnaryPredicate>
954auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
955 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
956}
957
958/// Provide wrappers to std::remove_if which take ranges instead of having to
959/// pass begin/end explicitly.
960template <typename R, typename UnaryPredicate>
961auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
962 return std::remove_if(adl_begin(Range), adl_end(Range), P);
963}
964
965/// Provide wrappers to std::copy_if which take ranges instead of having to
966/// pass begin/end explicitly.
967template <typename R, typename OutputIt, typename UnaryPredicate>
968OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
969 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
970}
971
972template <typename R, typename OutputIt>
973OutputIt copy(R &&Range, OutputIt Out) {
974 return std::copy(adl_begin(Range), adl_end(Range), Out);
975}
976
977/// Wrapper function around std::find to detect if an element exists
978/// in a container.
979template <typename R, typename E>
980bool is_contained(R &&Range, const E &Element) {
981 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
982}
983
984/// Wrapper function around std::count to count the number of times an element
985/// \p Element occurs in the given range \p Range.
986template <typename R, typename E>
987auto count(R &&Range, const E &Element) ->
988 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
989 return std::count(adl_begin(Range), adl_end(Range), Element);
990}
991
992/// Wrapper function around std::count_if to count the number of times an
993/// element satisfying a given predicate occurs in a range.
994template <typename R, typename UnaryPredicate>
995auto count_if(R &&Range, UnaryPredicate P) ->
996 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
997 return std::count_if(adl_begin(Range), adl_end(Range), P);
998}
999
1000/// Wrapper function around std::transform to apply a function to a range and
1001/// store the result elsewhere.
1002template <typename R, typename OutputIt, typename UnaryPredicate>
1003OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
1004 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
1005}
1006
1007/// Provide wrappers to std::partition which take ranges instead of having to
1008/// pass begin/end explicitly.
1009template <typename R, typename UnaryPredicate>
1010auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1011 return std::partition(adl_begin(Range), adl_end(Range), P);
1012}
1013
1014/// Provide wrappers to std::lower_bound which take ranges instead of having to
1015/// pass begin/end explicitly.
1016template <typename R, typename ForwardIt>
1017auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
1018 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
1019}
1020
1021/// Given a range of type R, iterate the entire range and return a
1022/// SmallVector with elements of the vector. This is useful, for example,
1023/// when you want to iterate a range and then sort the results.
1024template <unsigned Size, typename R>
1025SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
1026to_vector(R &&Range) {
1027 return {adl_begin(Range), adl_end(Range)};
1028}
1029
1030/// Provide a container algorithm similar to C++ Library Fundamentals v2's
1031/// `erase_if` which is equivalent to:
1032///
1033/// C.erase(remove_if(C, pred), C.end());
1034///
1035/// This version works for any container with an erase method call accepting
1036/// two iterators.
1037template <typename Container, typename UnaryPredicate>
1038void erase_if(Container &C, UnaryPredicate P) {
1039 C.erase(remove_if(C, P), C.end());
1040}
1041
1042/// Get the size of a range. This is a wrapper function around std::distance
1043/// which is only enabled when the operation is O(1).
1044template <typename R>
1045auto size(R &&Range, typename std::enable_if<
1046 std::is_same<typename std::iterator_traits<decltype(
1047 Range.begin())>::iterator_category,
1048 std::random_access_iterator_tag>::value,
1049 void>::type * = nullptr)
1050 -> decltype(std::distance(Range.begin(), Range.end())) {
1051 return std::distance(Range.begin(), Range.end());
1052}
1053
1054//===----------------------------------------------------------------------===//
1055// Extra additions to <memory>
1056//===----------------------------------------------------------------------===//
1057
1058// Implement make_unique according to N3656.
1059
1060/// Constructs a `new T()` with the given args and returns a
1061/// `unique_ptr<T>` which owns the object.
1062///
1063/// Example:
1064///
1065/// auto p = make_unique<int>();
1066/// auto p = make_unique<std::tuple<int, int>>(0, 1);
1067template <class T, class... Args>
1068typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
1069make_unique(Args &&... args) {
1070 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
4
Calling constructor for 'BindRebaseSegInfo'
1071}
1072
1073/// Constructs a `new T[n]` with the given args and returns a
1074/// `unique_ptr<T[]>` which owns the object.
1075///
1076/// \param n size of the new array.
1077///
1078/// Example:
1079///
1080/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
1081template <class T>
1082typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
1083 std::unique_ptr<T>>::type
1084make_unique(size_t n) {
1085 return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
1086}
1087
1088/// This function isn't used and is only here to provide better compile errors.
1089template <class T, class... Args>
1090typename std::enable_if<std::extent<T>::value != 0>::type
1091make_unique(Args &&...) = delete;
1092
1093struct FreeDeleter {
1094 void operator()(void* v) {
1095 ::free(v);
1096 }
1097};
1098
1099template<typename First, typename Second>
1100struct pair_hash {
1101 size_t operator()(const std::pair<First, Second> &P) const {
1102 return std::hash<First>()(P.first) * 31 + std::hash<Sec