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-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-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/lib/Object -I /build/llvm-toolchain-snapshot-8~svn345461/lib/Object -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/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-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/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-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/lib/Object/MachOObjectFile.cpp -faddrsig

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