33 using namespace object;
44 std::string StringMsg =
"truncated or malformed object (" + Msg.
str() +
")";
45 return make_error<GenericBinaryError>(std::move(StringMsg),
53 if (P < O.getData().begin() || P +
sizeof(
T) > O.getData().end())
57 memcpy(&Cmd, P,
sizeof(
T));
66 if (P < O.getData().begin() || P +
sizeof(
T) > O.getData().end())
70 memcpy(&Cmd, P,
sizeof(
T));
79 uintptr_t CommandAddr =
reinterpret_cast<uintptr_t
>(L.
Ptr);
81 bool Is64 = O.is64Bit();
87 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec *
SectionSize;
88 return reinterpret_cast<const char*
>(SectionAddr);
91 static const char *
getPtr(
const MachOObjectFile &O,
size_t Offset) {
92 return O.getData().substr(Offset, 1).data();
97 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
98 return getStruct<MachO::nlist_base>(O,
P);
117 return O.getHeader().cputype;
132 if (O.isLittleEndian())
144 if (O.isLittleEndian())
156 if (O.isLittleEndian())
174 if (
auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
175 if (CmdOrErr->cmdsize < 8)
177 " with size less than 8 bytes");
180 return CmdOrErr.takeError();
188 return malformedError(
"load command 0 extends past the end all load "
189 "commands in the file");
199 Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
201 " extends past the end all load commands in the file");
205 template <
typename T>
208 if (
sizeof(
T) > Obj.getData().size()) {
209 Err =
malformedError(
"the mach header extends past the end of the "
213 if (
auto HeaderOrErr = getStructOrErr<T>(Obj,
getPtr(Obj, 0)))
214 Header = *HeaderOrErr;
216 Err = HeaderOrErr.takeError();
227 uint64_t
Offset, uint64_t Size,
232 for (
auto it=Elements.begin() ; it != Elements.end(); ++it) {
234 if ((Offset >=
E.Offset && Offset <
E.Offset +
E.Size) ||
235 (Offset + Size >
E.Offset && Offset + Size <
E.Offset +
E.Size) ||
236 (Offset <= E.Offset && Offset + Size >=
E.Offset +
E.Size))
238 " with a size of " +
Twine(Size) +
", overlaps " +
239 E.Name +
" at offset " +
Twine(
E.Offset) +
" with "
240 "a size of " +
Twine(
E.Size));
243 if (nt != Elements.end()) {
245 if (Offset + Size <=
N.Offset) {
246 Elements.insert(nt, {
Offset, Size, Name});
251 Elements.push_back({
Offset, Size, Name});
258 template <
typename Segment,
typename Section>
262 uint32_t LoadCommandIndex,
const char *CmdName, uint64_t SizeOfHeaders,
263 std::list<MachOElement> &Elements) {
264 const unsigned SegmentLoadSize =
sizeof(Segment);
265 if (Load.
C.
cmdsize < SegmentLoadSize)
267 " " + CmdName +
" cmdsize too small");
268 if (
auto SegOrErr = getStructOrErr<Segment>(Obj, Load.
Ptr)) {
269 Segment S = SegOrErr.get();
271 uint64_t FileSize = Obj.getData().size();
272 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
273 S.nsects * SectionSize > Load.
C.
cmdsize - SegmentLoadSize)
275 " inconsistent cmdsize in " + CmdName +
276 " for the number of sections");
277 for (
unsigned J = 0; J < S.nsects; ++J) {
280 Section s = getStruct<Section>(Obj, Sec);
287 CmdName +
" command " +
Twine(LoadCommandIndex) +
288 " extends past the end of the file");
293 s.offset < SizeOfHeaders && s.size != 0)
295 CmdName +
" command " +
Twine(LoadCommandIndex) +
296 " not past the headers of the file");
297 uint64_t BigSize = s.offset;
304 return malformedError(
"offset field plus size field of section " +
305 Twine(J) +
" in " + CmdName +
" command " +
306 Twine(LoadCommandIndex) +
307 " extends past the end of the file");
314 Twine(J) +
" in " + CmdName +
" command " +
315 Twine(LoadCommandIndex) +
316 " greater than the segment");
321 CmdName +
" command " +
Twine(LoadCommandIndex) +
322 " less than the segment's vmaddr");
325 uint64_t BigEnd = S.vmaddr;
327 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
329 " in " + CmdName +
" command " +
330 Twine(LoadCommandIndex) +
331 " greater than than "
332 "the segment's vmaddr plus vmsize");
340 if (s.reloff > FileSize)
342 CmdName +
" command " +
Twine(LoadCommandIndex) +
343 " extends past the end of the file");
347 if (BigSize > FileSize)
348 return malformedError(
"reloff field plus nreloc field times sizeof("
349 "struct relocation_info) of section " +
350 Twine(J) +
" in " + CmdName +
" command " +
351 Twine(LoadCommandIndex) +
352 " extends past the end of the file");
356 "section relocation entries"))
359 if (S.fileoff > FileSize)
361 " fileoff field in " + CmdName +
362 " extends past the end of the file");
363 uint64_t BigSize = S.fileoff;
364 BigSize += S.filesize;
365 if (BigSize > FileSize)
367 " fileoff field plus filesize field in " +
368 CmdName +
" extends past the end of the file");
369 if (S.vmsize != 0 && S.filesize > S.vmsize)
371 " fileoff field in " + CmdName +
372 " greater than vmsize field");
375 return SegOrErr.takeError();
383 const char **SymtabLoadCmd,
384 std::list<MachOElement> &Elements) {
387 " LC_SYMTAB cmdsize too small");
388 if (*SymtabLoadCmd !=
nullptr)
391 getStruct<MachO::symtab_command>(Obj, Load.
Ptr);
394 " has incorrect cmdsize");
395 uint64_t FileSize = Obj.getData().size();
396 if (Symtab.
symoff > FileSize)
398 Twine(LoadCommandIndex) +
" extends past the end "
400 uint64_t SymtabSize = Symtab.
nsyms;
401 const char *struct_nlist_name;
404 struct_nlist_name =
"struct nlist_64";
407 struct_nlist_name =
"struct nlist";
409 uint64_t BigSize = SymtabSize;
411 if (BigSize > FileSize)
412 return malformedError(
"symoff field plus nsyms field times sizeof(" +
413 Twine(struct_nlist_name) +
") of LC_SYMTAB command " +
414 Twine(LoadCommandIndex) +
" extends past the end "
419 if (Symtab.
stroff > FileSize)
421 Twine(LoadCommandIndex) +
" extends past the end "
425 if (BigSize > FileSize)
426 return malformedError(
"stroff field plus strsize field of LC_SYMTAB "
427 "command " +
Twine(LoadCommandIndex) +
" extends "
428 "past the end of the file");
430 Symtab.
strsize,
"string table"))
432 *SymtabLoadCmd = Load.
Ptr;
439 const char **DysymtabLoadCmd,
440 std::list<MachOElement> &Elements) {
443 " LC_DYSYMTAB cmdsize too small");
444 if (*DysymtabLoadCmd !=
nullptr)
447 getStruct<MachO::dysymtab_command>(Obj, Load.
Ptr);
450 " has incorrect cmdsize");
451 uint64_t FileSize = Obj.getData().size();
452 if (Dysymtab.
tocoff > FileSize)
454 Twine(LoadCommandIndex) +
" extends past the end of "
456 uint64_t BigSize = Dysymtab.
ntoc;
458 BigSize += Dysymtab.
tocoff;
459 if (BigSize > FileSize)
460 return malformedError(
"tocoff field plus ntoc field times sizeof(struct "
461 "dylib_table_of_contents) of LC_DYSYMTAB command " +
462 Twine(LoadCommandIndex) +
" extends past the end of "
465 Dysymtab.
ntoc *
sizeof(
struct
467 "table of contents"))
471 Twine(LoadCommandIndex) +
" extends past the end of "
474 const char *struct_dylib_module_name;
475 uint64_t sizeof_modtab;
478 struct_dylib_module_name =
"struct dylib_module_64";
481 struct_dylib_module_name =
"struct dylib_module";
483 BigSize *= sizeof_modtab;
485 if (BigSize > FileSize)
486 return malformedError(
"modtaboff field plus nmodtab field times sizeof(" +
487 Twine(struct_dylib_module_name) +
") of LC_DYSYMTAB "
488 "command " +
Twine(LoadCommandIndex) +
" extends "
489 "past the end of the file");
491 Dysymtab.
nmodtab * sizeof_modtab,
495 return malformedError(
"extrefsymoff field of LC_DYSYMTAB command " +
496 Twine(LoadCommandIndex) +
" extends past the end of "
501 if (BigSize > FileSize)
502 return malformedError(
"extrefsymoff field plus nextrefsyms field times "
503 "sizeof(struct dylib_reference) of LC_DYSYMTAB "
504 "command " +
Twine(LoadCommandIndex) +
" extends "
505 "past the end of the file");
512 return malformedError(
"indirectsymoff field of LC_DYSYMTAB command " +
513 Twine(LoadCommandIndex) +
" extends past the end of "
518 if (BigSize > FileSize)
519 return malformedError(
"indirectsymoff field plus nindirectsyms field times "
520 "sizeof(uint32_t) of LC_DYSYMTAB command " +
521 Twine(LoadCommandIndex) +
" extends past the end of "
530 Twine(LoadCommandIndex) +
" extends past the end of "
535 if (BigSize > FileSize)
536 return malformedError(
"extreloff field plus nextrel field times sizeof"
537 "(struct relocation_info) of LC_DYSYMTAB command " +
538 Twine(LoadCommandIndex) +
" extends past the end of "
543 "external relocation table"))
547 Twine(LoadCommandIndex) +
" extends past the end of "
552 if (BigSize > FileSize)
553 return malformedError(
"locreloff field plus nlocrel field times sizeof"
554 "(struct relocation_info) of LC_DYSYMTAB command " +
555 Twine(LoadCommandIndex) +
" extends past the end of "
560 "local relocation table"))
562 *DysymtabLoadCmd = Load.
Ptr;
569 const char **LoadCmd,
const char *CmdName,
570 std::list<MachOElement> &Elements,
571 const char *ElementName) {
574 CmdName +
" cmdsize too small");
575 if (*LoadCmd !=
nullptr)
578 getStruct<MachO::linkedit_data_command>(Obj, Load.
Ptr);
581 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
582 uint64_t FileSize = Obj.getData().size();
583 if (LinkData.
dataoff > FileSize)
585 Twine(LoadCommandIndex) +
" extends past the end of "
587 uint64_t BigSize = LinkData.
dataoff;
589 if (BigSize > FileSize)
591 Twine(CmdName) +
" command " +
592 Twine(LoadCommandIndex) +
" extends past the end of "
604 const char **LoadCmd,
const char *CmdName,
605 std::list<MachOElement> &Elements) {
608 CmdName +
" cmdsize too small");
609 if (*LoadCmd !=
nullptr)
610 return malformedError(
"more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
613 getStruct<MachO::dyld_info_command>(Obj, Load.
Ptr);
616 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
617 uint64_t FileSize = Obj.getData().size();
620 " command " +
Twine(LoadCommandIndex) +
" extends "
621 "past the end of the file");
624 if (BigSize > FileSize)
625 return malformedError(
"rebase_off field plus rebase_size field of " +
626 Twine(CmdName) +
" command " +
627 Twine(LoadCommandIndex) +
" extends past the end of "
635 " command " +
Twine(LoadCommandIndex) +
" extends "
636 "past the end of the file");
639 if (BigSize > FileSize)
641 Twine(CmdName) +
" command " +
642 Twine(LoadCommandIndex) +
" extends past the end of "
650 " command " +
Twine(LoadCommandIndex) +
" extends "
651 "past the end of the file");
654 if (BigSize > FileSize)
655 return malformedError(
"weak_bind_off field plus weak_bind_size field of " +
656 Twine(CmdName) +
" command " +
657 Twine(LoadCommandIndex) +
" extends past the end of "
661 "dyld weak bind info"))
665 " command " +
Twine(LoadCommandIndex) +
" extends "
666 "past the end of the file");
669 if (BigSize > FileSize)
670 return malformedError(
"lazy_bind_off field plus lazy_bind_size field of " +
671 Twine(CmdName) +
" command " +
672 Twine(LoadCommandIndex) +
" extends past the end of "
676 "dyld lazy bind info"))
680 " command " +
Twine(LoadCommandIndex) +
" extends "
681 "past the end of the file");
684 if (BigSize > FileSize)
685 return malformedError(
"export_off field plus export_size field of " +
686 Twine(CmdName) +
" command " +
687 Twine(LoadCommandIndex) +
" extends past the end of "
699 uint32_t LoadCommandIndex,
const char *CmdName) {
702 CmdName +
" cmdsize too small");
706 CmdName +
" name.offset field too small, not past "
707 "the end of the dylib_command struct");
710 CmdName +
" name.offset field extends past the end "
711 "of the load command");
715 const char *
P = (
const char *)Load.
Ptr;
721 CmdName +
" library name extends past the end of the "
729 const char **LoadCmd) {
733 if (*LoadCmd !=
nullptr)
737 return malformedError(
"LC_ID_DYLIB load command in non-dynamic library "
745 uint32_t LoadCommandIndex,
const char *CmdName) {
748 CmdName +
" cmdsize too small");
752 CmdName +
" name.offset field too small, not past "
753 "the end of the dylinker_command struct");
756 CmdName +
" name.offset field extends past the end "
757 "of the load command");
761 const char *
P = (
const char *)Load.
Ptr;
767 CmdName +
" dyld name extends past the end of the "
775 const char **LoadCmd,
const char *CmdName) {
778 CmdName +
" has incorrect cmdsize");
779 if (*LoadCmd !=
nullptr)
781 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
782 "LC_VERSION_MIN_WATCHOS command");
792 " LC_RPATH cmdsize too small");
796 " LC_RPATH path.offset field too small, not past "
797 "the end of the rpath_command struct");
800 " LC_RPATH path.offset field extends past the end "
801 "of the load command");
805 const char *
P = (
const char *)Load.
Ptr;
811 " LC_RPATH library name extends past the end of the "
819 uint64_t cryptoff, uint64_t cryptsize,
820 const char **LoadCmd,
const char *CmdName) {
821 if (*LoadCmd !=
nullptr)
823 "LC_ENCRYPTION_INFO_64 command");
824 uint64_t FileSize = Obj.getData().size();
825 if (cryptoff > FileSize)
827 " command " +
Twine(LoadCommandIndex) +
" extends "
828 "past the end of the file");
829 uint64_t BigSize = cryptoff;
830 BigSize += cryptsize;
831 if (BigSize > FileSize)
833 Twine(CmdName) +
" command " +
834 Twine(LoadCommandIndex) +
" extends past the end of "
845 " LC_LINKER_OPTION cmdsize too small");
847 getStruct<MachO::linker_option_command>(Obj, Load.
Ptr);
849 const char *
string = (
const char *)Load.
Ptr +
854 while (*
string ==
'\0' && left > 0) {
868 " LC_LINKER_OPTION string count " +
Twine(L.
count) +
869 " does not match number of strings");
875 uint32_t LoadCommandIndex,
const char *CmdName,
876 size_t SizeOfCmd,
const char *CmdStructName,
877 uint32_t PathOffset,
const char *PathFieldName) {
878 if (PathOffset < SizeOfCmd)
880 CmdName +
" " + PathFieldName +
".offset field too "
881 "small, not past the end of the " + CmdStructName);
884 CmdName +
" " + PathFieldName +
".offset field "
885 "extends past the end of the load command");
889 const char *
P = (
const char *)Load.
Ptr;
895 CmdName +
" " + PathFieldName +
" name extends past "
896 "the end of the load command");
903 const char *CmdName) {
906 CmdName +
" cmdsize too small");
908 getStruct<MachO::thread_command>(Obj, Load.
Ptr);
913 while (state < end) {
916 "flavor in " + CmdName +
" extends past end of "
919 memcpy(&flavor, state,
sizeof(
uint32_t));
926 " count in " + CmdName +
" extends past end of "
929 memcpy(&count, state,
sizeof(
uint32_t));
938 " count not x86_THREAD_STATE64_COUNT for "
939 "flavor number " +
Twine(nflavor) +
" which is "
940 "a x86_THREAD_STATE64 flavor in " + CmdName +
944 " x86_THREAD_STATE64 extends past end of "
945 "command in " + CmdName +
" command");
949 " unknown flavor (" +
Twine(flavor) +
") for "
950 "flavor number " +
Twine(nflavor) +
" in " +
951 CmdName +
" command");
957 " count not ARM_THREAD_STATE_COUNT for "
958 "flavor number " +
Twine(nflavor) +
" which is "
959 "a ARM_THREAD_STATE flavor in " + CmdName +
963 " ARM_THREAD_STATE extends past end of "
964 "command in " + CmdName +
" command");
968 " unknown flavor (" +
Twine(flavor) +
") for "
969 "flavor number " +
Twine(nflavor) +
" in " +
970 CmdName +
" command");
976 " count not ARM_THREAD_STATE64_COUNT for "
977 "flavor number " +
Twine(nflavor) +
" which is "
978 "a ARM_THREAD_STATE64 flavor in " + CmdName +
982 " ARM_THREAD_STATE64 extends past end of "
983 "command in " + CmdName +
" command");
987 " unknown flavor (" +
Twine(flavor) +
") for "
988 "flavor number " +
Twine(nflavor) +
" in " +
989 CmdName +
" command");
995 " count not PPC_THREAD_STATE_COUNT for "
996 "flavor number " +
Twine(nflavor) +
" which is "
997 "a PPC_THREAD_STATE flavor in " + CmdName +
1001 " PPC_THREAD_STATE extends past end of "
1002 "command in " + CmdName +
" command");
1006 " unknown flavor (" +
Twine(flavor) +
") for "
1007 "flavor number " +
Twine(nflavor) +
" in " +
1008 CmdName +
" command");
1012 "command " +
Twine(LoadCommandIndex) +
" for " +
1013 CmdName +
" command can't be checked");
1024 const char **LoadCmd,
1025 std::list<MachOElement> &Elements) {
1028 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1029 if (*LoadCmd !=
nullptr)
1030 return malformedError(
"more than one LC_TWOLEVEL_HINTS command");
1032 getStruct<MachO::twolevel_hints_command>(Obj, Load.
Ptr);
1033 uint64_t FileSize = Obj.getData().size();
1034 if (Hints.
offset > FileSize)
1035 return malformedError(
"offset field of LC_TWOLEVEL_HINTS command " +
1036 Twine(LoadCommandIndex) +
" extends past the end of "
1038 uint64_t BigSize = Hints.
nhints;
1041 if (BigSize > FileSize)
1042 return malformedError(
"offset field plus nhints times sizeof(struct "
1043 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1044 Twine(LoadCommandIndex) +
" extends past the end of "
1050 *LoadCmd = Load.
Ptr;
1058 if (cmd == MachO::LC_SYMSEG ||
1059 cmd == MachO::LC_LOADFVMLIB ||
1060 cmd == MachO::LC_IDFVMLIB ||
1061 cmd == MachO::LC_IDENT ||
1062 cmd == MachO::LC_FVMFILE ||
1063 cmd == MachO::LC_PREPAGE ||
1064 cmd == MachO::LC_PREBOUND_DYLIB ||
1065 cmd == MachO::LC_TWOLEVEL_HINTS ||
1066 cmd == MachO::LC_PREBIND_CKSUM)
1073 bool Is64Bits,
uint32_t UniversalCputype,
1076 std::unique_ptr<MachOObjectFile> Obj(
1078 Is64Bits, Err, UniversalCputype,
1081 return std::move(Err);
1082 return std::move(Obj);
1085 MachOObjectFile::MachOObjectFile(
MemoryBufferRef Object,
bool IsLittleEndian,
1086 bool Is64bits,
Error &Err,
1089 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1090 SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
1091 DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
1092 DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
1093 HasPageZeroSegment(
false) {
1095 uint64_t SizeOfHeaders;
1110 Err =
malformedError(
"load commands extend past the end of the file");
1113 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1115 Twine(UniversalIndex) +
"'s cputype does not match "
1116 "object file's mach header");
1119 std::list<MachOElement> Elements;
1120 Elements.push_back({0, SizeOfHeaders,
"Mach-O headers"});
1123 LoadCommandInfo
Load;
1124 if (LoadCommandCount != 0) {
1128 Err = LoadOrErr.takeError();
1133 const char *DyldIdLoadCmd =
nullptr;
1134 const char *FuncStartsLoadCmd =
nullptr;
1135 const char *SplitInfoLoadCmd =
nullptr;
1136 const char *CodeSignDrsLoadCmd =
nullptr;
1137 const char *CodeSignLoadCmd =
nullptr;
1138 const char *VersLoadCmd =
nullptr;
1139 const char *SourceLoadCmd =
nullptr;
1140 const char *EntryPointLoadCmd =
nullptr;
1141 const char *EncryptLoadCmd =
nullptr;
1142 const char *RoutinesLoadCmd =
nullptr;
1143 const char *UnixThreadLoadCmd =
nullptr;
1144 const char *TwoLevelHintsLoadCmd =
nullptr;
1145 for (
unsigned I = 0;
I < LoadCommandCount; ++
I) {
1147 if (Load.C.cmdsize % 8 != 0) {
1152 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1159 if (Load.C.cmdsize % 4 != 0) {
1166 if (Load.C.cmd == MachO::LC_SYMTAB) {
1169 }
else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1173 }
else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1175 "LC_DATA_IN_CODE", Elements,
1176 "data in code info")))
1178 }
else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1180 "LC_LINKER_OPTIMIZATION_HINT",
1181 Elements,
"linker optimization "
1184 }
else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1186 "LC_FUNCTION_STARTS", Elements,
1187 "function starts data")))
1189 }
else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1191 "LC_SEGMENT_SPLIT_INFO", Elements,
1192 "split info data")))
1194 }
else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1196 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1197 "code signing RDs data")))
1199 }
else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1201 "LC_CODE_SIGNATURE", Elements,
1202 "code signature data")))
1204 }
else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1206 "LC_DYLD_INFO", Elements)))
1208 }
else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1210 "LC_DYLD_INFO_ONLY", Elements)))
1212 }
else if (Load.C.cmd == MachO::LC_UUID) {
1222 UuidLoadCmd = Load.Ptr;
1223 }
else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1226 *
this, Load, Sections, HasPageZeroSegment,
I,
1227 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1229 }
else if (Load.C.cmd == MachO::LC_SEGMENT) {
1232 *
this, Load, Sections, HasPageZeroSegment,
I,
1233 "LC_SEGMENT", SizeOfHeaders, Elements)))
1235 }
else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1238 }
else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1242 }
else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1246 }
else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1250 }
else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1254 }
else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1258 }
else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1261 }
else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1264 }
else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1267 }
else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1269 "LC_VERSION_MIN_MACOSX")))
1271 }
else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1273 "LC_VERSION_MIN_IPHONEOS")))
1275 }
else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1277 "LC_VERSION_MIN_TVOS")))
1279 }
else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1281 "LC_VERSION_MIN_WATCHOS")))
1283 }
else if (Load.C.cmd == MachO::LC_RPATH) {
1286 }
else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1289 " has incorrect cmdsize");
1292 if (SourceLoadCmd) {
1296 SourceLoadCmd = Load.Ptr;
1297 }
else if (Load.C.cmd == MachO::LC_MAIN) {
1300 " has incorrect cmdsize");
1303 if (EntryPointLoadCmd) {
1307 EntryPointLoadCmd = Load.Ptr;
1308 }
else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1311 " has incorrect cmdsize");
1315 getStruct<MachO::encryption_info_command>(*
this, Load.Ptr);
1317 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO")))
1319 }
else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1322 " has incorrect cmdsize");
1326 getStruct<MachO::encryption_info_command_64>(*
this, Load.Ptr);
1328 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO_64")))
1330 }
else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1333 }
else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1336 " LC_SUB_FRAMEWORK cmdsize too small");
1340 getStruct<MachO::sub_framework_command>(*
this, Load.Ptr);
1343 "sub_framework_command", S.
umbrella,
1346 }
else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1349 " LC_SUB_UMBRELLA cmdsize too small");
1353 getStruct<MachO::sub_umbrella_command>(*
this, Load.Ptr);
1359 }
else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1362 " LC_SUB_LIBRARY cmdsize too small");
1366 getStruct<MachO::sub_library_command>(*
this, Load.Ptr);
1372 }
else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1375 " LC_SUB_CLIENT cmdsize too small");
1379 getStruct<MachO::sub_client_command>(*
this, Load.Ptr);
1382 "sub_client_command", S.
client,
"client")))
1384 }
else if (Load.C.cmd == MachO::LC_ROUTINES) {
1387 " has incorrect cmdsize");
1390 if (RoutinesLoadCmd) {
1391 Err =
malformedError(
"more than one LC_ROUTINES and or LC_ROUTINES_64 "
1395 RoutinesLoadCmd = Load.Ptr;
1396 }
else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1399 " has incorrect cmdsize");
1402 if (RoutinesLoadCmd) {
1403 Err =
malformedError(
"more than one LC_ROUTINES_64 and or LC_ROUTINES "
1407 RoutinesLoadCmd = Load.Ptr;
1408 }
else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1411 if (UnixThreadLoadCmd) {
1415 UnixThreadLoadCmd = Load.Ptr;
1416 }
else if (Load.C.cmd == MachO::LC_THREAD) {
1420 }
else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1422 &TwoLevelHintsLoadCmd, Elements)))
1426 Twine(Load.C.cmd) +
" is obsolete and not "
1433 if (
I < LoadCommandCount - 1) {
1437 Err = LoadOrErr.takeError();
1442 if (!SymtabLoadCmd) {
1443 if (DysymtabLoadCmd) {
1444 Err =
malformedError(
"contains LC_DYSYMTAB load command without a "
1445 "LC_SYMTAB load command");
1448 }
else if (DysymtabLoadCmd) {
1450 getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
1452 getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
1453 if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.
nsyms) {
1455 "extends past the end of the symbol table");
1458 uint64_t BigSize = Dysymtab.ilocalsym;
1459 BigSize += Dysymtab.nlocalsym;
1460 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.
nsyms) {
1461 Err =
malformedError(
"ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1462 "command extends past the end of the symbol table");
1465 if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.
nsyms) {
1467 "extends past the end of the symbol table");
1470 BigSize = Dysymtab.iextdefsym;
1471 BigSize += Dysymtab.nextdefsym;
1472 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.
nsyms) {
1473 Err =
malformedError(
"iextdefsym plus nextdefsym in LC_DYSYMTAB "
1474 "load command extends past the end of the symbol "
1478 if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.
nsyms) {
1480 "extends past the end of the symbol table");
1483 BigSize = Dysymtab.iundefsym;
1484 BigSize += Dysymtab.nundefsym;
1485 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.
nsyms) {
1486 Err =
malformedError(
"iundefsym plus nundefsym in LC_DYSYMTAB load "
1487 " command extends past the end of the symbol table");
1493 DyldIdLoadCmd ==
nullptr) {
1494 Err =
malformedError(
"no LC_ID_DYLIB load command in dynamic library "
1498 assert(LoadCommands.
size() == LoadCommandCount);
1516 uint64_t NValue = 0;
1539 if (NSect == 0 || NSect > Sections.
size())
1541 " for symbol at index " +
Twine(SymbolIndex));
1543 if ((NType & MachO::N_STAB) == 0 &&
1547 "the end of string table, for N_INDR symbol at "
1548 "index " +
Twine(SymbolIndex));
1551 (((NType & MachO::N_TYPE) ==
MachO::N_UNDF && NValue == 0) ||
1554 if (LibraryOrdinal != 0 &&
1557 LibraryOrdinal - 1 >= Libraries.
size() ) {
1559 " for symbol at index " +
Twine(SymbolIndex));
1564 " past the end of string table, for symbol at "
1565 "index " +
Twine(SymbolIndex));
1572 unsigned SymbolTableEntrySize =
is64Bit() ?
1575 Symb.
p += SymbolTableEntrySize;
1581 const char *Start = &StringTable.
data()[Entry.
n_strx];
1613 if (NValue >= StringTable.
size())
1615 const char *Start = &StringTable.
data()[NValue];
1617 return std::error_code();
1620 uint64_t MachOObjectFile::getSymbolValueImpl(
DataRefImpl Sym)
const {
1644 uint8_t n_type = Entry.
n_type;
1658 if (Sec->isData() || Sec->isBSS())
1668 uint8_t MachOType = Entry.
n_type;
1669 uint16_t MachOFlags = Entry.
n_desc;
1707 uint8_t index = Entry.
n_sect;
1712 DRI.
d.
a = index - 1;
1713 if (DRI.
d.
a >= Sections.
size()){
1734 return std::error_code();
1753 SectOffset = Sect.
offset;
1754 SectSize = Sect.
size;
1758 SectOffset = Sect.
offset;
1759 SectSize = Sect.
size;
1765 if (SectOffset > FileSize)
1767 if (FileSize - SectOffset < SectSize)
1768 return FileSize - SectOffset;
1788 return std::error_code();
1801 return uint64_t(1) << Align;
1842 return (SegmentName ==
"__LLVM" && SectName ==
"__bitcode");
1876 "Only implemented for MH_OBJECT");
1893 unsigned SymbolTableEntrySize =
is64Bit() ?
1896 uint64_t
Offset = S.
symoff + SymbolIdx * SymbolTableEntrySize;
1898 Sym.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
1917 unsigned Arch = this->
getArch();
1921 static const char *
const Table[] = {
1922 "GENERIC_RELOC_VANILLA",
1923 "GENERIC_RELOC_PAIR",
1924 "GENERIC_RELOC_SECTDIFF",
1925 "GENERIC_RELOC_PB_LA_PTR",
1926 "GENERIC_RELOC_LOCAL_SECTDIFF",
1927 "GENERIC_RELOC_TLV" };
1936 static const char *
const Table[] = {
1937 "X86_64_RELOC_UNSIGNED",
1938 "X86_64_RELOC_SIGNED",
1939 "X86_64_RELOC_BRANCH",
1940 "X86_64_RELOC_GOT_LOAD",
1942 "X86_64_RELOC_SUBTRACTOR",
1943 "X86_64_RELOC_SIGNED_1",
1944 "X86_64_RELOC_SIGNED_2",
1945 "X86_64_RELOC_SIGNED_4",
1946 "X86_64_RELOC_TLV" };
1955 static const char *
const Table[] = {
1956 "ARM_RELOC_VANILLA",
1958 "ARM_RELOC_SECTDIFF",
1959 "ARM_RELOC_LOCAL_SECTDIFF",
1960 "ARM_RELOC_PB_LA_PTR",
1962 "ARM_THUMB_RELOC_BR22",
1963 "ARM_THUMB_32BIT_BRANCH",
1965 "ARM_RELOC_HALF_SECTDIFF" };
1974 static const char *
const Table[] = {
1975 "ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
1976 "ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
1977 "ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
1978 "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
1979 "ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
1980 "ARM64_RELOC_ADDEND"
1990 static const char *
const Table[] = {
1991 "PPC_RELOC_VANILLA",
1999 "PPC_RELOC_SECTDIFF",
2000 "PPC_RELOC_PB_LA_PTR",
2001 "PPC_RELOC_HI16_SECTDIFF",
2002 "PPC_RELOC_LO16_SECTDIFF",
2003 "PPC_RELOC_HA16_SECTDIFF",
2005 "PPC_RELOC_LO14_SECTDIFF",
2006 "PPC_RELOC_LOCAL_SECTDIFF" };
2057 StringRef Foo,
F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2058 size_t a, b, c, d, Idx;
2060 isFramework =
false;
2064 a = Name.
rfind(
'/');
2065 if (a == Name.
npos || a == 0)
2070 Idx = Foo.
rfind(
'_');
2071 if (Idx != Foo.
npos && Foo.
size() >= 2) {
2073 Foo = Foo.
slice(0, Idx);
2077 b = Name.
rfind(
'/', a);
2083 DotFramework = Name.
slice(Idx + Foo.
size(),
2084 Idx + Foo.
size() +
sizeof(
".framework/")-1);
2085 if (F == Foo && DotFramework ==
".framework/") {
2093 c = Name.
rfind(
'/', b);
2094 if (c == Name.
npos || c == 0)
2099 d = Name.
rfind(
'/', c);
2105 DotFramework = Name.
slice(Idx + Foo.
size(),
2106 Idx + Foo.
size() +
sizeof(
".framework/")-1);
2107 if (F == Foo && DotFramework ==
".framework/") {
2114 a = Name.
rfind(
'.');
2115 if (a == Name.
npos || a == 0)
2118 if (Dylib !=
".dylib")
2123 Dot = Name.
slice(a-2, a-1);
2128 b = Name.
rfind(
'/', a);
2134 Idx = Name.
find(
'_', b);
2135 if (Idx != Name.
npos && Idx != b) {
2136 Lib = Name.
slice(b, Idx);
2137 Suffix = Name.
slice(Idx, a);
2140 Lib = Name.
slice(b, a);
2143 if (Lib.
size() >= 3) {
2154 b = Name.
rfind(
'/', a);
2156 Lib = Name.
slice(0, a);
2158 Lib = Name.
slice(b+1, a);
2160 if (Lib.
size() >= 3) {
2175 if (Index >= Libraries.
size())
2180 if (LibrariesShortNames.
size() == 0) {
2181 for (
unsigned i = 0;
i < Libraries.
size();
i++) {
2183 getStruct<MachO::dylib_command>(*
this, Libraries[
i]);
2186 const char *
P = (
const char *)(Libraries[
i]) + D.
dylib.
name;
2193 if (shortName.
empty())
2196 LibrariesShortNames.
push_back(shortName);
2200 Res = LibrariesShortNames[Index];
2201 return std::error_code();
2207 Sec.
d.
a = Rel->getRawDataRefImpl().d.a;
2214 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2223 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2226 unsigned SymbolTableEntrySize =
is64Bit() ?
2230 Symtab.
nsyms * SymbolTableEntrySize;
2231 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
2237 if (!SymtabLoadCmd || Index >= Symtab.
nsyms)
2239 unsigned SymbolTableEntrySize =
2242 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2243 DRI.
p += Index * SymbolTableEntrySize;
2251 unsigned SymbolTableEntrySize =
2254 DRIstart.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2255 uint64_t Index = (Symb.
p - DRIstart.
p) / SymbolTableEntrySize;
2266 DRI.
d.
a = Sections.
size();
2279 return "Mach-O 32-bit i386";
2281 return "Mach-O arm";
2283 return "Mach-O 32-bit ppc";
2285 return "Mach-O 32-bit unknown";
2291 return "Mach-O 64-bit x86-64";
2293 return "Mach-O arm64";
2295 return "Mach-O 64-bit ppc64";
2297 return "Mach-O 64-bit unknown";
2321 const char **McpuDefault,
2322 const char **ArchFlag) {
2324 *McpuDefault =
nullptr;
2326 *ArchFlag =
nullptr;
2334 return Triple(
"i386-apple-darwin");
2342 *ArchFlag =
"x86_64";
2343 return Triple(
"x86_64-apple-darwin");
2346 *ArchFlag =
"x86_64h";
2347 return Triple(
"x86_64h-apple-darwin");
2355 *ArchFlag =
"armv4t";
2356 return Triple(
"armv4t-apple-darwin");
2359 *ArchFlag =
"armv5e";
2360 return Triple(
"armv5e-apple-darwin");
2363 *ArchFlag =
"xscale";
2364 return Triple(
"xscale-apple-darwin");
2367 *ArchFlag =
"armv6";
2368 return Triple(
"armv6-apple-darwin");
2371 *McpuDefault =
"cortex-m0";
2373 *ArchFlag =
"armv6m";
2374 return Triple(
"armv6m-apple-darwin");
2377 *ArchFlag =
"armv7";
2378 return Triple(
"armv7-apple-darwin");
2381 *McpuDefault =
"cortex-m4";
2383 *ArchFlag =
"armv7em";
2384 return Triple(
"thumbv7em-apple-darwin");
2387 *ArchFlag =
"armv7k";
2388 return Triple(
"armv7k-apple-darwin");
2391 *McpuDefault =
"cortex-m3";
2393 *ArchFlag =
"armv7m";
2394 return Triple(
"thumbv7m-apple-darwin");
2397 *ArchFlag =
"armv7s";
2398 return Triple(
"armv7s-apple-darwin");
2406 *ArchFlag =
"arm64";
2407 return Triple(
"arm64-apple-darwin");
2416 return Triple(
"ppc-apple-darwin");
2424 *ArchFlag =
"ppc64";
2425 return Triple(
"ppc64-apple-darwin");
2441 .
Case(
"x86_64",
true)
2442 .
Case(
"x86_64h",
true)
2443 .
Case(
"armv4t",
true)
2445 .
Case(
"armv5e",
true)
2446 .
Case(
"armv6",
true)
2447 .
Case(
"armv6m",
true)
2448 .
Case(
"armv7",
true)
2449 .
Case(
"armv7em",
true)
2450 .
Case(
"armv7k",
true)
2451 .
Case(
"armv7m",
true)
2452 .
Case(
"armv7s",
true)
2453 .
Case(
"arm64",
true)
2455 .
Case(
"ppc64",
true)
2481 if (!DataInCodeLoadCmd)
2485 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, DicLC.
dataoff));
2491 if (!DataInCodeLoadCmd)
2496 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
2503 void ExportEntry::moveToFirst() {
2505 pushDownUntilBottom();
2508 void ExportEntry::moveToEnd() {
2515 if (Done || Other.Done)
2516 return (Done == Other.Done);
2518 if (Stack.
size() != Other.Stack.
size())
2521 if (!CumulativeString.
equals(Other.CumulativeString))
2524 for (
unsigned i=0;
i < Stack.
size(); ++
i) {
2525 if (Stack[
i].Start != Other.Stack[
i].Start)
2531 uint64_t ExportEntry::readULEB128(
const uint8_t *&
Ptr) {
2535 if (Ptr > Trie.
end()) {
2543 return CumulativeString;
2547 return Stack.
back().Flags;
2551 return Stack.
back().Address;
2555 return Stack.
back().Other;
2559 const char* ImportName = Stack.
back().ImportName;
2566 return Stack.
back().Start - Trie.
begin();
2569 ExportEntry::NodeState::NodeState(
const uint8_t *Ptr)
2571 ImportName(nullptr), ChildCount(0), NextChildIndex(0),
2572 ParentStringLength(0), IsExportNode(
false) {}
2574 void ExportEntry::pushNode(uint64_t offset) {
2575 const uint8_t *Ptr = Trie.
begin() + offset;
2576 NodeState State(Ptr);
2577 uint64_t ExportInfoSize = readULEB128(State.Current);
2578 State.IsExportNode = (ExportInfoSize != 0);
2579 const uint8_t* Children = State.Current + ExportInfoSize;
2580 if (State.IsExportNode) {
2581 State.Flags = readULEB128(State.Current);
2584 State.Other = readULEB128(State.Current);
2585 State.ImportName =
reinterpret_cast<const char*
>(State.Current);
2587 State.Address = readULEB128(State.Current);
2589 State.Other = readULEB128(State.Current);
2592 State.ChildCount = *Children;
2593 State.Current = Children + 1;
2594 State.NextChildIndex = 0;
2595 State.ParentStringLength = CumulativeString.
size();
2599 void ExportEntry::pushDownUntilBottom() {
2600 while (Stack.
back().NextChildIndex < Stack.
back().ChildCount) {
2601 NodeState &Top = Stack.
back();
2602 CumulativeString.
resize(Top.ParentStringLength);
2603 for (;*Top.Current != 0; Top.Current++) {
2604 char C = *Top.Current;
2608 uint64_t childNodeIndex = readULEB128(Top.Current);
2609 Top.NextChildIndex += 1;
2610 pushNode(childNodeIndex);
2612 if (!Stack.
back().IsExportNode) {
2634 if (Stack.
empty() || !Stack.
back().IsExportNode) {
2641 while (!Stack.
empty()) {
2642 NodeState &Top = Stack.
back();
2643 if (Top.NextChildIndex < Top.ChildCount) {
2644 pushDownUntilBottom();
2648 if (Top.IsExportNode) {
2650 CumulativeString.
resize(Top.ParentStringLength);
2662 if (Trie.
size() == 0)
2665 Start.moveToFirst();
2678 : Opcodes(Bytes), Ptr(Bytes.
begin()), SegmentOffset(0), SegmentIndex(0),
2679 RemainingLoopCount(0), AdvanceAmount(0),
RebaseType(0),
2680 PointerSize(is64Bit ? 8 : 4), Malformed(
false), Done(
false) {}
2682 void MachORebaseEntry::moveToFirst() {
2683 Ptr = Opcodes.
begin();
2687 void MachORebaseEntry::moveToEnd() {
2688 Ptr = Opcodes.
end();
2689 RemainingLoopCount = 0;
2695 SegmentOffset += AdvanceAmount;
2696 if (RemainingLoopCount) {
2697 --RemainingLoopCount;
2700 if (Ptr == Opcodes.
end()) {
2705 while (More && !Malformed) {
2707 uint8_t Byte = *Ptr++;
2721 llvm::dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: "
2722 <<
"RebaseType=" << (
int)
RebaseType <<
"\n");
2725 SegmentIndex = ImmValue;
2726 SegmentOffset = readULEB128();
2729 llvm::dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2730 <<
"SegmentIndex=" << SegmentIndex <<
", "
2731 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2735 SegmentOffset += readULEB128();
2737 llvm::dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: "
2738 <<
format(
"SegmentOffset=0x%06X",
2739 SegmentOffset) <<
"\n");
2742 SegmentOffset += ImmValue * PointerSize;
2744 llvm::dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
2745 <<
format(
"SegmentOffset=0x%06X",
2746 SegmentOffset) <<
"\n");
2749 AdvanceAmount = PointerSize;
2750 RemainingLoopCount = ImmValue - 1;
2753 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
2754 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2755 <<
", AdvanceAmount=" << AdvanceAmount
2756 <<
", RemainingLoopCount=" << RemainingLoopCount
2760 AdvanceAmount = PointerSize;
2761 RemainingLoopCount = readULEB128() - 1;
2764 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
2765 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2766 <<
", AdvanceAmount=" << AdvanceAmount
2767 <<
", RemainingLoopCount=" << RemainingLoopCount
2771 AdvanceAmount = readULEB128() + PointerSize;
2772 RemainingLoopCount = 0;
2775 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
2776 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2777 <<
", AdvanceAmount=" << AdvanceAmount
2778 <<
", RemainingLoopCount=" << RemainingLoopCount
2782 RemainingLoopCount = readULEB128() - 1;
2783 AdvanceAmount = readULEB128() + PointerSize;
2786 llvm::dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
2787 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2788 <<
", AdvanceAmount=" << AdvanceAmount
2789 <<
", RemainingLoopCount=" << RemainingLoopCount
2798 uint64_t MachORebaseEntry::readULEB128() {
2802 if (Ptr > Opcodes.
end()) {
2803 Ptr = Opcodes.
end();
2818 return "text abs32";
2820 return "text rel32";
2826 #ifdef EXPENSIVE_CHECKS
2827 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
2829 assert(Opcodes.
data() == Other.Opcodes.
data() &&
"compare iterators of different files");
2831 return (Ptr == Other.Ptr) &&
2832 (RemainingLoopCount == Other.RemainingLoopCount) &&
2833 (Done == Other.Done);
2839 Start.moveToFirst();
2852 : Opcodes(Bytes), Ptr(Bytes.
begin()), SegmentOffset(0), SegmentIndex(0),
2853 Ordinal(0),
Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
2854 BindType(0), PointerSize(is64Bit ? 8 : 4),
2855 TableKind(BK), Malformed(
false), Done(
false) {}
2857 void MachOBindEntry::moveToFirst() {
2858 Ptr = Opcodes.
begin();
2862 void MachOBindEntry::moveToEnd() {
2863 Ptr = Opcodes.
end();
2864 RemainingLoopCount = 0;
2870 SegmentOffset += AdvanceAmount;
2871 if (RemainingLoopCount) {
2872 --RemainingLoopCount;
2875 if (Ptr == Opcodes.
end()) {
2880 while (More && !Malformed) {
2882 uint8_t Byte = *Ptr++;
2885 int8_t SignExtended;
2886 const uint8_t *SymStart;
2892 bool NotLastEntry =
false;
2893 for (
const uint8_t *
P = Ptr;
P < Opcodes.
end(); ++
P) {
2895 NotLastEntry =
true;
2910 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
2911 <<
"Ordinal=" << Ordinal <<
"\n");
2914 Ordinal = readULEB128();
2917 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
2918 <<
"Ordinal=" << Ordinal <<
"\n");
2922 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
2923 Ordinal = SignExtended;
2928 llvm::dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
2929 <<
"Ordinal=" << Ordinal <<
"\n");
2937 SymbolName =
StringRef(reinterpret_cast<const char*>(SymStart),
2942 llvm::dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
2943 <<
"SymbolName=" << SymbolName <<
"\n");
2954 <<
"BindType=" << (
int)
BindType <<
"\n");
2957 Addend = readSLEB128();
2962 llvm::dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: "
2963 <<
"Addend=" << Addend <<
"\n");
2966 SegmentIndex = ImmValue;
2967 SegmentOffset = readULEB128();
2970 llvm::dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
2971 <<
"SegmentIndex=" << SegmentIndex <<
", "
2972 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2976 SegmentOffset += readULEB128();
2978 llvm::dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: "
2979 <<
format(
"SegmentOffset=0x%06X",
2980 SegmentOffset) <<
"\n");
2983 AdvanceAmount = PointerSize;
2984 RemainingLoopCount = 0;
2987 <<
format(
"SegmentOffset=0x%06X",
2988 SegmentOffset) <<
"\n");
2991 AdvanceAmount = readULEB128() + PointerSize;
2992 RemainingLoopCount = 0;
2997 llvm::dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
2998 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
2999 <<
", AdvanceAmount=" << AdvanceAmount
3000 <<
", RemainingLoopCount=" << RemainingLoopCount
3004 AdvanceAmount = ImmValue * PointerSize + PointerSize;
3005 RemainingLoopCount = 0;
3010 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
3011 <<
format(
"SegmentOffset=0x%06X",
3012 SegmentOffset) <<
"\n");
3015 RemainingLoopCount = readULEB128() - 1;
3016 AdvanceAmount = readULEB128() + PointerSize;
3021 llvm::dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
3022 <<
format(
"SegmentOffset=0x%06X", SegmentOffset)
3023 <<
", AdvanceAmount=" << AdvanceAmount
3024 <<
", RemainingLoopCount=" << RemainingLoopCount
3033 uint64_t MachOBindEntry::readULEB128() {
3037 if (Ptr > Opcodes.
end()) {
3038 Ptr = Opcodes.
end();
3044 int64_t MachOBindEntry::readSLEB128() {
3048 if (Ptr > Opcodes.
end()) {
3049 Ptr = Opcodes.
end();
3064 return "text abs32";
3066 return "text rel32";
3080 #ifdef EXPENSIVE_CHECKS
3081 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
3083 assert(Opcodes.
data() == Other.Opcodes.
data() &&
"compare iterators of different files");
3085 return (Ptr == Other.Ptr) &&
3086 (RemainingLoopCount == Other.RemainingLoopCount) &&
3087 (Done == Other.Done);
3094 Start.moveToFirst();
3119 return LoadCommands.
begin();
3124 return LoadCommands.
end();
3140 assert(Sec.
d.
a < Sections.
size() &&
"Should have detected this earlier");
3141 const section_base *Base =
3142 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
3148 assert(Sec.
d.
a < Sections.
size() &&
"Should have detected this earlier");
3149 const section_base *Base =
3150 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
3172 return (RE.
r_word1 >> 27) & 1;
3188 return (RE.
r_word0 >> 24) & 0xf;
3229 DRI.
d.
a = SecNum - 1;
3234 assert(DRI.
d.
a < Sections.
size() &&
"Should have detected this earlier");
3235 return getStruct<MachO::section>(*
this, Sections[DRI.
d.
a]);
3239 assert(DRI.
d.
a < Sections.
size() &&
"Should have detected this earlier");
3240 return getStruct<MachO::section_64>(*
this, Sections[DRI.
d.
a]);
3244 unsigned Index)
const {
3246 return getStruct<MachO::section>(*
this, Sec);
3250 unsigned Index)
const {
3252 return getStruct<MachO::section_64>(*
this, Sec);
3257 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
3258 return getStruct<MachO::nlist>(*
this,
P);
3263 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
3264 return getStruct<MachO::nlist_64>(*
this,
P);
3269 return getStruct<MachO::linkedit_data_command>(*
this, L.
Ptr);
3274 return getStruct<MachO::segment_command>(*
this, L.
Ptr);
3279 return getStruct<MachO::segment_command_64>(*
this, L.
Ptr);
3284 return getStruct<MachO::linker_option_command>(*
this, L.
Ptr);
3289 return getStruct<MachO::version_min_command>(*
this, L.
Ptr);
3294 return getStruct<MachO::dylib_command>(*
this, L.
Ptr);
3299 return getStruct<MachO::dyld_info_command>(*
this, L.
Ptr);
3304 return getStruct<MachO::dylinker_command>(*
this, L.
Ptr);
3309 return getStruct<MachO::uuid_command>(*
this, L.
Ptr);
3314 return getStruct<MachO::rpath_command>(*
this, L.
Ptr);
3319 return getStruct<MachO::source_version_command>(*
this, L.
Ptr);
3324 return getStruct<MachO::entry_point_command>(*
this, L.
Ptr);
3329 return getStruct<MachO::encryption_info_command>(*
this, L.
Ptr);
3334 return getStruct<MachO::encryption_info_command_64>(*
this, L.
Ptr);
3339 return getStruct<MachO::sub_framework_command>(*
this, L.
Ptr);
3344 return getStruct<MachO::sub_umbrella_command>(*
this, L.
Ptr);
3349 return getStruct<MachO::sub_library_command>(*
this, L.
Ptr);
3354 return getStruct<MachO::sub_client_command>(*
this, L.
Ptr);
3359 return getStruct<MachO::routines_command>(*
this, L.
Ptr);
3364 return getStruct<MachO::routines_command_64>(*
this, L.
Ptr);
3369 return getStruct<MachO::thread_command>(*
this, L.
Ptr);
3387 return getStruct<MachO::any_relocation_info>(
3388 *
this, reinterpret_cast<const char *>(
P));
3393 const char *
P =
reinterpret_cast<const char *
>(Rel.
p);
3394 return getStruct<MachO::data_in_code_entry>(*
this,
P);
3408 unsigned Index)
const {
3410 return getStruct<uint32_t>(*
this,
getPtr(*
this, Offset));
3415 unsigned Index)
const {
3417 return getStruct<MachO::data_in_code_entry>(*
this,
getPtr(*
this, Offset));
3422 return getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
3426 Cmd.
cmd = MachO::LC_SYMTAB;
3436 if (DysymtabLoadCmd)
3437 return getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
3441 Cmd.
cmd = MachO::LC_DYSYMTAB;
3453 Cmd.extrefsymoff = 0;
3454 Cmd.nextrefsyms = 0;
3455 Cmd.indirectsymoff = 0;
3456 Cmd.nindirectsyms = 0;
3466 if (DataInCodeLoadCmd)
3467 return getStruct<MachO::linkedit_data_command>(*
this, DataInCodeLoadCmd);
3471 Cmd.
cmd = MachO::LC_DATA_IN_CODE;
3480 if (LinkOptHintsLoadCmd)
3481 return getStruct<MachO::linkedit_data_command>(*
this, LinkOptHintsLoadCmd);
3486 Cmd.
cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
3494 if (!DyldInfoLoadCmd)
3498 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
3499 const uint8_t *Ptr =
3505 if (!DyldInfoLoadCmd)
3509 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
3510 const uint8_t *Ptr =
3511 reinterpret_cast<const uint8_t *
>(
getPtr(*
this, DyldInfo.
bind_off));
3516 if (!DyldInfoLoadCmd)
3520 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
3521 const uint8_t *Ptr =
3527 if (!DyldInfoLoadCmd)
3531 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
3532 const uint8_t *Ptr =
3538 if (!DyldInfoLoadCmd)
3542 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
3543 const uint8_t *Ptr =
3553 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
3572 while (uint64_t delta = extractor.
getULEB128(&offset)) {
3587 if (Magic ==
"\xFE\xED\xFA\xCE")
3589 UniversalCputype, UniversalIndex);
3590 if (Magic ==
"\xCE\xFA\xED\xFE")
3592 UniversalCputype, UniversalIndex);
3593 if (Magic ==
"\xFE\xED\xFA\xCF")
3595 UniversalCputype, UniversalIndex);
3596 if (Magic ==
"\xCF\xFA\xED\xFE")
3598 UniversalCputype, UniversalIndex);
3599 return make_error<GenericBinaryError>(
"Unrecognized MachO magic number",
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
void swapStruct(fat_header &mh)
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
iterator_range< export_iterator > exports() const
For use iterating over all exported symbols.
static unsigned int getMachOType(bool isLE, bool is64Bits)
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
void swapByteOrder(T &Value)
load_command_iterator end_load_commands() const
DataRefImpl getRawDataRefImpl() const
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
StringRef getStringTableData() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
StringRef getFileFormatName() const override
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool isSectionVirtual(DataRefImpl Sec) const override
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
void moveRelocationNext(DataRefImpl &Rel) const override
ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...
StringRef typeName() const
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
symbol_iterator_range symbols() const
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
static const char * getPtr(const MachOObjectFile &O, size_t Offset)
static Triple getHostArch()
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const
uint8_t getRelocationLength(DataRefImpl Rel) const
This class is the base class for all object file types.
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
uint64_t getRelocationType(DataRefImpl Rel) const override
const_iterator begin(StringRef path)
Get begin iterator over path.
StringRef otherName() const
static StringRef parseSegmentOrSectionName(const char *P)
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
uint64_t getSectionAlignment(DataRefImpl Sec) const override
struct llvm::object::DataRefImpl::@119 d
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
Error takeError()
Take ownership of the stored error.
load_command_iterator begin_load_commands() const
DataRefImpl getRawDataRefImpl() const
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
bool operator==(const MachORebaseEntry &) const
iterator_range< rebase_iterator > rebaseTable() const
For use iterating over all rebase table entries.
bool isSectionBitcode(DataRefImpl Sec) const override
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
uint64_t getSectionAddress(DataRefImpl Sec) const override
content_iterator< ExportEntry > export_iterator
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
basic_symbol_iterator symbol_begin() const override
bool operator==(const ExportEntry &) const
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
const uint32_t ARM_THREAD_STATE_COUNT
std::string str() const
Return the twine contents as a std::string.
bool isSectionText(DataRefImpl Sec) const override
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
static void advance(T &it, size_t Val)
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
StringRef getData() const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
uint64_t segmentOffset() const
bool equals(StringRef RHS) const
Check for string equality.
uint64_t getSymbolIndex(DataRefImpl Symb) const
Tagged union holding either a T or a Error.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
uint32_t nodeOffset() const
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
dice_iterator end_dices() const
LLVM_NODISCARD bool empty() const
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
static const bool IsLittleEndianHost
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getArch() const override
static unsigned getCPUType(const MachOObjectFile &O)
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
ExportEntry(ArrayRef< uint8_t > Trie)
Function Alias Analysis false
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
const MachO::mach_header & getHeader() const
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
basic_symbol_iterator symbol_end() const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
MachO::section_64 getSection64(DataRefImpl DRI) const
size_t size() const
size - Get the array size.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
static bool isLoadCommandObsolete(uint32_t cmd)
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a ULEB128 value.
StringRef symbolName() const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
void moveSectionNext(DataRefImpl &Sec) const override
content_iterator< SectionRef > section_iterator
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
static uint8_t GET_COMM_ALIGN(uint16_t n_desc)
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
A switch()-like statement whose cases are string literals.
bool isSectionCompressed(DataRefImpl Sec) const override
unsigned int getType() const
unsigned getSectionID(SectionRef Sec) const
const MachO::mach_header_64 & getHeader64() const
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getUuid() const
iterator_range< load_command_iterator > load_commands() const
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
uint32_t segmentIndex() const
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
MachO::section getSection(DataRefImpl DRI) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static bool is64Bit(const char *name)
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
const uint32_t x86_THREAD_STATE64_COUNT
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)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
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)
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
MachO::linkedit_data_command getDataInCodeLoadCommand() const
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
static T getStruct(const MachOObjectFile &O, const char *P)
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
MachORebaseEntry(ArrayRef< uint8_t > opcodes, bool is64Bit)
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
content_iterator< MachOBindEntry > bind_iterator
bool operator==(const MachOBindEntry &) const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
content_iterator< RelocationRef > relocation_iterator
StringRef typeName() const
static Error malformedError(Twine Msg)
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
uint64_t getNValue(DataRefImpl Sym) const
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 uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
Triple - Helper class for working with autoconf configuration names.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr)
Utility function to decode a SLEB128 value.
section_iterator getRelocationSection(DataRefImpl Rel) const
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
static const char *const Magic
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
content_iterator< BasicSymbolRef > basic_symbol_iterator
Triple getArchTriple(const char **McpuDefault=nullptr) const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
void moveSymbolNext(DataRefImpl &Symb) const override
static ErrorSuccess success()
Create a success value.
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
friend class RelocationRef
unsigned getSymbolSectionID(SymbolRef Symb) const
bool isSectionData(DataRefImpl Sec) const override
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
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 Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
StringRef getBuffer() const
content_iterator< DiceRef > dice_iterator
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
uint64_t segmentOffset() const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint32_t getSymbolFlags(DataRefImpl Symb) const override
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
A range adaptor for a pair of iterators.
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
Helper for Errors used as out-parameters.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
This is a value type class that represents a single symbol in the list of symbols in the object file...
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
MachO::mach_header_64 Header64
MachOBindEntry(ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
bool isSectionBSS(DataRefImpl Sec) const override
MachO::symtab_command getSymtabLoadCommand() const
uint64_t getSymbolValue(DataRefImpl Symb) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
basic_symbol_iterator getSymbolByIndex(unsigned Index) const
bool isLittleEndian() const
dice_iterator begin_dices() const
section_iterator section_begin() const override
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
static bool isValidArch(StringRef ArchFlag)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
MachO::dysymtab_command getDysymtabLoadCommand() const
MachO::mach_header Header
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
unsigned getSectionType(SectionRef Sec) const
Lightweight error class with error context and mandatory checking.
const uint32_t ARM_THREAD_STATE64_COUNT
section_iterator section_end() const override
iterator_range< bind_iterator > lazyBindTable() const
For use iterating over all lazy bind table entries.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
StringRef - Represent a constant reference to a string, i.e.
S_ZEROFILL - Zero fill on demand section.
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
SectionType
These are the section type and attributes fields.
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
content_iterator< MachORebaseEntry > rebase_iterator
iterator_range< bind_iterator > bindTable() const
For use iterating over all bind table entries.
iterator_range< bind_iterator > weakBindTable() const
For use iterating over all lazy bind table entries.
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Error checkSymbolTable() const
uint32_t segmentIndex() const
const uint32_t PPC_THREAD_STATE_COUNT
This is a value type class that represents a single section in the list of sections in the object fil...
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
uint64_t getSectionSize(DataRefImpl Sec) const override
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const