1//===- MachOObjectFile.cpp - Mach-O object file binding -------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file defines the MachOObjectFile class, which binds the MachOObject 10// class to the generic ObjectFile wrapper. 12//===----------------------------------------------------------------------===// 49#include <system_error> 61}
// end anonymous namespace 64return make_error<GenericBinaryError>(
"truncated or malformed object (" +
66 object_error::parse_failed);
69// FIXME: Replace all uses of this function with getStructOrErr. 72// Don't read before the beginning or past the end of the file 73if (
P < O.getData().begin() ||
P +
sizeof(
T) > O.getData().end())
77 memcpy(&Cmd,
P,
sizeof(
T));
85// Don't read before the beginning or past the end of the file 86if (
P < O.getData().begin() ||
P +
sizeof(
T) > O.getData().end())
90 memcpy(&Cmd,
P,
sizeof(
T));
99 uintptr_t CommandAddr =
reinterpret_cast<uintptr_t
>(L.Ptr);
101bool Is64 = O.is64Bit();
107 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
108returnreinterpret_cast<constchar*
>(SectionAddr);
112size_t MachOFilesetEntryOffset = 0) {
114 MachOFilesetEntryOffset <= O.getData().size());
115return O.getData().data() +
Offset + MachOFilesetEntryOffset;
120constchar *
P =
reinterpret_cast<constchar *
>(DRI.
p);
121return getStruct<MachO::nlist_base>(O,
P);
128// Not null terminated, so this is a 16 char string. 133return O.getHeader().cputype;
137return O.getHeader().cpusubtype & ~MachO::CPU_SUBTYPE_MASK;
152if (O.isLittleEndian())
164if (O.isLittleEndian())
176if (O.isLittleEndian())
194if (
auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj,
Ptr)) {
197" extends past end of file");
198if (CmdOrErr->cmdsize < 8)
200" with size less than 8 bytes");
203return CmdOrErr.takeError();
211returnmalformedError(
"load command 0 extends past the end all load " 212"commands in the file");
226" extends past the end all load commands in the file");
234 Err =
malformedError(
"the mach header extends past the end of the " 238if (
auto HeaderOrErr = getStructOrErr<T>(
240 Header = *HeaderOrErr;
242 Err = HeaderOrErr.takeError();
245// This is used to check for overlapping of Mach-O elements. 258for (
auto it = Elements.begin(); it != Elements.end(); ++it) {
262 (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
264" with a size of " +
Twine(
Size) +
", overlaps " +
265 E.Name +
" at offset " +
Twine(E.Offset) +
" with " 266"a size of " +
Twine(E.Size));
269if (nt != Elements.end()) {
281// Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all 282// sections to \param Sections, and optionally sets 283// \param IsPageZeroSegment to true. 284template <
typename Segment,
typename Section>
289 std::list<MachOElement> &Elements) {
290constunsigned SegmentLoadSize =
sizeof(Segment);
291if (Load.C.cmdsize < SegmentLoadSize)
293" " + CmdName +
" cmdsize too small");
294if (
auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
295 Segment S = SegOrErr.get();
296constunsigned SectionSize =
sizeof(Section);
298if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
299 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
301" inconsistent cmdsize in " + CmdName +
302" for the number of sections");
303for (
unsigned J = 0; J < S.nsects; ++J) {
306auto SectionOrErr = getStructOrErr<Section>(Obj, Sec);
308return SectionOrErr.takeError();
309 Section s = SectionOrErr.get();
316 CmdName +
" command " +
Twine(LoadCommandIndex) +
317" extends past the end of the file");
322 s.offset < SizeOfHeaders && s.size != 0)
324 CmdName +
" command " +
Twine(LoadCommandIndex) +
325" not past the headers of the file");
334Twine(J) +
" in " + CmdName +
" command " +
335Twine(LoadCommandIndex) +
336" extends past the end of the file");
343Twine(J) +
" in " + CmdName +
" command " +
344Twine(LoadCommandIndex) +
345" greater than the segment");
350 CmdName +
" command " +
Twine(LoadCommandIndex) +
351" less than the segment's vmaddr");
356if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
358" in " + CmdName +
" command " +
359Twine(LoadCommandIndex) +
361"the segment's vmaddr plus vmsize");
369if (s.reloff > FileSize)
371 CmdName +
" command " +
Twine(LoadCommandIndex) +
372" extends past the end of the file");
376if (BigSize > FileSize)
377returnmalformedError(
"reloff field plus nreloc field times sizeof(" 378"struct relocation_info) of section " +
379Twine(J) +
" in " + CmdName +
" command " +
380Twine(LoadCommandIndex) +
381" extends past the end of the file");
385"section relocation entries"))
388if (S.fileoff > FileSize)
390" fileoff field in " + CmdName +
391" extends past the end of the file");
393 BigSize += S.filesize;
394if (BigSize > FileSize)
396" fileoff field plus filesize field in " +
397 CmdName +
" extends past the end of the file");
398if (S.vmsize != 0 && S.filesize > S.vmsize)
400" filesize field in " + CmdName +
401" greater than vmsize field");
402 IsPageZeroSegment |=
StringRef(
"__PAGEZERO") == S.segname;
404return SegOrErr.takeError();
412constchar **SymtabLoadCmd,
413 std::list<MachOElement> &Elements) {
416" LC_SYMTAB cmdsize too small");
417if (*SymtabLoadCmd !=
nullptr)
419auto SymtabOrErr = getStructOrErr<MachO::symtab_command>(Obj, Load.Ptr);
421return SymtabOrErr.takeError();
425" has incorrect cmdsize");
427if (Symtab.
symoff > FileSize)
429Twine(LoadCommandIndex) +
" extends past the end " 432constchar *struct_nlist_name;
435 struct_nlist_name =
"struct nlist_64";
438 struct_nlist_name =
"struct nlist";
442if (BigSize > FileSize)
443returnmalformedError(
"symoff field plus nsyms field times sizeof(" +
444Twine(struct_nlist_name) +
") of LC_SYMTAB command " +
445Twine(LoadCommandIndex) +
" extends past the end " 450if (Symtab.
stroff > FileSize)
452Twine(LoadCommandIndex) +
" extends past the end " 456if (BigSize > FileSize)
457returnmalformedError(
"stroff field plus strsize field of LC_SYMTAB " 458"command " +
Twine(LoadCommandIndex) +
" extends " 459"past the end of the file");
461 Symtab.
strsize,
"string table"))
463 *SymtabLoadCmd = Load.Ptr;
470constchar **DysymtabLoadCmd,
471 std::list<MachOElement> &Elements) {
474" LC_DYSYMTAB cmdsize too small");
475if (*DysymtabLoadCmd !=
nullptr)
478 getStructOrErr<MachO::dysymtab_command>(Obj, Load.Ptr);
480return DysymtabOrErr.takeError();
484" has incorrect cmdsize");
486if (Dysymtab.
tocoff > FileSize)
488Twine(LoadCommandIndex) +
" extends past the end of " 492 BigSize += Dysymtab.
tocoff;
493if (BigSize > FileSize)
494returnmalformedError(
"tocoff field plus ntoc field times sizeof(struct " 495"dylib_table_of_contents) of LC_DYSYMTAB command " +
496Twine(LoadCommandIndex) +
" extends past the end of " 499 Dysymtab.
ntoc *
sizeof(
struct 505Twine(LoadCommandIndex) +
" extends past the end of " 508constchar *struct_dylib_module_name;
512 struct_dylib_module_name =
"struct dylib_module_64";
515 struct_dylib_module_name =
"struct dylib_module";
517 BigSize *= sizeof_modtab;
519if (BigSize > FileSize)
520returnmalformedError(
"modtaboff field plus nmodtab field times sizeof(" +
521Twine(struct_dylib_module_name) +
") of LC_DYSYMTAB " 522"command " +
Twine(LoadCommandIndex) +
" extends " 523"past the end of the file");
525 Dysymtab.
nmodtab * sizeof_modtab,
529returnmalformedError(
"extrefsymoff field of LC_DYSYMTAB command " +
530Twine(LoadCommandIndex) +
" extends past the end of " 535if (BigSize > FileSize)
536returnmalformedError(
"extrefsymoff field plus nextrefsyms field times " 537"sizeof(struct dylib_reference) of LC_DYSYMTAB " 538"command " +
Twine(LoadCommandIndex) +
" extends " 539"past the end of the file");
546returnmalformedError(
"indirectsymoff field of LC_DYSYMTAB command " +
547Twine(LoadCommandIndex) +
" extends past the end of " 552if (BigSize > FileSize)
553returnmalformedError(
"indirectsymoff field plus nindirectsyms field times " 554"sizeof(uint32_t) of LC_DYSYMTAB command " +
555Twine(LoadCommandIndex) +
" extends past the end of " 564Twine(LoadCommandIndex) +
" extends past the end of " 569if (BigSize > FileSize)
570returnmalformedError(
"extreloff field plus nextrel field times sizeof" 571"(struct relocation_info) of LC_DYSYMTAB command " +
572Twine(LoadCommandIndex) +
" extends past the end of " 577"external relocation table"))
581Twine(LoadCommandIndex) +
" extends past the end of " 586if (BigSize > FileSize)
587returnmalformedError(
"locreloff field plus nlocrel field times sizeof" 588"(struct relocation_info) of LC_DYSYMTAB command " +
589Twine(LoadCommandIndex) +
" extends past the end of " 594"local relocation table"))
596 *DysymtabLoadCmd = Load.Ptr;
603constchar **LoadCmd,
constchar *CmdName,
604 std::list<MachOElement> &Elements,
605constchar *ElementName) {
608 CmdName +
" cmdsize too small");
609if (*LoadCmd !=
nullptr)
611auto LinkDataOrError =
612 getStructOrErr<MachO::linkedit_data_command>(Obj, Load.Ptr);
614return LinkDataOrError.takeError();
618Twine(LoadCommandIndex) +
" has incorrect cmdsize");
620if (LinkData.
dataoff > FileSize)
622Twine(LoadCommandIndex) +
" extends past the end of " 626if (BigSize > FileSize)
628Twine(CmdName) +
" command " +
629Twine(LoadCommandIndex) +
" extends past the end of " 641constchar **LoadCmd,
constchar *CmdName,
642 std::list<MachOElement> &Elements) {
645 CmdName +
" cmdsize too small");
646if (*LoadCmd !=
nullptr)
647returnmalformedError(
"more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY " 650 getStructOrErr<MachO::dyld_info_command>(Obj, Load.Ptr);
652return DyldInfoOrErr.takeError();
656Twine(LoadCommandIndex) +
" has incorrect cmdsize");
660" command " +
Twine(LoadCommandIndex) +
" extends " 661"past the end of the file");
664if (BigSize > FileSize)
665returnmalformedError(
"rebase_off field plus rebase_size field of " +
666Twine(CmdName) +
" command " +
667Twine(LoadCommandIndex) +
" extends past the end of " 675" command " +
Twine(LoadCommandIndex) +
" extends " 676"past the end of the file");
679if (BigSize > FileSize)
681Twine(CmdName) +
" command " +
682Twine(LoadCommandIndex) +
" extends past the end of " 690" command " +
Twine(LoadCommandIndex) +
" extends " 691"past the end of the file");
694if (BigSize > FileSize)
695returnmalformedError(
"weak_bind_off field plus weak_bind_size field of " +
696Twine(CmdName) +
" command " +
697Twine(LoadCommandIndex) +
" extends past the end of " 701"dyld weak bind info"))
705" command " +
Twine(LoadCommandIndex) +
" extends " 706"past the end of the file");
709if (BigSize > FileSize)
710returnmalformedError(
"lazy_bind_off field plus lazy_bind_size field of " +
711Twine(CmdName) +
" command " +
712Twine(LoadCommandIndex) +
" extends past the end of " 716"dyld lazy bind info"))
720" command " +
Twine(LoadCommandIndex) +
" extends " 721"past the end of the file");
724if (BigSize > FileSize)
725returnmalformedError(
"export_off field plus export_size field of " +
726Twine(CmdName) +
" command " +
727Twine(LoadCommandIndex) +
" extends past the end of " 739uint32_t LoadCommandIndex,
constchar *CmdName) {
742 CmdName +
" cmdsize too small");
743auto CommandOrErr = getStructOrErr<MachO::dylib_command>(Obj, Load.Ptr);
745return CommandOrErr.takeError();
749 CmdName +
" name.offset field too small, not past " 750"the end of the dylib_command struct");
751if (
D.dylib.name >=
D.cmdsize)
753 CmdName +
" name.offset field extends past the end " 754"of the load command");
755// Make sure there is a null between the starting offset of the name and 756// the end of the load command. 758constchar *
P = (
constchar *)Load.Ptr;
759for (i =
D.dylib.name; i <
D.cmdsize; i++)
764 CmdName +
" library name extends past the end of the " 772constchar **LoadCmd) {
776if (*LoadCmd !=
nullptr)
780returnmalformedError(
"LC_ID_DYLIB load command in non-dynamic library " 788uint32_t LoadCommandIndex,
constchar *CmdName) {
791 CmdName +
" cmdsize too small");
792auto CommandOrErr = getStructOrErr<MachO::dylinker_command>(Obj, Load.Ptr);
794return CommandOrErr.takeError();
798 CmdName +
" name.offset field too small, not past " 799"the end of the dylinker_command struct");
800if (
D.name >=
D.cmdsize)
802 CmdName +
" name.offset field extends past the end " 803"of the load command");
804// Make sure there is a null between the starting offset of the name and 805// the end of the load command. 807constchar *
P = (
constchar *)Load.Ptr;
808for (i =
D.name; i <
D.cmdsize; i++)
813 CmdName +
" dyld name extends past the end of the " 821constchar **LoadCmd,
constchar *CmdName) {
824 CmdName +
" has incorrect cmdsize");
825if (*LoadCmd !=
nullptr)
827"LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or " 828"LC_VERSION_MIN_WATCHOS command");
836 std::list<MachOElement> &Elements) {
839" LC_NOTE has incorrect cmdsize");
840auto NoteCmdOrErr = getStructOrErr<MachO::note_command>(Obj, Load.Ptr);
842return NoteCmdOrErr.takeError();
847Twine(LoadCommandIndex) +
" extends " 848"past the end of the file");
851if (BigSize > FileSize)
852returnmalformedError(
"size field plus offset field of LC_NOTE command " +
853Twine(LoadCommandIndex) +
" extends past the end of " 867 getStructOrErr<MachO::build_version_command>(Obj, Load.Ptr);
869return BVCOrErr.takeError();
875" LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
879for (
unsigned i = 0; i < BVC.
ntools; ++i)
890" LC_RPATH cmdsize too small");
891auto ROrErr = getStructOrErr<MachO::rpath_command>(Obj, Load.Ptr);
893return ROrErr.takeError();
897" LC_RPATH path.offset field too small, not past " 898"the end of the rpath_command struct");
899if (R.path >= R.cmdsize)
901" LC_RPATH path.offset field extends past the end " 902"of the load command");
903// Make sure there is a null between the starting offset of the path and 904// the end of the load command. 906constchar *
P = (
constchar *)Load.Ptr;
907for (i = R.path; i < R.cmdsize; i++)
912" LC_RPATH library name extends past the end of the " 921constchar **LoadCmd,
constchar *CmdName) {
922if (*LoadCmd !=
nullptr)
924"LC_ENCRYPTION_INFO_64 command");
926if (cryptoff > FileSize)
928" command " +
Twine(LoadCommandIndex) +
" extends " 929"past the end of the file");
931 BigSize += cryptsize;
932if (BigSize > FileSize)
934Twine(CmdName) +
" command " +
935Twine(LoadCommandIndex) +
" extends past the end of " 946" LC_LINKER_OPTION cmdsize too small");
947auto LinkOptionOrErr =
948 getStructOrErr<MachO::linker_option_command>(Obj, Load.Ptr);
950return LinkOptionOrErr.takeError();
952// Make sure the count of strings is correct. 953constchar *
string = (
constchar *)Load.Ptr +
958while (*
string ==
'\0' && left > 0) {
965if (0xffffffff == NullPos)
967" LC_LINKER_OPTION string #" +
Twine(i) +
968" is not NULL terminated");
969uint32_t len = std::min(NullPos, left) + 1;
976" LC_LINKER_OPTION string count " +
Twine(L.count) +
977" does not match number of strings");
983uint32_t LoadCommandIndex,
constchar *CmdName,
984size_t SizeOfCmd,
constchar *CmdStructName,
985uint32_t PathOffset,
constchar *PathFieldName) {
986if (PathOffset < SizeOfCmd)
988 CmdName +
" " + PathFieldName +
".offset field too " 989"small, not past the end of the " + CmdStructName);
990if (PathOffset >= Load.C.cmdsize)
992 CmdName +
" " + PathFieldName +
".offset field " 993"extends past the end of the load command");
994// Make sure there is a null between the starting offset of the path and 995// the end of the load command. 997constchar *
P = (
constchar *)Load.Ptr;
998for (i = PathOffset; i < Load.C.cmdsize; i++)
1001if (i >= Load.C.cmdsize)
1003 CmdName +
" " + PathFieldName +
" name extends past " 1004"the end of the load command");
1011constchar *CmdName) {
1014 CmdName +
" cmdsize too small");
1015auto ThreadCommandOrErr =
1016 getStructOrErr<MachO::thread_command>(Obj, Load.Ptr);
1017if (!ThreadCommandOrErr)
1018return ThreadCommandOrErr.takeError();
1021constchar *end = Load.Ptr +
T.cmdsize;
1024while (state < end) {
1027"flavor in " + CmdName +
" extends past end of " 1030 memcpy(&flavor, state,
sizeof(
uint32_t));
1037" count in " + CmdName +
" extends past end of " 1049" count not x86_THREAD_STATE32_COUNT for " 1050"flavor number " +
Twine(nflavor) +
" which is " 1051"a x86_THREAD_STATE32 flavor in " + CmdName +
1055" x86_THREAD_STATE32 extends past end of " 1056"command in " + CmdName +
" command");
1060" unknown flavor (" +
Twine(flavor) +
") for " 1061"flavor number " +
Twine(nflavor) +
" in " +
1062 CmdName +
" command");
1068" count not x86_THREAD_STATE_COUNT for " 1069"flavor number " +
Twine(nflavor) +
" which is " 1070"a x86_THREAD_STATE flavor in " + CmdName +
1074" x86_THREAD_STATE extends past end of " 1075"command in " + CmdName +
" command");
1080" count not x86_FLOAT_STATE_COUNT for " 1081"flavor number " +
Twine(nflavor) +
" which is " 1082"a x86_FLOAT_STATE flavor in " + CmdName +
1086" x86_FLOAT_STATE extends past end of " 1087"command in " + CmdName +
" command");
1092" count not x86_EXCEPTION_STATE_COUNT for " 1093"flavor number " +
Twine(nflavor) +
" which is " 1094"a x86_EXCEPTION_STATE flavor in " + CmdName +
1098" x86_EXCEPTION_STATE extends past end of " 1099"command in " + CmdName +
" command");
1104" count not x86_THREAD_STATE64_COUNT for " 1105"flavor number " +
Twine(nflavor) +
" which is " 1106"a x86_THREAD_STATE64 flavor in " + CmdName +
1110" x86_THREAD_STATE64 extends past end of " 1111"command in " + CmdName +
" command");
1116" count not x86_EXCEPTION_STATE64_COUNT for " 1117"flavor number " +
Twine(nflavor) +
" which is " 1118"a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1122" x86_EXCEPTION_STATE64 extends past end of " 1123"command in " + CmdName +
" command");
1127" unknown flavor (" +
Twine(flavor) +
") for " 1128"flavor number " +
Twine(nflavor) +
" in " +
1129 CmdName +
" command");
1135" count not ARM_THREAD_STATE_COUNT for " 1136"flavor number " +
Twine(nflavor) +
" which is " 1137"a ARM_THREAD_STATE flavor in " + CmdName +
1141" ARM_THREAD_STATE extends past end of " 1142"command in " + CmdName +
" command");
1146" unknown flavor (" +
Twine(flavor) +
") for " 1147"flavor number " +
Twine(nflavor) +
" in " +
1148 CmdName +
" command");
1155" count not ARM_THREAD_STATE64_COUNT for " 1156"flavor number " +
Twine(nflavor) +
" which is " 1157"a ARM_THREAD_STATE64 flavor in " + CmdName +
1161" ARM_THREAD_STATE64 extends past end of " 1162"command in " + CmdName +
" command");
1166" unknown flavor (" +
Twine(flavor) +
") for " 1167"flavor number " +
Twine(nflavor) +
" in " +
1168 CmdName +
" command");
1174" count not PPC_THREAD_STATE_COUNT for " 1175"flavor number " +
Twine(nflavor) +
" which is " 1176"a PPC_THREAD_STATE flavor in " + CmdName +
1180" PPC_THREAD_STATE extends past end of " 1181"command in " + CmdName +
" command");
1185" unknown flavor (" +
Twine(flavor) +
") for " 1186"flavor number " +
Twine(nflavor) +
" in " +
1187 CmdName +
" command");
1191"command " +
Twine(LoadCommandIndex) +
" for " +
1192 CmdName +
" command can't be checked");
1204 std::list<MachOElement> &Elements) {
1207" LC_TWOLEVEL_HINTS has incorrect cmdsize");
1208if (*LoadCmd !=
nullptr)
1210auto HintsOrErr = getStructOrErr<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1212return HintsOrErr.takeError();
1215if (Hints.
offset > FileSize)
1216returnmalformedError(
"offset field of LC_TWOLEVEL_HINTS command " +
1217Twine(LoadCommandIndex) +
" extends past the end of " 1222if (BigSize > FileSize)
1223returnmalformedError(
"offset field plus nhints times sizeof(struct " 1224"twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1225Twine(LoadCommandIndex) +
" extends past the end of " 1231 *LoadCmd = Load.Ptr;
1235// Returns true if the libObject code does not support the load command and its 1236// contents. The cmd value it is treated as an unknown load command but with 1237// an error message that says the cmd value is obsolete. 1239if (
cmd == MachO::LC_SYMSEG ||
1240cmd == MachO::LC_LOADFVMLIB ||
1241cmd == MachO::LC_IDFVMLIB ||
1242cmd == MachO::LC_IDENT ||
1243cmd == MachO::LC_FVMFILE ||
1244cmd == MachO::LC_PREPAGE ||
1245cmd == MachO::LC_PREBOUND_DYLIB ||
1246cmd == MachO::LC_TWOLEVEL_HINTS ||
1247cmd == MachO::LC_PREBIND_CKSUM)
1254bool Is64Bits,
uint32_t UniversalCputype,
1256size_t MachOFilesetEntryOffset) {
1259 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,
1260 UniversalIndex, MachOFilesetEntryOffset));
1262return std::move(Err);
1263return std::move(Obj);
1266MachOObjectFile::MachOObjectFile(
MemoryBufferRef Object,
bool IsLittleEndian,
1267bool Is64bits,
Error &Err,
1270size_t MachOFilesetEntryOffset)
1271 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1272 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {
1289 Err =
malformedError(
"load commands extend past the end of the file");
1292if (UniversalCputype != 0 && cputype != UniversalCputype) {
1294Twine(UniversalIndex) +
"'s cputype does not match " 1295"object file's mach header");
1299Elements.push_back({0, SizeOfHeaders,
"Mach-O headers"});
1302 LoadCommandInfo
Load;
1303if (LoadCommandCount != 0) {
1307 Err = LoadOrErr.takeError();
1312constchar *DyldIdLoadCmd =
nullptr;
1313constchar *SplitInfoLoadCmd =
nullptr;
1314constchar *CodeSignDrsLoadCmd =
nullptr;
1315constchar *CodeSignLoadCmd =
nullptr;
1316constchar *VersLoadCmd =
nullptr;
1317constchar *SourceLoadCmd =
nullptr;
1318constchar *EntryPointLoadCmd =
nullptr;
1319constchar *EncryptLoadCmd =
nullptr;
1320constchar *RoutinesLoadCmd =
nullptr;
1321constchar *UnixThreadLoadCmd =
nullptr;
1322constchar *TwoLevelHintsLoadCmd =
nullptr;
1323for (
unsignedI = 0;
I < LoadCommandCount; ++
I) {
1325if (
Load.C.cmdsize % 8 != 0) {
1326// We have a hack here to allow 64-bit Mach-O core files to have 1327// LC_THREAD commands that are only a multiple of 4 and not 8 to be 1328// allowed since the macOS kernel produces them. 1330Load.C.cmd != MachO::LC_THREAD ||
Load.C.cmdsize % 4) {
1337if (
Load.C.cmdsize % 4 != 0) {
1344if (
Load.C.cmd == MachO::LC_SYMTAB) {
1347 }
elseif (
Load.C.cmd == MachO::LC_DYSYMTAB) {
1351 }
elseif (
Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1353"LC_DATA_IN_CODE", Elements,
1354"data in code info")))
1356 }
elseif (
Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1358"LC_LINKER_OPTIMIZATION_HINT",
1359 Elements,
"linker optimization " 1362 }
elseif (
Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1364"LC_FUNCTION_STARTS", Elements,
1365"function starts data")))
1367 }
elseif (
Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1369"LC_SEGMENT_SPLIT_INFO", Elements,
1372 }
elseif (
Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1374"LC_DYLIB_CODE_SIGN_DRS", Elements,
1375"code signing RDs data")))
1377 }
elseif (
Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1379"LC_CODE_SIGNATURE", Elements,
1380"code signature data")))
1382 }
elseif (
Load.C.cmd == MachO::LC_DYLD_INFO) {
1384"LC_DYLD_INFO", Elements)))
1386 }
elseif (
Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1388"LC_DYLD_INFO_ONLY", Elements)))
1390 }
elseif (
Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1392 *
this, Load,
I, &DyldChainedFixupsLoadCmd,
1393"LC_DYLD_CHAINED_FIXUPS", Elements,
"chained fixups")))
1395 }
elseif (
Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {
1397 *
this, Load,
I, &DyldExportsTrieLoadCmd,
"LC_DYLD_EXPORTS_TRIE",
1398 Elements,
"exports trie")))
1400 }
elseif (
Load.C.cmd == MachO::LC_UUID) {
1410 UuidLoadCmd =
Load.Ptr;
1411 }
elseif (
Load.C.cmd == MachO::LC_SEGMENT_64) {
1414 *
this, Load, Sections, HasPageZeroSegment,
I,
1415"LC_SEGMENT_64", SizeOfHeaders, Elements)))
1417 }
elseif (
Load.C.cmd == MachO::LC_SEGMENT) {
1420 *
this, Load, Sections, HasPageZeroSegment,
I,
1421"LC_SEGMENT", SizeOfHeaders, Elements)))
1423 }
elseif (
Load.C.cmd == MachO::LC_ID_DYLIB) {
1426 }
elseif (
Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1430 }
elseif (
Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1434 }
elseif (
Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1438 }
elseif (
Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1442 }
elseif (
Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1446 }
elseif (
Load.C.cmd == MachO::LC_ID_DYLINKER) {
1449 }
elseif (
Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1452 }
elseif (
Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1455 }
elseif (
Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1457"LC_VERSION_MIN_MACOSX")))
1459 }
elseif (
Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1461"LC_VERSION_MIN_IPHONEOS")))
1463 }
elseif (
Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1465"LC_VERSION_MIN_TVOS")))
1467 }
elseif (
Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1469"LC_VERSION_MIN_WATCHOS")))
1471 }
elseif (
Load.C.cmd == MachO::LC_NOTE) {
1474 }
elseif (
Load.C.cmd == MachO::LC_BUILD_VERSION) {
1477 }
elseif (
Load.C.cmd == MachO::LC_RPATH) {
1480 }
elseif (
Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1483" has incorrect cmdsize");
1490 SourceLoadCmd =
Load.Ptr;
1491 }
elseif (
Load.C.cmd == MachO::LC_MAIN) {
1494" has incorrect cmdsize");
1497if (EntryPointLoadCmd) {
1501 EntryPointLoadCmd =
Load.Ptr;
1502 }
elseif (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1505" has incorrect cmdsize");
1509 getStruct<MachO::encryption_info_command>(*
this,
Load.Ptr);
1511 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO")))
1513 }
elseif (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1516" has incorrect cmdsize");
1520 getStruct<MachO::encryption_info_command_64>(*
this,
Load.Ptr);
1522 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO_64")))
1524 }
elseif (
Load.C.cmd == MachO::LC_LINKER_OPTION) {
1527 }
elseif (
Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1530" LC_SUB_FRAMEWORK cmdsize too small");
1534 getStruct<MachO::sub_framework_command>(*
this,
Load.Ptr);
1537"sub_framework_command", S.
umbrella,
1540 }
elseif (
Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1543" LC_SUB_UMBRELLA cmdsize too small");
1547 getStruct<MachO::sub_umbrella_command>(*
this,
Load.Ptr);
1553 }
elseif (
Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1556" LC_SUB_LIBRARY cmdsize too small");
1560 getStruct<MachO::sub_library_command>(*
this,
Load.Ptr);
1566 }
elseif (
Load.C.cmd == MachO::LC_SUB_CLIENT) {
1569" LC_SUB_CLIENT cmdsize too small");
1573 getStruct<MachO::sub_client_command>(*
this,
Load.Ptr);
1576"sub_client_command", S.
client,
"client")))
1578 }
elseif (
Load.C.cmd == MachO::LC_ROUTINES) {
1581" has incorrect cmdsize");
1584if (RoutinesLoadCmd) {
1585 Err =
malformedError(
"more than one LC_ROUTINES and or LC_ROUTINES_64 " 1589 RoutinesLoadCmd =
Load.Ptr;
1590 }
elseif (
Load.C.cmd == MachO::LC_ROUTINES_64) {
1593" has incorrect cmdsize");
1596if (RoutinesLoadCmd) {
1597 Err =
malformedError(
"more than one LC_ROUTINES_64 and or LC_ROUTINES " 1601 RoutinesLoadCmd =
Load.Ptr;
1602 }
elseif (
Load.C.cmd == MachO::LC_UNIXTHREAD) {
1605if (UnixThreadLoadCmd) {
1609 UnixThreadLoadCmd =
Load.Ptr;
1610 }
elseif (
Load.C.cmd == MachO::LC_THREAD) {
1613// Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported. 1614 }
elseif (
Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1616 &TwoLevelHintsLoadCmd, Elements)))
1618 }
elseif (
Load.C.cmd == MachO::LC_IDENT) {
1619// Note: LC_IDENT is ignored. 1623Twine(
Load.C.cmd) +
" is obsolete and not " 1627// TODO: generate a error for unknown load commands by default. But still 1628// need work out an approach to allow or not allow unknown values like this 1629// as an option for some uses like lldb. 1630if (
I < LoadCommandCount - 1) {
1634 Err = LoadOrErr.takeError();
1639if (!SymtabLoadCmd) {
1640if (DysymtabLoadCmd) {
1641 Err =
malformedError(
"contains LC_DYSYMTAB load command without a " 1642"LC_SYMTAB load command");
1645 }
elseif (DysymtabLoadCmd) {
1647 getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
1649 getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
1652"extends past the end of the symbol table");
1658 Err =
malformedError(
"ilocalsym plus nlocalsym in LC_DYSYMTAB load " 1659"command extends past the end of the symbol table");
1664"extends past the end of the symbol table");
1671"load command extends past the end of the symbol " 1677"extends past the end of the symbol table");
1683 Err =
malformedError(
"iundefsym plus nundefsym in LC_DYSYMTAB load " 1684" command extends past the end of the symbol table");
1690 DyldIdLoadCmd ==
nullptr) {
1691 Err =
malformedError(
"no LC_ID_DYLIB load command in dynamic library " 1695assert(LoadCommands.
size() == LoadCommandCount);
1735if (NSect == 0 || NSect > Sections.
size())
1737" for symbol at index " +
Twine(SymbolIndex));
1742"the end of string table, for N_INDR symbol at " 1743"index " +
Twine(SymbolIndex));
1749if (LibraryOrdinal != 0 &&
1752 LibraryOrdinal - 1 >= Libraries.
size() ) {
1754" for symbol at index " +
Twine(SymbolIndex));
1760" past the end of string table, for symbol at " 1761"index " +
Twine(SymbolIndex));
1777if (Entry.n_strx == 0)
1778// A n_strx value of 0 indicates that no name is associated with a 1779// particular symbol table entry. 1781constchar *Start = &
StringTable.data()[Entry.n_strx];
1798return Entry.n_value;
1801return Entry.n_value;
1804// getIndirectName() returns the name of the alias'ed symbol who's string table 1805// index is in the n_value field. 1817return std::error_code();
1846// If this is a STAB debugging symbol, we can do nothing more. 1870uint8_t MachOType = Entry.n_type;
1918 DRI.
d.
a = index - 1;
1919if (DRI.
d.
a >= Sections.
size()){
1929return Entry.n_sect - 1;
1952// In the case if a malformed Mach-O file where the section offset is past 1953// the end of the file or some part of the section size is past the end of 1954// the file return a size of zero or a size that covers the rest of the file 1955// but does not extend past the end of the file. 1961 SectOffset = Sect.
offset;
1962 SectSize = Sect.
size;
1966 SectOffset = Sect.
offset;
1967 SectSize = Sect.
size;
1973if (SectOffset > FileSize)
1975if (FileSize - SectOffset < SectSize)
1976return FileSize - SectOffset;
2017if (SectionIndex < 1 || SectionIndex > Sections.
size())
2021 DRI.
d.
a = SectionIndex - 1;
2027auto NameOrErr = Section.getName();
2029return NameOrErr.takeError();
2063if (!SectionNameOrErr) {
2064// TODO: Report the error message properly. 2076template <
typename LoadCommandType>
2080auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.
Ptr);
2085auto &Segment = SegmentOrErr.get();
2088 Segment.fileoff, Segment.fileoff + Segment.filesize));
2092template <
typename LoadCommandType>
2095auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.
Ptr);
2100auto &Segment = SegmentOrErr.get();
2101return arrayRefFromStringRef(
2110switch (LoadCmd.
C.
cmd) {
2111case MachO::LC_SEGMENT:
2112 Contents = ::getSegmentContents<MachO::segment_command>(*
this, LoadCmd,
2115case MachO::LC_SEGMENT_64:
2116 Contents = ::getSegmentContents<MachO::segment_command_64>(*
this, LoadCmd,
2122if (!Contents.
empty())
2132switch (LoadCmd.
C.
cmd) {
2133case MachO::LC_SEGMENT:
2134if (
Idx == SegmentIndex)
2135 return ::getSegmentContents<MachO::segment_command>(*
this, LoadCmd);
2138case MachO::LC_SEGMENT_64:
2139if (
Idx == SegmentIndex)
2140 return ::getSegmentContents<MachO::segment_command_64>(*
this, LoadCmd);
2164return (SegmentName ==
"__LLVM" && *NameOrErr ==
"__bitcode");
2200// for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2201 Ret.d.a = 0;
// Would normally be a section index. 2202 Ret.d.b = 0;
// Index into the external relocations 2209// for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2210 Ret.d.a = 0;
// Would normally be a section index. 2211 Ret.d.b = DysymtabLoadCmd.
nextrel;
// Index into the external relocations 2217// for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2218 Ret.d.a = 1;
// Would normally be a section index. 2219 Ret.d.b = 0;
// Index into the local relocations 2226// for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2227 Ret.d.a = 1;
// Would normally be a section index. 2228 Ret.d.b = DysymtabLoadCmd.
nlocrel;
// Index into the local relocations 2239"Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2280unsigned Arch = this->
getArch();
2284staticconstchar *
const Table[] = {
2285"GENERIC_RELOC_VANILLA",
2286"GENERIC_RELOC_PAIR",
2287"GENERIC_RELOC_SECTDIFF",
2288"GENERIC_RELOC_PB_LA_PTR",
2289"GENERIC_RELOC_LOCAL_SECTDIFF",
2290"GENERIC_RELOC_TLV" };
2299staticconstchar *
const Table[] = {
2300"X86_64_RELOC_UNSIGNED",
2301"X86_64_RELOC_SIGNED",
2302"X86_64_RELOC_BRANCH",
2303"X86_64_RELOC_GOT_LOAD",
2305"X86_64_RELOC_SUBTRACTOR",
2306"X86_64_RELOC_SIGNED_1",
2307"X86_64_RELOC_SIGNED_2",
2308"X86_64_RELOC_SIGNED_4",
2309"X86_64_RELOC_TLV" };
2318staticconstchar *
const Table[] = {
2321"ARM_RELOC_SECTDIFF",
2322"ARM_RELOC_LOCAL_SECTDIFF",
2323"ARM_RELOC_PB_LA_PTR",
2325"ARM_THUMB_RELOC_BR22",
2326"ARM_THUMB_32BIT_BRANCH",
2328"ARM_RELOC_HALF_SECTDIFF" };
2338staticconstchar *
const Table[] = {
2339"ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
2340"ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
2341"ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
2342"ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
2343"ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2344"ARM64_RELOC_ADDEND",
"ARM64_RELOC_AUTHENTICATED_POINTER" 2347if (RType >= std::size(Table))
2354staticconstchar *
const Table[] = {
2363"PPC_RELOC_SECTDIFF",
2364"PPC_RELOC_PB_LA_PTR",
2365"PPC_RELOC_HI16_SECTDIFF",
2366"PPC_RELOC_LO16_SECTDIFF",
2367"PPC_RELOC_HA16_SECTDIFF",
2369"PPC_RELOC_LO14_SECTDIFF",
2370"PPC_RELOC_LOCAL_SECTDIFF" };
2382 Result.append(res.
begin(), res.
end());
2391// guessLibraryShortName() is passed a name of a dynamic library and returns a 2392// guess on what the short name is. Then name is returned as a substring of the 2393// StringRef Name passed in. The name of the dynamic library is recognized as 2394// a framework if it has one of the two following forms: 2395// Foo.framework/Versions/A/Foo 2397// Where A and Foo can be any string. And may contain a trailing suffix 2398// starting with an underbar. If the Name is recognized as a framework then 2399// isFramework is set to true else it is set to false. If the Name has a 2400// suffix then Suffix is set to the substring in Name that contains the suffix 2401// else it is set to a NULL StringRef. 2403// The Name of the dynamic library is recognized as a library name if it has 2404// one of the two following forms: 2408// The library may have a suffix trailing the name Foo of the form: 2409// libFoo_profile.A.dylib 2410// libFoo_profile.dylib 2411// These dyld image suffixes are separated from the short name by a '_' 2412// character. Because the '_' character is commonly used to separate words in 2413// filenames guessLibraryShortName() cannot reliably separate a dylib's short 2414// name from an arbitrary image suffix; imagine if both the short name and the 2415// suffix contains an '_' character! To better deal with this ambiguity, 2416// guessLibraryShortName() will recognize only "_debug" and "_profile" as valid 2417// Suffix values. Calling code needs to be tolerant of guessLibraryShortName() 2418// guessing incorrectly. 2420// The Name of the dynamic library is also recognized as a library name if it 2421// has the following form: 2424// If the Name of the dynamic library is none of the forms above then a NULL 2425// StringRef is returned. 2430size_t a, b, c, d,
Idx;
2435// Pull off the last component and make Foo point to it 2437if (a ==
Name.npos || a == 0)
2439 Foo =
Name.substr(a + 1);
2441// Look for a suffix starting with a '_' 2445if (Suffix !=
"_debug" && Suffix !=
"_profile")
2451// First look for the form Foo.framework/Foo 2452 b =
Name.rfind(
'/', a);
2458 DotFramework =
Name.substr(
Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2459if (
F == Foo && DotFramework ==
".framework/") {
2464// Next look for the form Foo.framework/Versions/A/Foo 2467 c =
Name.rfind(
'/', b);
2468if (c ==
Name.npos || c == 0)
2470 V =
Name.substr(c + 1);
2471if (!V.starts_with(
"Versions/"))
2473 d =
Name.rfind(
'/', c);
2479 DotFramework =
Name.substr(
Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2480if (
F == Foo && DotFramework ==
".framework/") {
2486// pull off the suffix after the "." and make a point to it 2488if (a ==
Name.npos || a == 0)
2490 Dylib =
Name.substr(a);
2491if (Dylib !=
".dylib")
2494// First pull off the version letter for the form Foo.A.dylib if any. 2496 Dot =
Name.substr(a - 2, 1);
2501 b =
Name.rfind(
'/', a);
2506// ignore any suffix after an underbar like Foo_profile.A.dylib 2511if (Suffix !=
"_debug" && Suffix !=
"_profile") {
2518// There are incorrect library names of the form: 2519// libATS.A_profile.dylib so check for these. 2520if (
Lib.size() >= 3) {
2521 Dot =
Lib.substr(
Lib.size() - 2, 1);
2528 Qtx =
Name.substr(a);
2531 b =
Name.rfind(
'/', a);
2536// There are library names of the form: QT.A.qtx so check for these. 2537if (
Lib.size() >= 3) {
2538 Dot =
Lib.substr(
Lib.size() - 2, 1);
2545// getLibraryShortNameByIndex() is used to get the short name of the library 2546// for an undefined symbol in a linked Mach-O binary that was linked with the 2547// normal two-level namespace default (that is MH_TWOLEVEL in the header). 2548// It is passed the index (0 - based) of the library as translated from 2549// GET_LIBRARY_ORDINAL (1 - based). 2552if (Index >= Libraries.
size())
2555// If the cache of LibrariesShortNames is not built up do that first for 2556// all the Libraries. 2557if (LibrariesShortNames.
size() == 0) {
2558for (
unsigned i = 0; i < Libraries.
size(); i++) {
2560 getStructOrErr<MachO::dylib_command>(*
this, Libraries[i]);
2564if (
D.dylib.name >=
D.cmdsize)
2566constchar *
P = (
constchar *)(Libraries[i]) +
D.dylib.name;
2568if (
D.dylib.name+
Name.size() >=
D.cmdsize)
2573if (shortName.
empty())
2576 LibrariesShortNames.
push_back(shortName);
2580 Res = LibrariesShortNames[Index];
2581return std::error_code();
2585return Libraries.
size();
2591 Sec.
d.
a = Rel->getRawDataRefImpl().d.a;
2598if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2607if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2621if (!SymtabLoadCmd || Index >= Symtab.
nsyms)
2626 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2638 DRIstart.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2650 DRI.
d.
a = Sections.
size();
2663return"Mach-O 32-bit i386";
2667return"Mach-O arm64 (ILP32)";
2669return"Mach-O 32-bit ppc";
2671return"Mach-O 32-bit unknown";
2677return"Mach-O 64-bit x86-64";
2679return"Mach-O arm64";
2681return"Mach-O 64-bit ppc64";
2683return"Mach-O 64-bit unknown";
2709constchar **McpuDefault,
2710constchar **ArchFlag) {
2712 *McpuDefault =
nullptr;
2722returnTriple(
"i386-apple-darwin");
2730 *ArchFlag =
"x86_64";
2731returnTriple(
"x86_64-apple-darwin");
2734 *ArchFlag =
"x86_64h";
2735returnTriple(
"x86_64h-apple-darwin");
2743 *ArchFlag =
"armv4t";
2744returnTriple(
"armv4t-apple-darwin");
2747 *ArchFlag =
"armv5e";
2748returnTriple(
"armv5e-apple-darwin");
2751 *ArchFlag =
"xscale";
2752returnTriple(
"xscale-apple-darwin");
2756returnTriple(
"armv6-apple-darwin");
2759 *McpuDefault =
"cortex-m0";
2761 *ArchFlag =
"armv6m";
2762returnTriple(
"armv6m-apple-darwin");
2766returnTriple(
"armv7-apple-darwin");
2769 *McpuDefault =
"cortex-m4";
2771 *ArchFlag =
"armv7em";
2772returnTriple(
"thumbv7em-apple-darwin");
2775 *McpuDefault =
"cortex-a7";
2777 *ArchFlag =
"armv7k";
2778returnTriple(
"armv7k-apple-darwin");
2781 *McpuDefault =
"cortex-m3";
2783 *ArchFlag =
"armv7m";
2784returnTriple(
"thumbv7m-apple-darwin");
2787 *McpuDefault =
"cortex-a7";
2789 *ArchFlag =
"armv7s";
2790returnTriple(
"armv7s-apple-darwin");
2798 *McpuDefault =
"cyclone";
2801returnTriple(
"arm64-apple-darwin");
2804 *McpuDefault =
"apple-a12";
2806 *ArchFlag =
"arm64e";
2807returnTriple(
"arm64e-apple-darwin");
2815 *McpuDefault =
"cyclone";
2817 *ArchFlag =
"arm64_32";
2818returnTriple(
"arm64_32-apple-darwin");
2827returnTriple(
"ppc-apple-darwin");
2836returnTriple(
"ppc64-apple-darwin");
2855staticconst std::array<StringRef, 18> ValidArchs = {{
2901if (!DataInCodeLoadCmd)
2905 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, DicLC.
dataoff));
2911if (!DataInCodeLoadCmd)
2923void ExportEntry::moveToFirst() {
2928 pushDownUntilBottom();
2931void ExportEntry::moveToEnd() {
2937// Common case, one at end, other iterating from begin. 2938if (Done ||
Other.Done)
2939return (Done ==
Other.Done);
2940// Not equal if different stack sizes. 2943// Not equal if different cumulative strings. 2944if (!CumulativeString.
equals(
Other.CumulativeString))
2946// Equal if all nodes in both stacks match. 2947for (
unsigned i=0; i < Stack.
size(); ++i) {
2948if (Stack[i].Start !=
Other.Stack[i].Start)
2964return CumulativeString;
2968return Stack.
back().Flags;
2972return Stack.
back().Address;
2976return Stack.
back().Other;
2980constchar* ImportName = Stack.
back().ImportName;
2987return Stack.
back().Start - Trie.
begin();
2990ExportEntry::NodeState::NodeState(
constuint8_t *
Ptr)
2991 : Start(
Ptr), Current(
Ptr) {}
2993void ExportEntry::pushNode(
uint64_t offset) {
2996 NodeState State(
Ptr);
2997constchar *
error =
nullptr;
2998uint64_t ExportInfoSize = readULEB128(State.Current, &
error);
3001" in export trie data at node: 0x" +
3006 State.IsExportNode = (ExportInfoSize != 0);
3007constuint8_t* Children = State.Current + ExportInfoSize;
3008if (Children > Trie.
end()) {
3012" too big and extends past end of trie data");
3016if (State.IsExportNode) {
3017constuint8_t *ExportStart = State.Current;
3018 State.Flags = readULEB128(State.Current, &
error);
3021" in export trie data at node: 0x" +
3027if (State.Flags != 0 &&
3032"unsupported exported symbol kind: " +
Twine((
int)
Kind) +
3040 State.Other = readULEB128(State.Current, &
error);
// dylib ordinal 3043" in export trie data at node: 0x" +
3049// Only positive numbers represent library ordinals. Zero and negative 3050// numbers have special meaning (see BindSpecialDylib). 3053"bad library ordinal: " +
Twine((
int)State.Other) +
" (max " +
3060 State.ImportName =
reinterpret_cast<constchar*
>(State.Current);
3061if (*State.ImportName ==
'\0') {
3066 *E =
malformedError(
"import name of re-export in export trie data at " 3069" starts past end of trie data");
3076 *E =
malformedError(
"import name of re-export in export trie data at " 3079" extends past end of trie data");
3083 State.Current =
End + 1;
3086 State.Address = readULEB128(State.Current, &
error);
3089" in export trie data at node: 0x" +
3095 State.Other = readULEB128(State.Current, &
error);
3098" in export trie data at node: 0x" +
3105if (ExportStart + ExportInfoSize < State.Current) {
3107"inconsistent export info size: 0x" +
3116if (State.ChildCount != 0 && Children + 1 >= Trie.
end()) {
3117 *E =
malformedError(
"byte for count of childern in export trie data at " 3120" extends past end of trie data");
3125 State.NextChildIndex = 0;
3126 State.ParentStringLength = CumulativeString.
size();
3130void ExportEntry::pushDownUntilBottom() {
3132constchar *
error =
nullptr;
3133while (Stack.
back().NextChildIndex < Stack.
back().ChildCount) {
3134 NodeState &Top = Stack.
back();
3135 CumulativeString.
resize(Top.ParentStringLength);
3136for (;*Top.Current != 0 && Top.Current < Trie.
end(); Top.Current++) {
3137charC = *Top.Current;
3140if (Top.Current >= Trie.
end()) {
3141 *E =
malformedError(
"edge sub-string in export trie data at node: 0x" +
3143" for child #" +
Twine((
int)Top.NextChildIndex) +
3144" extends past end of trie data");
3152" in export trie data at node: 0x" +
3157for (
const NodeState &node : nodes()) {
3158if (node.Start == Trie.
begin() + childNodeIndex){
3159 *E =
malformedError(
"loop in childern in export trie data at node: 0x" +
3161" back to node: 0x" +
3167 Top.NextChildIndex += 1;
3168 pushNode(childNodeIndex);
3172if (!Stack.
back().IsExportNode) {
3173 *E =
malformedError(
"node is not an export node in export trie data at " 3181// We have a trie data structure and need a way to walk it that is compatible 3182// with the C++ iterator model. The solution is a non-recursive depth first 3183// traversal where the iterator contains a stack of parent nodes along with a 3184// string that is the accumulation of all edge strings along the parent chain 3187// There is one "export" node for each exported symbol. But because some 3188// symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 3189// node may have child nodes too. 3191// The algorithm for moveNext() is to keep moving down the leftmost unvisited 3192// child until hitting a node with no children (which is an export node or 3193// else the trie is malformed). On the way down, each node is pushed on the 3194// stack ivar. If there is no more ways down, it pops up one and tries to go 3195// down a sibling path until a childless node is reached. 3197assert(!Stack.
empty() &&
"ExportEntry::moveNext() with empty node stack");
3198if (!Stack.
back().IsExportNode) {
3199 *E =
malformedError(
"node is not an export node in export trie data at " 3207while (!Stack.
empty()) {
3208 NodeState &Top = Stack.
back();
3209if (Top.NextChildIndex < Top.ChildCount) {
3210 pushDownUntilBottom();
3211// Now at the next export node. 3214if (Top.IsExportNode) {
3215// This node has no children but is itself an export node. 3216 CumulativeString.
resize(Top.ParentStringLength);
3232 Start.moveToFirst();
3244elseif (DyldExportsTrieLoadCmd)
3253// Cache the vmaddress of __TEXT 3255if (Command.C.cmd == MachO::LC_SEGMENT) {
3258 TextAddress = SLC.vmaddr;
3261 }
elseif (Command.C.cmd == MachO::LC_SEGMENT_64) {
3264 TextAddress = SLC_64.
vmaddr;
3325 FixupTargets = *FixupTargetsOrErr;
3327 *
E = FixupTargetsOrErr.takeError();
3332 Segments = std::move(SegmentsOrErr->second);
3334 *
E = SegmentsOrErr.takeError();
3339void MachOChainedFixupEntry::findNextPageWithFixups() {
3340auto FindInSegment = [
this]() {
3342while (PageIndex < SegInfo.
PageStarts.size() &&
3348while (InfoSegIndex < Segments.size()) {
3349if (FindInSegment()) {
3350 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3362if (Segments.empty()) {
3370 findNextPageWithFixups();
3381if (InfoSegIndex == Segments.size()) {
3390// FIXME: Handle other pointer formats. 3395" has unsupported chained fixup pointer_format " +
3396Twine(PointerFormat));
3410" extends past segment's end");
3420// The bit extraction below assumes little-endian fixup entries. 3422"by getDyldChainedFixupTargets()");
3427// The `bind` field (most significant bit) of the encoded fixup determines 3428// whether it is dyld_chained_ptr_64_bind or dyld_chained_ptr_64_rebase. 3429bool IsBind =
Field(63, 1);
3436if (ImportOrdinal >= FixupTargets.size()) {
3439" has out-of range import ordinal " +
3440Twine(ImportOrdinal));
3459// The stride is 4 bytes for DYLD_CHAINED_PTR_64(_OFFSET). 3461 PageOffset += 4 * Next;
3464 findNextPageWithFixups();
3474return InfoSegIndex ==
Other.InfoSegIndex && PageIndex ==
Other.PageIndex &&
3475 PageOffset ==
Other.PageOffset;
3480 : E(E), O(O), Opcodes(Bytes),
Ptr(Bytes.begin()),
3481 PointerSize(
is64Bit ? 8 : 4) {}
3483void MachORebaseEntry::moveToFirst() {
3488void MachORebaseEntry::moveToEnd() {
3490 RemainingLoopCount = 0;
3496// If in the middle of some loop, move to next rebasing in loop. 3497 SegmentOffset += AdvanceAmount;
3498if (RemainingLoopCount) {
3499 --RemainingLoopCount;
3505// REBASE_OPCODE_DONE is only used for padding if we are not aligned to 3506// pointer size. Therefore it is possible to reach the end without ever 3507// having seen REBASE_OPCODE_DONE. 3508if (
Ptr == Opcodes.
end()) {
3513// Parse next opcode and set up next loop. 3519constchar *
error =
nullptr;
3528 RebaseType = ImmValue;
3530 *E =
malformedError(
"for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3531Twine((
int)RebaseType) +
" for opcode at: 0x" +
3538dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: " 3539 <<
"RebaseType=" << (
int) RebaseType <<
"\n");
3542 SegmentIndex = ImmValue;
3543 SegmentOffset = readULEB128(&
error);
3545 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3554 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3562dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3563 <<
"SegmentIndex=" << SegmentIndex <<
", " 3564 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3568 SegmentOffset += readULEB128(&
error);
3571" for opcode at: 0x" +
3580" for opcode at: 0x" +
3586dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: " 3587 <<
format(
"SegmentOffset=0x%06X",
3588 SegmentOffset) <<
"\n");
3591 SegmentOffset += ImmValue * PointerSize;
3602dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 3603 <<
format(
"SegmentOffset=0x%06X",
3604 SegmentOffset) <<
"\n");
3607 AdvanceAmount = PointerSize;
3611 RemainingLoopCount = ImmValue - 1;
3613 RemainingLoopCount = 0;
3615 PointerSize, Count, Skip);
3625dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 3626 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3627 <<
", AdvanceAmount=" << AdvanceAmount
3628 <<
", RemainingLoopCount=" << RemainingLoopCount
3632 AdvanceAmount = PointerSize;
3634 Count = readULEB128(&
error);
3643 RemainingLoopCount = Count - 1;
3645 RemainingLoopCount = 0;
3647 PointerSize, Count, Skip);
3657dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 3658 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3659 <<
", AdvanceAmount=" << AdvanceAmount
3660 <<
", RemainingLoopCount=" << RemainingLoopCount
3664 Skip = readULEB128(&
error);
3666 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3672 AdvanceAmount = Skip + PointerSize;
3674 RemainingLoopCount = 0;
3676 PointerSize, Count, Skip);
3678 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3686dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 3687 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3688 <<
", AdvanceAmount=" << AdvanceAmount
3689 <<
", RemainingLoopCount=" << RemainingLoopCount
3693 Count = readULEB128(&
error);
3695 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3703 RemainingLoopCount = Count - 1;
3705 RemainingLoopCount = 0;
3706 Skip = readULEB128(&
error);
3708 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3715 AdvanceAmount = Skip + PointerSize;
3718 PointerSize, Count, Skip);
3720 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3729dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 3730 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3731 <<
", AdvanceAmount=" << AdvanceAmount
3732 <<
", RemainingLoopCount=" << RemainingLoopCount
3749if (Ptr > Opcodes.
end())
3759switch (RebaseType) {
3770// For use with the SegIndex of a checked Mach-O Rebase entry 3771// to get the segment name. 3776// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3777// to get the section name. 3782// For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3783// to get the address. 3789#ifdef EXPENSIVE_CHECKS 3790assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
3792assert(Opcodes.
data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
3795 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
3796 (Done ==
Other.Done);
3802if (O->BindRebaseSectionTable ==
nullptr)
3803 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3805 Start.moveToFirst();
3819 : E(E), O(O), Opcodes(Bytes),
Ptr(Bytes.begin()),
3820 PointerSize(
is64Bit ? 8 : 4), TableKind(BK) {}
3822void MachOBindEntry::moveToFirst() {
3827void MachOBindEntry::moveToEnd() {
3829 RemainingLoopCount = 0;
3835// If in the middle of some loop, move to next binding in loop. 3836 SegmentOffset += AdvanceAmount;
3837if (RemainingLoopCount) {
3838 --RemainingLoopCount;
3844// BIND_OPCODE_DONE is only used for padding if we are not aligned to 3845// pointer size. Therefore it is possible to reach the end without ever 3846// having seen BIND_OPCODE_DONE. 3847if (
Ptr == Opcodes.
end()) {
3852// Parse next opcode and set up next loop. 3857 int8_t SignExtended;
3860constchar *
error =
nullptr;
3864// Lazying bindings have a DONE opcode between entries. Need to ignore 3865// it to advance to next entry. But need not if this is last entry. 3866bool NotLastEntry =
false;
3881 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in " 3882"weak bind table for opcode at: 0x" +
3888 LibraryOrdinalSet =
true;
3891"library ordinal: " +
3892Twine((
int)ImmValue) +
" (max " +
3894") for opcode at: 0x" +
3901dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 3902 <<
"Ordinal=" << Ordinal <<
"\n");
3906 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in " 3907"weak bind table for opcode at: 0x" +
3912 Ordinal = readULEB128(&
error);
3913 LibraryOrdinalSet =
true;
3923"library ordinal: " +
3924Twine((
int)Ordinal) +
" (max " +
3926") for opcode at: 0x" +
3933dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 3934 <<
"Ordinal=" << Ordinal <<
"\n");
3938 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in " 3939"weak bind table for opcode at: 0x" +
3946 Ordinal = SignExtended;
3948 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown " 3949"special ordinal: " +
3950Twine((
int)Ordinal) +
" for opcode at: 0x" +
3957 LibraryOrdinalSet =
true;
3960dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 3961 <<
"Ordinal=" << Ordinal <<
"\n");
3969if (
Ptr == Opcodes.
end()) {
3971"for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM " 3972"symbol name extends past opcodes for opcode at: 0x" +
3977 SymbolName =
StringRef(
reinterpret_cast<constchar*
>(SymStart),
3982dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 3983 <<
"SymbolName=" << SymbolName <<
"\n");
3990 BindType = ImmValue;
3992 *E =
malformedError(
"for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3993Twine((
int)ImmValue) +
" for opcode at: 0x" +
4000dbgs() <<
"BIND_OPCODE_SET_TYPE_IMM: " 4001 <<
"BindType=" << (
int)BindType <<
"\n");
4004 Addend = readSLEB128(&
error);
4007" for opcode at: 0x" +
4014dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: " 4015 <<
"Addend=" << Addend <<
"\n");
4018 SegmentIndex = ImmValue;
4019 SegmentOffset = readULEB128(&
error);
4021 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4030 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4038dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 4039 <<
"SegmentIndex=" << SegmentIndex <<
", " 4040 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4044 SegmentOffset += readULEB128(&
error);
4047" for opcode at: 0x" +
4056" for opcode at: 0x" +
4062dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: " 4063 <<
format(
"SegmentOffset=0x%06X",
4064 SegmentOffset) <<
"\n");
4067 AdvanceAmount = PointerSize;
4068 RemainingLoopCount = 0;
4073" for opcode at: 0x" +
4080"for BIND_OPCODE_DO_BIND missing preceding " 4081"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4086if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4089"BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4095dbgs() <<
"BIND_OPCODE_DO_BIND: " 4096 <<
format(
"SegmentOffset=0x%06X",
4097 SegmentOffset) <<
"\n");
4101 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in " 4102"lazy bind table for opcode at: 0x" +
4118"for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 4119"preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode " 4125if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4127"for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 4128"preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4133 AdvanceAmount = readULEB128(&
error) + PointerSize;
4141// Note, this is not really an error until the next bind but make no sense 4142// for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another 4145 AdvanceAmount, PointerSize);
4147 *E =
malformedError(
"for BIND_OPCODE_ADD_ADDR_ULEB (after adding " 4154 RemainingLoopCount = 0;
4157dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 4158 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4159 <<
", AdvanceAmount=" << AdvanceAmount
4160 <<
", RemainingLoopCount=" << RemainingLoopCount
4165 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not " 4166"allowed in lazy bind table for opcode at: 0x" +
4173"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 4174"missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 4180if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4182"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 4183"missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 4189 AdvanceAmount = ImmValue * PointerSize + PointerSize;
4190 RemainingLoopCount = 0;
4192 AdvanceAmount, PointerSize);
4194 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4202 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 4203 <<
format(
"SegmentOffset=0x%06X", SegmentOffset) <<
"\n");
4207 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not " 4208"allowed in lazy bind table for opcode at: 0x" +
4213 Count = readULEB128(&
error);
4215 RemainingLoopCount = Count - 1;
4217 RemainingLoopCount = 0;
4219 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 4226 Skip = readULEB128(&
error);
4227 AdvanceAmount = Skip + PointerSize;
4229 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 4238"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 4239"missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 4245if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4247"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 4248"missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 4255 PointerSize, Count, Skip);
4258malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4266dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 4267 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4268 <<
", AdvanceAmount=" << AdvanceAmount
4269 <<
", RemainingLoopCount=" << RemainingLoopCount
4286if (Ptr > Opcodes.
end())
4291int64_t MachOBindEntry::readSLEB128(
constchar **
error) {
4295if (Ptr > Opcodes.
end())
4324// For use with the SegIndex of a checked Mach-O Bind entry 4325// to get the segment name. 4330// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 4331// to get the section name. 4336// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 4337// to get the address. 4343#ifdef EXPENSIVE_CHECKS 4344assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
4346assert(Opcodes.
data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
4349 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
4350 (Done ==
Other.Done);
4353// Build table of sections so SegIndex/SegOffset pairs can be translated. 4364Info.SectionName = *NameOrErr;
4365Info.Address = Section.getAddress();
4366Info.Size = Section.getSize();
4369if (
Info.SegmentName != CurSegName) {
4371 CurSegName =
Info.SegmentName;
4372 CurSegAddress =
Info.Address;
4374Info.SegmentIndex = CurSegIndex - 1;
4375Info.OffsetInSegment =
Info.Address - CurSegAddress;
4376Info.SegmentStartAddress = CurSegAddress;
4379 MaxSegIndex = CurSegIndex;
4382// For use with a SegIndex, SegOffset, and PointerSize triple in 4383// MachOBindEntry::moveNext() to validate a MachOBindEntry or MachORebaseEntry. 4385// Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists 4386// that fully contains a pointer at that location. Multiple fixups in a bind 4387// (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can 4388// be tested via the Count and Skip parameters. 4395return"missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4396if (SegIndex >= MaxSegIndex)
4397return"bad segIndex (too large)";
4398for (
uint64_t i = 0; i < Count; ++i) {
4399uint64_t Start = SegOffset + i * (PointerSize + Skip);
4402for (
const SectionInfo &SI : Sections) {
4403if (SI.SegmentIndex != SegIndex)
4405if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4406if (
End <= SI.OffsetInSegment + SI.Size) {
4411return"bad offset, extends beyond section boundary";
4415return"bad offset, not in section";
4420// For use with the SegIndex of a checked Mach-O Bind or Rebase entry 4421// to get the segment name. 4423for (
const SectionInfo &SI : Sections) {
4424if (SI.SegmentIndex == SegIndex)
4425return SI.SegmentName;
4430// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4431// to get the SectionInfo. 4432const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4433 int32_t SegIndex,
uint64_t SegOffset) {
4434for (
const SectionInfo &SI : Sections) {
4435if (SI.SegmentIndex != SegIndex)
4437if (SI.OffsetInSegment > SegOffset)
4439if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4446// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4447// entry to get the section name. 4450return findSection(SegIndex, SegOffset).SectionName;
4453// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4454// entry to get the address. 4456const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4457return SI.SegmentStartAddress + OffsetInSeg;
4464if (O->BindRebaseSectionTable ==
nullptr)
4465 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4467 Start.moveToFirst();
4491if (BindRebaseSectionTable ==
nullptr)
4492 BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(
this);
4495 Start.moveToFirst();
4505return LoadCommands.
begin();
4510return LoadCommands.
end();
4526assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4527const section_base *
Base =
4528reinterpret_cast<constsection_base *
>(Sections[Sec.
d.
a]);
4534assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4535const section_base *
Base =
4536reinterpret_cast<constsection_base *
>(Sections[Sec.
d.
a]);
4574return (RE.
r_word0 >> 24) & 0xf;
4615 DRI.
d.
a = SecNum - 1;
4620assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4621return getStruct<MachO::section>(*
this, Sections[DRI.
d.
a]);
4625assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4626return getStruct<MachO::section_64>(*
this, Sections[DRI.
d.
a]);
4630unsigned Index)
const{
4632return getStruct<MachO::section>(*
this, Sec);
4636unsigned Index)
const{
4638return getStruct<MachO::section_64>(*
this, Sec);
4643constchar *
P =
reinterpret_cast<constchar *
>(DRI.
p);
4644return getStruct<MachO::nlist>(*
this,
P);
4649constchar *
P =
reinterpret_cast<constchar *
>(DRI.
p);
4650return getStruct<MachO::nlist_64>(*
this,
P);
4655return getStruct<MachO::linkedit_data_command>(*
this, L.Ptr);
4660return getStruct<MachO::segment_command>(*
this, L.Ptr);
4665return getStruct<MachO::segment_command_64>(*
this, L.Ptr);
4670return getStruct<MachO::linker_option_command>(*
this, L.Ptr);
4675return getStruct<MachO::version_min_command>(*
this, L.Ptr);
4680return getStruct<MachO::note_command>(*
this, L.Ptr);
4685return getStruct<MachO::build_version_command>(*
this, L.Ptr);
4690return getStruct<MachO::build_tool_version>(*
this, BuildTools[index]);
4695return getStruct<MachO::dylib_command>(*
this, L.Ptr);
4700return getStruct<MachO::dyld_info_command>(*
this, L.Ptr);
4705return getStruct<MachO::dylinker_command>(*
this, L.Ptr);
4710return getStruct<MachO::uuid_command>(*
this, L.Ptr);
4715return getStruct<MachO::rpath_command>(*
this, L.Ptr);
4720return getStruct<MachO::source_version_command>(*
this, L.Ptr);
4725return getStruct<MachO::entry_point_command>(*
this, L.Ptr);
4730return getStruct<MachO::encryption_info_command>(*
this, L.Ptr);
4735return getStruct<MachO::encryption_info_command_64>(*
this, L.Ptr);
4740return getStruct<MachO::sub_framework_command>(*
this, L.Ptr);
4745return getStruct<MachO::sub_umbrella_command>(*
this, L.Ptr);
4750return getStruct<MachO::sub_library_command>(*
this, L.Ptr);
4755return getStruct<MachO::sub_client_command>(*
this, L.Ptr);
4760return getStruct<MachO::routines_command>(*
this, L.Ptr);
4765return getStruct<MachO::routines_command_64>(*
this, L.Ptr);
4770return getStruct<MachO::thread_command>(*
this, L.Ptr);
4775return getStruct<MachO::fileset_entry_command>(*
this, L.Ptr);
4794Offset = DysymtabLoadCmd.
extreloff;
// Offset to the external relocations 4801return getStruct<MachO::any_relocation_info>(
4802 *
this,
reinterpret_cast<constchar *
>(
P));
4807constchar *
P =
reinterpret_cast<constchar *
>(Rel.
p);
4808return getStruct<MachO::data_in_code_entry>(*
this,
P);
4822unsigned Index)
const{
4829unsigned Index)
const{
4831return getStruct<MachO::data_in_code_entry>(*
this,
getPtr(*
this,
Offset));
4836return getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
4838// If there is no SymtabLoadCmd return a load command with zero'ed fields. 4840 Cmd.
cmd = MachO::LC_SYMTAB;
4851return getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
4853// If there is no DysymtabLoadCmd return a load command with zero'ed fields. 4855 Cmd.
cmd = MachO::LC_DYSYMTAB;
4880if (DataInCodeLoadCmd)
4881return getStruct<MachO::linkedit_data_command>(*
this, DataInCodeLoadCmd);
4883// If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 4885 Cmd.
cmd = MachO::LC_DATA_IN_CODE;
4894if (LinkOptHintsLoadCmd)
4895return getStruct<MachO::linkedit_data_command>(*
this, LinkOptHintsLoadCmd);
4897// If there is no LinkOptHintsLoadCmd return a load command with zero'ed 4900 Cmd.
cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4908if (!DyldInfoLoadCmd)
4912 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4922if (!DyldInfoLoadCmd)
4926 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4936if (!DyldInfoLoadCmd)
4940 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4950if (!DyldInfoLoadCmd)
4954 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4964if (!DyldInfoLoadCmd)
4968 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4979// Load the dyld chained fixups load command. 4980if (!DyldChainedFixupsLoadCmd)
4982auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
4983 *
this, DyldChainedFixupsLoadCmd);
4984if (!DyldChainedFixupsOrErr)
4985return DyldChainedFixupsOrErr.takeError();
4987 *DyldChainedFixupsOrErr;
4989// If the load command is present but the data offset has been zeroed out, 4990// as is the case for dylib stubs, return std::nullopt (no error). 4991if (!DyldChainedFixups.
dataoff)
4993return DyldChainedFixups;
5000return CFOrErr.takeError();
5001if (!CFOrErr->has_value())
5009// Load the dyld chained fixups header. 5010constchar *CFHeaderPtr =
getPtr(*
this, CFHeaderOffset);
5012 getStructOrErr<MachO::dyld_chained_fixups_header>(*
this, CFHeaderPtr);
5014return CFHeaderOrErr.takeError();
5017// Reject unknown chained fixup formats. 5023Twine(
"bad chained fixups: unknown imports format: ") +
5026// Validate the image format. 5028// Load the image starts. 5033" overlaps with chained fixups header");
5035uint32_t EndOffset = CFHeaderOffset + CFSize;
5039Twine(CFImageStartsOffset +
5041" extends past end " +
Twine(EndOffset));
5051return CFOrErr.takeError();
5053 std::vector<ChainedFixupsSegment> Segments;
5054if (!CFOrErr->has_value())
5055return std::make_pair(0, Segments);
5061return HeaderOrErr.takeError();
5062if (!HeaderOrErr->has_value())
5063return std::make_pair(0, Segments);
5066constchar *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5068auto ImageStartsOrErr = getStructOrErr<MachO::dyld_chained_starts_in_image>(
5069 *
this, Contents +
Header.starts_offset);
5070if (!ImageStartsOrErr)
5071return ImageStartsOrErr.takeError();
5074constchar *SegOffsPtr =
5075 Contents +
Header.starts_offset +
5077constchar *SegOffsEnd =
5079if (SegOffsEnd > Contents + DyldChainedFixups.
datasize)
5081"bad chained fixups: seg_info_offset extends past end");
5083constchar *LastSegEnd =
nullptr;
5086 getStructOrErr<uint32_t>(*
this, SegOffsPtr +
I *
sizeof(
uint32_t));
5088return OffOrErr.takeError();
5089// seg_info_offset == 0 means there is no associated starts_in_segment 5096" at offset " +
Twine(*OffOrErr) + Message);
5099constchar *SegPtr = Contents +
Header.starts_offset + *OffOrErr;
5100if (LastSegEnd && SegPtr < LastSegEnd)
5101returnFail(
" overlaps with previous segment info");
5104 getStructOrErr<MachO::dyld_chained_starts_in_segment>(*
this, SegPtr);
5106return SegOrErr.takeError();
5109 LastSegEnd = SegPtr + Seg.
size;
5113constchar *PageStart =
5116if (PageEnd > SegPtr + Seg.
size)
5117returnFail(
" : page_starts extend past seg_info size");
5119// FIXME: This does not account for multiple offsets on a single page 5120// (DYLD_CHAINED_PTR_START_MULTI; 32-bit only). 5121 std::vector<uint16_t> PageStarts;
5122for (
size_t PageIdx = 0; PageIdx < Seg.
page_count; ++PageIdx) {
5127 PageStarts.push_back(Start);
5130 Segments.emplace_back(
I, *OffOrErr, Seg, std::move(PageStarts));
5133return std::make_pair(ImageStarts.
seg_count, Segments);
5136// The special library ordinals have a negative value, but they are encoded in 5137// an unsigned bitfield, so we need to sign extend the value. 5142return SignExtend32<sizeof(T) * CHAR_BIT>(
Value);
5146template <
typename T,
unsigned N>
5148 std::array<T, N> RawValue;
5149 memcpy(RawValue.data(),
Ptr,
N *
sizeof(
T));
5151for (
auto &Element : RawValue)
5160return CFOrErr.takeError();
5162 std::vector<ChainedFixupTarget> Targets;
5163if (!CFOrErr->has_value())
5170return CFHeaderOrErr.takeError();
5171if (!(*CFHeaderOrErr))
5175size_t ImportSize = 0;
5183returnmalformedError(
"bad chained fixups: unknown imports format: " +
5186constchar *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5187constchar *Imports = Contents +
Header.imports_offset;
5188size_t ImportsEndOffset =
5189Header.imports_offset + ImportSize *
Header.imports_count;
5190constchar *ImportsEnd = Contents + ImportsEndOffset;
5191constchar *Symbols = Contents +
Header.symbols_offset;
5192constchar *SymbolsEnd = Contents + DyldChainedFixups.
datasize;
5194if (ImportsEnd > Symbols)
5196Twine(ImportsEndOffset) +
" overlaps with symbols");
5198// We use bit manipulation to extract data from the bitfields. This is correct 5199// for both LE and BE hosts, but we assume that the object is little-endian. 5201returncreateError(
"parsing big-endian chained fixups is not implemented");
5202for (
constchar *ImportPtr = Imports; ImportPtr < ImportsEnd;
5203 ImportPtr += ImportSize) {
5210auto RawValue = getArray<uint32_t, 1>(*
this, ImportPtr);
5212 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5213 WeakImport = (RawValue[0] >> 8) & 1;
5214 NameOffset = RawValue[0] >> 9;
5219auto RawValue = getArray<uint32_t, 2>(*
this, ImportPtr);
5221 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5222 WeakImport = (RawValue[0] >> 8) & 1;
5223 NameOffset = RawValue[0] >> 9;
5224 Addend = bit_cast<int32_t>(RawValue[1]);
5226static_assert(2 *
sizeof(
uint64_t) ==
5228auto RawValue = getArray<uint64_t, 2>(*
this, ImportPtr);
5230 LibOrdinal = getEncodedOrdinal<uint16_t>(RawValue[0] & 0xFFFF);
5231 NameOffset = (RawValue[0] >> 16) & 1;
5232 WeakImport = RawValue[0] >> 17;
5233 Addend = RawValue[1];
5238constchar *Str = Symbols + NameOffset;
5239if (Str >= SymbolsEnd)
5241Twine(NameOffset) +
" extends past end " +
5243 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5246return std::move(Targets);
5250if (!DyldExportsTrieLoadCmd)
5253auto DyldExportsTrieOrError = getStructOrErr<MachO::linkedit_data_command>(
5254 *
this, DyldExportsTrieLoadCmd);
5255if (!DyldExportsTrieOrError)
5264if (!FuncStartsLoadCmd)
5268 getStructOrErr<MachO::linkedit_data_command>(*
this, FuncStartsLoadCmd);
5275return std::move(FunctionStarts);
5281// Returning a pointer is fine as uuid doesn't need endian swapping. 5312/// Create a MachOObjectFile instance from a given buffer. 5314/// \param Buffer Memory buffer containing the MachO binary data. 5315/// \param UniversalCputype CPU type when the MachO part of a universal binary. 5316/// \param UniversalIndex Index of the MachO within a universal binary. 5317/// \param MachOFilesetEntryOffset Offset of the MachO entry in a fileset MachO. 5318/// \returns A std::unique_ptr to a MachOObjectFile instance on success. 5321size_t MachOFilesetEntryOffset) {
5323if (Magic ==
"\xFE\xED\xFA\xCE")
5325 UniversalIndex, MachOFilesetEntryOffset);
5326if (Magic ==
"\xCE\xFA\xED\xFE")
5328 UniversalIndex, MachOFilesetEntryOffset);
5329if (Magic ==
"\xFE\xED\xFA\xCF")
5331 UniversalIndex, MachOFilesetEntryOffset);
5332if (Magic ==
"\xCF\xFA\xED\xFE")
5334 UniversalIndex, MachOFilesetEntryOffset);
5335return make_error<GenericBinaryError>(
"Unrecognized MachO magic number",
5341 .
Case(
"debug_str_offs",
"debug_str_offsets")
5348// Normalize input path. This is necessary to accept `bundle.dSYM/`. 5352return std::vector<std::string>();
5358 EC,
"%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5359 Path.str().c_str());
5363 std::vector<std::string> ObjectPaths;
5365 Dir != DirEnd && !EC; Dir.increment(EC)) {
5374 ObjectPaths.push_back(ObjectPath.
str());
5381if (ObjectPaths.empty())
5383"%s: no objects found in dSYM bundle",
5384 Path.str().c_str());
5391#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) \ 5392 .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND) 5395#include "llvm/BinaryFormat/Swift.def" 5397#undef HANDLE_SWIFT_SECTION for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
#define offsetof(TYPE, MEMBER)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
static Error parseBuildVersionCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &BuildTools, uint32_t LoadCommandIndex)
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
static const char * getPtr(const MachOObjectFile &O, size_t Offset, size_t MachOFilesetEntryOffset=0)
static Error parseSegmentLoadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &Sections, bool &IsPageZeroSegment, uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders, std::list< MachOElement > &Elements)
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static Error checkSubCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName, size_t SizeOfCmd, const char *CmdStructName, uint32_t PathOffset, const char *PathFieldName)
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static T getStruct(const MachOObjectFile &O, const char *P)
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static std::array< T, N > getArray(const MachOObjectFile &O, const void *Ptr)
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements, const char *ElementName)
static Error malformedError(const Twine &Msg)
static bool isLoadCommandObsolete(uint32_t cmd)
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
static int getEncodedOrdinal(T Value)
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
static StringRef parseSegmentOrSectionName(const char *P)
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
static unsigned getCPUType(const MachOObjectFile &O)
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Error checkNoteCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, std::list< MachOElement > &Elements)
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
static unsigned getCPUSubType(const MachOObjectFile &O)
static Error checkEncryptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, uint64_t cryptoff, uint64_t cryptsize, const char **LoadCmd, const char *CmdName)
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
static Error malformedError(Twine Msg)
OptimizedStructLayoutField Field
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
static StringRef substr(StringRef Str, uint64_t Len)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool is64Bit(const char *name)
This file implements the C++20 <bit> header.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
StringRef getBuffer() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
bool equals(StringRef RHS) const
Check for string equality.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
constexpr size_t size() const
Returns the byte size of the table.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
LLVM Value Representation.
A range adaptor for a pair of iterators.
StringRef getData() const
unsigned int getType() const
bool isLittleEndian() const
static unsigned int getMachOType(bool isLE, bool is64Bits)
StringRef segmentName(int32_t SegIndex)
StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)
BindRebaseSegInfo(const MachOObjectFile *Obj)
const char * checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0)
uint64_t address(uint32_t SegIndex, uint64_t SegOffset)
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...
ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Trie)
bool operator==(const ExportEntry &) const
StringRef otherName() const
uint32_t nodeOffset() const
MachOAbstractFixupEntry is an abstract class representing a fixup in a MH_DYLDLINK file.
StringRef sectionName() const
uint64_t segmentAddress() const
int32_t segmentIndex() const
StringRef typeName() const
MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O)
uint64_t textAddress() const
StringRef symbolName() const
StringRef segmentName() const
const MachOObjectFile * O
uint64_t segmentOffset() const
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
bool operator==(const MachOBindEntry &) const
StringRef symbolName() const
StringRef sectionName() const
MachOBindEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
StringRef segmentName() const
uint64_t segmentOffset() const
int32_t segmentIndex() const
StringRef typeName() const
bool operator==(const MachOChainedFixupEntry &) const
MachOChainedFixupEntry(Error *Err, const MachOObjectFile *O, bool Parse)
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
void moveSectionNext(DataRefImpl &Sec) const override
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
Triple::ArchType getArch() const override
MachO::mach_header_64 Header64
bool isSectionData(DataRefImpl Sec) const override
const MachO::mach_header_64 & getHeader64() const
Expected< std::vector< ChainedFixupTarget > > getDyldChainedFixupTargets() const
uint64_t getSectionAlignment(DataRefImpl Sec) const override
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Expected< SectionRef > getSection(unsigned SectionIndex) const
iterator_range< rebase_iterator > rebaseTable(Error &Err)
For use iterating over all rebase table entries.
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
load_command_iterator begin_load_commands() const
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
StringRef getFileFormatName() const override
dice_iterator begin_dices() const
basic_symbol_iterator symbol_begin() const override
Expected< std::optional< MachO::linkedit_data_command > > getChainedFixupsLoadCommand() const
iterator_range< export_iterator > exports(Error &Err) const
For use iterating over all exported symbols.
uint64_t getSymbolIndex(DataRefImpl Symb) const
MachO::build_version_command getBuildVersionLoadCommand(const LoadCommandInfo &L) const
section_iterator section_end() const override
MachO::build_tool_version getBuildToolVersion(unsigned index) const
MachO::linkedit_data_command getDataInCodeLoadCommand() const
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
unsigned getSymbolSectionID(SymbolRef Symb) const
static Expected< std::vector< std::string > > findDsymObjectMembers(StringRef Path)
If the input path is a .dSYM bundle (as created by the dsymutil tool), return the paths to the object...
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
uint32_t getLibraryCount() const
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
const char * RebaseEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const
uint64_t getRelocationOffset(DataRefImpl Rel) const override
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
void moveSymbolNext(DataRefImpl &Symb) const override
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
MachO::dysymtab_command getDysymtabLoadCommand() const
iterator_range< bind_iterator > bindTable(Error &Err)
For use iterating over all bind table entries.
MachO::mach_header Header
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
MachO::section_64 getSection64(DataRefImpl DRI) const
MachO::fileset_entry_command getFilesetEntryLoadCommand(const LoadCommandInfo &L) const
MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
ArrayRef< uint8_t > getSectionContents(uint32_t Offset, uint64_t Size) const
const char * BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const
section_iterator section_begin() const override
Error checkSymbolTable() const
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
bool isDebugSection(DataRefImpl Sec) const override
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
unsigned getSectionType(SectionRef Sec) const
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
dice_iterator end_dices() const
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
SmallVector< uint64_t > getFunctionStarts() const
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
ArrayRef< uint8_t > getDyldExportsTrie() const
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
bool isSectionBSS(DataRefImpl Sec) const override
Expected< std::pair< size_t, std::vector< ChainedFixupsSegment > > > getChainedFixupsSegments() const
bool isSectionVirtual(DataRefImpl Sec) const override
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
symbol_iterator getSymbolByIndex(unsigned Index) const
static Triple getHostArch()
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
const MachO::mach_header & getHeader() const
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
iterator_range< bind_iterator > weakBindTable(Error &Err)
For use iterating over all weak bind table entries.
static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch)
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
iterator_range< load_command_iterator > load_commands() const
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
MachO::symtab_command getSymtabLoadCommand() const
Triple getArchTriple(const char **McpuDefault=nullptr) const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getUuid() const
uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the address.
bool is64Bit() const override
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
uint64_t getRelocationType(DataRefImpl Rel) const override
StringRef BindRebaseSegmentName(int32_t SegIndex) const
For use with the SegIndex of a checked Mach-O Bind or Rebase entry to get the segment name.
relocation_iterator extrel_begin() const
void moveRelocationNext(DataRefImpl &Rel) const override
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
basic_symbol_iterator symbol_end() const override
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
bool isSectionStripped(DataRefImpl Sec) const override
When dsymutil generates the companion file, it strips all unnecessary sections (e....
uint64_t getSectionIndex(DataRefImpl Sec) const override
iterator_range< fixup_iterator > fixupTable(Error &Err)
For iterating over all chained fixups.
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the section ...
iterator_range< bind_iterator > lazyBindTable(Error &Err)
For use iterating over all lazy bind table entries.
load_command_iterator end_load_commands() const
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
uint64_t getSectionAddress(DataRefImpl Sec) const override
bool hasPageZeroSegment() const
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
uint8_t getRelocationLength(DataRefImpl Rel) const
llvm::binaryformat::Swift5ReflectionSectionKind mapReflectionSectionNameToEnumValue(StringRef SectionName) const override
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
static bool isValidArch(StringRef ArchFlag)
bool isSectionText(DataRefImpl Sec) const override
bool isSectionCompressed(DataRefImpl Sec) const override
static ArrayRef< StringRef > getValidArchs()
bool isSectionBitcode(DataRefImpl Sec) const override
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
relocation_iterator locrel_begin() const
Expected< std::optional< MachO::dyld_chained_fixups_header > > getChainedFixupsHeader() const
If the optional is std::nullopt, no header was found, but the object was well-formed.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
StringRef getStringTableData() const
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
uint64_t getNValue(DataRefImpl Sym) const
ArrayRef< uint8_t > getSegmentContents(StringRef SegmentName) const
Return the raw contents of an entire segment.
section_iterator getRelocationSection(DataRefImpl Rel) const
unsigned getSectionID(SectionRef Sec) const
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
size_t getMachOFilesetEntryOffset() const
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
uint64_t getSectionSize(DataRefImpl Sec) const override
relocation_iterator extrel_end() const
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
relocation_iterator locrel_end() const
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
int32_t segmentIndex() const
StringRef segmentName() const
MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)
bool operator==(const MachORebaseEntry &) const
StringRef sectionName() const
uint64_t segmentOffset() const
StringRef typeName() const
This class is the base class for all object file types.
friend class RelocationRef
static Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)
Create a MachOObjectFile instance from a given buffer.
section_iterator_range sections() const
symbol_iterator_range symbols() const
Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
bool isData() const
Whether this section contains data, not instructions.
bool isBSS() const
Whether this section contains BSS uninitialized data.
This is a value type class that represents a single symbol in the list of symbols in the object file.
directory_iterator - Iterates through the entries in path.
Represents the result of a call to sys::fs::status().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
const uint32_t x86_FLOAT_STATE_COUNT
@ DYLD_CHAINED_IMPORT_ADDEND
@ DYLD_CHAINED_IMPORT_ADDEND64
const uint32_t ARM_THREAD_STATE64_COUNT
@ EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
@ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
@ EXPORT_SYMBOL_FLAGS_KIND_REGULAR
@ BIND_TYPE_TEXT_ABSOLUTE32
@ S_ATTR_PURE_INSTRUCTIONS
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
const uint32_t x86_EXCEPTION_STATE_COUNT
@ REBASE_TYPE_TEXT_ABSOLUTE32
@ REBASE_TYPE_TEXT_PCREL32
@ S_GB_ZEROFILL
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
@ S_THREAD_LOCAL_ZEROFILL
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
@ S_ZEROFILL
S_ZEROFILL - Zero fill on demand section.
@ BIND_SPECIAL_DYLIB_WEAK_LOOKUP
@ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
@ BIND_SPECIAL_DYLIB_FLAT_LOOKUP
@ DYLD_CHAINED_PTR_START_NONE
uint8_t GET_COMM_ALIGN(uint16_t n_desc)
void swapStruct(fat_header &mh)
const uint32_t x86_THREAD_STATE32_COUNT
@ EXPORT_SYMBOL_FLAGS_REEXPORT
@ EXPORT_SYMBOL_FLAGS_KIND_MASK
@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
@ CPU_SUBTYPE_POWERPC_ALL
@ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
@ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
@ BIND_OPCODE_SET_ADDEND_SLEB
@ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
@ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
@ BIND_OPCODE_ADD_ADDR_ULEB
@ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
@ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
@ BIND_OPCODE_SET_TYPE_IMM
@ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
@ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
const uint32_t PPC_THREAD_STATE_COUNT
const uint32_t ARM_THREAD_STATE_COUNT
@ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
@ REBASE_OPCODE_DO_REBASE_IMM_TIMES
@ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES
@ REBASE_OPCODE_ADD_ADDR_ULEB
@ REBASE_OPCODE_SET_TYPE_IMM
@ REBASE_OPCODE_ADD_ADDR_IMM_SCALED
const uint32_t x86_THREAD_STATE_COUNT
@ CPU_SUBTYPE_ARM64_32_V8
@ GENERIC_RELOC_LOCAL_SECTDIFF
@ ARM_RELOC_LOCAL_SECTDIFF
@ ARM_RELOC_HALF_SECTDIFF
@ X86_64_RELOC_SUBTRACTOR
uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
@ DYLD_CHAINED_PTR_64_OFFSET
const uint32_t x86_EXCEPTION_STATE64_COUNT
const uint32_t x86_THREAD_STATE64_COUNT
@ BIND_SYMBOL_FLAGS_WEAK_IMPORT
@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
constexpr size_t SymbolTableEntrySize
Swift5ReflectionSectionKind
Error createError(const Twine &Err)
content_iterator< ExportEntry > export_iterator
content_iterator< MachOChainedFixupEntry > fixup_iterator
content_iterator< DiceRef > dice_iterator
content_iterator< SectionRef > section_iterator
content_iterator< MachOBindEntry > bind_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
content_iterator< MachORebaseEntry > rebase_iterator
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
bool is_directory(const basic_file_status &status)
Does status represent a directory?
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
static const bool IsLittleEndianHost
void swapByteOrder(T &Value)
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ no_such_file_or_directory
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Structs for dyld chained fixups.
uint32_t imports_format
DYLD_CHAINED_IMPORT*.
uint32_t starts_offset
Offset of dyld_chained_starts_in_image.
dyld_chained_starts_in_image is embedded in LC_DYLD_CHAINED_FIXUPS payload.
uint16_t page_count
Length of the page_start array.
uint16_t page_size
Page size in bytes (0x1000 or 0x4000)
uint16_t pointer_format
DYLD_CHAINED_PTR*.
uint32_t size
Size of this, including chain_starts entries.
ChainedFixupTarget holds all the information about an external symbol necessary to bind this binary t...
MachO::dyld_chained_starts_in_segment Header
std::vector< uint16_t > PageStarts
struct llvm::object::DataRefImpl::@370 d