LLVM: lib/Object/MachOObjectFile.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
41#include
42#include
43#include
44#include
45#include
46#include
47#include
48#include
49#include <system_error>
50
51using namespace llvm;
52using namespace object;
53
54namespace {
55
56 struct section_base {
57 char sectname[16];
58 char segname[16];
59 };
60
61}
62
64 return make_error("truncated or malformed object (" +
65 Msg + ")",
66 object_error::parse_failed);
67}
68
69
70template
72
73 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
75
76 T Cmd;
77 memcpy(&Cmd, P, sizeof(T));
80 return Cmd;
81}
82
83template
85
86 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end())
88
89 T Cmd;
90 memcpy(&Cmd, P, sizeof(T));
93 return Cmd;
94}
95
96static const char *
98 unsigned Sec) {
99 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
100
101 bool Is64 = O.is64Bit();
106
107 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
108 return reinterpret_cast<const char*>(SectionAddr);
109}
110
112 size_t MachOFilesetEntryOffset = 0) {
114 MachOFilesetEntryOffset <= O.getData().size());
115 return O.getData().data() + Offset + MachOFilesetEntryOffset;
116}
117
120 const char *P = reinterpret_cast<const char *>(DRI.p);
121 return getStructMachO::nlist\_base(O, P);
122}
123
125 if (P[15] == 0)
126
127 return P;
128
130}
131
133 return O.getHeader().cputype;
134}
135
137 return O.getHeader().cpusubtype & ~MachO::CPU_SUBTYPE_MASK;
138}
139
143}
144
145static unsigned
147 return RE.r_word0 & 0xffffff;
148}
149
152 if (O.isLittleEndian())
153 return (RE.r_word1 >> 24) & 1;
154 return (RE.r_word1 >> 7) & 1;
155}
156
157static bool
159 return (RE.r_word0 >> 30) & 1;
160}
161
164 if (O.isLittleEndian())
165 return (RE.r_word1 >> 25) & 3;
166 return (RE.r_word1 >> 5) & 3;
167}
168
169static unsigned
171 return (RE.r_word0 >> 28) & 3;
172}
173
176 if (O.isLittleEndian())
179}
180
183 if (O.is64Bit()) {
185 return Sect.flags;
186 }
188 return Sect.flags;
189}
190
194 if (auto CmdOrErr = getStructOrErrMachO::load\_command(Obj, Ptr)) {
195 if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())
197 " extends past end of file");
198 if (CmdOrErr->cmdsize < 8)
200 " with size less than 8 bytes");
202 } else
203 return CmdOrErr.takeError();
204}
205
211 return malformedError("load command 0 extends past the end all load "
212 "commands in the file");
215}
216
226 " extends past the end all load commands in the file");
227 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
228}
229
230template
234 Err = malformedError("the mach header extends past the end of the "
235 "file");
236 return;
237 }
238 if (auto HeaderOrErr = getStructOrErr(
240 Header = *HeaderOrErr;
241 else
242 Err = HeaderOrErr.takeError();
243}
244
245
250};
251
254 const char *Name) {
255 if (Size == 0)
257
258 for (auto it = Elements.begin(); it != Elements.end(); ++it) {
259 const auto &E = *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));
267 auto nt = it;
268 nt++;
269 if (nt != Elements.end()) {
270 const auto &N = *nt;
274 }
275 }
276 }
279}
280
281
282
283
284template <typename Segment, typename Section>
288 uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
289 std::list &Elements) {
290 const unsigned SegmentLoadSize = sizeof(Segment);
291 if (Load.C.cmdsize < SegmentLoadSize)
293 " " + CmdName + " cmdsize too small");
294 if (auto SegOrErr = getStructOrErr(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
307 if (!SectionOrErr)
308 return SectionOrErr.takeError();
309 Section s = SectionOrErr.get();
314 s.offset > FileSize)
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");
327 BigSize += s.size;
332 BigSize > FileSize)
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");
341 s.size > S.filesize)
343 Twine(J) + " in " + CmdName + " command " +
344 Twine(LoadCommandIndex) +
345 " greater than the segment");
348 s.addr < S.vmaddr)
350 CmdName + " command " + Twine(LoadCommandIndex) +
351 " less than the segment's vmaddr");
352 BigSize = s.addr;
353 BigSize += s.size;
355 BigEnd += S.vmsize;
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");
367 "section contents"))
368 return Err;
369 if (s.reloff > FileSize)
371 CmdName + " command " + Twine(LoadCommandIndex) +
372 " extends past the end of the file");
373 BigSize = s.nreloc;
375 BigSize += s.reloff;
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");
383 sizeof(struct
385 "section relocation entries"))
386 return Err;
387 }
388 if (S.fileoff > FileSize)
390 " fileoff field in " + CmdName +
391 " extends past the end of the file");
392 uint64_t BigSize = S.fileoff;
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;
403 } else
404 return SegOrErr.takeError();
405
407}
408
412 const char **SymtabLoadCmd,
413 std::list &Elements) {
416 " LC_SYMTAB cmdsize too small");
417 if (*SymtabLoadCmd != nullptr)
418 return malformedError("more than one LC_SYMTAB command");
419 auto SymtabOrErr = getStructOrErrMachO::symtab\_command(Obj, Load.Ptr);
420 if (!SymtabOrErr)
421 return SymtabOrErr.takeError();
425 " has incorrect cmdsize");
427 if (Symtab.symoff > FileSize)
428 return malformedError("symoff field of LC_SYMTAB command " +
429 Twine(LoadCommandIndex) + " extends past the end "
430 "of the file");
432 const char *struct_nlist_name;
435 struct_nlist_name = "struct nlist_64";
436 } else {
438 struct_nlist_name = "struct nlist";
439 }
440 uint64_t BigSize = SymtabSize;
441 BigSize += Symtab.symoff;
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 "
446 "of the file");
448 "symbol table"))
449 return Err;
450 if (Symtab.stroff > FileSize)
451 return malformedError("stroff field of LC_SYMTAB command " +
452 Twine(LoadCommandIndex) + " extends past the end "
453 "of the file");
454 BigSize = Symtab.stroff;
455 BigSize += Symtab.strsize;
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"))
462 return Err;
463 *SymtabLoadCmd = Load.Ptr;
465}
466
470 const char **DysymtabLoadCmd,
471 std::list &Elements) {
474 " LC_DYSYMTAB cmdsize too small");
475 if (*DysymtabLoadCmd != nullptr)
476 return malformedError("more than one LC_DYSYMTAB command");
477 auto DysymtabOrErr =
478 getStructOrErrMachO::dysymtab\_command(Obj, Load.Ptr);
479 if (!DysymtabOrErr)
480 return DysymtabOrErr.takeError();
484 " has incorrect cmdsize");
486 if (Dysymtab.tocoff > FileSize)
487 return malformedError("tocoff field of LC_DYSYMTAB command " +
488 Twine(LoadCommandIndex) + " extends past the end of "
489 "the file");
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 "
497 "the file");
499 Dysymtab.ntoc * sizeof(struct
501 "table of contents"))
502 return Err;
503 if (Dysymtab.modtaboff > FileSize)
504 return malformedError("modtaboff field of LC_DYSYMTAB command " +
505 Twine(LoadCommandIndex) + " extends past the end of "
506 "the file");
507 BigSize = Dysymtab.nmodtab;
508 const char *struct_dylib_module_name;
512 struct_dylib_module_name = "struct dylib_module_64";
513 } else {
515 struct_dylib_module_name = "struct dylib_module";
516 }
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,
526 "module table"))
527 return Err;
529 return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
530 Twine(LoadCommandIndex) + " extends past the end of "
531 "the file");
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");
543 "reference table"))
544 return Err;
546 return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
547 Twine(LoadCommandIndex) + " extends past the end of "
548 "the file");
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 "
556 "the file");
560 "indirect table"))
561 return Err;
562 if (Dysymtab.extreloff > FileSize)
563 return malformedError("extreloff field of LC_DYSYMTAB command " +
564 Twine(LoadCommandIndex) + " extends past the end of "
565 "the file");
566 BigSize = Dysymtab.nextrel;
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 "
573 "the file");
577 "external relocation table"))
578 return Err;
579 if (Dysymtab.locreloff > FileSize)
580 return malformedError("locreloff field of LC_DYSYMTAB command " +
581 Twine(LoadCommandIndex) + " extends past the end of "
582 "the file");
583 BigSize = Dysymtab.nlocrel;
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 "
590 "the file");
594 "local relocation table"))
595 return Err;
596 *DysymtabLoadCmd = Load.Ptr;
598}
599
603 const char **LoadCmd, const char *CmdName,
604 std::list &Elements,
605 const char *ElementName) {
608 CmdName + " cmdsize too small");
609 if (*LoadCmd != nullptr)
611 auto LinkDataOrError =
612 getStructOrErrMachO::linkedit\_data\_command(Obj, Load.Ptr);
613 if (!LinkDataOrError)
614 return LinkDataOrError.takeError();
618 Twine(LoadCommandIndex) + " has incorrect cmdsize");
620 if (LinkData.dataoff > FileSize)
621 return malformedError("dataoff field of " + Twine(CmdName) + " command " +
622 Twine(LoadCommandIndex) + " extends past the end of "
623 "the file");
625 BigSize += LinkData.datasize;
626 if (BigSize > FileSize)
627 return malformedError("dataoff field plus datasize field of " +
628 Twine(CmdName) + " command " +
629 Twine(LoadCommandIndex) + " extends past the end of "
630 "the file");
632 LinkData.datasize, ElementName))
633 return Err;
634 *LoadCmd = Load.Ptr;
636}
637
641 const char **LoadCmd, const char *CmdName,
642 std::list &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 "
648 "command");
649 auto DyldInfoOrErr =
650 getStructOrErrMachO::dyld\_info\_command(Obj, Load.Ptr);
651 if (!DyldInfoOrErr)
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 "
668 "the file");
671 "dyld rebase info"))
672 return Err;
673 if (DyldInfo.bind_off > FileSize)
675 " command " + Twine(LoadCommandIndex) + " extends "
676 "past the end of the file");
679 if (BigSize > FileSize)
680 return malformedError("bind_off field plus bind_size field of " +
681 Twine(CmdName) + " command " +
682 Twine(LoadCommandIndex) + " extends past the end of "
683 "the file");
686 "dyld bind info"))
687 return Err;
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 "
698 "the file");
701 "dyld weak bind info"))
702 return Err;
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 "
713 "the file");
716 "dyld lazy bind info"))
717 return Err;
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 "
728 "the file");
731 "dyld export info"))
732 return Err;
733 *LoadCmd = Load.Ptr;
735}
736
739 uint32_t LoadCommandIndex, const char *CmdName) {
742 CmdName + " cmdsize too small");
743 auto CommandOrErr = getStructOrErrMachO::dylib\_command(Obj, Load.Ptr);
744 if (!CommandOrErr)
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");
755
756
758 const char *P = (const char *)Load.Ptr;
759 for (i = D.dylib.name; i < D.cmdsize; i++)
760 if (P[i] == '\0')
761 break;
762 if (i >= D.cmdsize)
764 CmdName + " library name extends past the end of the "
765 "load command");
767}
768
772 const char **LoadCmd) {
774 "LC_ID_DYLIB"))
775 return Err;
776 if (*LoadCmd != nullptr)
777 return malformedError("more than one LC_ID_DYLIB command");
780 return malformedError("LC_ID_DYLIB load command in non-dynamic library "
781 "file type");
782 *LoadCmd = Load.Ptr;
784}
785
788 uint32_t LoadCommandIndex, const char *CmdName) {
791 CmdName + " cmdsize too small");
792 auto CommandOrErr = getStructOrErrMachO::dylinker\_command(Obj, Load.Ptr);
793 if (!CommandOrErr)
794 return CommandOrErr.takeError();
798 CmdName + " name.offset field too small, not past "
799 "the end of the dylinker_command struct");
802 CmdName + " name.offset field extends past the end "
803 "of the load command");
804
805
807 const char *P = (const char *)Load.Ptr;
808 for (i = D.name; i < D.cmdsize; i++)
809 if (P[i] == '\0')
810 break;
811 if (i >= D.cmdsize)
813 CmdName + " dyld name extends past the end of the "
814 "load command");
816}
817
821 const char **LoadCmd, const char *CmdName) {
824 CmdName + " has incorrect cmdsize");
825 if (*LoadCmd != nullptr)
826 return malformedError("more than one LC_VERSION_MIN_MACOSX, "
827 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
828 "LC_VERSION_MIN_WATCHOS command");
829 *LoadCmd = Load.Ptr;
831}
832
836 std::list &Elements) {
839 " LC_NOTE has incorrect cmdsize");
840 auto NoteCmdOrErr = getStructOrErrMachO::note\_command(Obj, Load.Ptr);
841 if (!NoteCmdOrErr)
842 return NoteCmdOrErr.takeError();
845 if (Nt.offset > FileSize)
846 return malformedError("offset field of LC_NOTE command " +
847 Twine(LoadCommandIndex) + " extends "
848 "past the end of the file");
850 BigSize += Nt.size;
851 if (BigSize > FileSize)
852 return malformedError("size field plus offset field of LC_NOTE command " +
853 Twine(LoadCommandIndex) + " extends past the end of "
854 "the file");
856 "LC_NOTE data"))
857 return Err;
859}
860
866 auto BVCOrErr =
867 getStructOrErrMachO::build\_version\_command(Obj, Load.Ptr);
868 if (!BVCOrErr)
869 return BVCOrErr.takeError();
871 if (Load.C.cmdsize !=
875 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
876
879 for (unsigned i = 0; i < BVC.ntools; ++i)
881
883}
884
890 " LC_RPATH cmdsize too small");
891 auto ROrErr = getStructOrErrMachO::rpath\_command(Obj, Load.Ptr);
892 if (!ROrErr)
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");
903
904
906 const char *P = (const char *)Load.Ptr;
907 for (i = R.path; i < R.cmdsize; i++)
908 if (P[i] == '\0')
909 break;
910 if (i >= R.cmdsize)
912 " LC_RPATH library name extends past the end of the "
913 "load command");
915}
916
921 const char **LoadCmd, const char *CmdName) {
922 if (*LoadCmd != nullptr)
923 return malformedError("more than one LC_ENCRYPTION_INFO and or "
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)
933 return malformedError("cryptoff field plus cryptsize field of " +
934 Twine(CmdName) + " command " +
935 Twine(LoadCommandIndex) + " extends past the end of "
936 "the file");
937 *LoadCmd = Load.Ptr;
939}
940
946 " LC_LINKER_OPTION cmdsize too small");
947 auto LinkOptionOrErr =
948 getStructOrErrMachO::linker\_option\_command(Obj, Load.Ptr);
949 if (!LinkOptionOrErr)
950 return LinkOptionOrErr.takeError();
952
953 const char *string = (const char *)Load.Ptr +
957 while (left > 0) {
958 while (*string == '\0' && left > 0) {
959 string++;
960 left--;
961 }
962 if (left > 0) {
963 i++;
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;
970 string += len;
971 left -= len;
972 }
973 }
974 if (L.count != i)
976 " LC_LINKER_OPTION string count " + Twine(L.count) +
977 " does not match number of strings");
979}
980
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");
994
995
997 const char *P = (const char *)Load.Ptr;
998 for (i = PathOffset; i < Load.C.cmdsize; i++)
999 if (P[i] == '\0')
1000 break;
1001 if (i >= Load.C.cmdsize)
1003 CmdName + " " + PathFieldName + " name extends past "
1004 "the end of the load command");
1006}
1007
1011 const char *CmdName) {
1014 CmdName + " cmdsize too small");
1015 auto ThreadCommandOrErr =
1016 getStructOrErrMachO::thread\_command(Obj, Load.Ptr);
1017 if (!ThreadCommandOrErr)
1018 return ThreadCommandOrErr.takeError();
1021 const char *end = Load.Ptr + T.cmdsize;
1024 while (state < end) {
1025 if(state + sizeof(uint32_t) > end)
1027 "flavor in " + CmdName + " extends past end of "
1028 "command");
1030 memcpy(&flavor, state, sizeof(uint32_t));
1034
1035 if(state + sizeof(uint32_t) > end)
1037 " count in " + CmdName + " extends past end of "
1038 "command");
1044
1049 " count not x86_THREAD_STATE32_COUNT for "
1050 "flavor number " + Twine(nflavor) + " which is "
1051 "a x86_THREAD_STATE32 flavor in " + CmdName +
1052 " command");
1055 " x86_THREAD_STATE32 extends past end of "
1056 "command in " + CmdName + " command");
1058 } else {
1060 " unknown flavor (" + Twine(flavor) + ") for "
1061 "flavor number " + Twine(nflavor) + " in " +
1062 CmdName + " command");
1063 }
1068 " count not x86_THREAD_STATE_COUNT for "
1069 "flavor number " + Twine(nflavor) + " which is "
1070 "a x86_THREAD_STATE flavor in " + CmdName +
1071 " command");
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 +
1083 " command");
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 +
1095 " command");
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 +
1107 " command");
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 +
1119 " command");
1122 " x86_EXCEPTION_STATE64 extends past end of "
1123 "command in " + CmdName + " command");
1125 } else {
1127 " unknown flavor (" + Twine(flavor) + ") for "
1128 "flavor number " + Twine(nflavor) + " in " +
1129 CmdName + " command");
1130 }
1135 " count not ARM_THREAD_STATE_COUNT for "
1136 "flavor number " + Twine(nflavor) + " which is "
1137 "a ARM_THREAD_STATE flavor in " + CmdName +
1138 " command");
1141 " ARM_THREAD_STATE extends past end of "
1142 "command in " + CmdName + " command");
1144 } else {
1146 " unknown flavor (" + Twine(flavor) + ") for "
1147 "flavor number " + Twine(nflavor) + " in " +
1148 CmdName + " command");
1149 }
1155 " count not ARM_THREAD_STATE64_COUNT for "
1156 "flavor number " + Twine(nflavor) + " which is "
1157 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1158 " command");
1161 " ARM_THREAD_STATE64 extends past end of "
1162 "command in " + CmdName + " command");
1164 } else {
1166 " unknown flavor (" + Twine(flavor) + ") for "
1167 "flavor number " + Twine(nflavor) + " in " +
1168 CmdName + " command");
1169 }
1174 " count not PPC_THREAD_STATE_COUNT for "
1175 "flavor number " + Twine(nflavor) + " which is "
1176 "a PPC_THREAD_STATE flavor in " + CmdName +
1177 " command");
1180 " PPC_THREAD_STATE extends past end of "
1181 "command in " + CmdName + " command");
1183 } else {
1185 " unknown flavor (" + Twine(flavor) + ") for "
1186 "flavor number " + Twine(nflavor) + " in " +
1187 CmdName + " command");
1188 }
1189 } else {
1191 "command " + Twine(LoadCommandIndex) + " for " +
1192 CmdName + " command can't be checked");
1193 }
1194 nflavor++;
1195 }
1197}
1198
1201 &Load,
1203 const char **LoadCmd,
1204 std::list &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 = getStructOrErrMachO::twolevel\_hints\_command(Obj, Load.Ptr);
1211 if(!HintsOrErr)
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 "
1218 "the file");
1221 BigSize += Hints.offset;
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 "
1226 "the file");
1229 "two level hints"))
1230 return Err;
1231 *LoadCmd = Load.Ptr;
1233}
1234
1235
1236
1237
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)
1248 return true;
1249 return false;
1250}
1251
1254 bool Is64Bits, uint32_t UniversalCputype,
1256 size_t MachOFilesetEntryOffset) {
1258 std::unique_ptr Obj(new MachOObjectFile(
1259 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,
1260 UniversalIndex, MachOFilesetEntryOffset));
1261 if (Err)
1262 return std::move(Err);
1263 return std::move(Obj);
1264}
1265
1266MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1267 bool Is64bits, Error &Err,
1270 size_t MachOFilesetEntryOffset)
1271 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1272 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {
1280 } else {
1284 }
1285 if (Err)
1286 return;
1289 Err = malformedError("load commands extend past the end of the file");
1290 return;
1291 }
1292 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1293 Err = malformedError("universal header architecture: " +
1294 Twine(UniversalIndex) + "'s cputype does not match "
1295 "object file's mach header");
1296 return;
1297 }
1298 std::list Elements;
1299 Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1300
1302 LoadCommandInfo Load;
1303 if (LoadCommandCount != 0) {
1305 Load = *LoadOrErr;
1306 else {
1307 Err = LoadOrErr.takeError();
1308 return;
1309 }
1310 }
1311
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) {
1326
1327
1328
1330 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1332 "multiple of 8");
1333 return;
1334 }
1335 }
1336 } else {
1337 if (Load.C.cmdsize % 4 != 0) {
1339 "multiple of 4");
1340 return;
1341 }
1342 }
1344 if (Load.C.cmd == MachO::LC_SYMTAB) {
1345 if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1346 return;
1347 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1349 Elements)))
1350 return;
1351 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1353 "LC_DATA_IN_CODE", Elements,
1354 "data in code info")))
1355 return;
1356 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1358 "LC_LINKER_OPTIMIZATION_HINT",
1359 Elements, "linker optimization "
1360 "hints")))
1361 return;
1362 } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1364 "LC_FUNCTION_STARTS", Elements,
1365 "function starts data")))
1366 return;
1367 } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1369 "LC_SEGMENT_SPLIT_INFO", Elements,
1370 "split info data")))
1371 return;
1372 } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1374 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1375 "code signing RDs data")))
1376 return;
1377 } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1379 "LC_CODE_SIGNATURE", Elements,
1380 "code signature data")))
1381 return;
1382 } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1384 "LC_DYLD_INFO", Elements)))
1385 return;
1386 } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1388 "LC_DYLD_INFO_ONLY", Elements)))
1389 return;
1390 } else if (Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1392 *this, Load, I, &DyldChainedFixupsLoadCmd,
1393 "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))
1394 return;
1395 } else if (Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {
1397 *this, Load, I, &DyldExportsTrieLoadCmd, "LC_DYLD_EXPORTS_TRIE",
1398 Elements, "exports trie")))
1399 return;
1400 } else if (Load.C.cmd == MachO::LC_UUID) {
1403 "cmdsize");
1404 return;
1405 }
1406 if (UuidLoadCmd) {
1407 Err = malformedError("more than one LC_UUID command");
1408 return;
1409 }
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)))
1416 return;
1417 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1420 *this, Load, Sections, HasPageZeroSegment, I,
1421 "LC_SEGMENT", SizeOfHeaders, Elements)))
1422 return;
1423 } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1425 return;
1426 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1428 return;
1430 } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1431 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1432 return;
1434 } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1435 if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1436 return;
1438 } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1440 return;
1442 } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1443 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1444 return;
1446 } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1448 return;
1449 } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1450 if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1451 return;
1452 } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1453 if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1454 return;
1455 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1457 "LC_VERSION_MIN_MACOSX")))
1458 return;
1459 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1461 "LC_VERSION_MIN_IPHONEOS")))
1462 return;
1463 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1465 "LC_VERSION_MIN_TVOS")))
1466 return;
1467 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1469 "LC_VERSION_MIN_WATCHOS")))
1470 return;
1471 } else if (Load.C.cmd == MachO::LC_NOTE) {
1473 return;
1474 } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1476 return;
1477 } else if (Load.C.cmd == MachO::LC_RPATH) {
1479 return;
1480 } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1483 " has incorrect cmdsize");
1484 return;
1485 }
1486 if (SourceLoadCmd) {
1487 Err = malformedError("more than one LC_SOURCE_VERSION command");
1488 return;
1489 }
1490 SourceLoadCmd = Load.Ptr;
1491 } else if (Load.C.cmd == MachO::LC_MAIN) {
1494 " has incorrect cmdsize");
1495 return;
1496 }
1497 if (EntryPointLoadCmd) {
1498 Err = malformedError("more than one LC_MAIN command");
1499 return;
1500 }
1501 EntryPointLoadCmd = Load.Ptr;
1502 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1505 " has incorrect cmdsize");
1506 return;
1507 }
1509 getStructMachO::encryption\_info\_command(*this, Load.Ptr);
1511 &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1512 return;
1513 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1516 " has incorrect cmdsize");
1517 return;
1518 }
1520 getStructMachO::encryption\_info\_command\_64(*this, Load.Ptr);
1522 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1523 return;
1524 } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1526 return;
1527 } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1530 " LC_SUB_FRAMEWORK cmdsize too small");
1531 return;
1532 }
1534 getStructMachO::sub\_framework\_command(*this, Load.Ptr);
1535 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1537 "sub_framework_command", S.umbrella,
1538 "umbrella")))
1539 return;
1540 } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1543 " LC_SUB_UMBRELLA cmdsize too small");
1544 return;
1545 }
1547 getStructMachO::sub\_umbrella\_command(*this, Load.Ptr);
1548 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1551 "sub_umbrella")))
1552 return;
1553 } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1556 " LC_SUB_LIBRARY cmdsize too small");
1557 return;
1558 }
1560 getStructMachO::sub\_library\_command(*this, Load.Ptr);
1561 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1564 "sub_library")))
1565 return;
1566 } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1569 " LC_SUB_CLIENT cmdsize too small");
1570 return;
1571 }
1573 getStructMachO::sub\_client\_command(*this, Load.Ptr);
1576 "sub_client_command", S.client, "client")))
1577 return;
1578 } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1581 " has incorrect cmdsize");
1582 return;
1583 }
1584 if (RoutinesLoadCmd) {
1585 Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1586 "command");
1587 return;
1588 }
1589 RoutinesLoadCmd = Load.Ptr;
1590 } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1593 " has incorrect cmdsize");
1594 return;
1595 }
1596 if (RoutinesLoadCmd) {
1597 Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1598 "command");
1599 return;
1600 }
1601 RoutinesLoadCmd = Load.Ptr;
1602 } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1604 return;
1605 if (UnixThreadLoadCmd) {
1606 Err = malformedError("more than one LC_UNIXTHREAD command");
1607 return;
1608 }
1609 UnixThreadLoadCmd = Load.Ptr;
1610 } else if (Load.C.cmd == MachO::LC_THREAD) {
1612 return;
1613
1614 } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1616 &TwoLevelHintsLoadCmd, Elements)))
1617 return;
1618 } else if (Load.C.cmd == MachO::LC_IDENT) {
1619
1620 continue;
1623 Twine(Load.C.cmd) + " is obsolete and not "
1624 "supported");
1625 return;
1626 }
1627
1628
1629
1630 if (I < LoadCommandCount - 1) {
1632 Load = *LoadOrErr;
1633 else {
1634 Err = LoadOrErr.takeError();
1635 return;
1636 }
1637 }
1638 }
1639 if (!SymtabLoadCmd) {
1640 if (DysymtabLoadCmd) {
1641 Err = malformedError("contains LC_DYSYMTAB load command without a "
1642 "LC_SYMTAB load command");
1643 return;
1644 }
1645 } else if (DysymtabLoadCmd) {
1647 getStructMachO::symtab\_command(*this, SymtabLoadCmd);
1649 getStructMachO::dysymtab\_command(*this, DysymtabLoadCmd);
1651 Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1652 "extends past the end of the symbol table");
1653 return;
1654 }
1657 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1658 Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1659 "command extends past the end of the symbol table");
1660 return;
1661 }
1663 Err = malformedError("iextdefsym in LC_DYSYMTAB load command "
1664 "extends past the end of the symbol table");
1665 return;
1666 }
1669 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1670 Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1671 "load command extends past the end of the symbol "
1672 "table");
1673 return;
1674 }
1676 Err = malformedError("iundefsym in LC_DYSYMTAB load command "
1677 "extends past the end of the symbol table");
1678 return;
1679 }
1682 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1683 Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1684 " command extends past the end of the symbol table");
1685 return;
1686 }
1687 }
1690 DyldIdLoadCmd == nullptr) {
1691 Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1692 "filetype");
1693 return;
1694 }
1695 assert(LoadCommands.size() == LoadCommandCount);
1696
1698}
1699
1704 Flags = H_64.flags;
1705 } else {
1707 Flags = H.flags;
1708 }
1717 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1720 NType = STE_64.n_type;
1721 NSect = STE_64.n_sect;
1722 NDesc = STE_64.n_desc;
1723 NStrx = STE_64.n_strx;
1724 NValue = STE_64.n_value;
1725 } else {
1732 }
1735 if (NSect == 0 || NSect > Sections.size())
1737 " for symbol at index " + Twine(SymbolIndex));
1738 }
1740 if (NValue >= S.strsize)
1742 "the end of string table, for N_INDR symbol at "
1743 "index " + Twine(SymbolIndex));
1744 }
1749 if (LibraryOrdinal != 0 &&
1752 LibraryOrdinal - 1 >= Libraries.size() ) {
1754 " for symbol at index " + Twine(SymbolIndex));
1755 }
1756 }
1757 }
1760 " past the end of string table, for symbol at "
1761 "index " + Twine(SymbolIndex));
1762 SymbolIndex++;
1763 }
1765}
1766
1772}
1773
1777 if (Entry.n_strx == 0)
1778
1779
1781 const char *Start = &StringTable.data()[Entry.n_strx];
1782 if (Start < getData().begin() || Start >= getData().end()) {
1785 }
1787}
1788
1793}
1794
1798 return Entry.n_value;
1799 }
1801 return Entry.n_value;
1802}
1803
1804
1805
1815 const char *Start = &StringTable.data()[NValue];
1817 return std::error_code();
1818}
1819
1822}
1823
1826}
1827
1833 }
1834 return 0;
1835}
1836
1839}
1840
1844 uint8_t n_type = Entry.n_type;
1845
1846
1849
1855 if (!SecOrError)
1863 }
1865}
1866
1869
1870 uint8_t MachOType = Entry.n_type;
1871 uint16_t MachOFlags = Entry.n_desc;
1872
1874
1877
1880
1886 else
1888 }
1889
1892 else
1894
1897
1900
1903
1906
1907 return Result;
1908}
1909
1913 uint8_t index = Entry.n_sect;
1914
1915 if (index == 0)
1919 if (DRI.d.a >= Sections.size()){
1922 }
1924}
1925
1929 return Entry.n_sect - 1;
1930}
1931
1934}
1935
1939}
1940
1945}
1946
1949}
1950
1952
1953
1954
1955
1956 uint32_t SectOffset, SectType;
1958
1961 SectOffset = Sect.offset;
1962 SectSize = Sect.size;
1964 } else {
1966 SectOffset = Sect.offset;
1967 SectSize = Sect.size;
1969 }
1971 return SectSize;
1973 if (SectOffset > FileSize)
1974 return 0;
1975 if (FileSize - SectOffset < SectSize)
1976 return FileSize - SectOffset;
1977 return SectSize;
1978}
1979
1983}
1984
1989
1994 } else {
1998 }
1999
2001}
2002
2008 } else {
2011 }
2012
2014}
2015
2017 if (SectionIndex < 1 || SectionIndex > Sections.size())
2018 return malformedError("bad section index: " + Twine((int)SectionIndex));
2019
2021 DRI.d.a = SectionIndex - 1;
2023}
2024
2027 auto NameOrErr = Section.getName();
2028 if (!NameOrErr)
2029 return NameOrErr.takeError();
2031 return Section;
2032 }
2034}
2035
2037 return false;
2038}
2039
2043}
2044
2051}
2052
2059}
2060
2063 if (!SectionNameOrErr) {
2064
2066 return false;
2067 }
2069 return SectionName.starts_with("__debug") ||
2073}
2074
2075namespace {
2076template
2080 auto SegmentOrErr = getStructOrErr(Obj, LoadCmd.Ptr);
2081 if (!SegmentOrErr) {
2083 return {};
2084 }
2085 auto &Segment = SegmentOrErr.get();
2087 return arrayRefFromStringRef(Obj.getData().slice(
2088 Segment.fileoff, Segment.fileoff + Segment.filesize));
2089 return {};
2090}
2091
2092template
2095 auto SegmentOrErr = getStructOrErr(Obj, LoadCmd.Ptr);
2096 if (!SegmentOrErr) {
2098 return {};
2099 }
2100 auto &Segment = SegmentOrErr.get();
2101 return arrayRefFromStringRef(
2102 Obj.getData().substr(Segment.fileoff, Segment.filesize));
2103}
2104}
2105
2111 case MachO::LC_SEGMENT:
2112 Contents = ::getSegmentContentsMachO::segment\_command(*this, LoadCmd,
2113 SegmentName);
2114 break;
2115 case MachO::LC_SEGMENT_64:
2116 Contents = ::getSegmentContentsMachO::segment\_command\_64(*this, LoadCmd,
2117 SegmentName);
2118 break;
2119 default:
2120 continue;
2121 }
2122 if (!Contents.empty())
2123 return Contents;
2124 }
2125 return {};
2126}
2127
2130 size_t Idx = 0;
2133 case MachO::LC_SEGMENT:
2134 if (Idx == SegmentIndex)
2135 return ::getSegmentContentsMachO::segment\_command(*this, LoadCmd);
2137 break;
2138 case MachO::LC_SEGMENT_64:
2139 if (Idx == SegmentIndex)
2140 return ::getSegmentContentsMachO::segment\_command\_64(*this, LoadCmd);
2142 break;
2143 default:
2144 continue;
2145 }
2146 }
2147 return {};
2148}
2149
2152}
2153
2159}
2160
2164 return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");
2165 return false;
2166}
2167
2172}
2173
2177 Ret.d.b = 0;
2179}
2180
2187 } else {
2190 }
2191
2194 Ret.d.b = Num;
2196}
2197
2200
2201 Ret.d.a = 0;
2202 Ret.d.b = 0;
2204}
2205
2209
2210 Ret.d.a = 0;
2211 Ret.d.b = DysymtabLoadCmd.nextrel;
2213}
2214
2217
2218 Ret.d.a = 1;
2219 Ret.d.b = 0;
2221}
2222
2226
2227 Ret.d.a = 1;
2228 Ret.d.b = DysymtabLoadCmd.nlocrel;
2230}
2231
2234}
2235
2239 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2242}
2243
2249
2252 if (!isExtern)
2254
2261 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2263}
2264
2268}
2269
2273}
2274
2279
2280 unsigned Arch = this->getArch();
2281
2282 switch (Arch) {
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" };
2291
2292 if (RType > 5)
2293 res = "Unknown";
2294 else
2295 res = Table[RType];
2296 break;
2297 }
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",
2304 "X86_64_RELOC_GOT",
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" };
2310
2311 if (RType > 9)
2312 res = "Unknown";
2313 else
2314 res = Table[RType];
2315 break;
2316 }
2318 static const char *const Table[] = {
2319 "ARM_RELOC_VANILLA",
2320 "ARM_RELOC_PAIR",
2321 "ARM_RELOC_SECTDIFF",
2322 "ARM_RELOC_LOCAL_SECTDIFF",
2323 "ARM_RELOC_PB_LA_PTR",
2324 "ARM_RELOC_BR24",
2325 "ARM_THUMB_RELOC_BR22",
2326 "ARM_THUMB_32BIT_BRANCH",
2327 "ARM_RELOC_HALF",
2328 "ARM_RELOC_HALF_SECTDIFF" };
2329
2330 if (RType > 9)
2331 res = "Unknown";
2332 else
2333 res = Table[RType];
2334 break;
2335 }
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"
2345 };
2346
2347 if (RType >= std::size(Table))
2348 res = "Unknown";
2349 else
2350 res = Table[RType];
2351 break;
2352 }
2354 static const char *const Table[] = {
2355 "PPC_RELOC_VANILLA",
2356 "PPC_RELOC_PAIR",
2357 "PPC_RELOC_BR14",
2358 "PPC_RELOC_BR24",
2359 "PPC_RELOC_HI16",
2360 "PPC_RELOC_LO16",
2361 "PPC_RELOC_HA16",
2362 "PPC_RELOC_LO14",
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",
2368 "PPC_RELOC_JBSR",
2369 "PPC_RELOC_LO14_SECTDIFF",
2370 "PPC_RELOC_LOCAL_SECTDIFF" };
2371
2372 if (RType > 15)
2373 res = "Unknown";
2374 else
2375 res = Table[RType];
2376 break;
2377 }
2379 res = "Unknown";
2380 break;
2381 }
2382 Result.append(res.begin(), res.end());
2383}
2384
2388}
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2427 bool &isFramework,
2429 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2430 size_t a, b, c, d, Idx;
2431
2432 isFramework = false;
2434
2435
2436 a = Name.rfind('/');
2437 if (a == Name.npos || a == 0)
2438 goto guess_library;
2439 Foo = Name.substr(a + 1);
2440
2441
2443 if (Idx != Foo.npos && Foo.size() >= 2) {
2445 if (Suffix != "_debug" && Suffix != "_profile")
2447 else
2449 }
2450
2451
2452 b = Name.rfind('/', a);
2453 if (b == Name.npos)
2454 Idx = 0;
2455 else
2456 Idx = b+1;
2458 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);
2459 if (F == Foo && DotFramework == ".framework/") {
2460 isFramework = true;
2461 return Foo;
2462 }
2463
2464
2465 if (b == Name.npos)
2466 goto guess_library;
2467 c = Name.rfind('/', b);
2468 if (c == Name.npos || c == 0)
2469 goto guess_library;
2470 V = Name.substr(c + 1);
2471 if (!V.starts_with("Versions/"))
2472 goto guess_library;
2473 d = Name.rfind('/', c);
2474 if (d == Name.npos)
2475 Idx = 0;
2476 else
2477 Idx = d+1;
2479 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);
2480 if (F == Foo && DotFramework == ".framework/") {
2481 isFramework = true;
2482 return Foo;
2483 }
2484
2485guess_library:
2486
2487 a = Name.rfind('.');
2488 if (a == Name.npos || a == 0)
2490 Dylib = Name.substr(a);
2491 if (Dylib != ".dylib")
2492 goto guess_qtx;
2493
2494
2495 if (a >= 3) {
2496 Dot = Name.substr(a - 2, 1);
2497 if (Dot == ".")
2498 a = a - 2;
2499 }
2500
2501 b = Name.rfind('/', a);
2502 if (b == Name.npos)
2503 b = 0;
2504 else
2505 b = b+1;
2506
2510 Suffix = Name.slice(Idx, a);
2511 if (Suffix != "_debug" && Suffix != "_profile") {
2514 }
2515 }
2516 else
2518
2519
2520 if (Lib.size() >= 3) {
2521 Dot = Lib.substr(Lib.size() - 2, 1);
2522 if (Dot == ".")
2523 Lib = Lib.slice(0, Lib.size()-2);
2524 }
2525 return Lib;
2526
2527guess_qtx:
2528 Qtx = Name.substr(a);
2529 if (Qtx != ".qtx")
2531 b = Name.rfind('/', a);
2532 if (b == Name.npos)
2534 else
2535 Lib = Name.slice(b+1, a);
2536
2537 if (Lib.size() >= 3) {
2538 Dot = Lib.substr(Lib.size() - 2, 1);
2539 if (Dot == ".")
2540 Lib = Lib.slice(0, Lib.size()-2);
2541 }
2542 return Lib;
2543}
2544
2545
2546
2547
2548
2549
2552 if (Index >= Libraries.size())
2554
2555
2556
2557 if (LibrariesShortNames.size() == 0) {
2558 for (unsigned i = 0; i < Libraries.size(); i++) {
2559 auto CommandOrErr =
2560 getStructOrErrMachO::dylib\_command(*this, Libraries[i]);
2561 if (!CommandOrErr)
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)
2571 bool isFramework;
2573 if (shortName.empty())
2575 else
2576 LibrariesShortNames.push_back(shortName);
2577 }
2578 }
2579
2580 Res = LibrariesShortNames[Index];
2581 return std::error_code();
2582}
2583
2585 return Libraries.size();
2586}
2587
2591 Sec.d.a = Rel->getRawDataRefImpl().d.a;
2593}
2594
2598 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2600
2602}
2603
2607 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2609
2615 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2617}
2618
2621 if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2626 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2629}
2630
2633 if (!SymtabLoadCmd)
2634 report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2638 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2640 return Index;
2641}
2642
2646}
2647
2650 DRI.d.a = Sections.size();
2652}
2653
2655 return is64Bit() ? 8 : 4;
2656}
2657
2659 unsigned CPUType = getCPUType(*this);
2661 switch (CPUType) {
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";
2670 default:
2671 return "Mach-O 32-bit unknown";
2672 }
2673 }
2674
2675 switch (CPUType) {
2677 return "Mach-O 64-bit x86-64";
2679 return "Mach-O arm64";
2681 return "Mach-O 64-bit ppc64";
2682 default:
2683 return "Mach-O 64-bit unknown";
2684 }
2685}
2686
2688 switch (CPUType) {
2703 default:
2705 }
2706}
2707
2709 const char **McpuDefault,
2710 const char **ArchFlag) {
2711 if (McpuDefault)
2712 *McpuDefault = nullptr;
2713 if (ArchFlag)
2714 *ArchFlag = nullptr;
2715
2716 switch (CPUType) {
2720 if (ArchFlag)
2721 *ArchFlag = "i386";
2722 return Triple("i386-apple-darwin");
2723 default:
2725 }
2729 if (ArchFlag)
2730 *ArchFlag = "x86_64";
2731 return Triple("x86_64-apple-darwin");
2733 if (ArchFlag)
2734 *ArchFlag = "x86_64h";
2735 return Triple("x86_64h-apple-darwin");
2736 default:
2738 }
2742 if (ArchFlag)
2743 *ArchFlag = "armv4t";
2744 return Triple("armv4t-apple-darwin");
2746 if (ArchFlag)
2747 *ArchFlag = "armv5e";
2748 return Triple("armv5e-apple-darwin");
2750 if (ArchFlag)
2751 *ArchFlag = "xscale";
2752 return Triple("xscale-apple-darwin");
2754 if (ArchFlag)
2755 *ArchFlag = "armv6";
2756 return Triple("armv6-apple-darwin");
2758 if (McpuDefault)
2759 *McpuDefault = "cortex-m0";
2760 if (ArchFlag)
2761 *ArchFlag = "armv6m";
2762 return Triple("armv6m-apple-darwin");
2764 if (ArchFlag)
2765 *ArchFlag = "armv7";
2766 return Triple("armv7-apple-darwin");
2768 if (McpuDefault)
2769 *McpuDefault = "cortex-m4";
2770 if (ArchFlag)
2771 *ArchFlag = "armv7em";
2772 return Triple("thumbv7em-apple-darwin");
2774 if (McpuDefault)
2775 *McpuDefault = "cortex-a7";
2776 if (ArchFlag)
2777 *ArchFlag = "armv7k";
2778 return Triple("armv7k-apple-darwin");
2780 if (McpuDefault)
2781 *McpuDefault = "cortex-m3";
2782 if (ArchFlag)
2783 *ArchFlag = "armv7m";
2784 return Triple("thumbv7m-apple-darwin");
2786 if (McpuDefault)
2787 *McpuDefault = "cortex-a7";
2788 if (ArchFlag)
2789 *ArchFlag = "armv7s";
2790 return Triple("armv7s-apple-darwin");
2791 default:
2793 }
2797 if (McpuDefault)
2798 *McpuDefault = "cyclone";
2799 if (ArchFlag)
2800 *ArchFlag = "arm64";
2801 return Triple("arm64-apple-darwin");
2803 if (McpuDefault)
2804 *McpuDefault = "apple-a12";
2805 if (ArchFlag)
2806 *ArchFlag = "arm64e";
2807 return Triple("arm64e-apple-darwin");
2808 default:
2810 }
2814 if (McpuDefault)
2815 *McpuDefault = "cyclone";
2816 if (ArchFlag)
2817 *ArchFlag = "arm64_32";
2818 return Triple("arm64_32-apple-darwin");
2819 default:
2821 }
2825 if (ArchFlag)
2826 *ArchFlag = "ppc";
2827 return Triple("ppc-apple-darwin");
2828 default:
2830 }
2834 if (ArchFlag)
2835 *ArchFlag = "ppc64";
2836 return Triple("ppc64-apple-darwin");
2837 default:
2839 }
2840 default:
2842 }
2843}
2844
2847}
2848
2852}
2853
2855 static const std::array<StringRef, 18> ValidArchs = {{
2856 "i386",
2857 "x86_64",
2858 "x86_64h",
2859 "armv4t",
2860 "arm",
2861 "armv5e",
2862 "armv6",
2863 "armv6m",
2864 "armv7",
2865 "armv7em",
2866 "armv7k",
2867 "armv7m",
2868 "armv7s",
2869 "arm64",
2870 "arm64e",
2871 "arm64_32",
2872 "ppc",
2873 "ppc64",
2874 }};
2875
2876 return ValidArchs;
2877}
2878
2881}
2882
2885}
2886
2891}
2892
2897}
2898
2901 if (!DataInCodeLoadCmd)
2903
2905 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2907}
2908
2911 if (!DataInCodeLoadCmd)
2913
2916 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2918}
2919
2922
2923void ExportEntry::moveToFirst() {
2925 pushNode(0);
2926 if (*E)
2927 return;
2928 pushDownUntilBottom();
2929}
2930
2931void ExportEntry::moveToEnd() {
2933 Done = true;
2934}
2935
2937
2938 if (Done || Other.Done)
2939 return (Done == Other.Done);
2940
2941 if (Stack.size() != Other.Stack.size())
2942 return false;
2943
2944 if (!CumulativeString.equals(Other.CumulativeString))
2945 return false;
2946
2947 for (unsigned i=0; i < Stack.size(); ++i) {
2948 if (Stack[i].Start != Other.Stack[i].Start)
2949 return false;
2950 }
2951 return true;
2952}
2953
2955 unsigned Count;
2957 Ptr += Count;
2960 return Result;
2961}
2962
2964 return CumulativeString;
2965}
2966
2968 return Stack.back().Flags;
2969}
2970
2972 return Stack.back().Address;
2973}
2974
2976 return Stack.back().Other;
2977}
2978
2980 const char* ImportName = Stack.back().ImportName;
2981 if (ImportName)
2984}
2985
2987 return Stack.back().Start - Trie.begin();
2988}
2989
2990ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
2991 : Start(Ptr), Current(Ptr) {}
2992
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" +
3003 moveToEnd();
3004 return;
3005 }
3006 State.IsExportNode = (ExportInfoSize != 0);
3007 const uint8_t* Children = State.Current + ExportInfoSize;
3008 if (Children > Trie.end()) {
3011 " in export trie data at node: 0x" + Twine::utohexstr(offset) +
3012 " too big and extends past end of trie data");
3013 moveToEnd();
3014 return;
3015 }
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" +
3023 moveToEnd();
3024 return;
3025 }
3027 if (State.Flags != 0 &&
3032 "unsupported exported symbol kind: " + Twine((int)Kind) +
3034 " in export trie data at node: 0x" + Twine::utohexstr(offset));
3035 moveToEnd();
3036 return;
3037 }
3039 State.Address = 0;
3040 State.Other = readULEB128(State.Current, &error);
3043 " in export trie data at node: 0x" +
3045 moveToEnd();
3046 return;
3047 }
3048 if (O != nullptr) {
3049
3050
3051 if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3053 "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3055 ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3056 moveToEnd();
3057 return;
3058 }
3059 }
3060 State.ImportName = reinterpret_cast<const char*>(State.Current);
3061 if (*State.ImportName == '\0') {
3062 State.Current++;
3063 } else {
3064 const uint8_t *End = State.Current + 1;
3066 *E = malformedError("import name of re-export in export trie data at "
3067 "node: 0x" +
3069 " starts past end of trie data");
3070 moveToEnd();
3071 return;
3072 }
3073 while(*End != '\0' && End < Trie.end())
3075 if (*End != '\0') {
3076 *E = malformedError("import name of re-export in export trie data at "
3077 "node: 0x" +
3079 " extends past end of trie data");
3080 moveToEnd();
3081 return;
3082 }
3083 State.Current = End + 1;
3084 }
3085 } else {
3086 State.Address = readULEB128(State.Current, &error);
3089 " in export trie data at node: 0x" +
3091 moveToEnd();
3092 return;
3093 }
3095 State.Other = readULEB128(State.Current, &error);
3098 " in export trie data at node: 0x" +
3100 moveToEnd();
3101 return;
3102 }
3103 }
3104 }
3105 if (ExportStart + ExportInfoSize < State.Current) {
3107 "inconsistent export info size: 0x" +
3108 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3110 " in export trie data at node: 0x" + Twine::utohexstr(offset));
3111 moveToEnd();
3112 return;
3113 }
3114 }
3115 State.ChildCount = *Children;
3116 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3117 *E = malformedError("byte for count of childern in export trie data at "
3118 "node: 0x" +
3120 " extends past end of trie data");
3121 moveToEnd();
3122 return;
3123 }
3124 State.Current = Children + 1;
3125 State.NextChildIndex = 0;
3126 State.ParentStringLength = CumulativeString.size();
3128}
3129
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;
3139 }
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");
3145 moveToEnd();
3146 return;
3147 }
3148 Top.Current += 1;
3149 uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3152 " in export trie data at node: 0x" +
3154 moveToEnd();
3155 return;
3156 }
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" +
3163 moveToEnd();
3164 return;
3165 }
3166 }
3167 Top.NextChildIndex += 1;
3168 pushNode(childNodeIndex);
3169 if (*E)
3170 return;
3171 }
3172 if (!Stack.back().IsExportNode) {
3173 *E = malformedError("node is not an export node in export trie data at "
3174 "node: 0x" +
3176 moveToEnd();
3177 return;
3178 }
3179}
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
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 "
3200 "node: 0x" +
3202 moveToEnd();
3203 return;
3204 }
3205
3207 while (!Stack.empty()) {
3208 NodeState &Top = Stack.back();
3209 if (Top.NextChildIndex < Top.ChildCount) {
3210 pushDownUntilBottom();
3211
3212 return;
3213 } else {
3214 if (Top.IsExportNode) {
3215
3216 CumulativeString.resize(Top.ParentStringLength);
3217 return;
3218 }
3220 }
3221 }
3222 Done = true;
3223}
3224
3229 if (Trie.empty())
3230 Start.moveToEnd();
3231 else
3232 Start.moveToFirst();
3233
3235 Finish.moveToEnd();
3236
3238}
3239
3242 if (DyldInfoLoadCmd)
3244 else if (DyldExportsTrieLoadCmd)
3246
3247 return exports(Err, Trie, this);
3248}
3249
3252 : E(E), O(O) {
3253
3255 if (Command.C.cmd == MachO::LC_SEGMENT) {
3257 if (StringRef(SLC.segname) == "__TEXT") {
3258 TextAddress = SLC.vmaddr;
3259 break;
3260 }
3261 } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3264 TextAddress = SLC_64.vmaddr;
3265 break;
3266 }
3267 }
3268 }
3269}
3270
3272
3275}
3276
3279}
3280
3283}
3284
3287}
3288
3291}
3292
3294
3296
3298
3300
3302
3309 Done = false;
3310}
3311
3313
3315
3318 bool Parse)
3321 if (!Parse)
3322 return;
3323
3325 FixupTargets = *FixupTargetsOrErr;
3326 } else {
3327 *E = FixupTargetsOrErr.takeError();
3328 return;
3329 }
3330
3332 Segments = std::move(SegmentsOrErr->second);
3333 } else {
3334 *E = SegmentsOrErr.takeError();
3335 return;
3336 }
3337}
3338
3339void MachOChainedFixupEntry::findNextPageWithFixups() {
3340 auto FindInSegment = [this]() {
3342 while (PageIndex < SegInfo.PageStarts.size() &&
3344 ++PageIndex;
3345 return PageIndex < SegInfo.PageStarts.size();
3346 };
3347
3348 while (InfoSegIndex < Segments.size()) {
3349 if (FindInSegment()) {
3350 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3352 return;
3353 }
3354
3355 InfoSegIndex++;
3356 PageIndex = 0;
3357 }
3358}
3359
3362 if (Segments.empty()) {
3363 Done = true;
3364 return;
3365 }
3366
3367 InfoSegIndex = 0;
3368 PageIndex = 0;
3369
3370 findNextPageWithFixups();
3372}
3373
3376}
3377
3380
3381 if (InfoSegIndex == Segments.size()) {
3382 Done = true;
3383 return;
3384 }
3385
3389
3390
3395 " has unsupported chained fixup pointer_format " +
3396 Twine(PointerFormat));
3398 return;
3399 }
3400
3406
3410 " extends past segment's end");
3412 return;
3413 }
3414
3419
3420
3422 "by getDyldChainedFixupTargets()");
3424 return (RawValue >> Right) & ((1ULL << Count) - 1);
3425 };
3426
3427
3428
3429 bool IsBind = Field(63, 1);
3432 if (IsBind) {
3435
3436 if (ImportOrdinal >= FixupTargets.size()) {
3439 " has out-of range import ordinal " +
3440 Twine(ImportOrdinal));
3442 return;
3443 }
3444
3447 Addend = InlineAddend ? InlineAddend : Target.addend();
3450 } else {
3453
3457 }
3458
3459
3460 if (Next != 0) {
3461 PageOffset += 4 * Next;
3462 } else {
3463 ++PageIndex;
3464 findNextPageWithFixups();
3465 }
3466}
3467
3471 return true;
3473 return false;
3474 return InfoSegIndex == Other.InfoSegIndex && PageIndex == Other.PageIndex &&
3475 PageOffset == Other.PageOffset;
3476}
3477
3480 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3481 PointerSize(is64Bit ? 8 : 4) {}
3482
3483void MachORebaseEntry::moveToFirst() {
3486}
3487
3488void MachORebaseEntry::moveToEnd() {
3490 RemainingLoopCount = 0;
3491 Done = true;
3492}
3493
3496
3497 SegmentOffset += AdvanceAmount;
3498 if (RemainingLoopCount) {
3499 --RemainingLoopCount;
3500 return;
3501 }
3502
3503 bool More = true;
3504 while (More) {
3505
3506
3507
3508 if (Ptr == Opcodes.end()) {
3509 Done = true;
3510 return;
3511 }
3512
3513
3519 const char *error = nullptr;
3520 switch (Opcode) {
3522 More = false;
3523 Done = true;
3524 moveToEnd();
3526 break;
3528 RebaseType = ImmValue;
3530 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3531 Twine((int)RebaseType) + " for opcode at: 0x" +
3533 moveToEnd();
3534 return;
3535 }
3537 "mach-o-rebase",
3538 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3539 << "RebaseType=" << (int) RebaseType << "\n");
3540 break;
3542 SegmentIndex = ImmValue;
3543 SegmentOffset = readULEB128(&error);
3545 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3546 Twine(error) + " for opcode at: 0x" +
3548 moveToEnd();
3549 return;
3550 }
3552 PointerSize);
3554 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3555 Twine(error) + " for opcode at: 0x" +
3557 moveToEnd();
3558 return;
3559 }
3561 "mach-o-rebase",
3562 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3563 << "SegmentIndex=" << SegmentIndex << ", "
3564 << format("SegmentOffset=0x%06X", SegmentOffset)
3565 << "\n");
3566 break;
3568 SegmentOffset += readULEB128(&error);
3571 " for opcode at: 0x" +
3573 moveToEnd();
3574 return;
3575 }
3577 PointerSize);
3580 " for opcode at: 0x" +
3582 moveToEnd();
3583 return;
3584 }
3586 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3587 << format("SegmentOffset=0x%06X",
3588 SegmentOffset) << "\n");
3589 break;
3591 SegmentOffset += ImmValue * PointerSize;
3593 PointerSize);
3595 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3596 Twine(error) + " for opcode at: 0x" +
3598 moveToEnd();
3599 return;
3600 }
3602 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3603 << format("SegmentOffset=0x%06X",
3604 SegmentOffset) << "\n");
3605 break;
3607 AdvanceAmount = PointerSize;
3608 Skip = 0;
3609 Count = ImmValue;
3610 if (ImmValue != 0)
3611 RemainingLoopCount = ImmValue - 1;
3612 else
3613 RemainingLoopCount = 0;
3615 PointerSize, Count, Skip);
3617 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3618 Twine(error) + " for opcode at: 0x" +
3620 moveToEnd();
3621 return;
3622 }
3624 "mach-o-rebase",
3625 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3626 << format("SegmentOffset=0x%06X", SegmentOffset)
3627 << ", AdvanceAmount=" << AdvanceAmount
3628 << ", RemainingLoopCount=" << RemainingLoopCount
3629 << "\n");
3630 return;
3632 AdvanceAmount = PointerSize;
3633 Skip = 0;
3634 Count = readULEB128(&error);
3636 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3637 Twine(error) + " for opcode at: 0x" +
3639 moveToEnd();
3640 return;
3641 }
3642 if (Count != 0)
3643 RemainingLoopCount = Count - 1;
3644 else
3645 RemainingLoopCount = 0;
3647 PointerSize, Count, Skip);
3649 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3650 Twine(error) + " for opcode at: 0x" +
3652 moveToEnd();
3653 return;
3654 }
3656 "mach-o-rebase",
3657 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3658 << format("SegmentOffset=0x%06X", SegmentOffset)
3659 << ", AdvanceAmount=" << AdvanceAmount
3660 << ", RemainingLoopCount=" << RemainingLoopCount
3661 << "\n");
3662 return;
3664 Skip = readULEB128(&error);
3666 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3667 Twine(error) + " for opcode at: 0x" +
3669 moveToEnd();
3670 return;
3671 }
3672 AdvanceAmount = Skip + PointerSize;
3673 Count = 1;
3674 RemainingLoopCount = 0;
3676 PointerSize, Count, Skip);
3678 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3679 Twine(error) + " for opcode at: 0x" +
3681 moveToEnd();
3682 return;
3683 }
3685 "mach-o-rebase",
3686 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3687 << format("SegmentOffset=0x%06X", SegmentOffset)
3688 << ", AdvanceAmount=" << AdvanceAmount
3689 << ", RemainingLoopCount=" << RemainingLoopCount
3690 << "\n");
3691 return;
3693 Count = readULEB128(&error);
3695 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3696 "ULEB " +
3697 Twine(error) + " for opcode at: 0x" +
3699 moveToEnd();
3700 return;
3701 }
3702 if (Count != 0)
3703 RemainingLoopCount = Count - 1;
3704 else
3705 RemainingLoopCount = 0;
3706 Skip = readULEB128(&error);
3708 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3709 "ULEB " +
3710 Twine(error) + " for opcode at: 0x" +
3712 moveToEnd();
3713 return;
3714 }
3715 AdvanceAmount = Skip + PointerSize;
3716
3718 PointerSize, Count, Skip);
3720 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3721 "ULEB " +
3722 Twine(error) + " for opcode at: 0x" +
3724 moveToEnd();
3725 return;
3726 }
3728 "mach-o-rebase",
3729 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3730 << format("SegmentOffset=0x%06X", SegmentOffset)
3731 << ", AdvanceAmount=" << AdvanceAmount
3732 << ", RemainingLoopCount=" << RemainingLoopCount
3733 << "\n");
3734 return;
3735 default:
3736 *E = malformedError("bad rebase info (bad opcode value 0x" +
3739 moveToEnd();
3740 return;
3741 }
3742 }
3743}
3744
3745uint64_t MachORebaseEntry::readULEB128(const char **error) {
3746 unsigned Count;
3748 Ptr += Count;
3749 if (Ptr > Opcodes.end())
3751 return Result;
3752}
3753
3755
3757
3759 switch (RebaseType) {
3761 return "pointer";
3763 return "text abs32";
3765 return "text rel32";
3766 }
3767 return "unknown";
3768}
3769
3770
3771
3774}
3775
3776
3777
3780}
3781
3782
3783
3786}
3787
3789#ifdef EXPENSIVE_CHECKS
3790 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3791#else
3792 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3793#endif
3794 return (Ptr == Other.Ptr) &&
3795 (RemainingLoopCount == Other.RemainingLoopCount) &&
3796 (Done == Other.Done);
3797}
3798
3802 if (O->BindRebaseSectionTable == nullptr)
3803 O->BindRebaseSectionTable = std::make_unique(O);
3805 Start.moveToFirst();
3806
3808 Finish.moveToEnd();
3809
3811}
3812
3815}
3816
3819 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3820 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3821
3822void MachOBindEntry::moveToFirst() {
3825}
3826
3827void MachOBindEntry::moveToEnd() {
3829 RemainingLoopCount = 0;
3830 Done = true;
3831}
3832
3835
3836 SegmentOffset += AdvanceAmount;
3837 if (RemainingLoopCount) {
3838 --RemainingLoopCount;
3839 return;
3840 }
3841
3842 bool More = true;
3843 while (More) {
3844
3845
3846
3847 if (Ptr == Opcodes.end()) {
3848 Done = true;
3849 return;
3850 }
3851
3852
3857 int8_t SignExtended;
3858 const uint8_t *SymStart;
3860 const char *error = nullptr;
3861 switch (Opcode) {
3864
3865
3866 bool NotLastEntry = false;
3868 if (*P) {
3869 NotLastEntry = true;
3870 }
3871 }
3872 if (NotLastEntry)
3873 break;
3874 }
3875 More = false;
3876 moveToEnd();
3878 break;
3881 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3882 "weak bind table for opcode at: 0x" +
3884 moveToEnd();
3885 return;
3886 }
3887 Ordinal = ImmValue;
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" +
3896 moveToEnd();
3897 return;
3898 }
3900 "mach-o-bind",
3901 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3902 << "Ordinal=" << Ordinal << "\n");
3903 break;
3906 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3907 "weak bind table for opcode at: 0x" +
3909 moveToEnd();
3910 return;
3911 }
3912 Ordinal = readULEB128(&error);
3913 LibraryOrdinalSet = true;
3915 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3916 Twine(error) + " for opcode at: 0x" +
3918 moveToEnd();
3919 return;
3920 }
3922 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3923 "library ordinal: " +
3924 Twine((int)Ordinal) + " (max " +
3926 ") for opcode at: 0x" +
3928 moveToEnd();
3929 return;
3930 }
3932 "mach-o-bind",
3933 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3934 << "Ordinal=" << Ordinal << "\n");
3935 break;
3938 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3939 "weak bind table for opcode at: 0x" +
3941 moveToEnd();
3942 return;
3943 }
3944 if (ImmValue) {
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" +
3952 moveToEnd();
3953 return;
3954 }
3955 } else
3956 Ordinal = 0;
3957 LibraryOrdinalSet = true;
3959 "mach-o-bind",
3960 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3961 << "Ordinal=" << Ordinal << "\n");
3962 break;
3964 Flags = ImmValue;
3965 SymStart = Ptr;
3966 while (*Ptr && (Ptr < Opcodes.end())) {
3968 }
3969 if (Ptr == Opcodes.end()) {
3971 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3972 "symbol name extends past opcodes for opcode at: 0x" +
3974 moveToEnd();
3975 return;
3976 }
3977 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
3978 Ptr-SymStart);
3981 "mach-o-bind",
3982 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
3983 << "SymbolName=" << SymbolName << "\n");
3986 return;
3987 }
3988 break;
3990 BindType = ImmValue;
3992 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3993 Twine((int)ImmValue) + " for opcode at: 0x" +
3995 moveToEnd();
3996 return;
3997 }
3999 "mach-o-bind",
4000 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
4001 << "BindType=" << (int)BindType << "\n");
4002 break;
4004 Addend = readSLEB128(&error);
4007 " for opcode at: 0x" +
4009 moveToEnd();
4010 return;
4011 }
4013 "mach-o-bind",
4014 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
4015 << "Addend=" << Addend << "\n");
4016 break;
4018 SegmentIndex = ImmValue;
4019 SegmentOffset = readULEB128(&error);
4021 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4022 Twine(error) + " for opcode at: 0x" +
4024 moveToEnd();
4025 return;
4026 }
4028 PointerSize);
4030 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4031 Twine(error) + " for opcode at: 0x" +
4033 moveToEnd();
4034 return;
4035 }
4037 "mach-o-bind",
4038 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
4039 << "SegmentIndex=" << SegmentIndex << ", "
4040 << format("SegmentOffset=0x%06X", SegmentOffset)
4041 << "\n");
4042 break;
4044 SegmentOffset += readULEB128(&error);
4047 " for opcode at: 0x" +
4049 moveToEnd();
4050 return;
4051 }
4053 PointerSize);
4056 " for opcode at: 0x" +
4058 moveToEnd();
4059 return;
4060 }
4062 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
4063 << format("SegmentOffset=0x%06X",
4064 SegmentOffset) << "\n");
4065 break;
4067 AdvanceAmount = PointerSize;
4068 RemainingLoopCount = 0;
4070 PointerSize);
4073 " for opcode at: 0x" +
4075 moveToEnd();
4076 return;
4077 }
4078 if (SymbolName == StringRef()) {
4080 "for BIND_OPCODE_DO_BIND missing preceding "
4081 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4083 moveToEnd();
4084 return;
4085 }
4086 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4087 *E =
4088 malformedError("for BIND_OPCODE_DO_BIND missing preceding "
4089 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4091 moveToEnd();
4092 return;
4093 }
4095 dbgs() << "BIND_OPCODE_DO_BIND: "
4096 << format("SegmentOffset=0x%06X",
4097 SegmentOffset) << "\n");
4098 return;
4101 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
4102 "lazy bind table for opcode at: 0x" +
4104 moveToEnd();
4105 return;
4106 }
4108 PointerSize);
4110 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4111 Twine(error) + " for opcode at: 0x" +
4113 moveToEnd();
4114 return;
4115 }
4116 if (SymbolName == StringRef()) {
4118 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4119 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
4120 "at: 0x" +
4122 moveToEnd();
4123 return;
4124 }
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" +
4130 moveToEnd();
4131 return;
4132 }
4133 AdvanceAmount = readULEB128(&error) + PointerSize;
4135 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4136 Twine(error) + " for opcode at: 0x" +
4138 moveToEnd();
4139 return;
4140 }
4141
4142
4143
4145 AdvanceAmount, PointerSize);
4147 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
4148 "ULEB) " +
4149 Twine(error) + " for opcode at: 0x" +
4151 moveToEnd();
4152 return;
4153 }
4154 RemainingLoopCount = 0;
4156 "mach-o-bind",
4157 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
4158 << format("SegmentOffset=0x%06X", SegmentOffset)
4159 << ", AdvanceAmount=" << AdvanceAmount
4160 << ", RemainingLoopCount=" << RemainingLoopCount
4161 << "\n");
4162 return;
4165 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
4166 "allowed in lazy bind table for opcode at: 0x" +
4168 moveToEnd();
4169 return;
4170 }
4171 if (SymbolName == StringRef()) {
4173 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4174 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4175 "opcode at: 0x" +
4177 moveToEnd();
4178 return;
4179 }
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 "
4184 "at: 0x" +
4186 moveToEnd();
4187 return;
4188 }
4189 AdvanceAmount = ImmValue * PointerSize + PointerSize;
4190 RemainingLoopCount = 0;
4192 AdvanceAmount, PointerSize);
4194 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4195 Twine(error) + " for opcode at: 0x" +
4197 moveToEnd();
4198 return;
4199 }
4202 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4203 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4204 return;
4207 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4208 "allowed in lazy bind table for opcode at: 0x" +
4210 moveToEnd();
4211 return;
4212 }
4213 Count = readULEB128(&error);
4214 if (Count != 0)
4215 RemainingLoopCount = Count - 1;
4216 else
4217 RemainingLoopCount = 0;
4219 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4220 " (count value) " +
4221 Twine(error) + " for opcode at: 0x" +
4223 moveToEnd();
4224 return;
4225 }
4226 Skip = readULEB128(&error);
4227 AdvanceAmount = Skip + PointerSize;
4229 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4230 " (skip value) " +
4231 Twine(error) + " for opcode at: 0x" +
4233 moveToEnd();
4234 return;
4235 }
4236 if (SymbolName == StringRef()) {
4238 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4239 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4240 "opcode at: 0x" +
4242 moveToEnd();
4243 return;
4244 }
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 "
4249 "at: 0x" +
4251 moveToEnd();
4252 return;
4253 }
4255 PointerSize, Count, Skip);
4257 *E =
4258 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4259 Twine(error) + " for opcode at: 0x" +
4261 moveToEnd();
4262 return;
4263 }
4265 "mach-o-bind",
4266 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4267 << format("SegmentOffset=0x%06X", SegmentOffset)
4268 << ", AdvanceAmount=" << AdvanceAmount
4269 << ", RemainingLoopCount=" << RemainingLoopCount
4270 << "\n");
4271 return;
4272 default:
4273 *E = malformedError("bad bind info (bad opcode value 0x" +
4276 moveToEnd();
4277 return;
4278 }
4279 }
4280}
4281
4282uint64_t MachOBindEntry::readULEB128(const char **error) {
4283 unsigned Count;
4285 Ptr += Count;
4286 if (Ptr > Opcodes.end())
4288 return Result;
4289}
4290
4291int64_t MachOBindEntry::readSLEB128(const char **error) {
4292 unsigned Count;
4294 Ptr += Count;
4295 if (Ptr > Opcodes.end())
4297 return Result;
4298}
4299
4301
4303
4305 switch (BindType) {
4307 return "pointer";
4309 return "text abs32";
4311 return "text rel32";
4312 }
4313 return "unknown";
4314}
4315
4317
4319
4321
4323
4324
4325
4328}
4329
4330
4331
4334}
4335
4336
4337
4340}
4341
4343#ifdef EXPENSIVE_CHECKS
4344 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4345#else
4346 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4347#endif
4348 return (Ptr == Other.Ptr) &&
4349 (RemainingLoopCount == Other.RemainingLoopCount) &&
4350 (Done == Other.Done);
4351}
4352
4353
4359 SectionInfo Info;
4361 if (!NameOrErr)
4363 else
4364 Info.SectionName = *NameOrErr;
4365 Info.Address = Section.getAddress();
4366 Info.Size = Section.getSize();
4367 Info.SegmentName =
4369 if (Info.SegmentName != CurSegName) {
4370 ++CurSegIndex;
4371 CurSegName = Info.SegmentName;
4372 CurSegAddress = Info.Address;
4373 }
4374 Info.SegmentIndex = CurSegIndex - 1;
4375 Info.OffsetInSegment = Info.Address - CurSegAddress;
4376 Info.SegmentStartAddress = CurSegAddress;
4378 }
4379 MaxSegIndex = CurSegIndex;
4380}
4381
4382
4383
4384
4385
4386
4387
4388
4394 if (SegIndex == -1)
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);
4401 bool Found = false;
4402 for (const SectionInfo &SI : Sections) {
4403 if (SI.SegmentIndex != SegIndex)
4404 continue;
4405 if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4406 if (End <= SI.OffsetInSegment + SI.Size) {
4407 Found = true;
4408 break;
4409 }
4410 else
4411 return "bad offset, extends beyond section boundary";
4412 }
4413 }
4414 if (!Found)
4415 return "bad offset, not in section";
4416 }
4417 return nullptr;
4418}
4419
4420
4421
4423 for (const SectionInfo &SI : Sections) {
4424 if (SI.SegmentIndex == SegIndex)
4425 return SI.SegmentName;
4426 }
4428}
4429
4430
4431
4432const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4433 int32_t SegIndex, uint64_t SegOffset) {
4434 for (const SectionInfo &SI : Sections) {
4435 if (SI.SegmentIndex != SegIndex)
4436 continue;
4437 if (SI.OffsetInSegment > SegOffset)
4438 continue;
4439 if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4440 continue;
4441 return SI;
4442 }
4443 llvm_unreachable("SegIndex and SegOffset not in any section");
4444}
4445
4446
4447
4450 return findSection(SegIndex, SegOffset).SectionName;
4451}
4452
4453
4454
4456 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4457 return SI.SegmentStartAddress + OffsetInSeg;
4458}
4459
4464 if (O->BindRebaseSectionTable == nullptr)
4465 O->BindRebaseSectionTable = std::make_unique(O);
4466 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4467 Start.moveToFirst();
4468
4469 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4470 Finish.moveToEnd();
4471
4473}
4474
4478}
4479
4483}
4484
4488}
4489
4491 if (BindRebaseSectionTable == nullptr)
4492 BindRebaseSectionTable = std::make_unique(this);
4493
4495 Start.moveToFirst();
4496
4499
4501}
4502
4505 return LoadCommands.begin();
4506}
4507
4510 return LoadCommands.end();
4511}
4512
4516}
4517
4522}
4523
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]);
4530}
4531
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]);
4538}
4539
4540bool
4542 const {
4544 return false;
4546}
4547
4551 return RE.r_word1 & 0xffffff;
4553}
4554
4558 return (RE.r_word1 >> 27) & 1;
4559 return (RE.r_word1 >> 4) & 1;
4560}
4561
4564 return RE.r_word0 >> 31;
4565}
4566
4570}
4571
4574 return (RE.r_word0 >> 24) & 0xf;
4575}
4576
4582}
4583
4589}
4590
4596}
4597
4598unsigned
4604}
4605
4612 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4617}
4618
4620 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4621 return getStructMachO::section(*this, Sections[DRI.d.a]);
4622}
4623
4625 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4626 return getStructMachO::section\_64(*this, Sections[DRI.d.a]);
4627}
4628
4630 unsigned Index) const {
4631 const char *Sec = getSectionPtr(*this, L, Index);
4632 return getStructMachO::section(*this, Sec);
4633}
4634
4636 unsigned Index) const {
4637 const char *Sec = getSectionPtr(*this, L, Index);
4638 return getStructMachO::section\_64(*this, Sec);
4639}
4640
4643 const char *P = reinterpret_cast<const char *>(DRI.p);
4644 return getStructMachO::nlist(*this, P);
4645}
4646
4649 const char *P = reinterpret_cast<const char *>(DRI.p);
4650 return getStructMachO::nlist\_64(*this, P);
4651}
4652
4655 return getStructMachO::linkedit\_data\_command(*this, L.Ptr);
4656}
4657
4660 return getStructMachO::segment\_command(*this, L.Ptr);
4661}
4662
4665 return getStructMachO::segment\_command\_64(*this, L.Ptr);
4666}
4667
4670 return getStructMachO::linker\_option\_command(*this, L.Ptr);
4671}
4672
4675 return getStructMachO::version\_min\_command(*this, L.Ptr);
4676}
4677
4680 return getStructMachO::note\_command(*this, L.Ptr);
4681}
4682
4685 return getStructMachO::build\_version\_command(*this, L.Ptr);
4686}
4687
4690 return getStructMachO::build\_tool\_version(*this, BuildTools[index]);
4691}
4692
4695 return getStructMachO::dylib\_command(*this, L.Ptr);
4696}
4697
4700 return getStructMachO::dyld\_info\_command(*this, L.Ptr);
4701}
4702
4705 return getStructMachO::dylinker\_command(*this, L.Ptr);
4706}
4707
4710 return getStructMachO::uuid\_command(*this, L.Ptr);
4711}
4712
4715 return getStructMachO::rpath\_command(*this, L.Ptr);
4716}
4717
4720 return getStructMachO::source\_version\_command(*this, L.Ptr);
4721}
4722
4725 return getStructMachO::entry\_point\_command(*this, L.Ptr);
4726}
4727
4730 return getStructMachO::encryption\_info\_command(*this, L.Ptr);
4731}
4732
4735 return getStructMachO::encryption\_info\_command\_64(*this, L.Ptr);
4736}
4737
4740 return getStructMachO::sub\_framework\_command(*this, L.Ptr);
4741}
4742
4745 return getStructMachO::sub\_umbrella\_command(*this, L.Ptr);
4746}
4747
4750 return getStructMachO::sub\_library\_command(*this, L.Ptr);
4751}
4752
4755 return getStructMachO::sub\_client\_command(*this, L.Ptr);
4756}
4757
4760 return getStructMachO::routines\_command(*this, L.Ptr);
4761}
4762
4765 return getStructMachO::routines\_command\_64(*this, L.Ptr);
4766}
4767
4770 return getStructMachO::thread\_command(*this, L.Ptr);
4771}
4772
4775 return getStructMachO::fileset\_entry\_command(*this, L.Ptr);
4776}
4777
4787 } else {
4790 }
4791 } else {
4794 Offset = DysymtabLoadCmd.extreloff;
4795 else
4796 Offset = DysymtabLoadCmd.locreloff;
4797 }
4798
4801 return getStructMachO::any\_relocation\_info(
4802 *this, reinterpret_cast<const char *>(P));
4803}
4804
4807 const char *P = reinterpret_cast<const char *>(Rel.p);
4808 return getStructMachO::data\_in\_code\_entry(*this, P);
4809}
4810
4813}
4814
4818}
4819
4822 unsigned Index) const {
4824 return getStruct<uint32_t>(*this, getPtr(*this, Offset));
4825}
4826
4829 unsigned Index) const {
4831 return getStructMachO::data\_in\_code\_entry(*this, getPtr(*this, Offset));
4832}
4833
4835 if (SymtabLoadCmd)
4836 return getStructMachO::symtab\_command(*this, SymtabLoadCmd);
4837
4838
4840 Cmd.cmd = MachO::LC_SYMTAB;
4846 return Cmd;
4847}
4848
4850 if (DysymtabLoadCmd)
4851 return getStructMachO::dysymtab\_command(*this, DysymtabLoadCmd);
4852
4853
4855 Cmd.cmd = MachO::LC_DYSYMTAB;
4864 Cmd.ntoc = 0;
4875 return Cmd;
4876}
4877
4880 if (DataInCodeLoadCmd)
4881 return getStructMachO::linkedit\_data\_command(*this, DataInCodeLoadCmd);
4882
4883
4885 Cmd.cmd = MachO::LC_DATA_IN_CODE;
4889 return Cmd;
4890}
4891
4894 if (LinkOptHintsLoadCmd)
4895 return getStructMachO::linkedit\_data\_command(*this, LinkOptHintsLoadCmd);
4896
4897
4898
4900 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4904 return Cmd;
4905}
4906
4908 if (!DyldInfoLoadCmd)
4909 return {};
4910
4911 auto DyldInfoOrErr =
4912 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);
4913 if (!DyldInfoOrErr)
4914 return {};
4919}
4920
4922 if (!DyldInfoLoadCmd)
4923 return {};
4924
4925 auto DyldInfoOrErr =
4926 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);
4927 if (!DyldInfoOrErr)
4928 return {};
4933}
4934
4936 if (!DyldInfoLoadCmd)
4937 return {};
4938
4939 auto DyldInfoOrErr =
4940 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);
4941 if (!DyldInfoOrErr)
4942 return {};
4947}
4948
4950 if (!DyldInfoLoadCmd)
4951 return {};
4952
4953 auto DyldInfoOrErr =
4954 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);
4955 if (!DyldInfoOrErr)
4956 return {};
4961}
4962
4964 if (!DyldInfoLoadCmd)
4965 return {};
4966
4967 auto DyldInfoOrErr =
4968 getStructOrErrMachO::dyld\_info\_command(*this, DyldInfoLoadCmd);
4969 if (!DyldInfoOrErr)
4970 return {};
4975}
4976
4979
4980 if (!DyldChainedFixupsLoadCmd)
4981 return std::nullopt;
4982 auto DyldChainedFixupsOrErr = getStructOrErrMachO::linkedit\_data\_command(
4983 *this, DyldChainedFixupsLoadCmd);
4984 if (!DyldChainedFixupsOrErr)
4985 return DyldChainedFixupsOrErr.takeError();
4987 *DyldChainedFixupsOrErr;
4988
4989
4990
4991 if (!DyldChainedFixups.dataoff)
4992 return std::nullopt;
4993 return DyldChainedFixups;
4994}
4995
4999 if (!CFOrErr)
5000 return CFOrErr.takeError();
5001 if (!CFOrErr->has_value())
5002 return std::nullopt;
5003
5005
5008
5009
5010 const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
5011 auto CFHeaderOrErr =
5012 getStructOrErrMachO::dyld\_chained\_fixups\_header(*this, CFHeaderPtr);
5013 if (!CFHeaderOrErr)
5014 return CFHeaderOrErr.takeError();
5016
5017
5023 Twine("bad chained fixups: unknown imports format: ") +
5025
5026
5027
5028
5031 return malformedError(Twine("bad chained fixups: image starts offset ") +
5033 " overlaps with chained fixups header");
5034 }
5035 uint32_t EndOffset = CFHeaderOffset + CFSize;
5037 EndOffset) {
5039 Twine(CFImageStartsOffset +
5041 " extends past end " + Twine(EndOffset));
5042 }
5043
5044 return CFHeader;
5045}
5046
5050 if (!CFOrErr)
5051 return CFOrErr.takeError();
5052
5053 std::vector Segments;
5054 if (!CFOrErr->has_value())
5055 return std::make_pair(0, Segments);
5056
5058
5060 if (!HeaderOrErr)
5061 return HeaderOrErr.takeError();
5062 if (!HeaderOrErr->has_value())
5063 return std::make_pair(0, Segments);
5065
5066 const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);
5067
5068 auto ImageStartsOrErr = getStructOrErrMachO::dyld\_chained\_starts\_in\_image(
5069 *this, Contents + Header.starts_offset);
5070 if (!ImageStartsOrErr)
5071 return ImageStartsOrErr.takeError();
5073
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");
5082
5083 const char *LastSegEnd = nullptr;
5084 for (size_t I = 0, N = ImageStarts.seg_count; I < N; ++I) {
5085 auto OffOrErr =
5086 getStructOrErr<uint32_t>(*this, SegOffsPtr + I * sizeof(uint32_t));
5087 if (!OffOrErr)
5088 return OffOrErr.takeError();
5089
5090
5091 if (!*OffOrErr)
5092 continue;
5093
5094 auto Fail = [&](Twine Message) {
5096 " at offset " + Twine(*OffOrErr) + Message);
5097 };
5098
5099 const char *SegPtr = Contents + Header.starts_offset + *OffOrErr;
5100 if (LastSegEnd && SegPtr < LastSegEnd)
5101 return Fail(" overlaps with previous segment info");
5102
5103 auto SegOrErr =
5104 getStructOrErrMachO::dyld\_chained\_starts\_in\_segment(*this, SegPtr);
5105 if (!SegOrErr)
5106 return SegOrErr.takeError();
5108
5109 LastSegEnd = SegPtr + Seg.size;
5112
5113 const char *PageStart =
5115 const char *PageEnd = PageStart + Seg.page_count * sizeof(uint16_t);
5116 if (PageEnd > SegPtr + Seg.size)
5117 return Fail(" : page_starts extend past seg_info size");
5118
5119
5120
5121 std::vector<uint16_t> PageStarts;
5122 for (size_t PageIdx = 0; PageIdx < Seg.page_count; ++PageIdx) {
5124 memcpy(&Start, PageStart + PageIdx * sizeof(uint16_t), sizeof(uint16_t));
5127 PageStarts.push_back(Start);
5128 }
5129
5130 Segments.emplace_back(I, *OffOrErr, Seg, std::move(PageStarts));
5131 }
5132
5133 return std::make_pair(ImageStarts.seg_count, Segments);
5134}
5135
5136
5137
5142 return SignExtend32<sizeof(T) * CHAR_BIT>(Value);
5144}
5145
5146template <typename T, unsigned N>
5148 std::array<T, N> RawValue;
5149 memcpy(RawValue.data(), Ptr, N * sizeof(T));
5151 for (auto &Element : RawValue)
5153 return RawValue;
5154}
5155
5159 if (!CFOrErr)
5160 return CFOrErr.takeError();
5161
5162 std::vector Targets;
5163 if (!CFOrErr->has_value())
5164 return Targets;
5165
5167
5169 if (!CFHeaderOrErr)
5170 return CFHeaderOrErr.takeError();
5171 if (!(*CFHeaderOrErr))
5172 return Targets;
5174
5175 size_t ImportSize = 0;
5182 else
5183 return malformedError("bad chained fixups: unknown imports format: " +
5185
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;
5193
5194 if (ImportsEnd > Symbols)
5195 return malformedError("bad chained fixups: imports end " +
5196 Twine(ImportsEndOffset) + " overlaps with symbols");
5197
5198
5199
5201 return createError("parsing big-endian chained fixups is not implemented");
5202 for (const char *ImportPtr = Imports; ImportPtr < ImportsEnd;
5203 ImportPtr += ImportSize) {
5204 int LibOrdinal;
5205 bool WeakImport;
5210 auto RawValue = getArray<uint32_t, 1>(*this, ImportPtr);
5211
5212 LibOrdinal = getEncodedOrdinal<uint8_t>(RawValue[0] & 0xFF);
5213 WeakImport = (RawValue[0] >> 8) & 1;
5214 NameOffset = RawValue[0] >> 9;
5215 Addend = 0;
5217 static_assert(sizeof(uint64_t) ==
5219 auto RawValue = getArray<uint32_t, 2>(*this, ImportPtr);
5220
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);
5229
5230 LibOrdinal = getEncodedOrdinal<uint16_t>(RawValue[0] & 0xFFFF);
5231 NameOffset = (RawValue[0] >> 16) & 1;
5232 WeakImport = RawValue[0] >> 17;
5233 Addend = RawValue[1];
5234 } else {
5236 }
5237
5238 const char *Str = Symbols + NameOffset;
5239 if (Str >= SymbolsEnd)
5240 return malformedError("bad chained fixups: symbol offset " +
5241 Twine(NameOffset) + " extends past end " +
5243 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5244 }
5245
5246 return std::move(Targets);
5247}
5248
5250 if (!DyldExportsTrieLoadCmd)
5251 return {};
5252
5253 auto DyldExportsTrieOrError = getStructOrErrMachO::linkedit\_data\_command(
5254 *this, DyldExportsTrieLoadCmd);
5255 if (!DyldExportsTrieOrError)
5256 return {};
5261}
5262
5264 if (!FuncStartsLoadCmd)
5265 return {};
5266
5267 auto InfoOrErr =
5268 getStructOrErrMachO::linkedit\_data\_command(*this, FuncStartsLoadCmd);
5269 if (!InfoOrErr)
5270 return {};
5271
5275 return std::move(FunctionStarts);
5276}
5277
5279 if (!UuidLoadCmd)
5280 return {};
5281
5284}
5285
5289}
5290
5294}
5295
5299
5303 data += delta;
5305 }
5306}
5307
5310}
5311
5312
5313
5314
5315
5316
5317
5318
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("Unrecognized MachO magic number",
5337}
5338
5341 .Case("debug_str_offs", "debug_str_offsets")
5343}
5344
5348
5352 return std::vectorstd::string();
5353 sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
5354 bool IsDir;
5358 EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5359 Path.str().c_str());
5360 if (EC)
5362
5363 std::vectorstd::string ObjectPaths;
5365 Dir != DirEnd && !EC; Dir.increment(EC)) {
5366 StringRef ObjectPath = Dir->path();
5370 switch (Status.type()) {
5374 ObjectPaths.push_back(ObjectPath.str());
5375 break;
5376 default: ;
5377 }
5378 }
5379 if (EC)
5381 if (ObjectPaths.empty())
5383 "%s: no objects found in dSYM bundle",
5384 Path.str().c_str());
5385 return ObjectPaths;
5386}
5387
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
5398}
5399
5401 switch (Arch) {
5415 default:
5416 return false;
5417 }
5418}
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 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
Swift5ReflectionSectionKind
Error createError(const Twine &Err)
content_iterator< ExportEntry > export_iterator
content_iterator< MachOChainedFixupEntry > fixup_iterator
content_iterator< DiceRef > dice_iterator
content_iterator< SectionRef > section_iterator
content_iterator< MachOBindEntry > bind_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
content_iterator< MachORebaseEntry > rebase_iterator
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
bool is_directory(const basic_file_status &status)
Does status represent a directory?
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
static const bool IsLittleEndianHost
void swapByteOrder(T &Value)
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ no_such_file_or_directory
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
dyld_chained_starts_in_image is embedded in LC_DYLD_CHAINED_FIXUPS payload.
uint16_t page_count
Length of the page_start array.
uint16_t page_size
Page size in bytes (0x1000 or 0x4000)
uint16_t pointer_format
DYLD_CHAINED_PTR*.
uint32_t size
Size of this, including chain_starts entries.
ChainedFixupTarget holds all the information about an external symbol necessary to bind this binary t...
MachO::dyld_chained_starts_in_segment Header
std::vector< uint16_t > PageStarts
struct llvm::object::DataRefImpl::@370 d