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