49#include <system_error>
66 object_error::parse_failed);
73 if (
P < O.getData().begin() ||
P +
sizeof(
T) > O.getData().end())
77 memcpy(&Cmd,
P,
sizeof(
T));
86 if (
P < O.getData().begin() ||
P +
sizeof(
T) > O.getData().end())
90 memcpy(&Cmd,
P,
sizeof(
T));
101 bool Is64 = O.is64Bit();
107 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
108 return reinterpret_cast<const char*
>(SectionAddr);
112 size_t MachOFilesetEntryOffset = 0) {
114 MachOFilesetEntryOffset <= O.getData().size());
115 return O.getData().data() +
Offset + MachOFilesetEntryOffset;
120 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
133 return O.getHeader().cputype;
137 return O.getHeader().cpusubtype &
~MachO::CPU_SUBTYPE_MASK;
152 if (O.isLittleEndian())
164 if (O.isLittleEndian())
176 if (O.isLittleEndian())
195 assert(Ptr <= Obj.getData().end() &&
"Start must be before end");
196 if (CmdOrErr->cmdsize > (
uintptr_t)(Obj.getData().end() - Ptr))
198 " extends past end of file");
199 if (CmdOrErr->cmdsize < 8)
201 " with size less than 8 bytes");
212 return malformedError(
"load command 0 extends past the end all load "
213 "commands in the file");
215 Obj,
getPtr(Obj, HeaderSize, Obj.getMachOFilesetEntryOffset()), 0);
224 Obj.getData().data() + Obj.getMachOFilesetEntryOffset() + HeaderSize +
225 Obj.getHeader().sizeofcmds)
227 " extends past the end all load commands in the file");
234 if (
sizeof(
T) > Obj.getData().size()) {
235 Err =
malformedError(
"the mach header extends past the end of the "
240 Obj,
getPtr(Obj, 0, Obj.getMachOFilesetEntryOffset())))
241 Header = *HeaderOrErr;
243 Err = HeaderOrErr.takeError();
259 for (
auto it = Elements.begin(); it != Elements.end(); ++it) {
265 " with a size of " +
Twine(
Size) +
", overlaps " +
266 E.Name +
" at offset " +
Twine(
E.Offset) +
" with "
267 "a size of " +
Twine(
E.Size));
270 if (nt != Elements.end()) {
285template <
typename Segment,
typename Section>
290 std::list<MachOElement> &Elements) {
291 const unsigned SegmentLoadSize =
sizeof(Segment);
292 if (
Load.C.cmdsize < SegmentLoadSize)
294 " " + CmdName +
" cmdsize too small");
296 Segment S = SegOrErr.get();
297 const unsigned SectionSize =
sizeof(Section);
298 uint64_t FileSize = Obj.getData().size();
299 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
300 S.nsects * SectionSize >
Load.C.cmdsize - SegmentLoadSize)
302 " inconsistent cmdsize in " + CmdName +
303 " for the number of sections");
304 for (
unsigned J = 0; J < S.nsects; ++J) {
309 return SectionOrErr.takeError();
310 Section s = SectionOrErr.get();
317 CmdName +
" command " +
Twine(LoadCommandIndex) +
318 " extends past the end of the file");
323 s.offset < SizeOfHeaders && s.size != 0)
325 CmdName +
" command " +
Twine(LoadCommandIndex) +
326 " not past the headers of the file");
334 return malformedError(
"offset field plus size field of section " +
335 Twine(J) +
" in " + CmdName +
" command " +
336 Twine(LoadCommandIndex) +
337 " extends past the end of the file");
344 Twine(J) +
" in " + CmdName +
" command " +
345 Twine(LoadCommandIndex) +
346 " greater than the segment");
351 CmdName +
" command " +
Twine(LoadCommandIndex) +
352 " less than the segment's vmaddr");
357 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
359 " in " + CmdName +
" command " +
360 Twine(LoadCommandIndex) +
361 " greater than than "
362 "the segment's vmaddr plus vmsize");
370 if (s.reloff > FileSize)
372 CmdName +
" command " +
Twine(LoadCommandIndex) +
373 " extends past the end of the file");
377 if (BigSize > FileSize)
378 return malformedError(
"reloff field plus nreloc field times sizeof("
379 "struct relocation_info) of section " +
380 Twine(J) +
" in " + CmdName +
" command " +
381 Twine(LoadCommandIndex) +
382 " extends past the end of the file");
386 "section relocation entries"))
389 if (S.fileoff > FileSize)
391 " fileoff field in " + CmdName +
392 " extends past the end of the file");
394 BigSize += S.filesize;
395 if (BigSize > FileSize)
397 " fileoff field plus filesize field in " +
398 CmdName +
" extends past the end of the file");
399 if (S.vmsize != 0 && S.filesize > S.vmsize)
401 " filesize field in " + CmdName +
402 " greater than vmsize field");
403 IsPageZeroSegment |=
StringRef(
"__PAGEZERO") == S.segname;
405 return SegOrErr.takeError();
413 const char **SymtabLoadCmd,
414 std::list<MachOElement> &Elements) {
417 " LC_SYMTAB cmdsize too small");
418 if (*SymtabLoadCmd !=
nullptr)
422 return SymtabOrErr.takeError();
426 " has incorrect cmdsize");
427 uint64_t FileSize = Obj.getData().size();
428 if (Symtab.
symoff > FileSize)
430 Twine(LoadCommandIndex) +
" extends past the end "
433 const char *struct_nlist_name;
436 struct_nlist_name =
"struct nlist_64";
439 struct_nlist_name =
"struct nlist";
443 if (BigSize > FileSize)
444 return malformedError(
"symoff field plus nsyms field times sizeof(" +
445 Twine(struct_nlist_name) +
") of LC_SYMTAB command " +
446 Twine(LoadCommandIndex) +
" extends past the end "
451 if (Symtab.
stroff > FileSize)
453 Twine(LoadCommandIndex) +
" extends past the end "
457 if (BigSize > FileSize)
458 return malformedError(
"stroff field plus strsize field of LC_SYMTAB "
459 "command " +
Twine(LoadCommandIndex) +
" extends "
460 "past the end of the file");
462 Symtab.
strsize,
"string table"))
464 *SymtabLoadCmd =
Load.Ptr;
471 const char **DysymtabLoadCmd,
472 std::list<MachOElement> &Elements) {
475 " LC_DYSYMTAB cmdsize too small");
476 if (*DysymtabLoadCmd !=
nullptr)
481 return DysymtabOrErr.takeError();
485 " has incorrect cmdsize");
486 uint64_t FileSize = Obj.getData().size();
487 if (Dysymtab.
tocoff > FileSize)
489 Twine(LoadCommandIndex) +
" extends past the end of "
493 BigSize += Dysymtab.
tocoff;
494 if (BigSize > FileSize)
495 return malformedError(
"tocoff field plus ntoc field times sizeof(struct "
496 "dylib_table_of_contents) of LC_DYSYMTAB command " +
497 Twine(LoadCommandIndex) +
" extends past the end of "
500 Dysymtab.
ntoc *
sizeof(
struct
502 "table of contents"))
506 Twine(LoadCommandIndex) +
" extends past the end of "
509 const char *struct_dylib_module_name;
513 struct_dylib_module_name =
"struct dylib_module_64";
516 struct_dylib_module_name =
"struct dylib_module";
518 BigSize *= sizeof_modtab;
520 if (BigSize > FileSize)
521 return malformedError(
"modtaboff field plus nmodtab field times sizeof(" +
522 Twine(struct_dylib_module_name) +
") of LC_DYSYMTAB "
523 "command " +
Twine(LoadCommandIndex) +
" extends "
524 "past the end of the file");
526 Dysymtab.
nmodtab * sizeof_modtab,
530 return malformedError(
"extrefsymoff field of LC_DYSYMTAB command " +
531 Twine(LoadCommandIndex) +
" extends past the end of "
536 if (BigSize > FileSize)
537 return malformedError(
"extrefsymoff field plus nextrefsyms field times "
538 "sizeof(struct dylib_reference) of LC_DYSYMTAB "
539 "command " +
Twine(LoadCommandIndex) +
" extends "
540 "past the end of the file");
547 return malformedError(
"indirectsymoff field of LC_DYSYMTAB command " +
548 Twine(LoadCommandIndex) +
" extends past the end of "
553 if (BigSize > FileSize)
554 return malformedError(
"indirectsymoff field plus nindirectsyms field times "
555 "sizeof(uint32_t) of LC_DYSYMTAB command " +
556 Twine(LoadCommandIndex) +
" extends past the end of "
565 Twine(LoadCommandIndex) +
" extends past the end of "
570 if (BigSize > FileSize)
571 return malformedError(
"extreloff field plus nextrel field times sizeof"
572 "(struct relocation_info) of LC_DYSYMTAB command " +
573 Twine(LoadCommandIndex) +
" extends past the end of "
578 "external relocation table"))
582 Twine(LoadCommandIndex) +
" extends past the end of "
587 if (BigSize > FileSize)
588 return malformedError(
"locreloff field plus nlocrel field times sizeof"
589 "(struct relocation_info) of LC_DYSYMTAB command " +
590 Twine(LoadCommandIndex) +
" extends past the end of "
595 "local relocation table"))
597 *DysymtabLoadCmd =
Load.Ptr;
604 const char **LoadCmd,
const char *CmdName,
605 std::list<MachOElement> &Elements,
606 const char *ElementName) {
609 CmdName +
" cmdsize too small");
610 if (*LoadCmd !=
nullptr)
612 auto LinkDataOrError =
614 if (!LinkDataOrError)
615 return LinkDataOrError.takeError();
619 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
620 uint64_t FileSize = Obj.getData().size();
621 if (LinkData.
dataoff > FileSize)
623 Twine(LoadCommandIndex) +
" extends past the end of "
627 if (BigSize > FileSize)
629 Twine(CmdName) +
" command " +
630 Twine(LoadCommandIndex) +
" extends past the end of "
642 const char **LoadCmd,
const char *CmdName,
643 std::list<MachOElement> &Elements) {
646 CmdName +
" cmdsize too small");
647 if (*LoadCmd !=
nullptr)
648 return malformedError(
"more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
653 return DyldInfoOrErr.takeError();
657 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
658 uint64_t FileSize = Obj.getData().size();
661 " command " +
Twine(LoadCommandIndex) +
" extends "
662 "past the end of the file");
665 if (BigSize > FileSize)
666 return malformedError(
"rebase_off field plus rebase_size field of " +
667 Twine(CmdName) +
" command " +
668 Twine(LoadCommandIndex) +
" extends past the end of "
676 " command " +
Twine(LoadCommandIndex) +
" extends "
677 "past the end of the file");
680 if (BigSize > FileSize)
682 Twine(CmdName) +
" command " +
683 Twine(LoadCommandIndex) +
" extends past the end of "
691 " command " +
Twine(LoadCommandIndex) +
" extends "
692 "past the end of the file");
695 if (BigSize > FileSize)
696 return malformedError(
"weak_bind_off field plus weak_bind_size field of " +
697 Twine(CmdName) +
" command " +
698 Twine(LoadCommandIndex) +
" extends past the end of "
702 "dyld weak bind info"))
706 " command " +
Twine(LoadCommandIndex) +
" extends "
707 "past the end of the file");
710 if (BigSize > FileSize)
711 return malformedError(
"lazy_bind_off field plus lazy_bind_size field of " +
712 Twine(CmdName) +
" command " +
713 Twine(LoadCommandIndex) +
" extends past the end of "
717 "dyld lazy bind info"))
721 " command " +
Twine(LoadCommandIndex) +
" extends "
722 "past the end of the file");
725 if (BigSize > FileSize)
726 return malformedError(
"export_off field plus export_size field of " +
727 Twine(CmdName) +
" command " +
728 Twine(LoadCommandIndex) +
" extends past the end of "
740 uint32_t LoadCommandIndex,
const char *CmdName) {
743 CmdName +
" cmdsize too small");
746 return CommandOrErr.takeError();
750 CmdName +
" name.offset field too small, not past "
751 "the end of the dylib_command struct");
752 if (
D.dylib.name >=
D.cmdsize)
754 CmdName +
" name.offset field extends past the end "
755 "of the load command");
759 const char *
P = (
const char *)
Load.Ptr;
760 for (i =
D.dylib.name; i <
D.cmdsize; i++)
765 CmdName +
" library name extends past the end of the "
773 const char **LoadCmd) {
777 if (*LoadCmd !=
nullptr)
781 return malformedError(
"LC_ID_DYLIB load command in non-dynamic library "
789 uint32_t LoadCommandIndex,
const char *CmdName) {
792 CmdName +
" cmdsize too small");
795 return CommandOrErr.takeError();
799 CmdName +
" name.offset field too small, not past "
800 "the end of the dylinker_command struct");
801 if (
D.name >=
D.cmdsize)
803 CmdName +
" name.offset field extends past the end "
804 "of the load command");
808 const char *
P = (
const char *)
Load.Ptr;
809 for (i =
D.name; i <
D.cmdsize; i++)
814 CmdName +
" dyld name extends past the end of the "
822 const char **LoadCmd,
const char *CmdName) {
825 CmdName +
" has incorrect cmdsize");
826 if (*LoadCmd !=
nullptr)
828 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
829 "LC_VERSION_MIN_WATCHOS command");
837 std::list<MachOElement> &Elements) {
840 " LC_NOTE has incorrect cmdsize");
843 return NoteCmdOrErr.takeError();
845 uint64_t FileSize = Obj.getData().size();
848 Twine(LoadCommandIndex) +
" extends "
849 "past the end of the file");
852 if (BigSize > FileSize)
853 return malformedError(
"size field plus offset field of LC_NOTE command " +
854 Twine(LoadCommandIndex) +
" extends past the end of "
870 return BVCOrErr.takeError();
872 if (
Load.C.cmdsize !=
876 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
880 for (
unsigned i = 0; i < BVC.
ntools; ++i)
893 " LC_TARGET_TRIPLE cmdsize too small");
897 return TTOrErr.takeError();
903 "load command " +
Twine(LoadCommandIndex) +
904 " LC_TARGET_TRIPLE triple.offset field too small, not past the end of "
905 "the target_triple_command struct");
908 if (TT.triple >= TT.cmdsize)
910 " LC_TARGET_TRIPLE triple.offset field extends past "
911 "the end of the load command");
916 const char *
P = (
const char *)
Load.Ptr;
917 for (i = TT.triple; i < TT.cmdsize; i++)
922 " LC_TARGET_TRIPLE triple name extends past the end "
923 "of the load command");
933 " LC_RPATH cmdsize too small");
936 return ROrErr.takeError();
940 " LC_RPATH path.offset field too small, not past "
941 "the end of the rpath_command struct");
942 if (R.path >= R.cmdsize)
944 " LC_RPATH path.offset field extends past the end "
945 "of the load command");
949 const char *
P = (
const char *)
Load.Ptr;
950 for (i = R.path; i < R.cmdsize; i++)
955 " LC_RPATH library name extends past the end of the "
964 const char **LoadCmd,
const char *CmdName) {
965 if (*LoadCmd !=
nullptr)
967 "LC_ENCRYPTION_INFO_64 command");
968 uint64_t FileSize = Obj.getData().size();
969 if (cryptoff > FileSize)
971 " command " +
Twine(LoadCommandIndex) +
" extends "
972 "past the end of the file");
974 BigSize += cryptsize;
975 if (BigSize > FileSize)
977 Twine(CmdName) +
" command " +
978 Twine(LoadCommandIndex) +
" extends past the end of "
989 " LC_LINKER_OPTION cmdsize too small");
990 auto LinkOptionOrErr =
992 if (!LinkOptionOrErr)
993 return LinkOptionOrErr.takeError();
996 const char *
string = (
const char *)
Load.Ptr +
1001 while (*
string ==
'\0' && left > 0) {
1008 if (0xffffffff == NullPos)
1010 " LC_LINKER_OPTION string #" +
Twine(i) +
1011 " is not NULL terminated");
1012 uint32_t len = std::min(NullPos, left) + 1;
1019 " LC_LINKER_OPTION string count " +
Twine(L.count) +
1020 " does not match number of strings");
1026 uint32_t LoadCommandIndex,
const char *CmdName,
1027 size_t SizeOfCmd,
const char *CmdStructName,
1028 uint32_t PathOffset,
const char *PathFieldName) {
1029 if (PathOffset < SizeOfCmd)
1031 CmdName +
" " + PathFieldName +
".offset field too "
1032 "small, not past the end of the " + CmdStructName);
1033 if (PathOffset >=
Load.C.cmdsize)
1035 CmdName +
" " + PathFieldName +
".offset field "
1036 "extends past the end of the load command");
1040 const char *
P = (
const char *)
Load.Ptr;
1041 for (i = PathOffset; i <
Load.C.cmdsize; i++)
1044 if (i >=
Load.C.cmdsize)
1046 CmdName +
" " + PathFieldName +
" name extends past "
1047 "the end of the load command");
1054 const char *CmdName) {
1057 CmdName +
" cmdsize too small");
1058 auto ThreadCommandOrErr =
1060 if (!ThreadCommandOrErr)
1061 return ThreadCommandOrErr.takeError();
1064 const char *end =
Load.Ptr +
T.cmdsize;
1067 while (state < end) {
1070 "flavor in " + CmdName +
" extends past end of "
1073 memcpy(&flavor, state,
sizeof(
uint32_t));
1080 " count in " + CmdName +
" extends past end of "
1092 " count not x86_THREAD_STATE32_COUNT for "
1093 "flavor number " +
Twine(nflavor) +
" which is "
1094 "a x86_THREAD_STATE32 flavor in " + CmdName +
1098 " x86_THREAD_STATE32 extends past end of "
1099 "command in " + CmdName +
" command");
1103 " unknown flavor (" +
Twine(flavor) +
") for "
1104 "flavor number " +
Twine(nflavor) +
" in " +
1105 CmdName +
" command");
1111 " count not x86_THREAD_STATE_COUNT for "
1112 "flavor number " +
Twine(nflavor) +
" which is "
1113 "a x86_THREAD_STATE flavor in " + CmdName +
1117 " x86_THREAD_STATE extends past end of "
1118 "command in " + CmdName +
" command");
1123 " count not x86_FLOAT_STATE_COUNT for "
1124 "flavor number " +
Twine(nflavor) +
" which is "
1125 "a x86_FLOAT_STATE flavor in " + CmdName +
1129 " x86_FLOAT_STATE extends past end of "
1130 "command in " + CmdName +
" command");
1135 " count not x86_EXCEPTION_STATE_COUNT for "
1136 "flavor number " +
Twine(nflavor) +
" which is "
1137 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1141 " x86_EXCEPTION_STATE extends past end of "
1142 "command in " + CmdName +
" command");
1147 " count not x86_THREAD_STATE64_COUNT for "
1148 "flavor number " +
Twine(nflavor) +
" which is "
1149 "a x86_THREAD_STATE64 flavor in " + CmdName +
1153 " x86_THREAD_STATE64 extends past end of "
1154 "command in " + CmdName +
" command");
1159 " count not x86_EXCEPTION_STATE64_COUNT for "
1160 "flavor number " +
Twine(nflavor) +
" which is "
1161 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1165 " x86_EXCEPTION_STATE64 extends past end of "
1166 "command in " + CmdName +
" command");
1170 " unknown flavor (" +
Twine(flavor) +
") for "
1171 "flavor number " +
Twine(nflavor) +
" in " +
1172 CmdName +
" command");
1178 " count not ARM_THREAD_STATE_COUNT for "
1179 "flavor number " +
Twine(nflavor) +
" which is "
1180 "a ARM_THREAD_STATE flavor in " + CmdName +
1184 " ARM_THREAD_STATE extends past end of "
1185 "command in " + CmdName +
" command");
1189 " unknown flavor (" +
Twine(flavor) +
") for "
1190 "flavor number " +
Twine(nflavor) +
" in " +
1191 CmdName +
" command");
1198 " count not ARM_THREAD_STATE64_COUNT for "
1199 "flavor number " +
Twine(nflavor) +
" which is "
1200 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1204 " ARM_THREAD_STATE64 extends past end of "
1205 "command in " + CmdName +
" command");
1209 " unknown flavor (" +
Twine(flavor) +
") for "
1210 "flavor number " +
Twine(nflavor) +
" in " +
1211 CmdName +
" command");
1217 " count not PPC_THREAD_STATE_COUNT for "
1218 "flavor number " +
Twine(nflavor) +
" which is "
1219 "a PPC_THREAD_STATE flavor in " + CmdName +
1223 " PPC_THREAD_STATE extends past end of "
1224 "command in " + CmdName +
" command");
1228 " unknown flavor (" +
Twine(flavor) +
") for "
1229 "flavor number " +
Twine(nflavor) +
" in " +
1230 CmdName +
" command");
1234 "command " +
Twine(LoadCommandIndex) +
" for " +
1235 CmdName +
" command can't be checked");
1246 const char **LoadCmd,
1247 std::list<MachOElement> &Elements) {
1250 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1251 if (*LoadCmd !=
nullptr)
1252 return malformedError(
"more than one LC_TWOLEVEL_HINTS command");
1255 return HintsOrErr.takeError();
1257 uint64_t FileSize = Obj.getData().size();
1258 if (Hints.
offset > FileSize)
1259 return malformedError(
"offset field of LC_TWOLEVEL_HINTS command " +
1260 Twine(LoadCommandIndex) +
" extends past the end of "
1265 if (BigSize > FileSize)
1266 return malformedError(
"offset field plus nhints times sizeof(struct "
1267 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1268 Twine(LoadCommandIndex) +
" extends past the end of "
1274 *LoadCmd =
Load.Ptr;
1282 if (
cmd == MachO::LC_SYMSEG ||
1283 cmd == MachO::LC_LOADFVMLIB ||
1284 cmd == MachO::LC_IDFVMLIB ||
1285 cmd == MachO::LC_IDENT ||
1286 cmd == MachO::LC_FVMFILE ||
1287 cmd == MachO::LC_PREPAGE ||
1288 cmd == MachO::LC_PREBOUND_DYLIB ||
1289 cmd == MachO::LC_TWOLEVEL_HINTS ||
1290 cmd == MachO::LC_PREBIND_CKSUM)
1297 bool Is64Bits,
uint32_t UniversalCputype,
1299 size_t MachOFilesetEntryOffset) {
1301 std::unique_ptr<MachOObjectFile> Obj(
new MachOObjectFile(
1302 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,
1303 UniversalIndex, MachOFilesetEntryOffset));
1305 return std::move(Err);
1306 return std::move(Obj);
1309MachOObjectFile::MachOObjectFile(
MemoryBufferRef Object,
bool IsLittleEndian,
1310 bool Is64bits,
Error &Err,
1313 size_t MachOFilesetEntryOffset)
1314 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1315 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {
1317 uint64_t SizeOfHeaders;
1326 cputype = Header.cputype;
1332 Err =
malformedError(
"load commands extend past the end of the file");
1335 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1337 Twine(UniversalIndex) +
"'s cputype does not match "
1338 "object file's mach header");
1342 Elements.push_back({0, SizeOfHeaders,
"Mach-O headers"});
1346 if (LoadCommandCount != 0) {
1350 Err = LoadOrErr.takeError();
1355 const char *DyldIdLoadCmd =
nullptr;
1356 const char *SplitInfoLoadCmd =
nullptr;
1357 const char *CodeSignDrsLoadCmd =
nullptr;
1358 const char *CodeSignLoadCmd =
nullptr;
1359 const char *VersLoadCmd =
nullptr;
1360 const char *SourceLoadCmd =
nullptr;
1361 const char *EntryPointLoadCmd =
nullptr;
1362 const char *EncryptLoadCmd =
nullptr;
1363 const char *RoutinesLoadCmd =
nullptr;
1364 const char *UnixThreadLoadCmd =
nullptr;
1365 const char *TwoLevelHintsLoadCmd =
nullptr;
1366 for (
unsigned I = 0;
I < LoadCommandCount; ++
I) {
1368 if (
Load.C.cmdsize % 8 != 0) {
1373 Load.C.cmd != MachO::LC_THREAD ||
Load.C.cmdsize % 4) {
1380 if (
Load.C.cmdsize % 4 != 0) {
1386 LoadCommands.push_back(
Load);
1387 if (
Load.C.cmd == MachO::LC_SYMTAB) {
1390 }
else if (
Load.C.cmd == MachO::LC_DYSYMTAB) {
1394 }
else if (
Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1396 "LC_DATA_IN_CODE", Elements,
1397 "data in code info")))
1399 }
else if (
Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1401 "LC_LINKER_OPTIMIZATION_HINT",
1402 Elements,
"linker optimization "
1405 }
else if (
Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1407 "LC_FUNCTION_STARTS", Elements,
1408 "function starts data")))
1410 }
else if (
Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1412 "LC_SEGMENT_SPLIT_INFO", Elements,
1413 "split info data")))
1415 }
else if (
Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1417 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1418 "code signing RDs data")))
1420 }
else if (
Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1422 "LC_CODE_SIGNATURE", Elements,
1423 "code signature data")))
1425 }
else if (
Load.C.cmd == MachO::LC_DYLD_INFO) {
1427 "LC_DYLD_INFO", Elements)))
1429 }
else if (
Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1431 "LC_DYLD_INFO_ONLY", Elements)))
1433 }
else if (
Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1435 *
this,
Load,
I, &DyldChainedFixupsLoadCmd,
1436 "LC_DYLD_CHAINED_FIXUPS", Elements,
"chained fixups")))
1438 }
else if (
Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {
1440 *
this,
Load,
I, &DyldExportsTrieLoadCmd,
"LC_DYLD_EXPORTS_TRIE",
1441 Elements,
"exports trie")))
1443 }
else if (
Load.C.cmd == MachO::LC_UUID) {
1444 if (
Load.C.cmdsize !=
sizeof(MachO::uuid_command)) {
1445 Err =
malformedError(
"LC_UUID command " + Twine(
I) +
" has incorrect "
1453 UuidLoadCmd =
Load.Ptr;
1454 }
else if (
Load.C.cmd == MachO::LC_SEGMENT_64) {
1457 *
this,
Load, Sections, HasPageZeroSegment,
I,
1458 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1460 }
else if (
Load.C.cmd == MachO::LC_SEGMENT) {
1463 *
this,
Load, Sections, HasPageZeroSegment,
I,
1464 "LC_SEGMENT", SizeOfHeaders, Elements)))
1466 }
else if (
Load.C.cmd == MachO::LC_ID_DYLIB) {
1469 }
else if (
Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1472 Libraries.push_back(
Load.Ptr);
1473 }
else if (
Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1476 Libraries.push_back(
Load.Ptr);
1477 }
else if (
Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1480 Libraries.push_back(
Load.Ptr);
1481 }
else if (
Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1484 Libraries.push_back(
Load.Ptr);
1485 }
else if (
Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1488 Libraries.push_back(
Load.Ptr);
1489 }
else if (
Load.C.cmd == MachO::LC_ID_DYLINKER) {
1492 }
else if (
Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1495 }
else if (
Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1498 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1500 "LC_VERSION_MIN_MACOSX")))
1502 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1504 "LC_VERSION_MIN_IPHONEOS")))
1506 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1508 "LC_VERSION_MIN_TVOS")))
1510 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1512 "LC_VERSION_MIN_WATCHOS")))
1514 }
else if (
Load.C.cmd == MachO::LC_NOTE) {
1517 }
else if (
Load.C.cmd == MachO::LC_BUILD_VERSION) {
1520 }
else if (
Load.C.cmd == MachO::LC_TARGET_TRIPLE) {
1523 }
else if (
Load.C.cmd == MachO::LC_RPATH) {
1526 }
else if (
Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1527 if (
Load.C.cmdsize !=
sizeof(MachO::source_version_command)) {
1529 " has incorrect cmdsize");
1532 if (SourceLoadCmd) {
1536 SourceLoadCmd =
Load.Ptr;
1537 }
else if (
Load.C.cmd == MachO::LC_MAIN) {
1538 if (
Load.C.cmdsize !=
sizeof(MachO::entry_point_command)) {
1540 " has incorrect cmdsize");
1543 if (EntryPointLoadCmd) {
1547 EntryPointLoadCmd =
Load.Ptr;
1548 }
else if (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1549 if (
Load.C.cmdsize !=
sizeof(MachO::encryption_info_command)) {
1551 " has incorrect cmdsize");
1554 MachO::encryption_info_command
E =
1557 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO")))
1559 }
else if (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1560 if (
Load.C.cmdsize !=
sizeof(MachO::encryption_info_command_64)) {
1562 " has incorrect cmdsize");
1565 MachO::encryption_info_command_64
E =
1568 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO_64")))
1570 }
else if (
Load.C.cmd == MachO::LC_LINKER_OPTION) {
1573 }
else if (
Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1574 if (
Load.C.cmdsize <
sizeof(MachO::sub_framework_command)) {
1576 " LC_SUB_FRAMEWORK cmdsize too small");
1579 MachO::sub_framework_command S =
1582 sizeof(MachO::sub_framework_command),
1583 "sub_framework_command", S.
umbrella,
1586 }
else if (
Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1587 if (
Load.C.cmdsize <
sizeof(MachO::sub_umbrella_command)) {
1589 " LC_SUB_UMBRELLA cmdsize too small");
1592 MachO::sub_umbrella_command S =
1595 sizeof(MachO::sub_umbrella_command),
1599 }
else if (
Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1600 if (
Load.C.cmdsize <
sizeof(MachO::sub_library_command)) {
1602 " LC_SUB_LIBRARY cmdsize too small");
1605 MachO::sub_library_command S =
1608 sizeof(MachO::sub_library_command),
1612 }
else if (
Load.C.cmd == MachO::LC_SUB_CLIENT) {
1613 if (
Load.C.cmdsize <
sizeof(MachO::sub_client_command)) {
1615 " LC_SUB_CLIENT cmdsize too small");
1618 MachO::sub_client_command S =
1621 sizeof(MachO::sub_client_command),
1622 "sub_client_command", S.
client,
"client")))
1624 }
else if (
Load.C.cmd == MachO::LC_ROUTINES) {
1625 if (
Load.C.cmdsize !=
sizeof(MachO::routines_command)) {
1627 " has incorrect cmdsize");
1630 if (RoutinesLoadCmd) {
1631 Err =
malformedError(
"more than one LC_ROUTINES and or LC_ROUTINES_64 "
1635 RoutinesLoadCmd =
Load.Ptr;
1636 }
else if (
Load.C.cmd == MachO::LC_ROUTINES_64) {
1637 if (
Load.C.cmdsize !=
sizeof(MachO::routines_command_64)) {
1639 " has incorrect cmdsize");
1642 if (RoutinesLoadCmd) {
1643 Err =
malformedError(
"more than one LC_ROUTINES_64 and or LC_ROUTINES "
1647 RoutinesLoadCmd =
Load.Ptr;
1648 }
else if (
Load.C.cmd == MachO::LC_UNIXTHREAD) {
1651 if (UnixThreadLoadCmd) {
1655 UnixThreadLoadCmd =
Load.Ptr;
1656 }
else if (
Load.C.cmd == MachO::LC_THREAD) {
1660 }
else if (
Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1662 &TwoLevelHintsLoadCmd, Elements)))
1664 }
else if (
Load.C.cmd == MachO::LC_IDENT) {
1668 Err =
malformedError(
"load command " + Twine(
I) +
" for cmd value of: " +
1669 Twine(
Load.C.cmd) +
" is obsolete and not "
1676 if (
I < LoadCommandCount - 1) {
1680 Err = LoadOrErr.takeError();
1685 if (!SymtabLoadCmd) {
1686 if (DysymtabLoadCmd) {
1687 Err =
malformedError(
"contains LC_DYSYMTAB load command without a "
1688 "LC_SYMTAB load command");
1691 }
else if (DysymtabLoadCmd) {
1692 MachO::symtab_command Symtab =
1694 MachO::dysymtab_command Dysymtab =
1698 "extends past the end of the symbol table");
1704 Err =
malformedError(
"ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1705 "command extends past the end of the symbol table");
1710 "extends past the end of the symbol table");
1716 Err =
malformedError(
"iextdefsym plus nextdefsym in LC_DYSYMTAB "
1717 "load command extends past the end of the symbol "
1723 "extends past the end of the symbol table");
1729 Err =
malformedError(
"iundefsym plus nundefsym in LC_DYSYMTAB load "
1730 " command extends past the end of the symbol table");
1736 DyldIdLoadCmd ==
nullptr) {
1737 Err =
malformedError(
"no LC_ID_DYLIB load command in dynamic library "
1741 assert(LoadCommands.size() == LoadCommandCount);
1759 uint64_t NValue = 0;
1781 if (NSect == 0 || NSect > Sections.size())
1783 " for symbol at index " +
Twine(SymbolIndex));
1788 "the end of string table, for N_INDR symbol at "
1789 "index " +
Twine(SymbolIndex));
1795 if (LibraryOrdinal != 0 &&
1798 LibraryOrdinal - 1 >= Libraries.size() ) {
1800 " for symbol at index " +
Twine(SymbolIndex));
1806 " past the end of string table, for symbol at "
1807 "index " +
Twine(SymbolIndex));
1823 if (Entry.n_strx == 0)
1827 const char *Start = &
StringTable.data()[Entry.n_strx];
1844 return Entry.n_value;
1847 return Entry.n_value;
1863 return std::error_code();
1866uint64_t MachOObjectFile::getSymbolValueImpl(
DataRefImpl Sym)
const {
1890 uint8_t n_type = Entry.n_type;
1916 uint8_t MachOType = Entry.n_type;
1917 uint16_t MachOFlags = Entry.n_desc;
1964 DRI.
d.
a = index - 1;
1965 if (DRI.
d.
a >= Sections.size()){
1975 return Entry.n_sect - 1;
2007 SectOffset = Sect.
offset;
2008 SectSize = Sect.
size;
2012 SectOffset = Sect.
offset;
2013 SectSize = Sect.
size;
2019 if (SectOffset > FileSize)
2021 if (FileSize - SectOffset < SectSize)
2022 return FileSize - SectOffset;
2027 uint64_t
Size)
const {
2046 uint64_t PrevTrueOffset = 0;
2047 uint64_t SectOffsetAdjust = 0;
2048 for (
uint32_t SectIdx = 0; SectIdx < Sec.
d.
a; ++SectIdx) {
2051 uint64_t CurrTrueOffset = (uint64_t)CurrSect.
offset + SectOffsetAdjust;
2052 if ((SectOffsetAdjust > 0) && (PrevTrueOffset > CurrTrueOffset))
2053 return malformedError(
"section data exceeds 4GB and section file "
2054 "offsets are not ordered");
2055 const uint64_t EndSectFileOffset =
2057 if (EndSectFileOffset > UINT32_MAX)
2058 SectOffsetAdjust += EndSectFileOffset & 0xFFFFFFFF00000000ull;
2059 PrevTrueOffset = CurrTrueOffset;
2061 Offset += SectOffsetAdjust;
2085 if (SectionIndex < 1 || SectionIndex > Sections.size())
2089 DRI.
d.
a = SectionIndex - 1;
2095 auto NameOrErr = Section.getName();
2097 return NameOrErr.takeError();
2131 if (!SectionNameOrErr) {
2144template <
typename LoadCommandType>
2149 if (!SegmentOrErr) {
2153 auto &Segment = SegmentOrErr.get();
2156 Segment.fileoff, Segment.fileoff + Segment.filesize));
2160template <
typename LoadCommandType>
2161ArrayRef<uint8_t> getSegmentContents(
const MachOObjectFile &Obj,
2162 MachOObjectFile::LoadCommandInfo LoadCmd) {
2164 if (!SegmentOrErr) {
2168 auto &Segment = SegmentOrErr.get();
2170 Obj.getData().substr(Segment.fileoff, Segment.filesize));
2178 switch (LoadCmd.
C.
cmd) {
2179 case MachO::LC_SEGMENT:
2183 case MachO::LC_SEGMENT_64:
2190 if (!Contents.
empty())
2200 switch (LoadCmd.
C.
cmd) {
2201 case MachO::LC_SEGMENT:
2202 if (Idx == SegmentIndex)
2203 return ::getSegmentContents<MachO::segment_command>(*
this, LoadCmd);
2206 case MachO::LC_SEGMENT_64:
2207 if (Idx == SegmentIndex)
2208 return ::getSegmentContents<MachO::segment_command_64>(*
this, LoadCmd);
2232 return (SegmentName ==
"__LLVM" && *NameOrErr ==
"__bitcode");
2279 Ret.
d.
b = DysymtabLoadCmd.nextrel;
2296 Ret.
d.
b = DysymtabLoadCmd.nlocrel;
2307 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2348 unsigned Arch = this->
getArch();
2352 static const char *
const Table[] = {
2353 "GENERIC_RELOC_VANILLA",
2354 "GENERIC_RELOC_PAIR",
2355 "GENERIC_RELOC_SECTDIFF",
2356 "GENERIC_RELOC_PB_LA_PTR",
2357 "GENERIC_RELOC_LOCAL_SECTDIFF",
2358 "GENERIC_RELOC_TLV" };
2367 static const char *
const Table[] = {
2368 "X86_64_RELOC_UNSIGNED",
2369 "X86_64_RELOC_SIGNED",
2370 "X86_64_RELOC_BRANCH",
2371 "X86_64_RELOC_GOT_LOAD",
2373 "X86_64_RELOC_SUBTRACTOR",
2374 "X86_64_RELOC_SIGNED_1",
2375 "X86_64_RELOC_SIGNED_2",
2376 "X86_64_RELOC_SIGNED_4",
2377 "X86_64_RELOC_TLV" };
2386 static const char *
const Table[] = {
2387 "ARM_RELOC_VANILLA",
2389 "ARM_RELOC_SECTDIFF",
2390 "ARM_RELOC_LOCAL_SECTDIFF",
2391 "ARM_RELOC_PB_LA_PTR",
2393 "ARM_THUMB_RELOC_BR22",
2394 "ARM_THUMB_32BIT_BRANCH",
2396 "ARM_RELOC_HALF_SECTDIFF" };
2406 static const char *
const Table[] = {
2407 "ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
2408 "ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
2409 "ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
2410 "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
2411 "ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2412 "ARM64_RELOC_ADDEND",
"ARM64_RELOC_AUTHENTICATED_POINTER"
2415 if (RType >= std::size(
Table))
2422 static const char *
const Table[] = {
2423 "PPC_RELOC_VANILLA",
2431 "PPC_RELOC_SECTDIFF",
2432 "PPC_RELOC_PB_LA_PTR",
2433 "PPC_RELOC_HI16_SECTDIFF",
2434 "PPC_RELOC_LO16_SECTDIFF",
2435 "PPC_RELOC_HA16_SECTDIFF",
2437 "PPC_RELOC_LO14_SECTDIFF",
2438 "PPC_RELOC_LOCAL_SECTDIFF" };
2447 static const char *
const Table[] = {
2448 "RISCV_RELOC_UNSIGNED",
"RISCV_RELOC_SUBTRACTOR",
2449 "RISCV_RELOC_BRANCH21",
"RISCV_RELOC_HI20",
2450 "RISCV_RELOC_LO12",
"RISCV_RELOC_GOT_HI20",
2451 "RISCV_RELOC_GOT_LO12",
"RISCV_RELOC_POINTER_TO_GOT",
2452 "RISCV_RELOC_ADDEND",
2455 if (RType >= std::size(
Table))
2459 Result.append(res.
begin(), res.
end());
2466 Result.append(PCRel.
begin(), PCRel.
end());
2474 Result.append(res.
begin(), res.
end());
2522 size_t a, b, c, d, Idx;
2524 isFramework =
false;
2528 a = Name.rfind(
'/');
2529 if (a == Name.npos || a == 0)
2531 Foo = Name.substr(a + 1);
2534 Idx = Foo.
rfind(
'_');
2535 if (Idx != Foo.
npos && Foo.
size() >= 2) {
2536 Suffix = Foo.
substr(Idx);
2537 if (Suffix !=
"_debug" && Suffix !=
"_profile")
2540 Foo = Foo.
slice(0, Idx);
2544 b = Name.rfind(
'/', a);
2549 F = Name.substr(Idx, Foo.
size());
2550 DotFramework = Name.substr(Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2551 if (
F == Foo && DotFramework ==
".framework/") {
2559 c = Name.rfind(
'/', b);
2560 if (c == Name.npos || c == 0)
2562 V = Name.substr(c + 1);
2563 if (!V.starts_with(
"Versions/"))
2565 d = Name.rfind(
'/', c);
2570 F = Name.substr(Idx, Foo.
size());
2571 DotFramework = Name.substr(Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2572 if (
F == Foo && DotFramework ==
".framework/") {
2579 a = Name.rfind(
'.');
2580 if (a == Name.npos || a == 0)
2582 Dylib = Name.substr(a);
2583 if (Dylib !=
".dylib")
2588 Dot = Name.substr(a - 2, 1);
2593 b = Name.rfind(
'/', a);
2599 Idx = Name.rfind(
'_');
2600 if (Idx != Name.npos && Idx != b) {
2601 Lib = Name.slice(b, Idx);
2602 Suffix = Name.slice(Idx, a);
2603 if (Suffix !=
"_debug" && Suffix !=
"_profile") {
2605 Lib = Name.slice(b, a);
2609 Lib = Name.slice(b, a);
2612 if (
Lib.size() >= 3) {
2613 Dot =
Lib.substr(
Lib.size() - 2, 1);
2620 Qtx = Name.substr(a);
2623 b = Name.rfind(
'/', a);
2625 Lib = Name.slice(0, a);
2627 Lib = Name.slice(b+1, a);
2629 if (
Lib.size() >= 3) {
2630 Dot =
Lib.substr(
Lib.size() - 2, 1);
2644 if (Index >= Libraries.size())
2649 if (LibrariesShortNames.size() == 0) {
2650 for (
unsigned i = 0; i < Libraries.size(); i++) {
2656 if (
D.dylib.name >=
D.cmdsize)
2658 const char *
P = (
const char *)(Libraries[i]) +
D.dylib.name;
2660 if (
D.dylib.name+Name.size() >=
D.cmdsize)
2665 if (shortName.
empty())
2666 LibrariesShortNames.push_back(Name);
2668 LibrariesShortNames.push_back(shortName);
2672 Res = LibrariesShortNames[Index];
2673 return std::error_code();
2677 return Libraries.size();
2690 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2699 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2711 if (!SymtabLoadCmd || Index >= Symtab.
nsyms)
2740 DRI.
d.
a = Sections.size();
2753 return "Mach-O 32-bit i386";
2755 return "Mach-O arm";
2757 return "Mach-O arm64 (ILP32)";
2759 return "Mach-O 32-bit ppc";
2761 return "Mach-O 32-bit RISC-V";
2763 return "Mach-O 32-bit unknown";
2769 return "Mach-O 64-bit x86-64";
2771 return "Mach-O arm64";
2773 return "Mach-O 64-bit ppc64";
2775 return "Mach-O 64-bit unknown";
2803 const char **McpuDefault,
2804 const char **ArchFlag) {
2806 *McpuDefault =
nullptr;
2808 *ArchFlag =
nullptr;
2816 return Triple(
"i386-apple-darwin");
2824 *ArchFlag =
"x86_64";
2825 return Triple(
"x86_64-apple-darwin");
2828 *ArchFlag =
"x86_64h";
2829 return Triple(
"x86_64h-apple-darwin");
2837 *ArchFlag =
"armv4t";
2838 return Triple(
"armv4t-apple-darwin");
2841 *ArchFlag =
"armv5e";
2842 return Triple(
"armv5e-apple-darwin");
2845 *ArchFlag =
"xscale";
2846 return Triple(
"xscale-apple-darwin");
2849 *ArchFlag =
"armv6";
2850 return Triple(
"armv6-apple-darwin");
2853 *McpuDefault =
"cortex-m0";
2855 *ArchFlag =
"armv6m";
2856 return Triple(
"armv6m-apple-darwin");
2859 *ArchFlag =
"armv7";
2860 return Triple(
"armv7-apple-darwin");
2863 *McpuDefault =
"cortex-m4";
2865 *ArchFlag =
"armv7em";
2866 return Triple(
"thumbv7em-apple-darwin");
2869 *McpuDefault =
"cortex-a7";
2871 *ArchFlag =
"armv7k";
2872 return Triple(
"armv7k-apple-darwin");
2875 *McpuDefault =
"cortex-m3";
2877 *ArchFlag =
"armv7m";
2878 return Triple(
"thumbv7m-apple-darwin");
2881 *McpuDefault =
"cortex-a7";
2883 *ArchFlag =
"armv7s";
2884 return Triple(
"armv7s-apple-darwin");
2887 *McpuDefault =
"cortex-m23";
2889 *ArchFlag =
"armv8m.base";
2890 return Triple(
"thumbv8m-apple-darwin");
2893 *McpuDefault =
"cortex-m33";
2895 *ArchFlag =
"armv8m.main";
2896 return Triple(
"thumbv8m-apple-darwin");
2899 *McpuDefault =
"cortex-m52";
2901 *ArchFlag =
"armv8.1m.main";
2902 return Triple(
"thumbv8m-apple-darwin");
2910 *McpuDefault =
"cyclone";
2912 *ArchFlag =
"arm64";
2913 return Triple(
"arm64-apple-darwin");
2916 *McpuDefault =
"apple-a12";
2918 *ArchFlag =
"arm64e";
2919 return Triple(
"arm64e-apple-darwin");
2922 *McpuDefault =
"apple-a20";
2924 *ArchFlag =
"arm64e.x1";
2925 return Triple(
"arm64e.x1-apple-darwin");
2933 *McpuDefault =
"cyclone";
2935 *ArchFlag =
"arm64_32";
2936 return Triple(
"arm64_32-apple-darwin");
2945 return Triple(
"ppc-apple-darwin");
2953 *ArchFlag =
"ppc64";
2954 return Triple(
"ppc64-apple-darwin");
2962 *ArchFlag =
"riscv32";
2963 return Triple(
"riscv32-apple-macho");
2982 static const std::array<StringRef, 22> ValidArchs = {{
2983 "i386",
"x86_64",
"x86_64h",
"armv4t",
"arm",
2984 "armv5e",
"armv6",
"armv6m",
"armv7",
"armv7em",
2985 "armv7k",
"armv7m",
"armv7s",
"armv8m.base",
"armv8m.main",
2986 "armv8.1m.main",
"arm64",
"arm64e",
"arm64e.x1",
"arm64_32",
3015 if (!DataInCodeLoadCmd)
3025 if (!DataInCodeLoadCmd)
3037void ExportEntry::moveToFirst() {
3042 pushDownUntilBottom();
3045void ExportEntry::moveToEnd() {
3052 if (Done ||
Other.Done)
3053 return (Done ==
Other.Done);
3055 if (Stack.size() !=
Other.Stack.size())
3058 if (!CumulativeString.equals(
Other.CumulativeString))
3061 for (
unsigned i=0; i < Stack.size(); ++i) {
3062 if (Stack[i].Start !=
Other.Stack[i].Start)
3068uint64_t ExportEntry::readULEB128(
const uint8_t *&Ptr,
const char **
error) {
3072 if (Ptr > Trie.
end())
3078 return CumulativeString;
3082 return Stack.back().Flags;
3086 return Stack.back().Address;
3090 return Stack.back().Other;
3094 const char* ImportName = Stack.
back().ImportName;
3101 return Stack.back().Start - Trie.begin();
3104ExportEntry::NodeState::NodeState(
const uint8_t *Ptr)
3105 : Start(Ptr), Current(Ptr) {}
3107void ExportEntry::pushNode(uint64_t offset) {
3110 NodeState State(Ptr);
3111 const char *
error =
nullptr;
3115 " in export trie data at node: 0x" +
3120 State.IsExportNode = (ExportInfoSize != 0);
3121 const uint8_t* Children = State.Current + ExportInfoSize;
3122 if (Children > Trie.
end()) {
3126 " too big and extends past end of trie data");
3130 if (State.IsExportNode) {
3131 const uint8_t *ExportStart = State.Current;
3132 State.Flags = readULEB128(State.Current, &
error);
3135 " in export trie data at node: 0x" +
3141 if (State.Flags != 0 &&
3146 "unsupported exported symbol kind: " + Twine((
int)
Kind) +
3154 State.Other = readULEB128(State.Current, &
error);
3157 " in export trie data at node: 0x" +
3165 if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3167 "bad library ordinal: " + Twine((
int)State.Other) +
" (max " +
3168 Twine((
int)O->getLibraryCount()) +
3174 State.ImportName =
reinterpret_cast<const char*
>(State.Current);
3175 if (*State.ImportName ==
'\0') {
3178 const uint8_t *
End = State.Current + 1;
3179 if (
End >= Trie.end()) {
3180 *E =
malformedError(
"import name of re-export in export trie data at "
3183 " starts past end of trie data");
3187 while(*
End !=
'\0' &&
End < Trie.end())
3190 *E =
malformedError(
"import name of re-export in export trie data at "
3193 " extends past end of trie data");
3197 State.Current =
End + 1;
3200 State.Address = readULEB128(State.Current, &
error);
3203 " in export trie data at node: 0x" +
3209 State.Other = readULEB128(State.Current, &
error);
3212 " in export trie data at node: 0x" +
3219 if (ExportStart + ExportInfoSize < State.Current) {
3221 "inconsistent export info size: 0x" +
3230 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3231 *E =
malformedError(
"byte for count of children in export trie data at "
3234 " extends past end of trie data");
3239 State.NextChildIndex = 0;
3240 State.ParentStringLength = CumulativeString.size();
3241 Stack.push_back(State);
3244void ExportEntry::pushDownUntilBottom() {
3245 ErrorAsOutParameter ErrAsOutParam(E);
3246 const char *
error =
nullptr;
3247 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3248 NodeState &Top = Stack.back();
3249 CumulativeString.resize(Top.ParentStringLength);
3250 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3251 char C = *Top.Current;
3252 CumulativeString.push_back(
C);
3254 if (Top.Current >= Trie.end()) {
3255 *E =
malformedError(
"edge sub-string in export trie data at node: 0x" +
3257 " for child #" + Twine((
int)Top.NextChildIndex) +
3258 " extends past end of trie data");
3266 " in export trie data at node: 0x" +
3271 for (
const NodeState &node :
nodes()) {
3272 if (node.Start == Trie.begin() + childNodeIndex){
3273 *E =
malformedError(
"loop in children in export trie data at node: 0x" +
3275 " back to node: 0x" +
3281 Top.NextChildIndex += 1;
3282 pushNode(childNodeIndex);
3286 if (!Stack.back().IsExportNode) {
3287 *E =
malformedError(
"node is not an export node in export trie data at "
3311 assert(!Stack.empty() &&
"ExportEntry::moveNext() with empty node stack");
3312 if (!Stack.back().IsExportNode) {
3313 *E =
malformedError(
"node is not an export node in export trie data at "
3321 while (!Stack.empty()) {
3322 NodeState &Top = Stack.back();
3323 if (Top.NextChildIndex < Top.ChildCount) {
3324 pushDownUntilBottom();
3328 if (Top.IsExportNode) {
3330 CumulativeString.resize(Top.ParentStringLength);
3341 const MachOObjectFile *O) {
3346 Start.moveToFirst();
3356 if (DyldInfoLoadCmd)
3358 else if (DyldExportsTrieLoadCmd)
3361 return exports(Err, Trie,
this);
3368 for (
const auto &Command :
O->load_commands()) {
3369 if (Command.C.cmd == MachO::LC_SEGMENT) {
3370 MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
3371 if (StringRef(SLC.segname) ==
"__TEXT") {
3372 TextAddress = SLC.vmaddr;
3375 }
else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3376 MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
3377 if (StringRef(SLC_64.segname) ==
"__TEXT") {
3378 TextAddress = SLC_64.vmaddr;
3438 if (
auto FixupTargetsOrErr =
O->getDyldChainedFixupTargets()) {
3439 FixupTargets = *FixupTargetsOrErr;
3441 *
E = FixupTargetsOrErr.takeError();
3445 if (
auto SegmentsOrErr =
O->getChainedFixupsSegments()) {
3446 Segments = std::move(SegmentsOrErr->second);
3448 *
E = SegmentsOrErr.takeError();
3453void MachOChainedFixupEntry::findNextPageWithFixups() {
3454 auto FindInSegment = [
this]() {
3456 while (PageIndex < SegInfo.
PageStarts.size() &&
3459 return PageIndex < SegInfo.
PageStarts.size();
3462 while (InfoSegIndex < Segments.size()) {
3463 if (FindInSegment()) {
3464 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3476 if (Segments.empty()) {
3484 findNextPageWithFixups();
3495 if (InfoSegIndex == Segments.size()) {
3512 " has unsupported chained fixup pointer_format " +
3513 Twine(PointerFormat));
3523 IsAuthenticated =
false;
3524 HasAddressDiversity =
false;
3531 " extends past segment's end");
3542 assert(
O->isLittleEndian() &&
"big-endian object should have been rejected "
3543 "by getDyldChainedFixupTargets()");
3551 int64_t InlineAddend = 0;
3555 IsAuthenticated =
Field(63, 1);
3556 IsBind =
Field(62, 1);
3558 if (IsAuthenticated) {
3559 Diversity =
Field(32, 16);
3560 HasAddressDiversity =
Field(48, 1);
3564 ImportOrdinal =
Field(
3568 if (!IsAuthenticated)
3570 }
else if (IsAuthenticated) {
3584 IsBind =
Field(63, 1);
3587 ImportOrdinal =
Field(0, 24);
3588 InlineAddend =
Field(24, 8);
3591 uint64_t High8 =
Field(36, 8);
3601 if (ImportOrdinal >= FixupTargets.size()) {
3604 " has out-of range import ordinal " +
3605 Twine(ImportOrdinal));
3612 Addend = InlineAddend ? InlineAddend :
Target.addend();
3620 PageOffset += (IsArm64e ? 8 : 4) *
Next;
3623 findNextPageWithFixups();
3633 return InfoSegIndex ==
Other.InfoSegIndex && PageIndex ==
Other.PageIndex &&
3634 PageOffset ==
Other.PageOffset;
3639 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3640 PointerSize(
is64Bit ? 8 : 4) {}
3642void MachORebaseEntry::moveToFirst() {
3643 Ptr = Opcodes.
begin();
3647void MachORebaseEntry::moveToEnd() {
3648 Ptr = Opcodes.
end();
3649 RemainingLoopCount = 0;
3656 SegmentOffset += AdvanceAmount;
3657 if (RemainingLoopCount) {
3658 --RemainingLoopCount;
3667 if (Ptr == Opcodes.end()) {
3673 const uint8_t *OpcodeStart = Ptr;
3677 uint64_t
Count, Skip;
3678 const char *
error =
nullptr;
3687 RebaseType = ImmValue;
3689 *E =
malformedError(
"for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3690 Twine((
int)RebaseType) +
" for opcode at: 0x" +
3697 dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: "
3698 <<
"RebaseType=" << (
int) RebaseType <<
"\n");
3701 SegmentIndex = ImmValue;
3702 SegmentOffset = readULEB128(&
error);
3704 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3710 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3713 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3721 dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3722 <<
"SegmentIndex=" << SegmentIndex <<
", "
3723 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3727 SegmentOffset += readULEB128(&
error);
3730 " for opcode at: 0x" +
3735 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3739 " for opcode at: 0x" +
3745 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: "
3746 <<
format(
"SegmentOffset=0x%06X",
3747 SegmentOffset) <<
"\n");
3750 SegmentOffset += ImmValue * PointerSize;
3751 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3761 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3762 <<
format(
"SegmentOffset=0x%06X",
3763 SegmentOffset) <<
"\n");
3766 AdvanceAmount = PointerSize;
3770 RemainingLoopCount = ImmValue - 1;
3772 RemainingLoopCount = 0;
3773 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3774 PointerSize,
Count, Skip);
3784 dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3785 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3786 <<
", AdvanceAmount=" << AdvanceAmount
3787 <<
", RemainingLoopCount=" << RemainingLoopCount
3791 AdvanceAmount = PointerSize;
3802 RemainingLoopCount =
Count - 1;
3804 RemainingLoopCount = 0;
3805 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3806 PointerSize,
Count, Skip);
3816 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3817 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3818 <<
", AdvanceAmount=" << AdvanceAmount
3819 <<
", RemainingLoopCount=" << RemainingLoopCount
3823 Skip = readULEB128(&
error);
3825 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3831 AdvanceAmount = Skip + PointerSize;
3833 RemainingLoopCount = 0;
3834 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3835 PointerSize,
Count, Skip);
3837 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3845 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3846 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3847 <<
", AdvanceAmount=" << AdvanceAmount
3848 <<
", RemainingLoopCount=" << RemainingLoopCount
3854 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3862 RemainingLoopCount =
Count - 1;
3864 RemainingLoopCount = 0;
3865 Skip = readULEB128(&
error);
3867 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3874 AdvanceAmount = Skip + PointerSize;
3876 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3877 PointerSize,
Count, Skip);
3879 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3888 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3889 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3890 <<
", AdvanceAmount=" << AdvanceAmount
3891 <<
", RemainingLoopCount=" << RemainingLoopCount
3904uint64_t MachORebaseEntry::readULEB128(
const char **
error) {
3908 if (Ptr > Opcodes.
end())
3909 Ptr = Opcodes.
end();
3918 switch (RebaseType) {
3922 return "text abs32";
3924 return "text rel32";
3932 return O->BindRebaseSegmentName(SegmentIndex);
3938 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3944 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3948#ifdef EXPENSIVE_CHECKS
3949 assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
3951 assert(Opcodes.data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
3953 return (Ptr ==
Other.Ptr) &&
3954 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
3955 (Done ==
Other.Done);
3961 if (O->BindRebaseSectionTable ==
nullptr)
3962 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3964 Start.moveToFirst();
3978 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3979 PointerSize(
is64Bit ? 8 : 4), TableKind(BK) {}
3981void MachOBindEntry::moveToFirst() {
3982 Ptr = Opcodes.
begin();
3986void MachOBindEntry::moveToEnd() {
3987 Ptr = Opcodes.
end();
3988 RemainingLoopCount = 0;
3995 SegmentOffset += AdvanceAmount;
3996 if (RemainingLoopCount) {
3997 --RemainingLoopCount;
4006 if (Ptr == Opcodes.end()) {
4012 const uint8_t *OpcodeStart = Ptr;
4016 int8_t SignExtended;
4018 uint64_t
Count, Skip;
4019 const char *
error =
nullptr;
4025 bool NotLastEntry =
false;
4026 for (
const uint8_t *
P = Ptr;
P < Opcodes.end(); ++
P) {
4028 NotLastEntry =
true;
4040 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
4041 "weak bind table for opcode at: 0x" +
4047 LibraryOrdinalSet =
true;
4048 if (ImmValue > O->getLibraryCount()) {
4049 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
4050 "library ordinal: " +
4051 Twine((
int)ImmValue) +
" (max " +
4052 Twine((
int)O->getLibraryCount()) +
4053 ") for opcode at: 0x" +
4060 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
4061 <<
"Ordinal=" << Ordinal <<
"\n");
4065 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
4066 "weak bind table for opcode at: 0x" +
4071 Ordinal = readULEB128(&
error);
4072 LibraryOrdinalSet =
true;
4080 if (Ordinal > (
int)O->getLibraryCount()) {
4081 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
4082 "library ordinal: " +
4083 Twine((
int)Ordinal) +
" (max " +
4084 Twine((
int)O->getLibraryCount()) +
4085 ") for opcode at: 0x" +
4092 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
4093 <<
"Ordinal=" << Ordinal <<
"\n");
4097 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
4098 "weak bind table for opcode at: 0x" +
4105 Ordinal = SignExtended;
4107 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
4108 "special ordinal: " +
4109 Twine((
int)Ordinal) +
" for opcode at: 0x" +
4116 LibraryOrdinalSet =
true;
4119 dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
4120 <<
"Ordinal=" << Ordinal <<
"\n");
4125 while (*Ptr && (Ptr < Opcodes.end())) {
4128 if (Ptr == Opcodes.end()) {
4130 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
4131 "symbol name extends past opcodes for opcode at: 0x" +
4136 SymbolName =
StringRef(
reinterpret_cast<const char*
>(SymStart),
4141 dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
4142 <<
"SymbolName=" << SymbolName <<
"\n");
4149 BindType = ImmValue;
4151 *E =
malformedError(
"for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
4152 Twine((
int)ImmValue) +
" for opcode at: 0x" +
4159 dbgs() <<
"BIND_OPCODE_SET_TYPE_IMM: "
4160 <<
"BindType=" << (
int)BindType <<
"\n");
4163 Addend = readSLEB128(&
error);
4166 " for opcode at: 0x" +
4173 dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: "
4174 <<
"Addend=" << Addend <<
"\n");
4177 SegmentIndex = ImmValue;
4178 SegmentOffset = readULEB128(&
error);
4180 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4186 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4189 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4197 dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
4198 <<
"SegmentIndex=" << SegmentIndex <<
", "
4199 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4203 SegmentOffset += readULEB128(&
error);
4206 " for opcode at: 0x" +
4211 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4215 " for opcode at: 0x" +
4221 dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: "
4222 <<
format(
"SegmentOffset=0x%06X",
4223 SegmentOffset) <<
"\n");
4226 AdvanceAmount = PointerSize;
4227 RemainingLoopCount = 0;
4228 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4232 " for opcode at: 0x" +
4239 "for BIND_OPCODE_DO_BIND missing preceding "
4240 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4245 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4248 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4254 dbgs() <<
"BIND_OPCODE_DO_BIND: "
4255 <<
format(
"SegmentOffset=0x%06X",
4256 SegmentOffset) <<
"\n");
4260 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
4261 "lazy bind table for opcode at: 0x" +
4266 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4277 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4278 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
4284 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4286 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4287 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4292 AdvanceAmount = readULEB128(&
error) + PointerSize;
4303 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4304 AdvanceAmount, PointerSize);
4306 *E =
malformedError(
"for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
4313 RemainingLoopCount = 0;
4316 dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
4317 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4318 <<
", AdvanceAmount=" << AdvanceAmount
4319 <<
", RemainingLoopCount=" << RemainingLoopCount
4324 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
4325 "allowed in lazy bind table for opcode at: 0x" +
4332 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4333 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4339 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4341 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4342 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4348 AdvanceAmount = ImmValue * PointerSize + PointerSize;
4349 RemainingLoopCount = 0;
4350 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4351 AdvanceAmount, PointerSize);
4353 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4361 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4362 <<
format(
"SegmentOffset=0x%06X", SegmentOffset) <<
"\n");
4366 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4367 "allowed in lazy bind table for opcode at: 0x" +
4374 RemainingLoopCount =
Count - 1;
4376 RemainingLoopCount = 0;
4378 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4385 Skip = readULEB128(&
error);
4386 AdvanceAmount = Skip + PointerSize;
4388 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4397 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4398 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4404 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4406 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4407 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4413 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4414 PointerSize,
Count, Skip);
4417 malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4425 dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4426 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4427 <<
", AdvanceAmount=" << AdvanceAmount
4428 <<
", RemainingLoopCount=" << RemainingLoopCount
4441uint64_t MachOBindEntry::readULEB128(
const char **
error) {
4445 if (Ptr > Opcodes.
end())
4446 Ptr = Opcodes.
end();
4450int64_t MachOBindEntry::readSLEB128(
const char **
error) {
4454 if (Ptr > Opcodes.
end())
4455 Ptr = Opcodes.
end();
4468 return "text abs32";
4470 return "text rel32";
4486 return O->BindRebaseSegmentName(SegmentIndex);
4492 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4498 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4502#ifdef EXPENSIVE_CHECKS
4503 assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
4505 assert(Opcodes.data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
4507 return (Ptr ==
Other.Ptr) &&
4508 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
4509 (Done ==
Other.Done);
4514 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4516 uint64_t CurSegAddress;
4517 for (
const SectionRef &Section : Obj->sections()) {
4523 Info.SectionName = *NameOrErr;
4524 Info.Address = Section.getAddress();
4525 Info.Size = Section.getSize();
4527 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4528 if (Info.SegmentName != CurSegName) {
4530 CurSegName = Info.SegmentName;
4531 CurSegAddress = Info.Address;
4533 Info.SegmentIndex = CurSegIndex - 1;
4534 Info.OffsetInSegment = Info.Address - CurSegAddress;
4535 Info.SegmentStartAddress = CurSegAddress;
4536 Sections.push_back(Info);
4538 MaxSegIndex = CurSegIndex;
4554 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4555 if (SegIndex >= MaxSegIndex)
4556 return "bad segIndex (too large)";
4557 for (uint64_t i = 0; i <
Count; ++i) {
4558 uint64_t Start = SegOffset + i * (PointerSize + Skip);
4559 uint64_t
End = Start + PointerSize;
4561 for (
const SectionInfo &
SI : Sections) {
4562 if (
SI.SegmentIndex != SegIndex)
4564 if ((
SI.OffsetInSegment<=Start) && (Start<(
SI.OffsetInSegment+
SI.Size))) {
4565 if (
End <=
SI.OffsetInSegment +
SI.Size) {
4570 return "bad offset, extends beyond section boundary";
4574 return "bad offset, not in section";
4582 for (
const SectionInfo &
SI : Sections) {
4583 if (
SI.SegmentIndex == SegIndex)
4584 return SI.SegmentName;
4591const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4592 int32_t SegIndex, uint64_t SegOffset) {
4593 for (
const SectionInfo &
SI : Sections) {
4594 if (
SI.SegmentIndex != SegIndex)
4596 if (
SI.OffsetInSegment > SegOffset)
4598 if (SegOffset >= (
SI.OffsetInSegment +
SI.Size))
4608 uint64_t SegOffset) {
4609 return findSection(SegIndex, SegOffset).SectionName;
4615 const SectionInfo &
SI = findSection(SegIndex, OffsetInSeg);
4616 return SI.SegmentStartAddress + OffsetInSeg;
4623 if (O->BindRebaseSectionTable ==
nullptr)
4624 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4626 Start.moveToFirst();
4650 if (BindRebaseSectionTable ==
nullptr)
4651 BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(
this);
4654 Start.moveToFirst();
4664 return LoadCommands.begin();
4669 return LoadCommands.end();
4685 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4686 const section_base *
Base =
4687 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4693 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4694 const section_base *
Base =
4695 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4717 return (RE.
r_word1 >> 27) & 1;
4733 return (RE.
r_word0 >> 24) & 0xf;
4771 if (SecNum ==
MachO::R_ABS || SecNum > Sections.size())
4774 DRI.
d.
a = SecNum - 1;
4779 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4784 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4789 unsigned Index)
const {
4795 unsigned Index)
const {
4802 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4808 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4958 Offset = DysymtabLoadCmd.extreloff;
4960 Offset = DysymtabLoadCmd.locreloff;
4966 *
this,
reinterpret_cast<const char *
>(
P));
4971 const char *
P =
reinterpret_cast<const char *
>(Rel.
p);
4986 unsigned Index)
const {
4993 unsigned Index)
const {
5004 Cmd.
cmd = MachO::LC_SYMTAB;
5014 if (DysymtabLoadCmd)
5019 Cmd.
cmd = MachO::LC_DYSYMTAB;
5044 if (DataInCodeLoadCmd)
5049 Cmd.
cmd = MachO::LC_DATA_IN_CODE;
5058 if (LinkOptHintsLoadCmd)
5064 Cmd.
cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
5072 if (!DyldInfoLoadCmd)
5075 auto DyldInfoOrErr =
5086 if (!DyldInfoLoadCmd)
5089 auto DyldInfoOrErr =
5100 if (!DyldInfoLoadCmd)
5103 auto DyldInfoOrErr =
5114 if (!DyldInfoLoadCmd)
5117 auto DyldInfoOrErr =
5128 if (!DyldInfoLoadCmd)
5131 auto DyldInfoOrErr =
5144 if (!DyldChainedFixupsLoadCmd)
5145 return std::nullopt;
5147 *
this, DyldChainedFixupsLoadCmd);
5148 if (!DyldChainedFixupsOrErr)
5149 return DyldChainedFixupsOrErr.takeError();
5151 *DyldChainedFixupsOrErr;
5155 if (!DyldChainedFixups.
dataoff)
5156 return std::nullopt;
5157 return DyldChainedFixups;
5164 return CFOrErr.takeError();
5165 if (!CFOrErr->has_value())
5166 return std::nullopt;
5170 uint64_t CFHeaderOffset = DyldChainedFixups.
dataoff;
5171 uint64_t CFSize = DyldChainedFixups.
datasize;
5174 const char *CFHeaderPtr =
getPtr(*
this, CFHeaderOffset);
5175 auto CFHeaderOrErr =
5178 return CFHeaderOrErr.takeError();
5187 Twine(
"bad chained fixups: unknown imports format: ") +
5193 uint64_t CFImageStartsOffset = (CFHeaderOffset + CFHeader.
starts_offset);
5197 " overlaps with chained fixups header");
5199 uint32_t EndOffset = CFHeaderOffset + CFSize;
5203 Twine(CFImageStartsOffset +
5205 " extends past end " +
Twine(EndOffset));
5215 return CFOrErr.takeError();
5217 std::vector<ChainedFixupsSegment> Segments;
5218 if (!CFOrErr->has_value())
5219 return std::make_pair(0, Segments);
5225 return HeaderOrErr.takeError();
5226 if (!HeaderOrErr->has_value())
5227 return std::make_pair(0, Segments);
5230 const char *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5233 *
this, Contents +
Header.starts_offset);
5234 if (!ImageStartsOrErr)
5235 return ImageStartsOrErr.takeError();
5238 const char *SegOffsPtr =
5239 Contents +
Header.starts_offset +
5241 const char *SegOffsEnd =
5243 if (SegOffsEnd > Contents + DyldChainedFixups.
datasize)
5245 "bad chained fixups: seg_info_offset extends past end");
5247 const char *LastSegEnd =
nullptr;
5252 return OffOrErr.takeError();
5260 " at offset " +
Twine(*OffOrErr) + Message);
5263 const char *SegPtr = Contents +
Header.starts_offset + *OffOrErr;
5264 if (LastSegEnd && SegPtr < LastSegEnd)
5265 return Fail(
" overlaps with previous segment info");
5270 return SegOrErr.takeError();
5273 LastSegEnd = SegPtr + Seg.
size;
5277 const char *PageStart =
5279 const char *PageEnd = PageStart + Seg.
page_count *
sizeof(uint16_t);
5280 if (PageEnd > SegPtr + Seg.
size)
5281 return Fail(
" : page_starts extend past seg_info size");
5285 std::vector<uint16_t> PageStarts;
5286 for (
size_t PageIdx = 0; PageIdx < Seg.
page_count; ++PageIdx) {
5288 memcpy(&Start, PageStart + PageIdx *
sizeof(uint16_t),
sizeof(uint16_t));
5291 PageStarts.push_back(Start);
5294 Segments.emplace_back(
I, *OffOrErr, Seg, std::move(PageStarts));
5297 return std::make_pair(ImageStarts.
seg_count, Segments);
5310template <
typename T,
unsigned N>
5312 std::array<T, N> RawValue;
5313 memcpy(RawValue.data(), Ptr,
N *
sizeof(
T));
5315 for (
auto &Element : RawValue)
5320Expected<std::vector<ChainedFixupTarget>>
5324 return CFOrErr.takeError();
5326 std::vector<ChainedFixupTarget> Targets;
5327 if (!CFOrErr->has_value())
5334 return CFHeaderOrErr.takeError();
5335 if (!(*CFHeaderOrErr))
5339 size_t ImportSize = 0;
5347 return malformedError(
"bad chained fixups: unknown imports format: " +
5350 const char *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5351 const char *Imports = Contents +
Header.imports_offset;
5352 size_t ImportsEndOffset =
5353 Header.imports_offset + ImportSize *
Header.imports_count;
5354 const char *ImportsEnd = Contents + ImportsEndOffset;
5355 const char *Symbols = Contents +
Header.symbols_offset;
5356 const char *SymbolsEnd = Contents + DyldChainedFixups.
datasize;
5358 if (ImportsEnd > Symbols)
5360 Twine(ImportsEndOffset) +
" overlaps with symbols");
5365 return createError(
"parsing big-endian chained fixups is not implemented");
5366 for (
const char *ImportPtr = Imports; ImportPtr < ImportsEnd;
5367 ImportPtr += ImportSize) {
5377 WeakImport = (RawValue[0] >> 8) & 1;
5378 NameOffset = RawValue[0] >> 9;
5381 static_assert(
sizeof(uint64_t) ==
5386 WeakImport = (RawValue[0] >> 8) & 1;
5387 NameOffset = RawValue[0] >> 9;
5390 static_assert(2 *
sizeof(uint64_t) ==
5395 NameOffset = (RawValue[0] >> 16) & 1;
5396 WeakImport = RawValue[0] >> 17;
5397 Addend = RawValue[1];
5402 const char *Str = Symbols + NameOffset;
5403 if (Str >= SymbolsEnd)
5405 Twine(NameOffset) +
" extends past end " +
5407 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5410 return std::move(Targets);
5414 if (!DyldExportsTrieLoadCmd)
5418 *
this, DyldExportsTrieLoadCmd);
5419 if (!DyldExportsTrieOrError)
5428 if (!FuncStartsLoadCmd)
5439 return std::move(FunctionStarts);
5464 uint64_t offset = Index;
5466 while (uint64_t delta = extractor.
getULEB128(&offset)) {
5468 Out.push_back(
data);
5485 size_t MachOFilesetEntryOffset) {
5487 if (Magic ==
"\xFE\xED\xFA\xCE")
5489 UniversalIndex, MachOFilesetEntryOffset);
5490 if (Magic ==
"\xCE\xFA\xED\xFE")
5492 UniversalIndex, MachOFilesetEntryOffset);
5493 if (Magic ==
"\xFE\xED\xFA\xCF")
5495 UniversalIndex, MachOFilesetEntryOffset);
5496 if (Magic ==
"\xCF\xFA\xED\xFE")
5498 UniversalIndex, MachOFilesetEntryOffset);
5505 .
Case(
"debug_str_offs",
"debug_str_offsets")
5516 return std::vector<std::string>();
5522 EC,
"%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5523 Path.str().c_str());
5527 std::vector<std::string> ObjectPaths;
5529 Dir != DirEnd && !EC; Dir.increment(EC)) {
5538 ObjectPaths.push_back(ObjectPath.
str());
5545 if (ObjectPaths.empty())
5547 "%s: no objects found in dSYM bundle",
5548 Path.str().c_str());
5555#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) \
5556 .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
5559#include "llvm/BinaryFormat/Swift.def"
5561#undef HANDLE_SWIFT_SECTION
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define offsetof(TYPE, MEMBER)
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 Error checkTargetTripleCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
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
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...
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
static bool is64Bit(const char *name)
This file implements the C++20 <bit> header.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
Check if the array is empty.
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...
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.
Represent a constant reference to a string, i.e.
static constexpr size_t npos
std::string str() const
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
Check if the string is empty.
char back() const
Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
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.
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(uint64_t Val)
LLVM Value Representation.
A range adaptor for a pair of iterators.
DataRefImpl getRawDataRefImpl() const
StringRef getData() const
unsigned int getType() const
bool isLittleEndian() const
static unsigned int getMachOType(bool isLE, bool is64Bits)
LLVM_ABI StringRef segmentName(int32_t SegIndex)
LLVM_ABI StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)
LLVM_ABI BindRebaseSegInfo(const MachOObjectFile *Obj)
LLVM_ABI const char * checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0)
LLVM_ABI 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...
LLVM_ABI StringRef name() const
LLVM_ABI ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Trie)
LLVM_ABI bool operator==(const ExportEntry &) const
LLVM_ABI StringRef otherName() const
LLVM_ABI uint64_t address() const
LLVM_ABI uint64_t flags() const
LLVM_ABI uint32_t nodeOffset() const
friend class MachOObjectFile
LLVM_ABI uint64_t other() const
LLVM_ABI StringRef sectionName() const
LLVM_ABI uint64_t segmentAddress() const
LLVM_ABI int32_t segmentIndex() const
LLVM_ABI uint64_t address() const
LLVM_ABI StringRef typeName() const
LLVM_ABI int64_t addend() const
LLVM_ABI MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O)
uint64_t textAddress() const
LLVM_ABI uint32_t flags() const
LLVM_ABI StringRef symbolName() const
LLVM_ABI void moveToFirst()
LLVM_ABI int ordinal() const
LLVM_ABI StringRef segmentName() const
LLVM_ABI void moveToEnd()
const MachOObjectFile * O
LLVM_ABI uint64_t segmentOffset() const
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
LLVM_ABI uint32_t flags() const
LLVM_ABI bool operator==(const MachOBindEntry &) const
LLVM_ABI StringRef symbolName() const
LLVM_ABI int ordinal() const
LLVM_ABI StringRef sectionName() const
LLVM_ABI MachOBindEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
LLVM_ABI StringRef segmentName() const
LLVM_ABI uint64_t segmentOffset() const
LLVM_ABI int64_t addend() const
LLVM_ABI uint64_t address() const
friend class MachOObjectFile
LLVM_ABI int32_t segmentIndex() const
LLVM_ABI StringRef typeName() const
LLVM_ABI bool operator==(const MachOChainedFixupEntry &) const
LLVM_ABI MachOChainedFixupEntry(Error *Err, const MachOObjectFile *O, bool Parse)
LLVM_ABI void moveToEnd()
LLVM_ABI void moveToFirst()
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
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
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
LoadCommandList::const_iterator load_command_iterator
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
MachO::target_triple_command getTargetTripleLoadCommand(const LoadCommandInfo &L) 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
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
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
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
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
ArrayRef< uint8_t > getSectionContents(uint64_t Offset, uint64_t Size) const
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) 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.
LLVM_ABI int32_t segmentIndex() const
LLVM_ABI StringRef segmentName() const
LLVM_ABI MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)
LLVM_ABI bool operator==(const MachORebaseEntry &) const
LLVM_ABI uint64_t address() const
LLVM_ABI StringRef sectionName() const
friend class MachOObjectFile
LLVM_ABI uint64_t segmentOffset() const
LLVM_ABI 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
DataRefImpl getRawDataRefImpl() 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.
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.
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
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
@ BIND_SYMBOL_FLAGS_WEAK_IMPORT
@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
@ DYLD_CHAINED_PTR_ARM64E_USERLAND24
@ DYLD_CHAINED_PTR_64_OFFSET
@ DYLD_CHAINED_PTR_ARM64E
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
@ DYLD_CHAINED_PTR_START_NONE
@ 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
constexpr uint32_t S_ATTR_PURE_INSTRUCTIONS
Section contains only true machine instructions.
@ CPU_SUBTYPE_ARM_V8M_BASE
@ CPU_SUBTYPE_ARM_V8M_MAIN
@ CPU_SUBTYPE_ARM_V8_1M_MAIN
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)
const uint32_t x86_EXCEPTION_STATE64_COUNT
const uint32_t x86_THREAD_STATE64_COUNT
constexpr size_t SymbolTableEntrySize
content_iterator< SectionRef > section_iterator
Error createError(const Twine &Err)
content_iterator< MachOBindEntry > bind_iterator
content_iterator< MachOChainedFixupEntry > fixup_iterator
content_iterator< MachORebaseEntry > rebase_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
content_iterator< ExportEntry > export_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< DiceRef > dice_iterator
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI bool is_directory(const basic_file_status &status)
Does status represent a directory?
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
Remove '.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
constexpr bool IsLittleEndianHost
LLVM_ABI std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
void swapByteOrder(T &Value)
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.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct an array ref of bytes from a string ref.
@ Load
The value being inserted comes from a load (InsertElement only).
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
To bit_cast(const From &from) noexcept
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
@ End
Run the machine verifier once, at the end of the pipeline.
void consumeError(Error Err)
Consume a Error without doing anything.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end, const char **error, ULEB128DecodeError *errorCode)
Utility function to decode a ULEB128 value and report a typed error.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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::@005117267142344013370254144343227032034000327225 d