Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MachOObjectFile.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/lib/Object -I /build/llvm-toolchain-snapshot-7~svn325118/lib/Object -I /build/llvm-toolchain-snapshot-7~svn325118/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325118/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/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-7~svn325118/build-llvm/lib/Object -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-14-150435-17243-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325118/lib/Object/MachOObjectFile.cpp

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

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

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