49#include <system_error>
52using namespace object;
64 return make_error<GenericBinaryError>(
"truncated or malformed object (" +
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));
99 uintptr_t CommandAddr =
reinterpret_cast<uintptr_t
>(L.Ptr);
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);
121 return getStruct<MachO::nlist_base>(O,
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())
194 if (
auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj,
Ptr)) {
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");
204 return CmdOrErr.takeError();
212 return malformedError(
"load command 0 extends past the end all load "
213 "commands in the file");
227 " extends past the end all load commands in the file");
235 Err =
malformedError(
"the mach header extends past the end of the "
239 if (
auto HeaderOrErr = getStructOrErr<T>(
241 Header = *HeaderOrErr;
243 Err = HeaderOrErr.takeError();
259 for (
auto it = Elements.begin(); it != Elements.end(); ++it) {
261 if ((
Offset >= E.Offset &&
Offset < E.Offset + E.Size) ||
263 (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size))
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");
295 if (
auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
296 Segment S = SegOrErr.get();
297 const unsigned SectionSize =
sizeof(Section);
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) {
307 auto SectionOrErr = getStructOrErr<Section>(Obj, Sec);
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)
420 auto SymtabOrErr = getStructOrErr<MachO::symtab_command>(Obj, Load.Ptr);
422 return SymtabOrErr.takeError();
426 " has incorrect cmdsize");
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)
479 getStructOrErr<MachO::dysymtab_command>(Obj, Load.Ptr);
481 return DysymtabOrErr.takeError();
485 " has incorrect cmdsize");
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 =
613 getStructOrErr<MachO::linkedit_data_command>(Obj, Load.Ptr);
614 if (!LinkDataOrError)
615 return LinkDataOrError.takeError();
619 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
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 "
651 getStructOrErr<MachO::dyld_info_command>(Obj, Load.Ptr);
653 return DyldInfoOrErr.takeError();
657 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
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");
744 auto CommandOrErr = getStructOrErr<MachO::dylib_command>(Obj, Load.Ptr);
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");
793 auto CommandOrErr = getStructOrErr<MachO::dylinker_command>(Obj, Load.Ptr);
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");
841 auto NoteCmdOrErr = getStructOrErr<MachO::note_command>(Obj, Load.Ptr);
843 return NoteCmdOrErr.takeError();
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 "
868 getStructOrErr<MachO::build_version_command>(Obj, Load.Ptr);
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)
891 " LC_RPATH cmdsize too small");
892 auto ROrErr = getStructOrErr<MachO::rpath_command>(Obj, Load.Ptr);
894 return ROrErr.takeError();
898 " LC_RPATH path.offset field too small, not past "
899 "the end of the rpath_command struct");
900 if (R.path >= R.cmdsize)
902 " LC_RPATH path.offset field extends past the end "
903 "of the load command");
907 const char *
P = (
const char *)Load.Ptr;
908 for (i = R.path; i < R.cmdsize; i++)
913 " LC_RPATH library name extends past the end of the "
922 const char **LoadCmd,
const char *CmdName) {
923 if (*LoadCmd !=
nullptr)
925 "LC_ENCRYPTION_INFO_64 command");
927 if (cryptoff > FileSize)
929 " command " +
Twine(LoadCommandIndex) +
" extends "
930 "past the end of the file");
932 BigSize += cryptsize;
933 if (BigSize > FileSize)
935 Twine(CmdName) +
" command " +
936 Twine(LoadCommandIndex) +
" extends past the end of "
947 " LC_LINKER_OPTION cmdsize too small");
948 auto LinkOptionOrErr =
949 getStructOrErr<MachO::linker_option_command>(Obj, Load.Ptr);
950 if (!LinkOptionOrErr)
951 return LinkOptionOrErr.takeError();
954 const char *
string = (
const char *)Load.Ptr +
959 while (*
string ==
'\0' && left > 0) {
966 if (0xffffffff == NullPos)
968 " LC_LINKER_OPTION string #" +
Twine(i) +
969 " is not NULL terminated");
970 uint32_t len = std::min(NullPos, left) + 1;
977 " LC_LINKER_OPTION string count " +
Twine(L.count) +
978 " does not match number of strings");
984 uint32_t LoadCommandIndex,
const char *CmdName,
985 size_t SizeOfCmd,
const char *CmdStructName,
986 uint32_t PathOffset,
const char *PathFieldName) {
987 if (PathOffset < SizeOfCmd)
989 CmdName +
" " + PathFieldName +
".offset field too "
990 "small, not past the end of the " + CmdStructName);
991 if (PathOffset >= Load.C.cmdsize)
993 CmdName +
" " + PathFieldName +
".offset field "
994 "extends past the end of the load command");
998 const char *
P = (
const char *)Load.Ptr;
999 for (i = PathOffset; i < Load.C.cmdsize; i++)
1002 if (i >= Load.C.cmdsize)
1004 CmdName +
" " + PathFieldName +
" name extends past "
1005 "the end of the load command");
1012 const char *CmdName) {
1015 CmdName +
" cmdsize too small");
1016 auto ThreadCommandOrErr =
1017 getStructOrErr<MachO::thread_command>(Obj, Load.Ptr);
1018 if (!ThreadCommandOrErr)
1019 return ThreadCommandOrErr.takeError();
1022 const char *end = Load.Ptr +
T.cmdsize;
1025 while (state < end) {
1028 "flavor in " + CmdName +
" extends past end of "
1031 memcpy(&flavor, state,
sizeof(
uint32_t));
1038 " count in " + CmdName +
" extends past end of "
1050 " count not x86_THREAD_STATE32_COUNT for "
1051 "flavor number " +
Twine(nflavor) +
" which is "
1052 "a x86_THREAD_STATE32 flavor in " + CmdName +
1056 " x86_THREAD_STATE32 extends past end of "
1057 "command in " + CmdName +
" command");
1061 " unknown flavor (" +
Twine(flavor) +
") for "
1062 "flavor number " +
Twine(nflavor) +
" in " +
1063 CmdName +
" command");
1069 " count not x86_THREAD_STATE_COUNT for "
1070 "flavor number " +
Twine(nflavor) +
" which is "
1071 "a x86_THREAD_STATE flavor in " + CmdName +
1075 " x86_THREAD_STATE extends past end of "
1076 "command in " + CmdName +
" command");
1081 " count not x86_FLOAT_STATE_COUNT for "
1082 "flavor number " +
Twine(nflavor) +
" which is "
1083 "a x86_FLOAT_STATE flavor in " + CmdName +
1087 " x86_FLOAT_STATE extends past end of "
1088 "command in " + CmdName +
" command");
1093 " count not x86_EXCEPTION_STATE_COUNT for "
1094 "flavor number " +
Twine(nflavor) +
" which is "
1095 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1099 " x86_EXCEPTION_STATE extends past end of "
1100 "command in " + CmdName +
" command");
1105 " count not x86_THREAD_STATE64_COUNT for "
1106 "flavor number " +
Twine(nflavor) +
" which is "
1107 "a x86_THREAD_STATE64 flavor in " + CmdName +
1111 " x86_THREAD_STATE64 extends past end of "
1112 "command in " + CmdName +
" command");
1117 " count not x86_EXCEPTION_STATE64_COUNT for "
1118 "flavor number " +
Twine(nflavor) +
" which is "
1119 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1123 " x86_EXCEPTION_STATE64 extends past end of "
1124 "command in " + CmdName +
" command");
1128 " unknown flavor (" +
Twine(flavor) +
") for "
1129 "flavor number " +
Twine(nflavor) +
" in " +
1130 CmdName +
" command");
1136 " count not ARM_THREAD_STATE_COUNT for "
1137 "flavor number " +
Twine(nflavor) +
" which is "
1138 "a ARM_THREAD_STATE flavor in " + CmdName +
1142 " ARM_THREAD_STATE extends past end of "
1143 "command in " + CmdName +
" command");
1147 " unknown flavor (" +
Twine(flavor) +
") for "
1148 "flavor number " +
Twine(nflavor) +
" in " +
1149 CmdName +
" command");
1156 " count not ARM_THREAD_STATE64_COUNT for "
1157 "flavor number " +
Twine(nflavor) +
" which is "
1158 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1162 " ARM_THREAD_STATE64 extends past end of "
1163 "command in " + CmdName +
" command");
1167 " unknown flavor (" +
Twine(flavor) +
") for "
1168 "flavor number " +
Twine(nflavor) +
" in " +
1169 CmdName +
" command");
1175 " count not PPC_THREAD_STATE_COUNT for "
1176 "flavor number " +
Twine(nflavor) +
" which is "
1177 "a PPC_THREAD_STATE flavor in " + CmdName +
1181 " PPC_THREAD_STATE extends past end of "
1182 "command in " + CmdName +
" command");
1186 " unknown flavor (" +
Twine(flavor) +
") for "
1187 "flavor number " +
Twine(nflavor) +
" in " +
1188 CmdName +
" command");
1192 "command " +
Twine(LoadCommandIndex) +
" for " +
1193 CmdName +
" command can't be checked");
1204 const char **LoadCmd,
1205 std::list<MachOElement> &Elements) {
1208 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1209 if (*LoadCmd !=
nullptr)
1210 return malformedError(
"more than one LC_TWOLEVEL_HINTS command");
1211 auto HintsOrErr = getStructOrErr<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1213 return HintsOrErr.takeError();
1216 if (Hints.
offset > FileSize)
1217 return malformedError(
"offset field of LC_TWOLEVEL_HINTS command " +
1218 Twine(LoadCommandIndex) +
" extends past the end of "
1223 if (BigSize > FileSize)
1224 return malformedError(
"offset field plus nhints times sizeof(struct "
1225 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1226 Twine(LoadCommandIndex) +
" extends past the end of "
1232 *LoadCmd = Load.Ptr;
1240 if (
cmd == MachO::LC_SYMSEG ||
1241 cmd == MachO::LC_LOADFVMLIB ||
1242 cmd == MachO::LC_IDFVMLIB ||
1243 cmd == MachO::LC_IDENT ||
1244 cmd == MachO::LC_FVMFILE ||
1245 cmd == MachO::LC_PREPAGE ||
1246 cmd == MachO::LC_PREBOUND_DYLIB ||
1247 cmd == MachO::LC_TWOLEVEL_HINTS ||
1248 cmd == MachO::LC_PREBIND_CKSUM)
1255 bool Is64Bits,
uint32_t UniversalCputype,
1257 size_t MachOFilesetEntryOffset) {
1260 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,
1261 UniversalIndex, MachOFilesetEntryOffset));
1263 return std::move(Err);
1264 return std::move(Obj);
1267MachOObjectFile::MachOObjectFile(
MemoryBufferRef Object,
bool IsLittleEndian,
1268 bool Is64bits,
Error &Err,
1271 size_t MachOFilesetEntryOffset)
1272 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1273 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {
1290 Err =
malformedError(
"load commands extend past the end of the file");
1293 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1295 Twine(UniversalIndex) +
"'s cputype does not match "
1296 "object file's mach header");
1300 Elements.push_back({0, SizeOfHeaders,
"Mach-O headers"});
1303 LoadCommandInfo
Load;
1304 if (LoadCommandCount != 0) {
1308 Err = LoadOrErr.takeError();
1313 const char *DyldIdLoadCmd =
nullptr;
1314 const char *SplitInfoLoadCmd =
nullptr;
1315 const char *CodeSignDrsLoadCmd =
nullptr;
1316 const char *CodeSignLoadCmd =
nullptr;
1317 const char *VersLoadCmd =
nullptr;
1318 const char *SourceLoadCmd =
nullptr;
1319 const char *EntryPointLoadCmd =
nullptr;
1320 const char *EncryptLoadCmd =
nullptr;
1321 const char *RoutinesLoadCmd =
nullptr;
1322 const char *UnixThreadLoadCmd =
nullptr;
1323 const char *TwoLevelHintsLoadCmd =
nullptr;
1324 for (
unsigned I = 0;
I < LoadCommandCount; ++
I) {
1326 if (
Load.C.cmdsize % 8 != 0) {
1331 Load.C.cmd != MachO::LC_THREAD ||
Load.C.cmdsize % 4) {
1338 if (
Load.C.cmdsize % 4 != 0) {
1345 if (
Load.C.cmd == MachO::LC_SYMTAB) {
1348 }
else if (
Load.C.cmd == MachO::LC_DYSYMTAB) {
1352 }
else if (
Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1354 "LC_DATA_IN_CODE", Elements,
1355 "data in code info")))
1357 }
else if (
Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1359 "LC_LINKER_OPTIMIZATION_HINT",
1360 Elements,
"linker optimization "
1363 }
else if (
Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1365 "LC_FUNCTION_STARTS", Elements,
1366 "function starts data")))
1368 }
else if (
Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1370 "LC_SEGMENT_SPLIT_INFO", Elements,
1371 "split info data")))
1373 }
else if (
Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1375 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1376 "code signing RDs data")))
1378 }
else if (
Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1380 "LC_CODE_SIGNATURE", Elements,
1381 "code signature data")))
1383 }
else if (
Load.C.cmd == MachO::LC_DYLD_INFO) {
1385 "LC_DYLD_INFO", Elements)))
1387 }
else if (
Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1389 "LC_DYLD_INFO_ONLY", Elements)))
1391 }
else if (
Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1393 *
this, Load,
I, &DyldChainedFixupsLoadCmd,
1394 "LC_DYLD_CHAINED_FIXUPS", Elements,
"chained fixups")))
1396 }
else if (
Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {
1398 *
this, Load,
I, &DyldExportsTrieLoadCmd,
"LC_DYLD_EXPORTS_TRIE",
1399 Elements,
"exports trie")))
1401 }
else if (
Load.C.cmd == MachO::LC_UUID) {
1411 UuidLoadCmd =
Load.Ptr;
1412 }
else if (
Load.C.cmd == MachO::LC_SEGMENT_64) {
1415 *
this, Load, Sections, HasPageZeroSegment,
I,
1416 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1418 }
else if (
Load.C.cmd == MachO::LC_SEGMENT) {
1421 *
this, Load, Sections, HasPageZeroSegment,
I,
1422 "LC_SEGMENT", SizeOfHeaders, Elements)))
1424 }
else if (
Load.C.cmd == MachO::LC_ID_DYLIB) {
1427 }
else if (
Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1431 }
else if (
Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1435 }
else if (
Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1439 }
else if (
Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1443 }
else if (
Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1447 }
else if (
Load.C.cmd == MachO::LC_ID_DYLINKER) {
1450 }
else if (
Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1453 }
else if (
Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1456 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1458 "LC_VERSION_MIN_MACOSX")))
1460 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1462 "LC_VERSION_MIN_IPHONEOS")))
1464 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1466 "LC_VERSION_MIN_TVOS")))
1468 }
else if (
Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1470 "LC_VERSION_MIN_WATCHOS")))
1472 }
else if (
Load.C.cmd == MachO::LC_NOTE) {
1475 }
else if (
Load.C.cmd == MachO::LC_BUILD_VERSION) {
1478 }
else if (
Load.C.cmd == MachO::LC_RPATH) {
1481 }
else if (
Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1484 " has incorrect cmdsize");
1487 if (SourceLoadCmd) {
1491 SourceLoadCmd =
Load.Ptr;
1492 }
else if (
Load.C.cmd == MachO::LC_MAIN) {
1495 " has incorrect cmdsize");
1498 if (EntryPointLoadCmd) {
1502 EntryPointLoadCmd =
Load.Ptr;
1503 }
else if (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1506 " has incorrect cmdsize");
1510 getStruct<MachO::encryption_info_command>(*
this,
Load.Ptr);
1512 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO")))
1514 }
else if (
Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1517 " has incorrect cmdsize");
1521 getStruct<MachO::encryption_info_command_64>(*
this,
Load.Ptr);
1523 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO_64")))
1525 }
else if (
Load.C.cmd == MachO::LC_LINKER_OPTION) {
1528 }
else if (
Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1531 " LC_SUB_FRAMEWORK cmdsize too small");
1535 getStruct<MachO::sub_framework_command>(*
this,
Load.Ptr);
1538 "sub_framework_command", S.
umbrella,
1541 }
else if (
Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1544 " LC_SUB_UMBRELLA cmdsize too small");
1548 getStruct<MachO::sub_umbrella_command>(*
this,
Load.Ptr);
1554 }
else if (
Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1557 " LC_SUB_LIBRARY cmdsize too small");
1561 getStruct<MachO::sub_library_command>(*
this,
Load.Ptr);
1567 }
else if (
Load.C.cmd == MachO::LC_SUB_CLIENT) {
1570 " LC_SUB_CLIENT cmdsize too small");
1574 getStruct<MachO::sub_client_command>(*
this,
Load.Ptr);
1577 "sub_client_command", S.
client,
"client")))
1579 }
else if (
Load.C.cmd == MachO::LC_ROUTINES) {
1582 " has incorrect cmdsize");
1585 if (RoutinesLoadCmd) {
1586 Err =
malformedError(
"more than one LC_ROUTINES and or LC_ROUTINES_64 "
1590 RoutinesLoadCmd =
Load.Ptr;
1591 }
else if (
Load.C.cmd == MachO::LC_ROUTINES_64) {
1594 " has incorrect cmdsize");
1597 if (RoutinesLoadCmd) {
1598 Err =
malformedError(
"more than one LC_ROUTINES_64 and or LC_ROUTINES "
1602 RoutinesLoadCmd =
Load.Ptr;
1603 }
else if (
Load.C.cmd == MachO::LC_UNIXTHREAD) {
1606 if (UnixThreadLoadCmd) {
1610 UnixThreadLoadCmd =
Load.Ptr;
1611 }
else if (
Load.C.cmd == MachO::LC_THREAD) {
1615 }
else if (
Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1617 &TwoLevelHintsLoadCmd, Elements)))
1619 }
else if (
Load.C.cmd == MachO::LC_IDENT) {
1624 Twine(
Load.C.cmd) +
" is obsolete and not "
1631 if (
I < LoadCommandCount - 1) {
1635 Err = LoadOrErr.takeError();
1640 if (!SymtabLoadCmd) {
1641 if (DysymtabLoadCmd) {
1642 Err =
malformedError(
"contains LC_DYSYMTAB load command without a "
1643 "LC_SYMTAB load command");
1646 }
else if (DysymtabLoadCmd) {
1648 getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
1650 getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
1653 "extends past the end of the symbol table");
1659 Err =
malformedError(
"ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1660 "command extends past the end of the symbol table");
1665 "extends past the end of the symbol table");
1671 Err =
malformedError(
"iextdefsym plus nextdefsym in LC_DYSYMTAB "
1672 "load command extends past the end of the symbol "
1678 "extends past the end of the symbol table");
1684 Err =
malformedError(
"iundefsym plus nundefsym in LC_DYSYMTAB load "
1685 " command extends past the end of the symbol table");
1691 DyldIdLoadCmd ==
nullptr) {
1692 Err =
malformedError(
"no LC_ID_DYLIB load command in dynamic library "
1696 assert(LoadCommands.
size() == LoadCommandCount);
1736 if (NSect == 0 || NSect > Sections.
size())
1738 " for symbol at index " +
Twine(SymbolIndex));
1743 "the end of string table, for N_INDR symbol at "
1744 "index " +
Twine(SymbolIndex));
1750 if (LibraryOrdinal != 0 &&
1753 LibraryOrdinal - 1 >= Libraries.
size() ) {
1755 " for symbol at index " +
Twine(SymbolIndex));
1761 " past the end of string table, for symbol at "
1762 "index " +
Twine(SymbolIndex));
1778 if (Entry.n_strx == 0)
1782 const char *Start = &
StringTable.data()[Entry.n_strx];
1799 return Entry.n_value;
1802 return Entry.n_value;
1818 return std::error_code();
1845 uint8_t n_type = Entry.n_type;
1871 uint8_t MachOType = Entry.n_type;
1872 uint16_t MachOFlags = Entry.n_desc;
1919 DRI.
d.
a = index - 1;
1920 if (DRI.
d.
a >= Sections.
size()){
1930 return Entry.n_sect - 1;
1962 SectOffset = Sect.
offset;
1963 SectSize = Sect.
size;
1967 SectOffset = Sect.
offset;
1968 SectSize = Sect.
size;
1974 if (SectOffset > FileSize)
1976 if (FileSize - SectOffset < SectSize)
1977 return FileSize - SectOffset;
2018 if (SectionIndex < 1 || SectionIndex > Sections.
size())
2022 DRI.
d.
a = SectionIndex - 1;
2028 auto NameOrErr = Section.getName();
2030 return NameOrErr.takeError();
2064 if (!SectionNameOrErr) {
2077template <
typename LoadCommandType>
2081 auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.
Ptr);
2082 if (!SegmentOrErr) {
2086 auto &Segment = SegmentOrErr.get();
2089 Segment.fileoff, Segment.fileoff + Segment.filesize));
2093template <
typename LoadCommandType>
2096 auto SegmentOrErr = getStructOrErr<LoadCommandType>(Obj, LoadCmd.
Ptr);
2097 if (!SegmentOrErr) {
2101 auto &Segment = SegmentOrErr.get();
2102 return arrayRefFromStringRef(
2111 switch (LoadCmd.
C.
cmd) {
2112 case MachO::LC_SEGMENT:
2113 Contents = ::getSegmentContents<MachO::segment_command>(*
this, LoadCmd,
2116 case MachO::LC_SEGMENT_64:
2117 Contents = ::getSegmentContents<MachO::segment_command_64>(*
this, LoadCmd,
2123 if (!Contents.
empty())
2133 switch (LoadCmd.
C.
cmd) {
2134 case MachO::LC_SEGMENT:
2135 if (
Idx == SegmentIndex)
2136 return ::getSegmentContents<MachO::segment_command>(*
this, LoadCmd);
2139 case MachO::LC_SEGMENT_64:
2140 if (
Idx == SegmentIndex)
2141 return ::getSegmentContents<MachO::segment_command_64>(*
this, LoadCmd);
2165 return (SegmentName ==
"__LLVM" && *NameOrErr ==
"__bitcode");
2212 Ret.d.b = DysymtabLoadCmd.
nextrel;
2229 Ret.d.b = DysymtabLoadCmd.
nlocrel;
2240 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2281 unsigned Arch = this->
getArch();
2285 static const char *
const Table[] = {
2286 "GENERIC_RELOC_VANILLA",
2287 "GENERIC_RELOC_PAIR",
2288 "GENERIC_RELOC_SECTDIFF",
2289 "GENERIC_RELOC_PB_LA_PTR",
2290 "GENERIC_RELOC_LOCAL_SECTDIFF",
2291 "GENERIC_RELOC_TLV" };
2300 static const char *
const Table[] = {
2301 "X86_64_RELOC_UNSIGNED",
2302 "X86_64_RELOC_SIGNED",
2303 "X86_64_RELOC_BRANCH",
2304 "X86_64_RELOC_GOT_LOAD",
2306 "X86_64_RELOC_SUBTRACTOR",
2307 "X86_64_RELOC_SIGNED_1",
2308 "X86_64_RELOC_SIGNED_2",
2309 "X86_64_RELOC_SIGNED_4",
2310 "X86_64_RELOC_TLV" };
2319 static const char *
const Table[] = {
2320 "ARM_RELOC_VANILLA",
2322 "ARM_RELOC_SECTDIFF",
2323 "ARM_RELOC_LOCAL_SECTDIFF",
2324 "ARM_RELOC_PB_LA_PTR",
2326 "ARM_THUMB_RELOC_BR22",
2327 "ARM_THUMB_32BIT_BRANCH",
2329 "ARM_RELOC_HALF_SECTDIFF" };
2339 static const char *
const Table[] = {
2340 "ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
2341 "ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
2342 "ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
2343 "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
2344 "ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2345 "ARM64_RELOC_ADDEND",
"ARM64_RELOC_AUTHENTICATED_POINTER"
2348 if (RType >= std::size(Table))
2355 static const char *
const Table[] = {
2356 "PPC_RELOC_VANILLA",
2364 "PPC_RELOC_SECTDIFF",
2365 "PPC_RELOC_PB_LA_PTR",
2366 "PPC_RELOC_HI16_SECTDIFF",
2367 "PPC_RELOC_LO16_SECTDIFF",
2368 "PPC_RELOC_HA16_SECTDIFF",
2370 "PPC_RELOC_LO14_SECTDIFF",
2371 "PPC_RELOC_LOCAL_SECTDIFF" };
2383 Result.append(res.
begin(), res.
end());
2431 size_t a, b, c, d,
Idx;
2433 isFramework =
false;
2437 a =
Name.rfind(
'/');
2438 if (a ==
Name.npos || a == 0)
2440 Foo =
Name.substr(a + 1);
2446 if (Suffix !=
"_debug" && Suffix !=
"_profile")
2453 b =
Name.rfind(
'/', a);
2459 DotFramework =
Name.substr(
Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2460 if (
F == Foo && DotFramework ==
".framework/") {
2468 c =
Name.rfind(
'/', b);
2469 if (c ==
Name.npos || c == 0)
2471 V =
Name.substr(c + 1);
2472 if (!V.starts_with(
"Versions/"))
2474 d =
Name.rfind(
'/', c);
2480 DotFramework =
Name.substr(
Idx + Foo.
size(),
sizeof(
".framework/") - 1);
2481 if (
F == Foo && DotFramework ==
".framework/") {
2488 a =
Name.rfind(
'.');
2489 if (a ==
Name.npos || a == 0)
2491 Dylib =
Name.substr(a);
2492 if (Dylib !=
".dylib")
2497 Dot =
Name.substr(a - 2, 1);
2502 b =
Name.rfind(
'/', a);
2512 if (Suffix !=
"_debug" && Suffix !=
"_profile") {
2521 if (
Lib.size() >= 3) {
2522 Dot =
Lib.substr(
Lib.size() - 2, 1);
2529 Qtx =
Name.substr(a);
2532 b =
Name.rfind(
'/', a);
2538 if (
Lib.size() >= 3) {
2539 Dot =
Lib.substr(
Lib.size() - 2, 1);
2553 if (Index >= Libraries.
size())
2558 if (LibrariesShortNames.
size() == 0) {
2559 for (
unsigned i = 0; i < Libraries.
size(); i++) {
2561 getStructOrErr<MachO::dylib_command>(*
this, Libraries[i]);
2565 if (
D.dylib.name >=
D.cmdsize)
2567 const char *
P = (
const char *)(Libraries[i]) +
D.dylib.name;
2569 if (
D.dylib.name+
Name.size() >=
D.cmdsize)
2574 if (shortName.
empty())
2577 LibrariesShortNames.
push_back(shortName);
2581 Res = LibrariesShortNames[Index];
2582 return std::error_code();
2586 return Libraries.
size();
2592 Sec.
d.
a = Rel->getRawDataRefImpl().d.a;
2599 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2608 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2622 if (!SymtabLoadCmd || Index >= Symtab.
nsyms)
2627 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2639 DRIstart.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2651 DRI.
d.
a = Sections.
size();
2664 return "Mach-O 32-bit i386";
2666 return "Mach-O arm";
2668 return "Mach-O arm64 (ILP32)";
2670 return "Mach-O 32-bit ppc";
2672 return "Mach-O 32-bit unknown";
2678 return "Mach-O 64-bit x86-64";
2680 return "Mach-O arm64";
2682 return "Mach-O 64-bit ppc64";
2684 return "Mach-O 64-bit unknown";
2710 const char **McpuDefault,
2711 const char **ArchFlag) {
2713 *McpuDefault =
nullptr;
2715 *ArchFlag =
nullptr;
2723 return Triple(
"i386-apple-darwin");
2731 *ArchFlag =
"x86_64";
2732 return Triple(
"x86_64-apple-darwin");
2735 *ArchFlag =
"x86_64h";
2736 return Triple(
"x86_64h-apple-darwin");
2744 *ArchFlag =
"armv4t";
2745 return Triple(
"armv4t-apple-darwin");
2748 *ArchFlag =
"armv5e";
2749 return Triple(
"armv5e-apple-darwin");
2752 *ArchFlag =
"xscale";
2753 return Triple(
"xscale-apple-darwin");
2756 *ArchFlag =
"armv6";
2757 return Triple(
"armv6-apple-darwin");
2760 *McpuDefault =
"cortex-m0";
2762 *ArchFlag =
"armv6m";
2763 return Triple(
"armv6m-apple-darwin");
2766 *ArchFlag =
"armv7";
2767 return Triple(
"armv7-apple-darwin");
2770 *McpuDefault =
"cortex-m4";
2772 *ArchFlag =
"armv7em";
2773 return Triple(
"thumbv7em-apple-darwin");
2776 *McpuDefault =
"cortex-a7";
2778 *ArchFlag =
"armv7k";
2779 return Triple(
"armv7k-apple-darwin");
2782 *McpuDefault =
"cortex-m3";
2784 *ArchFlag =
"armv7m";
2785 return Triple(
"thumbv7m-apple-darwin");
2788 *McpuDefault =
"cortex-a7";
2790 *ArchFlag =
"armv7s";
2791 return Triple(
"armv7s-apple-darwin");
2799 *McpuDefault =
"cyclone";
2801 *ArchFlag =
"arm64";
2802 return Triple(
"arm64-apple-darwin");
2805 *McpuDefault =
"apple-a12";
2807 *ArchFlag =
"arm64e";
2808 return Triple(
"arm64e-apple-darwin");
2816 *McpuDefault =
"cyclone";
2818 *ArchFlag =
"arm64_32";
2819 return Triple(
"arm64_32-apple-darwin");
2828 return Triple(
"ppc-apple-darwin");
2836 *ArchFlag =
"ppc64";
2837 return Triple(
"ppc64-apple-darwin");
2856 static const std::array<StringRef, 18> ValidArchs = {{
2902 if (!DataInCodeLoadCmd)
2906 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, DicLC.
dataoff));
2912 if (!DataInCodeLoadCmd)
2924void ExportEntry::moveToFirst() {
2929 pushDownUntilBottom();
2932void ExportEntry::moveToEnd() {
2939 if (Done ||
Other.Done)
2940 return (Done ==
Other.Done);
2945 if (!CumulativeString.
equals(
Other.CumulativeString))
2948 for (
unsigned i=0; i < Stack.
size(); ++i) {
2949 if (Stack[i].Start !=
Other.Stack[i].Start)
2965 return CumulativeString;
2969 return Stack.
back().Flags;
2973 return Stack.
back().Address;
2977 return Stack.
back().Other;
2981 const char* ImportName = Stack.
back().ImportName;
2988 return Stack.
back().Start - Trie.
begin();
2991ExportEntry::NodeState::NodeState(
const uint8_t *
Ptr)
2992 : Start(
Ptr), Current(
Ptr) {}
2994void ExportEntry::pushNode(
uint64_t offset) {
2997 NodeState State(
Ptr);
2998 const char *
error =
nullptr;
2999 uint64_t ExportInfoSize = readULEB128(State.Current, &
error);
3002 " in export trie data at node: 0x" +
3007 State.IsExportNode = (ExportInfoSize != 0);
3008 const uint8_t* Children = State.Current + ExportInfoSize;
3009 if (Children > Trie.
end()) {
3013 " too big and extends past end of trie data");
3017 if (State.IsExportNode) {
3018 const uint8_t *ExportStart = State.Current;
3019 State.Flags = readULEB128(State.Current, &
error);
3022 " in export trie data at node: 0x" +
3028 if (State.Flags != 0 &&
3033 "unsupported exported symbol kind: " +
Twine((
int)
Kind) +
3041 State.Other = readULEB128(State.Current, &
error);
3044 " in export trie data at node: 0x" +
3054 "bad library ordinal: " +
Twine((
int)State.Other) +
" (max " +
3061 State.ImportName =
reinterpret_cast<const char*
>(State.Current);
3062 if (*State.ImportName ==
'\0') {
3067 *E =
malformedError(
"import name of re-export in export trie data at "
3070 " starts past end of trie data");
3077 *E =
malformedError(
"import name of re-export in export trie data at "
3080 " extends past end of trie data");
3084 State.Current =
End + 1;
3087 State.Address = readULEB128(State.Current, &
error);
3090 " in export trie data at node: 0x" +
3096 State.Other = readULEB128(State.Current, &
error);
3099 " in export trie data at node: 0x" +
3106 if (ExportStart + ExportInfoSize < State.Current) {
3108 "inconsistent export info size: 0x" +
3117 if (State.ChildCount != 0 && Children + 1 >= Trie.
end()) {
3118 *E =
malformedError(
"byte for count of children in export trie data at "
3121 " extends past end of trie data");
3126 State.NextChildIndex = 0;
3127 State.ParentStringLength = CumulativeString.
size();
3131void ExportEntry::pushDownUntilBottom() {
3133 const char *
error =
nullptr;
3134 while (Stack.
back().NextChildIndex < Stack.
back().ChildCount) {
3135 NodeState &Top = Stack.
back();
3136 CumulativeString.
resize(Top.ParentStringLength);
3137 for (;*Top.Current != 0 && Top.Current < Trie.
end(); Top.Current++) {
3138 char C = *Top.Current;
3141 if (Top.Current >= Trie.
end()) {
3142 *E =
malformedError(
"edge sub-string in export trie data at node: 0x" +
3144 " for child #" +
Twine((
int)Top.NextChildIndex) +
3145 " extends past end of trie data");
3153 " in export trie data at node: 0x" +
3158 for (
const NodeState &node : nodes()) {
3159 if (node.Start == Trie.
begin() + childNodeIndex){
3160 *E =
malformedError(
"loop in children in export trie data at node: 0x" +
3162 " back to node: 0x" +
3168 Top.NextChildIndex += 1;
3169 pushNode(childNodeIndex);
3173 if (!Stack.
back().IsExportNode) {
3174 *E =
malformedError(
"node is not an export node in export trie data at "
3198 assert(!Stack.
empty() &&
"ExportEntry::moveNext() with empty node stack");
3199 if (!Stack.
back().IsExportNode) {
3200 *E =
malformedError(
"node is not an export node in export trie data at "
3208 while (!Stack.
empty()) {
3209 NodeState &Top = Stack.
back();
3210 if (Top.NextChildIndex < Top.ChildCount) {
3211 pushDownUntilBottom();
3215 if (Top.IsExportNode) {
3217 CumulativeString.
resize(Top.ParentStringLength);
3233 Start.moveToFirst();
3243 if (DyldInfoLoadCmd)
3245 else if (DyldExportsTrieLoadCmd)
3248 return exports(Err, Trie,
this);
3256 if (Command.C.cmd == MachO::LC_SEGMENT) {
3258 if (
StringRef(SLC.segname) ==
"__TEXT") {
3259 TextAddress = SLC.vmaddr;
3262 }
else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3265 TextAddress = SLC_64.
vmaddr;
3326 FixupTargets = *FixupTargetsOrErr;
3328 *
E = FixupTargetsOrErr.takeError();
3333 Segments = std::move(SegmentsOrErr->second);
3335 *
E = SegmentsOrErr.takeError();
3340void MachOChainedFixupEntry::findNextPageWithFixups() {
3341 auto FindInSegment = [
this]() {
3343 while (PageIndex < SegInfo.
PageStarts.size() &&
3346 return PageIndex < SegInfo.
PageStarts.size();
3349 while (InfoSegIndex < Segments.size()) {
3350 if (FindInSegment()) {
3351 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3363 if (Segments.empty()) {
3371 findNextPageWithFixups();
3382 if (InfoSegIndex == Segments.size()) {
3396 " has unsupported chained fixup pointer_format " +
3397 Twine(PointerFormat));
3411 " extends past segment's end");
3423 "by getDyldChainedFixupTargets()");
3430 bool IsBind =
Field(63, 1);
3437 if (ImportOrdinal >= FixupTargets.size()) {
3440 " has out-of range import ordinal " +
3441 Twine(ImportOrdinal));
3448 Addend = InlineAddend ? InlineAddend :
Target.addend();
3462 PageOffset += 4 * Next;
3465 findNextPageWithFixups();
3475 return InfoSegIndex ==
Other.InfoSegIndex && PageIndex ==
Other.PageIndex &&
3476 PageOffset ==
Other.PageOffset;
3481 : E(E), O(O), Opcodes(Bytes),
Ptr(Bytes.begin()),
3482 PointerSize(
is64Bit ? 8 : 4) {}
3484void MachORebaseEntry::moveToFirst() {
3489void MachORebaseEntry::moveToEnd() {
3491 RemainingLoopCount = 0;
3498 SegmentOffset += AdvanceAmount;
3499 if (RemainingLoopCount) {
3500 --RemainingLoopCount;
3509 if (
Ptr == Opcodes.
end()) {
3520 const char *
error =
nullptr;
3529 RebaseType = ImmValue;
3531 *E =
malformedError(
"for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3532 Twine((
int)RebaseType) +
" for opcode at: 0x" +
3539 dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: "
3540 <<
"RebaseType=" << (
int) RebaseType <<
"\n");
3543 SegmentIndex = ImmValue;
3544 SegmentOffset = readULEB128(&
error);
3546 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3555 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3563 dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3564 <<
"SegmentIndex=" << SegmentIndex <<
", "
3565 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3569 SegmentOffset += readULEB128(&
error);
3572 " for opcode at: 0x" +
3581 " for opcode at: 0x" +
3587 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: "
3588 <<
format(
"SegmentOffset=0x%06X",
3589 SegmentOffset) <<
"\n");
3592 SegmentOffset += ImmValue * PointerSize;
3603 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3604 <<
format(
"SegmentOffset=0x%06X",
3605 SegmentOffset) <<
"\n");
3608 AdvanceAmount = PointerSize;
3612 RemainingLoopCount = ImmValue - 1;
3614 RemainingLoopCount = 0;
3616 PointerSize, Count, Skip);
3626 dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3627 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3628 <<
", AdvanceAmount=" << AdvanceAmount
3629 <<
", RemainingLoopCount=" << RemainingLoopCount
3633 AdvanceAmount = PointerSize;
3635 Count = readULEB128(&
error);
3644 RemainingLoopCount = Count - 1;
3646 RemainingLoopCount = 0;
3648 PointerSize, Count, Skip);
3658 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3659 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3660 <<
", AdvanceAmount=" << AdvanceAmount
3661 <<
", RemainingLoopCount=" << RemainingLoopCount
3665 Skip = readULEB128(&
error);
3667 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3673 AdvanceAmount = Skip + PointerSize;
3675 RemainingLoopCount = 0;
3677 PointerSize, Count, Skip);
3679 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3687 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3688 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3689 <<
", AdvanceAmount=" << AdvanceAmount
3690 <<
", RemainingLoopCount=" << RemainingLoopCount
3694 Count = readULEB128(&
error);
3696 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3704 RemainingLoopCount = Count - 1;
3706 RemainingLoopCount = 0;
3707 Skip = readULEB128(&
error);
3709 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3716 AdvanceAmount = Skip + PointerSize;
3719 PointerSize, Count, Skip);
3721 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3730 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3731 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3732 <<
", AdvanceAmount=" << AdvanceAmount
3733 <<
", RemainingLoopCount=" << RemainingLoopCount
3750 if (Ptr > Opcodes.
end())
3760 switch (RebaseType) {
3764 return "text abs32";
3766 return "text rel32";
3790#ifdef EXPENSIVE_CHECKS
3791 assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
3793 assert(Opcodes.
data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
3796 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
3797 (Done ==
Other.Done);
3803 if (O->BindRebaseSectionTable ==
nullptr)
3804 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
3806 Start.moveToFirst();
3820 : E(E), O(O), Opcodes(Bytes),
Ptr(Bytes.begin()),
3821 PointerSize(
is64Bit ? 8 : 4), TableKind(BK) {}
3823void MachOBindEntry::moveToFirst() {
3828void MachOBindEntry::moveToEnd() {
3830 RemainingLoopCount = 0;
3837 SegmentOffset += AdvanceAmount;
3838 if (RemainingLoopCount) {
3839 --RemainingLoopCount;
3848 if (
Ptr == Opcodes.
end()) {
3858 int8_t SignExtended;
3861 const char *
error =
nullptr;
3867 bool NotLastEntry =
false;
3870 NotLastEntry =
true;
3882 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3883 "weak bind table for opcode at: 0x" +
3889 LibraryOrdinalSet =
true;
3891 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3892 "library ordinal: " +
3893 Twine((
int)ImmValue) +
" (max " +
3895 ") for opcode at: 0x" +
3902 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3903 <<
"Ordinal=" << Ordinal <<
"\n");
3907 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3908 "weak bind table for opcode at: 0x" +
3913 Ordinal = readULEB128(&
error);
3914 LibraryOrdinalSet =
true;
3923 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3924 "library ordinal: " +
3925 Twine((
int)Ordinal) +
" (max " +
3927 ") for opcode at: 0x" +
3934 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3935 <<
"Ordinal=" << Ordinal <<
"\n");
3939 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3940 "weak bind table for opcode at: 0x" +
3947 Ordinal = SignExtended;
3949 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3950 "special ordinal: " +
3951 Twine((
int)Ordinal) +
" for opcode at: 0x" +
3958 LibraryOrdinalSet =
true;
3961 dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3962 <<
"Ordinal=" << Ordinal <<
"\n");
3970 if (
Ptr == Opcodes.
end()) {
3972 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3973 "symbol name extends past opcodes for opcode at: 0x" +
3978 SymbolName =
StringRef(
reinterpret_cast<const char*
>(SymStart),
3983 dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3984 <<
"SymbolName=" << SymbolName <<
"\n");
3991 BindType = ImmValue;
3993 *E =
malformedError(
"for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3994 Twine((
int)ImmValue) +
" for opcode at: 0x" +
4001 dbgs() <<
"BIND_OPCODE_SET_TYPE_IMM: "
4002 <<
"BindType=" << (
int)BindType <<
"\n");
4005 Addend = readSLEB128(&
error);
4008 " for opcode at: 0x" +
4015 dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: "
4016 <<
"Addend=" << Addend <<
"\n");
4019 SegmentIndex = ImmValue;
4020 SegmentOffset = readULEB128(&
error);
4022 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4031 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4039 dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
4040 <<
"SegmentIndex=" << SegmentIndex <<
", "
4041 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4045 SegmentOffset += readULEB128(&
error);
4048 " for opcode at: 0x" +
4057 " for opcode at: 0x" +
4063 dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: "
4064 <<
format(
"SegmentOffset=0x%06X",
4065 SegmentOffset) <<
"\n");
4068 AdvanceAmount = PointerSize;
4069 RemainingLoopCount = 0;
4074 " for opcode at: 0x" +
4081 "for BIND_OPCODE_DO_BIND missing preceding "
4082 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4087 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4090 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4096 dbgs() <<
"BIND_OPCODE_DO_BIND: "
4097 <<
format(
"SegmentOffset=0x%06X",
4098 SegmentOffset) <<
"\n");
4102 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
4103 "lazy bind table for opcode at: 0x" +
4119 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4120 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
4126 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4128 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4129 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4134 AdvanceAmount = readULEB128(&
error) + PointerSize;
4146 AdvanceAmount, PointerSize);
4148 *E =
malformedError(
"for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
4155 RemainingLoopCount = 0;
4158 dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
4159 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4160 <<
", AdvanceAmount=" << AdvanceAmount
4161 <<
", RemainingLoopCount=" << RemainingLoopCount
4166 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
4167 "allowed in lazy bind table for opcode at: 0x" +
4174 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4175 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4181 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4183 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4184 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4190 AdvanceAmount = ImmValue * PointerSize + PointerSize;
4191 RemainingLoopCount = 0;
4193 AdvanceAmount, PointerSize);
4195 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4203 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4204 <<
format(
"SegmentOffset=0x%06X", SegmentOffset) <<
"\n");
4208 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4209 "allowed in lazy bind table for opcode at: 0x" +
4214 Count = readULEB128(&
error);
4216 RemainingLoopCount = Count - 1;
4218 RemainingLoopCount = 0;
4220 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4227 Skip = readULEB128(&
error);
4228 AdvanceAmount = Skip + PointerSize;
4230 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4239 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4240 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4246 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
4248 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4249 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4256 PointerSize, Count, Skip);
4259 malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4267 dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4268 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
4269 <<
", AdvanceAmount=" << AdvanceAmount
4270 <<
", RemainingLoopCount=" << RemainingLoopCount
4287 if (Ptr > Opcodes.
end())
4292int64_t MachOBindEntry::readSLEB128(
const char **
error) {
4296 if (Ptr > Opcodes.
end())
4310 return "text abs32";
4312 return "text rel32";
4344#ifdef EXPENSIVE_CHECKS
4345 assert(Opcodes ==
Other.Opcodes &&
"compare iterators of different files");
4347 assert(Opcodes.
data() ==
Other.Opcodes.data() &&
"compare iterators of different files");
4350 (RemainingLoopCount ==
Other.RemainingLoopCount) &&
4351 (Done ==
Other.Done);
4365 Info.SectionName = *NameOrErr;
4366 Info.Address = Section.getAddress();
4367 Info.Size = Section.getSize();
4370 if (
Info.SegmentName != CurSegName) {
4372 CurSegName =
Info.SegmentName;
4373 CurSegAddress =
Info.Address;
4375 Info.SegmentIndex = CurSegIndex - 1;
4376 Info.OffsetInSegment =
Info.Address - CurSegAddress;
4377 Info.SegmentStartAddress = CurSegAddress;
4380 MaxSegIndex = CurSegIndex;
4396 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4397 if (SegIndex >= MaxSegIndex)
4398 return "bad segIndex (too large)";
4399 for (
uint64_t i = 0; i < Count; ++i) {
4400 uint64_t Start = SegOffset + i * (PointerSize + Skip);
4403 for (
const SectionInfo &SI : Sections) {
4404 if (SI.SegmentIndex != SegIndex)
4406 if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4407 if (
End <= SI.OffsetInSegment + SI.Size) {
4412 return "bad offset, extends beyond section boundary";
4416 return "bad offset, not in section";
4424 for (
const SectionInfo &SI : Sections) {
4425 if (SI.SegmentIndex == SegIndex)
4426 return SI.SegmentName;
4433const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4434 int32_t SegIndex,
uint64_t SegOffset) {
4435 for (
const SectionInfo &SI : Sections) {
4436 if (SI.SegmentIndex != SegIndex)
4438 if (SI.OffsetInSegment > SegOffset)
4440 if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4451 return findSection(SegIndex, SegOffset).SectionName;
4457 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4458 return SI.SegmentStartAddress + OffsetInSeg;
4465 if (O->BindRebaseSectionTable ==
nullptr)
4466 O->BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(O);
4468 Start.moveToFirst();
4492 if (BindRebaseSectionTable ==
nullptr)
4493 BindRebaseSectionTable = std::make_unique<BindRebaseSegInfo>(
this);
4496 Start.moveToFirst();
4506 return LoadCommands.
begin();
4511 return LoadCommands.
end();
4527 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4528 const section_base *
Base =
4529 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4535 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4536 const section_base *
Base =
4537 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4559 return (RE.
r_word1 >> 27) & 1;
4575 return (RE.
r_word0 >> 24) & 0xf;
4613 if (SecNum ==
MachO::R_ABS || SecNum > Sections.size())
4616 DRI.
d.
a = SecNum - 1;
4621 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4622 return getStruct<MachO::section>(*
this, Sections[DRI.
d.
a]);
4626 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4627 return getStruct<MachO::section_64>(*
this, Sections[DRI.
d.
a]);
4631 unsigned Index)
const {
4633 return getStruct<MachO::section>(*
this, Sec);
4637 unsigned Index)
const {
4639 return getStruct<MachO::section_64>(*
this, Sec);
4644 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4645 return getStruct<MachO::nlist>(*
this,
P);
4650 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4651 return getStruct<MachO::nlist_64>(*
this,
P);
4656 return getStruct<MachO::linkedit_data_command>(*
this, L.Ptr);
4661 return getStruct<MachO::segment_command>(*
this, L.Ptr);
4666 return getStruct<MachO::segment_command_64>(*
this, L.Ptr);
4671 return getStruct<MachO::linker_option_command>(*
this, L.Ptr);
4676 return getStruct<MachO::version_min_command>(*
this, L.Ptr);
4681 return getStruct<MachO::note_command>(*
this, L.Ptr);
4686 return getStruct<MachO::build_version_command>(*
this, L.Ptr);
4691 return getStruct<MachO::build_tool_version>(*
this, BuildTools[index]);
4696 return getStruct<MachO::dylib_command>(*
this, L.Ptr);
4701 return getStruct<MachO::dyld_info_command>(*
this, L.Ptr);
4706 return getStruct<MachO::dylinker_command>(*
this, L.Ptr);
4711 return getStruct<MachO::uuid_command>(*
this, L.Ptr);
4716 return getStruct<MachO::rpath_command>(*
this, L.Ptr);
4721 return getStruct<MachO::source_version_command>(*
this, L.Ptr);
4726 return getStruct<MachO::entry_point_command>(*
this, L.Ptr);
4731 return getStruct<MachO::encryption_info_command>(*
this, L.Ptr);
4736 return getStruct<MachO::encryption_info_command_64>(*
this, L.Ptr);
4741 return getStruct<MachO::sub_framework_command>(*
this, L.Ptr);
4746 return getStruct<MachO::sub_umbrella_command>(*
this, L.Ptr);
4751 return getStruct<MachO::sub_library_command>(*
this, L.Ptr);
4756 return getStruct<MachO::sub_client_command>(*
this, L.Ptr);
4761 return getStruct<MachO::routines_command>(*
this, L.Ptr);
4766 return getStruct<MachO::routines_command_64>(*
this, L.Ptr);
4771 return getStruct<MachO::thread_command>(*
this, L.Ptr);
4776 return getStruct<MachO::fileset_entry_command>(*
this, L.Ptr);
4802 return getStruct<MachO::any_relocation_info>(
4803 *
this,
reinterpret_cast<const char *
>(
P));
4808 const char *
P =
reinterpret_cast<const char *
>(Rel.
p);
4809 return getStruct<MachO::data_in_code_entry>(*
this,
P);
4823 unsigned Index)
const {
4825 return getStruct<uint32_t>(*
this,
getPtr(*
this,
Offset));
4830 unsigned Index)
const {
4832 return getStruct<MachO::data_in_code_entry>(*
this,
getPtr(*
this,
Offset));
4837 return getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
4841 Cmd.
cmd = MachO::LC_SYMTAB;
4851 if (DysymtabLoadCmd)
4852 return getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
4856 Cmd.
cmd = MachO::LC_DYSYMTAB;
4881 if (DataInCodeLoadCmd)
4882 return getStruct<MachO::linkedit_data_command>(*
this, DataInCodeLoadCmd);
4886 Cmd.
cmd = MachO::LC_DATA_IN_CODE;
4895 if (LinkOptHintsLoadCmd)
4896 return getStruct<MachO::linkedit_data_command>(*
this, LinkOptHintsLoadCmd);
4901 Cmd.
cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4909 if (!DyldInfoLoadCmd)
4912 auto DyldInfoOrErr =
4913 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4923 if (!DyldInfoLoadCmd)
4926 auto DyldInfoOrErr =
4927 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4937 if (!DyldInfoLoadCmd)
4940 auto DyldInfoOrErr =
4941 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4951 if (!DyldInfoLoadCmd)
4954 auto DyldInfoOrErr =
4955 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4965 if (!DyldInfoLoadCmd)
4968 auto DyldInfoOrErr =
4969 getStructOrErr<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4981 if (!DyldChainedFixupsLoadCmd)
4982 return std::nullopt;
4983 auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
4984 *
this, DyldChainedFixupsLoadCmd);
4985 if (!DyldChainedFixupsOrErr)
4986 return DyldChainedFixupsOrErr.takeError();
4988 *DyldChainedFixupsOrErr;
4992 if (!DyldChainedFixups.
dataoff)
4993 return std::nullopt;
4994 return DyldChainedFixups;
5001 return CFOrErr.takeError();
5002 if (!CFOrErr->has_value())
5003 return std::nullopt;
5011 const char *CFHeaderPtr =
getPtr(*
this, CFHeaderOffset);
5012 auto CFHeaderOrErr =
5013 getStructOrErr<MachO::dyld_chained_fixups_header>(*
this, CFHeaderPtr);
5015 return CFHeaderOrErr.takeError();
5024 Twine(
"bad chained fixups: unknown imports format: ") +
5034 " overlaps with chained fixups header");
5036 uint32_t EndOffset = CFHeaderOffset + CFSize;
5040 Twine(CFImageStartsOffset +
5042 " extends past end " +
Twine(EndOffset));
5052 return CFOrErr.takeError();
5054 std::vector<ChainedFixupsSegment> Segments;
5055 if (!CFOrErr->has_value())
5056 return std::make_pair(0, Segments);
5062 return HeaderOrErr.takeError();
5063 if (!HeaderOrErr->has_value())
5064 return std::make_pair(0, Segments);
5067 const char *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5069 auto ImageStartsOrErr = getStructOrErr<MachO::dyld_chained_starts_in_image>(
5070 *
this, Contents +
Header.starts_offset);
5071 if (!ImageStartsOrErr)
5072 return ImageStartsOrErr.takeError();
5075 const char *SegOffsPtr =
5076 Contents +
Header.starts_offset +
5078 const char *SegOffsEnd =
5080 if (SegOffsEnd > Contents + DyldChainedFixups.
datasize)
5082 "bad chained fixups: seg_info_offset extends past end");
5084 const char *LastSegEnd =
nullptr;
5087 getStructOrErr<uint32_t>(*
this, SegOffsPtr +
I *
sizeof(
uint32_t));
5089 return OffOrErr.takeError();
5097 " at offset " +
Twine(*OffOrErr) + Message);
5100 const char *SegPtr = Contents +
Header.starts_offset + *OffOrErr;
5101 if (LastSegEnd && SegPtr < LastSegEnd)
5102 return Fail(
" overlaps with previous segment info");
5105 getStructOrErr<MachO::dyld_chained_starts_in_segment>(*
this, SegPtr);
5107 return SegOrErr.takeError();
5110 LastSegEnd = SegPtr + Seg.
size;
5114 const char *PageStart =
5117 if (PageEnd > SegPtr + Seg.
size)
5118 return Fail(
" : page_starts extend past seg_info size");
5122 std::vector<uint16_t> PageStarts;
5123 for (
size_t PageIdx = 0; PageIdx < Seg.
page_count; ++PageIdx) {
5128 PageStarts.push_back(Start);
5131 Segments.emplace_back(
I, *OffOrErr, Seg, std::move(PageStarts));
5134 return std::make_pair(ImageStarts.
seg_count, Segments);
5143 return SignExtend32<sizeof(T) * CHAR_BIT>(
Value);
5147template <
typename T,
unsigned N>
5149 std::array<T, N> RawValue;
5150 memcpy(RawValue.data(),
Ptr,
N *
sizeof(
T));
5152 for (
auto &Element : RawValue)
5161 return CFOrErr.takeError();
5163 std::vector<ChainedFixupTarget> Targets;
5164 if (!CFOrErr->has_value())
5171 return CFHeaderOrErr.takeError();
5172 if (!(*CFHeaderOrErr))
5176 size_t ImportSize = 0;
5184 return malformedError(
"bad chained fixups: unknown imports format: " +
5187 const char *Contents =
getPtr(*
this, DyldChainedFixups.
dataoff);
5188 const char *Imports = Contents +
Header.imports_offset;
5189 size_t ImportsEndOffset =
5190 Header.imports_offset + ImportSize *
Header.imports_count;
5191 const char *ImportsEnd = Contents + ImportsEndOffset;
5192 const char *Symbols = Contents +
Header.symbols_offset;
5193 const char *SymbolsEnd = Contents + DyldChainedFixups.
datasize;
5195 if (ImportsEnd > Symbols)
5197 Twine(ImportsEndOffset) +
" overlaps with symbols");
5202 return createError(
"parsing big-endian chained fixups is not implemented");
5203 for (
const char *ImportPtr = Imports; ImportPtr < ImportsEnd;
5204 ImportPtr += ImportSize) {
5211 auto RawValue = getArray<uint32_t, 1>(*
this, ImportPtr);
5213 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5214 WeakImport = (RawValue[0] >> 8) & 1;
5215 NameOffset = RawValue[0] >> 9;
5220 auto RawValue = getArray<uint32_t, 2>(*
this, ImportPtr);
5222 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5223 WeakImport = (RawValue[0] >> 8) & 1;
5224 NameOffset = RawValue[0] >> 9;
5225 Addend = bit_cast<int32_t>(RawValue[1]);
5227 static_assert(2 *
sizeof(
uint64_t) ==
5229 auto RawValue = getArray<uint64_t, 2>(*
this, ImportPtr);
5231 LibOrdinal = getEncodedOrdinal<uint16_t>(RawValue[0] & 0xFFFF);
5232 NameOffset = (RawValue[0] >> 16) & 1;
5233 WeakImport = RawValue[0] >> 17;
5234 Addend = RawValue[1];
5239 const char *Str = Symbols + NameOffset;
5240 if (Str >= SymbolsEnd)
5242 Twine(NameOffset) +
" extends past end " +
5244 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5247 return std::move(Targets);
5251 if (!DyldExportsTrieLoadCmd)
5254 auto DyldExportsTrieOrError = getStructOrErr<MachO::linkedit_data_command>(
5255 *
this, DyldExportsTrieLoadCmd);
5256 if (!DyldExportsTrieOrError)
5265 if (!FuncStartsLoadCmd)
5269 getStructOrErr<MachO::linkedit_data_command>(*
this, FuncStartsLoadCmd);
5276 return std::move(FunctionStarts);
5322 size_t MachOFilesetEntryOffset) {
5324 if (Magic ==
"\xFE\xED\xFA\xCE")
5326 UniversalIndex, MachOFilesetEntryOffset);
5327 if (Magic ==
"\xCE\xFA\xED\xFE")
5329 UniversalIndex, MachOFilesetEntryOffset);
5330 if (Magic ==
"\xFE\xED\xFA\xCF")
5332 UniversalIndex, MachOFilesetEntryOffset);
5333 if (Magic ==
"\xCF\xFA\xED\xFE")
5335 UniversalIndex, MachOFilesetEntryOffset);
5336 return make_error<GenericBinaryError>(
"Unrecognized MachO magic number",
5342 .
Case(
"debug_str_offs",
"debug_str_offsets")
5353 return std::vector<std::string>();
5359 EC,
"%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5360 Path.str().c_str());
5364 std::vector<std::string> ObjectPaths;
5366 Dir != DirEnd && !EC; Dir.increment(EC)) {
5375 ObjectPaths.push_back(ObjectPath.
str());
5382 if (ObjectPaths.empty())
5384 "%s: no objects found in dSYM bundle",
5385 Path.str().c_str());
5392#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) \
5393 .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
5396#include "llvm/BinaryFormat/Swift.def"
5398#undef HANDLE_SWIFT_SECTION
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define offsetof(TYPE, MEMBER)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
static Error parseBuildVersionCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &BuildTools, uint32_t LoadCommandIndex)
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
static const char * getPtr(const MachOObjectFile &O, size_t Offset, size_t MachOFilesetEntryOffset=0)
static Error parseSegmentLoadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &Sections, bool &IsPageZeroSegment, uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders, std::list< MachOElement > &Elements)
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static Error checkSubCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName, size_t SizeOfCmd, const char *CmdStructName, uint32_t PathOffset, const char *PathFieldName)
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static T getStruct(const MachOObjectFile &O, const char *P)
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
static std::array< T, N > getArray(const MachOObjectFile &O, const void *Ptr)
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements, const char *ElementName)
static Error malformedError(const Twine &Msg)
static bool isLoadCommandObsolete(uint32_t cmd)
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
static int getEncodedOrdinal(T Value)
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
static StringRef parseSegmentOrSectionName(const char *P)
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
static unsigned getCPUType(const MachOObjectFile &O)
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
static Error checkNoteCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, std::list< MachOElement > &Elements)
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
static unsigned getCPUSubType(const MachOObjectFile &O)
static Error checkEncryptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, uint64_t cryptoff, uint64_t cryptsize, const char **LoadCmd, const char *CmdName)
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
static Error malformedError(Twine Msg)
OptimizedStructLayoutField Field
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 bool is64Bit(const char *name)
This file implements the C++20 <bit> header.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
StringRef getBuffer() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
bool equals(StringRef RHS) const
Check for string equality.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
constexpr size_t size() const
Returns the byte size of the table.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
LLVM Value Representation.
A range adaptor for a pair of iterators.
StringRef getData() const
unsigned int getType() const
bool isLittleEndian() const
static unsigned int getMachOType(bool isLE, bool is64Bits)
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
LLVM_ABI uint64_t other() const
MachOAbstractFixupEntry is an abstract class representing a fixup in a MH_DYLDLINK file.
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
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
const char * RebaseEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const
uint64_t getRelocationOffset(DataRefImpl Rel) const override
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
void moveSymbolNext(DataRefImpl &Symb) const override
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
MachO::dysymtab_command getDysymtabLoadCommand() const
iterator_range< bind_iterator > bindTable(Error &Err)
For use iterating over all bind table entries.
MachO::mach_header Header
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
MachO::section_64 getSection64(DataRefImpl DRI) const
MachO::fileset_entry_command getFilesetEntryLoadCommand(const LoadCommandInfo &L) const
MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
ArrayRef< uint8_t > getSectionContents(uint32_t Offset, uint64_t Size) const
const char * BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0) const
section_iterator section_begin() const override
Error checkSymbolTable() const
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
bool isDebugSection(DataRefImpl Sec) const override
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
unsigned getSectionType(SectionRef Sec) const
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
dice_iterator end_dices() const
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
SmallVector< uint64_t > getFunctionStarts() const
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
ArrayRef< uint8_t > getDyldExportsTrie() const
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
bool isSectionBSS(DataRefImpl Sec) const override
Expected< std::pair< size_t, std::vector< ChainedFixupsSegment > > > getChainedFixupsSegments() const
bool isSectionVirtual(DataRefImpl Sec) const override
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
symbol_iterator getSymbolByIndex(unsigned Index) const
static Triple getHostArch()
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
const MachO::mach_header & getHeader() const
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
iterator_range< bind_iterator > weakBindTable(Error &Err)
For use iterating over all weak bind table entries.
static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch)
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
iterator_range< load_command_iterator > load_commands() const
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
MachO::symtab_command getSymtabLoadCommand() const
Triple getArchTriple(const char **McpuDefault=nullptr) const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getUuid() const
uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the address.
bool is64Bit() const override
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
uint64_t getRelocationType(DataRefImpl Rel) const override
StringRef BindRebaseSegmentName(int32_t SegIndex) const
For use with the SegIndex of a checked Mach-O Bind or Rebase entry to get the segment name.
relocation_iterator extrel_begin() const
void moveRelocationNext(DataRefImpl &Rel) const override
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
basic_symbol_iterator symbol_end() const override
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
bool isSectionStripped(DataRefImpl Sec) const override
When dsymutil generates the companion file, it strips all unnecessary sections (e....
uint64_t getSectionIndex(DataRefImpl Sec) const override
iterator_range< fixup_iterator > fixupTable(Error &Err)
For iterating over all chained fixups.
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the section ...
iterator_range< bind_iterator > lazyBindTable(Error &Err)
For use iterating over all lazy bind table entries.
load_command_iterator end_load_commands() const
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
uint64_t getSectionAddress(DataRefImpl Sec) const override
bool hasPageZeroSegment() const
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
uint8_t getRelocationLength(DataRefImpl Rel) const
llvm::binaryformat::Swift5ReflectionSectionKind mapReflectionSectionNameToEnumValue(StringRef SectionName) const override
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
static bool isValidArch(StringRef ArchFlag)
bool isSectionText(DataRefImpl Sec) const override
bool isSectionCompressed(DataRefImpl Sec) const override
static ArrayRef< StringRef > getValidArchs()
bool isSectionBitcode(DataRefImpl Sec) const override
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
relocation_iterator locrel_begin() const
Expected< std::optional< MachO::dyld_chained_fixups_header > > getChainedFixupsHeader() const
If the optional is std::nullopt, no header was found, but the object was well-formed.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
StringRef getStringTableData() const
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
uint64_t getNValue(DataRefImpl Sym) const
ArrayRef< uint8_t > getSegmentContents(StringRef SegmentName) const
Return the raw contents of an entire segment.
section_iterator getRelocationSection(DataRefImpl Rel) const
unsigned getSectionID(SectionRef Sec) const
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
size_t getMachOFilesetEntryOffset() const
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
uint64_t getSectionSize(DataRefImpl Sec) const override
relocation_iterator extrel_end() const
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
relocation_iterator locrel_end() const
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
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
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
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
bool isData() const
Whether this section contains data, not instructions.
bool isBSS() const
Whether this section contains BSS uninitialized data.
This is a value type class that represents a single symbol in the list of symbols in the object file.
directory_iterator - Iterates through the entries in path.
Represents the result of a call to sys::fs::status().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
const uint32_t x86_FLOAT_STATE_COUNT
@ DYLD_CHAINED_IMPORT_ADDEND
@ DYLD_CHAINED_IMPORT_ADDEND64
const uint32_t ARM_THREAD_STATE64_COUNT
@ EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
@ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
@ EXPORT_SYMBOL_FLAGS_KIND_REGULAR
@ BIND_TYPE_TEXT_ABSOLUTE32
const uint32_t x86_EXCEPTION_STATE_COUNT
@ REBASE_TYPE_TEXT_ABSOLUTE32
@ REBASE_TYPE_TEXT_PCREL32
@ S_ATTR_PURE_INSTRUCTIONS
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
@ BIND_SYMBOL_FLAGS_WEAK_IMPORT
@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
@ S_GB_ZEROFILL
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
@ S_THREAD_LOCAL_ZEROFILL
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
@ S_ZEROFILL
S_ZEROFILL - Zero fill on demand section.
@ BIND_SPECIAL_DYLIB_WEAK_LOOKUP
@ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
@ BIND_SPECIAL_DYLIB_FLAT_LOOKUP
@ DYLD_CHAINED_PTR_64_OFFSET
uint8_t GET_COMM_ALIGN(uint16_t n_desc)
void swapStruct(fat_header &mh)
const uint32_t x86_THREAD_STATE32_COUNT
@ CPU_SUBTYPE_POWERPC_ALL
@ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
@ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
@ BIND_OPCODE_SET_ADDEND_SLEB
@ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
@ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
@ BIND_OPCODE_ADD_ADDR_ULEB
@ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
@ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
@ BIND_OPCODE_SET_TYPE_IMM
@ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
@ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
const uint32_t PPC_THREAD_STATE_COUNT
const uint32_t ARM_THREAD_STATE_COUNT
@ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
@ REBASE_OPCODE_DO_REBASE_IMM_TIMES
@ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
@ REBASE_OPCODE_DO_REBASE_ULEB_TIMES
@ REBASE_OPCODE_ADD_ADDR_ULEB
@ REBASE_OPCODE_SET_TYPE_IMM
@ REBASE_OPCODE_ADD_ADDR_IMM_SCALED
const uint32_t x86_THREAD_STATE_COUNT
@ CPU_SUBTYPE_ARM64_32_V8
@ GENERIC_RELOC_LOCAL_SECTDIFF
@ ARM_RELOC_LOCAL_SECTDIFF
@ ARM_RELOC_HALF_SECTDIFF
@ X86_64_RELOC_SUBTRACTOR
uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
@ DYLD_CHAINED_PTR_START_NONE
const uint32_t x86_EXCEPTION_STATE64_COUNT
@ EXPORT_SYMBOL_FLAGS_REEXPORT
@ EXPORT_SYMBOL_FLAGS_KIND_MASK
@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
const uint32_t x86_THREAD_STATE64_COUNT
constexpr size_t SymbolTableEntrySize
Error createError(const Twine &Err)
content_iterator< ExportEntry > export_iterator
content_iterator< MachOChainedFixupEntry > fixup_iterator
content_iterator< DiceRef > dice_iterator
content_iterator< SectionRef > section_iterator
content_iterator< MachOBindEntry > bind_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
content_iterator< MachORebaseEntry > rebase_iterator
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)
In-place remove any '.
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.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ no_such_file_or_directory
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.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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::@378 d