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
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);
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
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
195 assert(Ptr <= Obj.getData().end() && "Start must be before end");
196 if (CmdOrErr->cmdsize > (uintptr_t)(Obj.getData().end() - Ptr))
198 " extends past end of file");
199 if (CmdOrErr->cmdsize < 8)
201 " with size less than 8 bytes");
203 } else
205}
206
212 return malformedError("load command 0 extends past the end all load "
213 "commands in the file");
215 Obj, getPtr(Obj, HeaderSize, Obj.getMachOFilesetEntryOffset()), 0);
216}
217
224 Obj.getData().data() + Obj.getMachOFilesetEntryOffset() + HeaderSize +
225 Obj.getHeader().sizeofcmds)
227 " extends past the end all load commands in the file");
228 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
229}
230
231template
234 if (sizeof(T) > Obj.getData().size()) {
235 Err = malformedError("the mach header extends past the end of the "
236 "file");
237 return;
238 }
240 Obj, getPtr(Obj, 0, Obj.getMachOFilesetEntryOffset())))
241 Header = *HeaderOrErr;
242 else
243 Err = HeaderOrErr.takeError();
244}
245
246
252
255 const char *Name) {
256 if (Size == 0)
258
259 for (auto it = Elements.begin(); it != Elements.end(); ++it) {
260 const auto &E = *it;
261 if ((Offset >= E.Offset && Offset < E.Offset + E.Size) ||
265 " with a size of " + Twine(Size) + ", overlaps " +
266 E.Name + " at offset " + Twine(E.Offset) + " with "
267 "a size of " + Twine(E.Size));
268 auto nt = it;
269 nt++;
270 if (nt != Elements.end()) {
271 const auto &N = *nt;
273 Elements.insert(nt, {Offset, Size, Name});
275 }
276 }
277 }
278 Elements.push_back({Offset, Size, Name});
280}
281
282
283
284
285template <typename Segment, typename Section>
289 uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders,
290 std::list &Elements) {
291 const unsigned SegmentLoadSize = sizeof(Segment);
292 if (Load.C.cmdsize < SegmentLoadSize)
294 " " + CmdName + " cmdsize too small");
296 Segment S = SegOrErr.get();
297 const unsigned SectionSize = sizeof(Section);
298 uint64_t FileSize = Obj.getData().size();
299 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
300 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
302 " inconsistent cmdsize in " + CmdName +
303 " for the number of sections");
304 for (unsigned J = 0; J < S.nsects; ++J) {
308 if (!SectionOrErr)
309 return SectionOrErr.takeError();
310 Section s = SectionOrErr.get();
315 s.offset > FileSize)
317 CmdName + " command " + Twine(LoadCommandIndex) +
318 " extends past the end of the file");
323 s.offset < SizeOfHeaders && s.size != 0)
325 CmdName + " command " + Twine(LoadCommandIndex) +
326 " not past the headers of the file");
328 BigSize += s.size;
333 BigSize > FileSize)
334 return malformedError("offset field plus size field of section " +
335 Twine(J) + " in " + CmdName + " command " +
336 Twine(LoadCommandIndex) +
337 " extends past the end of the file");
342 s.size > S.filesize)
344 Twine(J) + " in " + CmdName + " command " +
345 Twine(LoadCommandIndex) +
346 " greater than the segment");
348 Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 &&
349 s.addr < S.vmaddr)
351 CmdName + " command " + Twine(LoadCommandIndex) +
352 " less than the segment's vmaddr");
353 BigSize = s.addr;
354 BigSize += s.size;
356 BigEnd += S.vmsize;
357 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
359 " in " + CmdName + " command " +
360 Twine(LoadCommandIndex) +
361 " greater than than "
362 "the segment's vmaddr plus vmsize");
368 "section contents"))
369 return Err;
370 if (s.reloff > FileSize)
372 CmdName + " command " + Twine(LoadCommandIndex) +
373 " extends past the end of the file");
374 BigSize = s.nreloc;
376 BigSize += s.reloff;
377 if (BigSize > FileSize)
378 return malformedError("reloff field plus nreloc field times sizeof("
379 "struct relocation_info) of section " +
380 Twine(J) + " in " + CmdName + " command " +
381 Twine(LoadCommandIndex) +
382 " extends past the end of the file");
384 sizeof(struct
386 "section relocation entries"))
387 return Err;
388 }
389 if (S.fileoff > FileSize)
391 " fileoff field in " + CmdName +
392 " extends past the end of the file");
393 uint64_t BigSize = S.fileoff;
394 BigSize += S.filesize;
395 if (BigSize > FileSize)
397 " fileoff field plus filesize field in " +
398 CmdName + " extends past the end of the file");
399 if (S.vmsize != 0 && S.filesize > S.vmsize)
401 " filesize field in " + CmdName +
402 " greater than vmsize field");
403 IsPageZeroSegment |= StringRef("__PAGEZERO") == S.segname;
404 } else
405 return SegOrErr.takeError();
406
408}
409
413 const char **SymtabLoadCmd,
414 std::list &Elements) {
417 " LC_SYMTAB cmdsize too small");
418 if (*SymtabLoadCmd != nullptr)
419 return malformedError("more than one LC_SYMTAB command");
421 if (!SymtabOrErr)
422 return SymtabOrErr.takeError();
426 " has incorrect cmdsize");
427 uint64_t FileSize = Obj.getData().size();
428 if (Symtab.symoff > FileSize)
429 return malformedError("symoff field of LC_SYMTAB command " +
430 Twine(LoadCommandIndex) + " extends past the end "
431 "of the file");
433 const char *struct_nlist_name;
434 if (Obj.is64Bit()) {
436 struct_nlist_name = "struct nlist_64";
437 } else {
439 struct_nlist_name = "struct nlist";
440 }
441 uint64_t BigSize = SymtabSize;
442 BigSize += Symtab.symoff;
443 if (BigSize > FileSize)
444 return malformedError("symoff field plus nsyms field times sizeof(" +
445 Twine(struct_nlist_name) + ") of LC_SYMTAB command " +
446 Twine(LoadCommandIndex) + " extends past the end "
447 "of the file");
449 "symbol table"))
450 return Err;
451 if (Symtab.stroff > FileSize)
452 return malformedError("stroff field of LC_SYMTAB command " +
453 Twine(LoadCommandIndex) + " extends past the end "
454 "of the file");
455 BigSize = Symtab.stroff;
456 BigSize += Symtab.strsize;
457 if (BigSize > FileSize)
458 return malformedError("stroff field plus strsize field of LC_SYMTAB "
459 "command " + Twine(LoadCommandIndex) + " extends "
460 "past the end of the file");
462 Symtab.strsize, "string table"))
463 return Err;
464 *SymtabLoadCmd = Load.Ptr;
466}
467
471 const char **DysymtabLoadCmd,
472 std::list &Elements) {
475 " LC_DYSYMTAB cmdsize too small");
476 if (*DysymtabLoadCmd != nullptr)
477 return malformedError("more than one LC_DYSYMTAB command");
478 auto DysymtabOrErr =
480 if (!DysymtabOrErr)
481 return DysymtabOrErr.takeError();
485 " has incorrect cmdsize");
486 uint64_t FileSize = Obj.getData().size();
487 if (Dysymtab.tocoff > FileSize)
488 return malformedError("tocoff field of LC_DYSYMTAB command " +
489 Twine(LoadCommandIndex) + " extends past the end of "
490 "the file");
493 BigSize += Dysymtab.tocoff;
494 if (BigSize > FileSize)
495 return malformedError("tocoff field plus ntoc field times sizeof(struct "
496 "dylib_table_of_contents) of LC_DYSYMTAB command " +
497 Twine(LoadCommandIndex) + " extends past the end of "
498 "the file");
500 Dysymtab.ntoc * sizeof(struct
502 "table of contents"))
503 return Err;
504 if (Dysymtab.modtaboff > FileSize)
505 return malformedError("modtaboff field of LC_DYSYMTAB command " +
506 Twine(LoadCommandIndex) + " extends past the end of "
507 "the file");
508 BigSize = Dysymtab.nmodtab;
509 const char *struct_dylib_module_name;
511 if (Obj.is64Bit()) {
513 struct_dylib_module_name = "struct dylib_module_64";
514 } else {
516 struct_dylib_module_name = "struct dylib_module";
517 }
518 BigSize *= sizeof_modtab;
520 if (BigSize > FileSize)
521 return malformedError("modtaboff field plus nmodtab field times sizeof(" +
522 Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB "
523 "command " + Twine(LoadCommandIndex) + " extends "
524 "past the end of the file");
526 Dysymtab.nmodtab * sizeof_modtab,
527 "module table"))
528 return Err;
530 return malformedError("extrefsymoff field of LC_DYSYMTAB command " +
531 Twine(LoadCommandIndex) + " extends past the end of "
532 "the file");
536 if (BigSize > FileSize)
537 return malformedError("extrefsymoff field plus nextrefsyms field times "
538 "sizeof(struct dylib_reference) of LC_DYSYMTAB "
539 "command " + Twine(LoadCommandIndex) + " extends "
540 "past the end of the file");
544 "reference table"))
545 return Err;
547 return malformedError("indirectsymoff field of LC_DYSYMTAB command " +
548 Twine(LoadCommandIndex) + " extends past the end of "
549 "the file");
553 if (BigSize > FileSize)
554 return malformedError("indirectsymoff field plus nindirectsyms field times "
555 "sizeof(uint32_t) of LC_DYSYMTAB command " +
556 Twine(LoadCommandIndex) + " extends past the end of "
557 "the file");
561 "indirect table"))
562 return Err;
563 if (Dysymtab.extreloff > FileSize)
564 return malformedError("extreloff field of LC_DYSYMTAB command " +
565 Twine(LoadCommandIndex) + " extends past the end of "
566 "the file");
567 BigSize = Dysymtab.nextrel;
570 if (BigSize > FileSize)
571 return malformedError("extreloff field plus nextrel field times sizeof"
572 "(struct relocation_info) of LC_DYSYMTAB command " +
573 Twine(LoadCommandIndex) + " extends past the end of "
574 "the file");
578 "external relocation table"))
579 return Err;
580 if (Dysymtab.locreloff > FileSize)
581 return malformedError("locreloff field of LC_DYSYMTAB command " +
582 Twine(LoadCommandIndex) + " extends past the end of "
583 "the file");
584 BigSize = Dysymtab.nlocrel;
587 if (BigSize > FileSize)
588 return malformedError("locreloff field plus nlocrel field times sizeof"
589 "(struct relocation_info) of LC_DYSYMTAB command " +
590 Twine(LoadCommandIndex) + " extends past the end of "
591 "the file");
595 "local relocation table"))
596 return Err;
597 *DysymtabLoadCmd = Load.Ptr;
599}
600
604 const char **LoadCmd, const char *CmdName,
605 std::list &Elements,
606 const char *ElementName) {
609 CmdName + " cmdsize too small");
610 if (*LoadCmd != nullptr)
612 auto LinkDataOrError =
614 if (!LinkDataOrError)
615 return LinkDataOrError.takeError();
619 Twine(LoadCommandIndex) + " has incorrect cmdsize");
620 uint64_t FileSize = Obj.getData().size();
621 if (LinkData.dataoff > FileSize)
622 return malformedError("dataoff field of " + Twine(CmdName) + " command " +
623 Twine(LoadCommandIndex) + " extends past the end of "
624 "the file");
626 BigSize += LinkData.datasize;
627 if (BigSize > FileSize)
628 return malformedError("dataoff field plus datasize field of " +
629 Twine(CmdName) + " command " +
630 Twine(LoadCommandIndex) + " extends past the end of "
631 "the file");
633 LinkData.datasize, ElementName))
634 return Err;
635 *LoadCmd = Load.Ptr;
637}
638
642 const char **LoadCmd, const char *CmdName,
643 std::list &Elements) {
646 CmdName + " cmdsize too small");
647 if (*LoadCmd != nullptr)
648 return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY "
649 "command");
650 auto DyldInfoOrErr =
652 if (!DyldInfoOrErr)
653 return DyldInfoOrErr.takeError();
657 Twine(LoadCommandIndex) + " has incorrect cmdsize");
658 uint64_t FileSize = Obj.getData().size();
661 " command " + Twine(LoadCommandIndex) + " extends "
662 "past the end of the file");
665 if (BigSize > FileSize)
666 return malformedError("rebase_off field plus rebase_size field of " +
667 Twine(CmdName) + " command " +
668 Twine(LoadCommandIndex) + " extends past the end of "
669 "the file");
672 "dyld rebase info"))
673 return Err;
674 if (DyldInfo.bind_off > FileSize)
676 " command " + Twine(LoadCommandIndex) + " extends "
677 "past the end of the file");
680 if (BigSize > FileSize)
681 return malformedError("bind_off field plus bind_size field of " +
682 Twine(CmdName) + " command " +
683 Twine(LoadCommandIndex) + " extends past the end of "
684 "the file");
687 "dyld bind info"))
688 return Err;
691 " command " + Twine(LoadCommandIndex) + " extends "
692 "past the end of the file");
695 if (BigSize > FileSize)
696 return malformedError("weak_bind_off field plus weak_bind_size field of " +
697 Twine(CmdName) + " command " +
698 Twine(LoadCommandIndex) + " extends past the end of "
699 "the file");
702 "dyld weak bind info"))
703 return Err;
706 " command " + Twine(LoadCommandIndex) + " extends "
707 "past the end of the file");
710 if (BigSize > FileSize)
711 return malformedError("lazy_bind_off field plus lazy_bind_size field of " +
712 Twine(CmdName) + " command " +
713 Twine(LoadCommandIndex) + " extends past the end of "
714 "the file");
717 "dyld lazy bind info"))
718 return Err;
721 " command " + Twine(LoadCommandIndex) + " extends "
722 "past the end of the file");
725 if (BigSize > FileSize)
726 return malformedError("export_off field plus export_size field of " +
727 Twine(CmdName) + " command " +
728 Twine(LoadCommandIndex) + " extends past the end of "
729 "the file");
732 "dyld export info"))
733 return Err;
734 *LoadCmd = Load.Ptr;
736}
737
740 uint32_t LoadCommandIndex, const char *CmdName) {
743 CmdName + " cmdsize too small");
745 if (!CommandOrErr)
746 return CommandOrErr.takeError();
750 CmdName + " name.offset field too small, not past "
751 "the end of the dylib_command struct");
752 if (D.dylib.name >= D.cmdsize)
754 CmdName + " name.offset field extends past the end "
755 "of the load command");
756
757
759 const char *P = (const char *)Load.Ptr;
760 for (i = D.dylib.name; i < D.cmdsize; i++)
761 if (P[i] == '\0')
762 break;
763 if (i >= D.cmdsize)
765 CmdName + " library name extends past the end of the "
766 "load command");
768}
769
773 const char **LoadCmd) {
775 "LC_ID_DYLIB"))
776 return Err;
777 if (*LoadCmd != nullptr)
778 return malformedError("more than one LC_ID_DYLIB command");
781 return malformedError("LC_ID_DYLIB load command in non-dynamic library "
782 "file type");
783 *LoadCmd = Load.Ptr;
785}
786
789 uint32_t LoadCommandIndex, const char *CmdName) {
792 CmdName + " cmdsize too small");
794 if (!CommandOrErr)
795 return CommandOrErr.takeError();
799 CmdName + " name.offset field too small, not past "
800 "the end of the dylinker_command struct");
803 CmdName + " name.offset field extends past the end "
804 "of the load command");
805
806
808 const char *P = (const char *)Load.Ptr;
809 for (i = D.name; i < D.cmdsize; i++)
810 if (P[i] == '\0')
811 break;
812 if (i >= D.cmdsize)
814 CmdName + " dyld name extends past the end of the "
815 "load command");
817}
818
822 const char **LoadCmd, const char *CmdName) {
825 CmdName + " has incorrect cmdsize");
826 if (*LoadCmd != nullptr)
827 return malformedError("more than one LC_VERSION_MIN_MACOSX, "
828 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or "
829 "LC_VERSION_MIN_WATCHOS command");
830 *LoadCmd = Load.Ptr;
832}
833
837 std::list &Elements) {
840 " LC_NOTE has incorrect cmdsize");
842 if (!NoteCmdOrErr)
843 return NoteCmdOrErr.takeError();
845 uint64_t FileSize = Obj.getData().size();
846 if (Nt.offset > FileSize)
847 return malformedError("offset field of LC_NOTE command " +
848 Twine(LoadCommandIndex) + " extends "
849 "past the end of the file");
851 BigSize += Nt.size;
852 if (BigSize > FileSize)
853 return malformedError("size field plus offset field of LC_NOTE command " +
854 Twine(LoadCommandIndex) + " extends past the end of "
855 "the file");
857 "LC_NOTE data"))
858 return Err;
860}
861
867 auto BVCOrErr =
869 if (!BVCOrErr)
870 return BVCOrErr.takeError();
872 if (Load.C.cmdsize !=
876 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
877
880 for (unsigned i = 0; i < BVC.ntools; ++i)
882
884}
885
891 " LC_RPATH cmdsize too small");
893 if (!ROrErr)
894 return ROrErr.takeError();
898 " LC_RPATH path.offset field too small, not past "
899 "the end of the rpath_command struct");
900 if (R.path >= R.cmdsize)
902 " LC_RPATH path.offset field extends past the end "
903 "of the load command");
904
905
907 const char *P = (const char *)Load.Ptr;
908 for (i = R.path; i < R.cmdsize; i++)
909 if (P[i] == '\0')
910 break;
911 if (i >= R.cmdsize)
913 " LC_RPATH library name extends past the end of the "
914 "load command");
916}
917
922 const char **LoadCmd, const char *CmdName) {
923 if (*LoadCmd != nullptr)
924 return malformedError("more than one LC_ENCRYPTION_INFO and or "
925 "LC_ENCRYPTION_INFO_64 command");
926 uint64_t FileSize = Obj.getData().size();
927 if (cryptoff > FileSize)
929 " command " + Twine(LoadCommandIndex) + " extends "
930 "past the end of the file");
932 BigSize += cryptsize;
933 if (BigSize > FileSize)
934 return malformedError("cryptoff field plus cryptsize field of " +
935 Twine(CmdName) + " command " +
936 Twine(LoadCommandIndex) + " extends past the end of "
937 "the file");
938 *LoadCmd = Load.Ptr;
940}
941
947 " LC_LINKER_OPTION cmdsize too small");
948 auto LinkOptionOrErr =
950 if (!LinkOptionOrErr)
951 return LinkOptionOrErr.takeError();
953
954 const char *string = (const char *)Load.Ptr +
958 while (left > 0) {
959 while (*string == '\0' && left > 0) {
960 string++;
961 left--;
962 }
963 if (left > 0) {
964 i++;
966 if (0xffffffff == NullPos)
968 " LC_LINKER_OPTION string #" + Twine(i) +
969 " is not NULL terminated");
970 uint32_t len = std::min(NullPos, left) + 1;
971 string += len;
972 left -= len;
973 }
974 }
975 if (L.count != i)
977 " LC_LINKER_OPTION string count " + Twine(L.count) +
978 " does not match number of strings");
980}
981
984 uint32_t LoadCommandIndex, const char *CmdName,
985 size_t SizeOfCmd, const char *CmdStructName,
986 uint32_t PathOffset, const char *PathFieldName) {
987 if (PathOffset < SizeOfCmd)
989 CmdName + " " + PathFieldName + ".offset field too "
990 "small, not past the end of the " + CmdStructName);
991 if (PathOffset >= Load.C.cmdsize)
993 CmdName + " " + PathFieldName + ".offset field "
994 "extends past the end of the load command");
995
996
998 const char *P = (const char *)Load.Ptr;
999 for (i = PathOffset; i < Load.C.cmdsize; i++)
1000 if (P[i] == '\0')
1001 break;
1002 if (i >= Load.C.cmdsize)
1004 CmdName + " " + PathFieldName + " name extends past "
1005 "the end of the load command");
1007}
1008
1012 const char *CmdName) {
1015 CmdName + " cmdsize too small");
1016 auto ThreadCommandOrErr =
1018 if (!ThreadCommandOrErr)
1019 return ThreadCommandOrErr.takeError();
1022 const char *end = Load.Ptr + T.cmdsize;
1025 while (state < end) {
1026 if(state + sizeof(uint32_t) > end)
1028 "flavor in " + CmdName + " extends past end of "
1029 "command");
1031 memcpy(&flavor, state, sizeof(uint32_t));
1035
1036 if(state + sizeof(uint32_t) > end)
1038 " count in " + CmdName + " extends past end of "
1039 "command");
1045
1050 " count not x86_THREAD_STATE32_COUNT for "
1051 "flavor number " + Twine(nflavor) + " which is "
1052 "a x86_THREAD_STATE32 flavor in " + CmdName +
1053 " command");
1056 " x86_THREAD_STATE32 extends past end of "
1057 "command in " + CmdName + " command");
1059 } else {
1061 " unknown flavor (" + Twine(flavor) + ") for "
1062 "flavor number " + Twine(nflavor) + " in " +
1063 CmdName + " command");
1064 }
1069 " count not x86_THREAD_STATE_COUNT for "
1070 "flavor number " + Twine(nflavor) + " which is "
1071 "a x86_THREAD_STATE flavor in " + CmdName +
1072 " command");
1075 " x86_THREAD_STATE extends past end of "
1076 "command in " + CmdName + " command");
1081 " count not x86_FLOAT_STATE_COUNT for "
1082 "flavor number " + Twine(nflavor) + " which is "
1083 "a x86_FLOAT_STATE flavor in " + CmdName +
1084 " command");
1087 " x86_FLOAT_STATE extends past end of "
1088 "command in " + CmdName + " command");
1093 " count not x86_EXCEPTION_STATE_COUNT for "
1094 "flavor number " + Twine(nflavor) + " which is "
1095 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1096 " command");
1099 " x86_EXCEPTION_STATE extends past end of "
1100 "command in " + CmdName + " command");
1105 " count not x86_THREAD_STATE64_COUNT for "
1106 "flavor number " + Twine(nflavor) + " which is "
1107 "a x86_THREAD_STATE64 flavor in " + CmdName +
1108 " command");
1111 " x86_THREAD_STATE64 extends past end of "
1112 "command in " + CmdName + " command");
1117 " count not x86_EXCEPTION_STATE64_COUNT for "
1118 "flavor number " + Twine(nflavor) + " which is "
1119 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1120 " command");
1123 " x86_EXCEPTION_STATE64 extends past end of "
1124 "command in " + CmdName + " command");
1126 } else {
1128 " unknown flavor (" + Twine(flavor) + ") for "
1129 "flavor number " + Twine(nflavor) + " in " +
1130 CmdName + " command");
1131 }
1136 " count not ARM_THREAD_STATE_COUNT for "
1137 "flavor number " + Twine(nflavor) + " which is "
1138 "a ARM_THREAD_STATE flavor in " + CmdName +
1139 " command");
1142 " ARM_THREAD_STATE extends past end of "
1143 "command in " + CmdName + " command");
1145 } else {
1147 " unknown flavor (" + Twine(flavor) + ") for "
1148 "flavor number " + Twine(nflavor) + " in " +
1149 CmdName + " command");
1150 }
1156 " count not ARM_THREAD_STATE64_COUNT for "
1157 "flavor number " + Twine(nflavor) + " which is "
1158 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1159 " command");
1162 " ARM_THREAD_STATE64 extends past end of "
1163 "command in " + CmdName + " command");
1165 } else {
1167 " unknown flavor (" + Twine(flavor) + ") for "
1168 "flavor number " + Twine(nflavor) + " in " +
1169 CmdName + " command");
1170 }
1175 " count not PPC_THREAD_STATE_COUNT for "
1176 "flavor number " + Twine(nflavor) + " which is "
1177 "a PPC_THREAD_STATE flavor in " + CmdName +
1178 " command");
1181 " PPC_THREAD_STATE extends past end of "
1182 "command in " + CmdName + " command");
1184 } else {
1186 " unknown flavor (" + Twine(flavor) + ") for "
1187 "flavor number " + Twine(nflavor) + " in " +
1188 CmdName + " command");
1189 }
1190 } else {
1192 "command " + Twine(LoadCommandIndex) + " for " +
1193 CmdName + " command can't be checked");
1194 }
1195 nflavor++;
1196 }
1198}
1199
1202 &Load,
1204 const char **LoadCmd,
1205 std::list &Elements) {
1208 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1209 if (*LoadCmd != nullptr)
1210 return malformedError("more than one LC_TWOLEVEL_HINTS command");
1212 if(!HintsOrErr)
1213 return HintsOrErr.takeError();
1215 uint64_t FileSize = Obj.getData().size();
1216 if (Hints.offset > FileSize)
1217 return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
1218 Twine(LoadCommandIndex) + " extends past the end of "
1219 "the file");
1222 BigSize += Hints.offset;
1223 if (BigSize > FileSize)
1224 return malformedError("offset field plus nhints times sizeof(struct "
1225 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1226 Twine(LoadCommandIndex) + " extends past the end of "
1227 "the file");
1230 "two level hints"))
1231 return Err;
1232 *LoadCmd = Load.Ptr;
1234}
1235
1236
1237
1238
1240 if (cmd == MachO::LC_SYMSEG ||
1241 cmd == MachO::LC_LOADFVMLIB ||
1242 cmd == MachO::LC_IDFVMLIB ||
1243 cmd == MachO::LC_IDENT ||
1244 cmd == MachO::LC_FVMFILE ||
1245 cmd == MachO::LC_PREPAGE ||
1246 cmd == MachO::LC_PREBOUND_DYLIB ||
1247 cmd == MachO::LC_TWOLEVEL_HINTS ||
1248 cmd == MachO::LC_PREBIND_CKSUM)
1249 return true;
1250 return false;
1251}
1252
1255 bool Is64Bits, uint32_t UniversalCputype,
1257 size_t MachOFilesetEntryOffset) {
1259 std::unique_ptr Obj(new MachOObjectFile(
1260 std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype,
1261 UniversalIndex, MachOFilesetEntryOffset));
1262 if (Err)
1263 return std::move(Err);
1264 return std::move(Obj);
1265}
1266
1267MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
1268 bool Is64bits, Error &Err,
1271 size_t MachOFilesetEntryOffset)
1272 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
1273 MachOFilesetEntryOffset(MachOFilesetEntryOffset) {
1281 } else {
1284 cputype = Header.cputype;
1285 }
1286 if (Err)
1287 return;
1290 Err = malformedError("load commands extend past the end of the file");
1291 return;
1292 }
1293 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1294 Err = malformedError("universal header architecture: " +
1295 Twine(UniversalIndex) + "'s cputype does not match "
1296 "object file's mach header");
1297 return;
1298 }
1299 std::list Elements;
1300 Elements.push_back({0, SizeOfHeaders, "Mach-O headers"});
1301
1304 if (LoadCommandCount != 0) {
1306 Load = *LoadOrErr;
1307 else {
1308 Err = LoadOrErr.takeError();
1309 return;
1310 }
1311 }
1312
1313 const char *DyldIdLoadCmd = nullptr;
1314 const char *SplitInfoLoadCmd = nullptr;
1315 const char *CodeSignDrsLoadCmd = nullptr;
1316 const char *CodeSignLoadCmd = nullptr;
1317 const char *VersLoadCmd = nullptr;
1318 const char *SourceLoadCmd = nullptr;
1319 const char *EntryPointLoadCmd = nullptr;
1320 const char *EncryptLoadCmd = nullptr;
1321 const char *RoutinesLoadCmd = nullptr;
1322 const char *UnixThreadLoadCmd = nullptr;
1323 const char *TwoLevelHintsLoadCmd = nullptr;
1324 for (unsigned I = 0; I < LoadCommandCount; ++I) {
1326 if (Load.C.cmdsize % 8 != 0) {
1327
1328
1329
1331 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
1332 Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1333 "multiple of 8");
1334 return;
1335 }
1336 }
1337 } else {
1338 if (Load.C.cmdsize % 4 != 0) {
1339 Err = malformedError("load command " + Twine(I) + " cmdsize not a "
1340 "multiple of 4");
1341 return;
1342 }
1343 }
1344 LoadCommands.push_back(Load);
1345 if (Load.C.cmd == MachO::LC_SYMTAB) {
1346 if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements)))
1347 return;
1348 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
1350 Elements)))
1351 return;
1352 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
1354 "LC_DATA_IN_CODE", Elements,
1355 "data in code info")))
1356 return;
1357 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1359 "LC_LINKER_OPTIMIZATION_HINT",
1360 Elements, "linker optimization "
1361 "hints")))
1362 return;
1363 } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) {
1365 "LC_FUNCTION_STARTS", Elements,
1366 "function starts data")))
1367 return;
1368 } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1370 "LC_SEGMENT_SPLIT_INFO", Elements,
1371 "split info data")))
1372 return;
1373 } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1375 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1376 "code signing RDs data")))
1377 return;
1378 } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) {
1380 "LC_CODE_SIGNATURE", Elements,
1381 "code signature data")))
1382 return;
1383 } else if (Load.C.cmd == MachO::LC_DYLD_INFO) {
1385 "LC_DYLD_INFO", Elements)))
1386 return;
1387 } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
1389 "LC_DYLD_INFO_ONLY", Elements)))
1390 return;
1391 } else if (Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
1393 *this, Load, I, &DyldChainedFixupsLoadCmd,
1394 "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))
1395 return;
1396 } else if (Load.C.cmd == MachO::LC_DYLD_EXPORTS_TRIE) {
1398 *this, Load, I, &DyldExportsTrieLoadCmd, "LC_DYLD_EXPORTS_TRIE",
1399 Elements, "exports trie")))
1400 return;
1401 } else if (Load.C.cmd == MachO::LC_UUID) {
1402 if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
1403 Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
1404 "cmdsize");
1405 return;
1406 }
1407 if (UuidLoadCmd) {
1408 Err = malformedError("more than one LC_UUID command");
1409 return;
1410 }
1411 UuidLoadCmd = Load.Ptr;
1412 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
1414 MachO::section_64>(
1415 *this, Load, Sections, HasPageZeroSegment, I,
1416 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1417 return;
1418 } else if (Load.C.cmd == MachO::LC_SEGMENT) {
1420 MachO::section>(
1421 *this, Load, Sections, HasPageZeroSegment, I,
1422 "LC_SEGMENT", SizeOfHeaders, Elements)))
1423 return;
1424 } else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
1426 return;
1427 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) {
1429 return;
1430 Libraries.push_back(Load.Ptr);
1431 } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1432 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB")))
1433 return;
1434 Libraries.push_back(Load.Ptr);
1435 } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1436 if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB")))
1437 return;
1438 Libraries.push_back(Load.Ptr);
1439 } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) {
1441 return;
1442 Libraries.push_back(Load.Ptr);
1443 } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1444 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB")))
1445 return;
1446 Libraries.push_back(Load.Ptr);
1447 } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) {
1449 return;
1450 } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) {
1451 if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER")))
1452 return;
1453 } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
1454 if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT")))
1455 return;
1456 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
1458 "LC_VERSION_MIN_MACOSX")))
1459 return;
1460 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1462 "LC_VERSION_MIN_IPHONEOS")))
1463 return;
1464 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) {
1466 "LC_VERSION_MIN_TVOS")))
1467 return;
1468 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1470 "LC_VERSION_MIN_WATCHOS")))
1471 return;
1472 } else if (Load.C.cmd == MachO::LC_NOTE) {
1474 return;
1475 } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
1477 return;
1478 } else if (Load.C.cmd == MachO::LC_RPATH) {
1480 return;
1481 } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) {
1482 if (Load.C.cmdsize != sizeof(MachO::source_version_command)) {
1483 Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) +
1484 " has incorrect cmdsize");
1485 return;
1486 }
1487 if (SourceLoadCmd) {
1488 Err = malformedError("more than one LC_SOURCE_VERSION command");
1489 return;
1490 }
1491 SourceLoadCmd = Load.Ptr;
1492 } else if (Load.C.cmd == MachO::LC_MAIN) {
1493 if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) {
1495 " has incorrect cmdsize");
1496 return;
1497 }
1498 if (EntryPointLoadCmd) {
1499 Err = malformedError("more than one LC_MAIN command");
1500 return;
1501 }
1502 EntryPointLoadCmd = Load.Ptr;
1503 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) {
1504 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) {
1505 Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) +
1506 " has incorrect cmdsize");
1507 return;
1508 }
1509 MachO::encryption_info_command E =
1512 &EncryptLoadCmd, "LC_ENCRYPTION_INFO")))
1513 return;
1514 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
1515 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) {
1516 Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) +
1517 " has incorrect cmdsize");
1518 return;
1519 }
1520 MachO::encryption_info_command_64 E =
1523 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
1524 return;
1525 } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
1527 return;
1528 } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
1529 if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
1531 " LC_SUB_FRAMEWORK cmdsize too small");
1532 return;
1533 }
1534 MachO::sub_framework_command S =
1536 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK",
1537 sizeof(MachO::sub_framework_command),
1538 "sub_framework_command", S.umbrella,
1539 "umbrella")))
1540 return;
1541 } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
1542 if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
1544 " LC_SUB_UMBRELLA cmdsize too small");
1545 return;
1546 }
1547 MachO::sub_umbrella_command S =
1549 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA",
1550 sizeof(MachO::sub_umbrella_command),
1552 "sub_umbrella")))
1553 return;
1554 } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
1555 if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
1557 " LC_SUB_LIBRARY cmdsize too small");
1558 return;
1559 }
1560 MachO::sub_library_command S =
1562 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY",
1563 sizeof(MachO::sub_library_command),
1565 "sub_library")))
1566 return;
1567 } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
1568 if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
1570 " LC_SUB_CLIENT cmdsize too small");
1571 return;
1572 }
1573 MachO::sub_client_command S =
1576 sizeof(MachO::sub_client_command),
1577 "sub_client_command", S.client, "client")))
1578 return;
1579 } else if (Load.C.cmd == MachO::LC_ROUTINES) {
1580 if (Load.C.cmdsize != sizeof(MachO::routines_command)) {
1581 Err = malformedError("LC_ROUTINES command " + Twine(I) +
1582 " has incorrect cmdsize");
1583 return;
1584 }
1585 if (RoutinesLoadCmd) {
1586 Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 "
1587 "command");
1588 return;
1589 }
1590 RoutinesLoadCmd = Load.Ptr;
1591 } else if (Load.C.cmd == MachO::LC_ROUTINES_64) {
1592 if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) {
1593 Err = malformedError("LC_ROUTINES_64 command " + Twine(I) +
1594 " has incorrect cmdsize");
1595 return;
1596 }
1597 if (RoutinesLoadCmd) {
1598 Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES "
1599 "command");
1600 return;
1601 }
1602 RoutinesLoadCmd = Load.Ptr;
1603 } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) {
1605 return;
1606 if (UnixThreadLoadCmd) {
1607 Err = malformedError("more than one LC_UNIXTHREAD command");
1608 return;
1609 }
1610 UnixThreadLoadCmd = Load.Ptr;
1611 } else if (Load.C.cmd == MachO::LC_THREAD) {
1613 return;
1614
1615 } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
1617 &TwoLevelHintsLoadCmd, Elements)))
1618 return;
1619 } else if (Load.C.cmd == MachO::LC_IDENT) {
1620
1621 continue;
1623 Err = malformedError("load command " + Twine(I) + " for cmd value of: " +
1624 Twine(Load.C.cmd) + " is obsolete and not "
1625 "supported");
1626 return;
1627 }
1628
1629
1630
1631 if (I < LoadCommandCount - 1) {
1633 Load = *LoadOrErr;
1634 else {
1635 Err = LoadOrErr.takeError();
1636 return;
1637 }
1638 }
1639 }
1640 if (!SymtabLoadCmd) {
1641 if (DysymtabLoadCmd) {
1642 Err = malformedError("contains LC_DYSYMTAB load command without a "
1643 "LC_SYMTAB load command");
1644 return;
1645 }
1646 } else if (DysymtabLoadCmd) {
1647 MachO::symtab_command Symtab =
1649 MachO::dysymtab_command Dysymtab =
1652 Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
1653 "extends past the end of the symbol table");
1654 return;
1655 }
1656 uint64_t BigSize = Dysymtab.ilocalsym;
1658 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
1659 Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
1660 "command extends past the end of the symbol table");
1661 return;
1662 }
1664 Err = malformedError("iextdefsym in LC_DYSYMTAB load command "
1665 "extends past the end of the symbol table");
1666 return;
1667 }
1670 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
1671 Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
1672 "load command extends past the end of the symbol "
1673 "table");
1674 return;
1675 }
1677 Err = malformedError("iundefsym in LC_DYSYMTAB load command "
1678 "extends past the end of the symbol table");
1679 return;
1680 }
1683 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
1684 Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
1685 " command extends past the end of the symbol table");
1686 return;
1687 }
1688 }
1691 DyldIdLoadCmd == nullptr) {
1692 Err = malformedError("no LC_ID_DYLIB load command in dynamic library "
1693 "filetype");
1694 return;
1695 }
1696 assert(LoadCommands.size() == LoadCommandCount);
1697
1699}
1700
1705 Flags = H_64.flags;
1706 } else {
1708 Flags = H.flags;
1709 }
1718 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1721 NType = STE_64.n_type;
1722 NSect = STE_64.n_sect;
1723 NDesc = STE_64.n_desc;
1724 NStrx = STE_64.n_strx;
1725 NValue = STE_64.n_value;
1726 } else {
1733 }
1736 if (NSect == 0 || NSect > Sections.size())
1738 " for symbol at index " + Twine(SymbolIndex));
1739 }
1741 if (NValue >= S.strsize)
1743 "the end of string table, for N_INDR symbol at "
1744 "index " + Twine(SymbolIndex));
1745 }
1750 if (LibraryOrdinal != 0 &&
1753 LibraryOrdinal - 1 >= Libraries.size() ) {
1755 " for symbol at index " + Twine(SymbolIndex));
1756 }
1757 }
1758 }
1761 " past the end of string table, for symbol at "
1762 "index " + Twine(SymbolIndex));
1763 SymbolIndex++;
1764 }
1766}
1767
1774
1778 if (Entry.n_strx == 0)
1779
1780
1782 const char *Start = &StringTable.data()[Entry.n_strx];
1783 if (Start < getData().begin() || Start >= getData().end()) {
1786 }
1788}
1789
1795
1799 return Entry.n_value;
1800 }
1802 return Entry.n_value;
1803}
1804
1805
1806
1816 const char *Start = &StringTable.data()[NValue];
1818 return std::error_code();
1819}
1820
1823}
1824
1828
1834 }
1835 return 0;
1836}
1837
1841
1845 uint8_t n_type = Entry.n_type;
1846
1847
1850
1856 if (!SecOrError)
1864 }
1866}
1867
1870
1871 uint8_t MachOType = Entry.n_type;
1872 uint16_t MachOFlags = Entry.n_desc;
1873
1875
1878
1881
1887 else
1889 }
1890
1893 else
1895
1898
1901
1904
1907
1908 return Result;
1909}
1910
1914 uint8_t index = Entry.n_sect;
1915
1916 if (index == 0)
1920 if (DRI.d.a >= Sections.size()){
1923 }
1925}
1926
1930 return Entry.n_sect - 1;
1931}
1932
1936
1941
1947
1950}
1951
1953
1954
1955
1956
1957 uint32_t SectOffset, SectType;
1959
1962 SectOffset = Sect.offset;
1963 SectSize = Sect.size;
1965 } else {
1967 SectOffset = Sect.offset;
1968 SectSize = Sect.size;
1970 }
1972 return SectSize;
1974 if (SectOffset > FileSize)
1975 return 0;
1976 if (FileSize - SectOffset < SectSize)
1977 return FileSize - SectOffset;
1978 return SectSize;
1979}
1980
1985
1990
1995
1996
1997
1998
1999
2000
2001 uint64_t PrevTrueOffset = 0;
2002 uint64_t SectOffsetAdjust = 0;
2003 for (uint32_t SectIdx = 0; SectIdx < Sec.d.a; ++SectIdx) {
2007 if ((SectOffsetAdjust > 0) && (PrevTrueOffset > CurrTrueOffset))
2008 return malformedError("section data exceeds 4GB and section file "
2009 "offsets are not ordered");
2010 const uint64_t EndSectFileOffset =
2012 if (EndSectFileOffset > UINT32_MAX)
2013 SectOffsetAdjust += EndSectFileOffset & 0xFFFFFFFF00000000ull;
2014 PrevTrueOffset = CurrTrueOffset;
2015 }
2016 Offset += SectOffsetAdjust;
2017 } else {
2021 }
2022
2024}
2025
2031 } else {
2034 }
2035
2037}
2038
2040 if (SectionIndex < 1 || SectionIndex > Sections.size())
2041 return malformedError("bad section index: " + Twine((int)SectionIndex));
2042
2044 DRI.d.a = SectionIndex - 1;
2046}
2047
2050 auto NameOrErr = Section.getName();
2051 if (!NameOrErr)
2052 return NameOrErr.takeError();
2054 return Section;
2055 }
2057}
2058
2062
2067
2075
2083
2086 if (!SectionNameOrErr) {
2087
2089 return false;
2090 }
2092 return SectionName.starts_with("__debug") ||
2096}
2097
2098namespace {
2099template
2104 if (!SegmentOrErr) {
2106 return {};
2107 }
2108 auto &Segment = SegmentOrErr.get();
2111 Segment.fileoff, Segment.fileoff + Segment.filesize));
2112 return {};
2113}
2114
2115template
2116ArrayRef<uint8_t> getSegmentContents(const MachOObjectFile &Obj,
2117 MachOObjectFile::LoadCommandInfo LoadCmd) {
2119 if (!SegmentOrErr) {
2121 return {};
2122 }
2123 auto &Segment = SegmentOrErr.get();
2125 Obj.getData().substr(Segment.fileoff, Segment.filesize));
2126}
2127}
2128
2129ArrayRef<uint8_t>
2134 case MachO::LC_SEGMENT:
2136 SegmentName);
2137 break;
2138 case MachO::LC_SEGMENT_64:
2140 SegmentName);
2141 break;
2142 default:
2143 continue;
2144 }
2145 if (!Contents.empty())
2146 return Contents;
2147 }
2148 return {};
2149}
2150
2153 size_t Idx = 0;
2156 case MachO::LC_SEGMENT:
2157 if (Idx == SegmentIndex)
2158 return ::getSegmentContentsMachO::segment\_command(*this, LoadCmd);
2159 ++Idx;
2160 break;
2161 case MachO::LC_SEGMENT_64:
2162 if (Idx == SegmentIndex)
2163 return ::getSegmentContentsMachO::segment\_command\_64(*this, LoadCmd);
2164 ++Idx;
2165 break;
2166 default:
2167 continue;
2168 }
2169 }
2170 return {};
2171}
2172
2176
2183
2187 return (SegmentName == "__LLVM" && *NameOrErr == "__bitcode");
2188 return false;
2189}
2190
2196
2202}
2203
2210 } else {
2213 }
2214
2219}
2220
2223
2227}
2228
2232
2234 Ret.d.b = DysymtabLoadCmd.nextrel;
2236}
2237
2240
2244}
2245
2249
2251 Ret.d.b = DysymtabLoadCmd.nlocrel;
2253}
2254
2258
2262 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2265}
2266
2272
2275 if (!isExtern)
2277
2284 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2286}
2287
2292
2297
2302
2303 unsigned Arch = this->getArch();
2304
2305 switch (Arch) {
2307 static const char *const Table[] = {
2308 "GENERIC_RELOC_VANILLA",
2309 "GENERIC_RELOC_PAIR",
2310 "GENERIC_RELOC_SECTDIFF",
2311 "GENERIC_RELOC_PB_LA_PTR",
2312 "GENERIC_RELOC_LOCAL_SECTDIFF",
2313 "GENERIC_RELOC_TLV" };
2314
2315 if (RType > 5)
2316 res = "Unknown";
2317 else
2318 res = Table[RType];
2319 break;
2320 }
2322 static const char *const Table[] = {
2323 "X86_64_RELOC_UNSIGNED",
2324 "X86_64_RELOC_SIGNED",
2325 "X86_64_RELOC_BRANCH",
2326 "X86_64_RELOC_GOT_LOAD",
2327 "X86_64_RELOC_GOT",
2328 "X86_64_RELOC_SUBTRACTOR",
2329 "X86_64_RELOC_SIGNED_1",
2330 "X86_64_RELOC_SIGNED_2",
2331 "X86_64_RELOC_SIGNED_4",
2332 "X86_64_RELOC_TLV" };
2333
2334 if (RType > 9)
2335 res = "Unknown";
2336 else
2337 res = Table[RType];
2338 break;
2339 }
2341 static const char *const Table[] = {
2342 "ARM_RELOC_VANILLA",
2343 "ARM_RELOC_PAIR",
2344 "ARM_RELOC_SECTDIFF",
2345 "ARM_RELOC_LOCAL_SECTDIFF",
2346 "ARM_RELOC_PB_LA_PTR",
2347 "ARM_RELOC_BR24",
2348 "ARM_THUMB_RELOC_BR22",
2349 "ARM_THUMB_32BIT_BRANCH",
2350 "ARM_RELOC_HALF",
2351 "ARM_RELOC_HALF_SECTDIFF" };
2352
2353 if (RType > 9)
2354 res = "Unknown";
2355 else
2356 res = Table[RType];
2357 break;
2358 }
2361 static const char *const Table[] = {
2362 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
2363 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
2364 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
2365 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
2366 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2367 "ARM64_RELOC_ADDEND", "ARM64_RELOC_AUTHENTICATED_POINTER"
2368 };
2369
2370 if (RType >= std::size(Table))
2371 res = "Unknown";
2372 else
2373 res = Table[RType];
2374 break;
2375 }
2377 static const char *const Table[] = {
2378 "PPC_RELOC_VANILLA",
2379 "PPC_RELOC_PAIR",
2380 "PPC_RELOC_BR14",
2381 "PPC_RELOC_BR24",
2382 "PPC_RELOC_HI16",
2383 "PPC_RELOC_LO16",
2384 "PPC_RELOC_HA16",
2385 "PPC_RELOC_LO14",
2386 "PPC_RELOC_SECTDIFF",
2387 "PPC_RELOC_PB_LA_PTR",
2388 "PPC_RELOC_HI16_SECTDIFF",
2389 "PPC_RELOC_LO16_SECTDIFF",
2390 "PPC_RELOC_HA16_SECTDIFF",
2391 "PPC_RELOC_JBSR",
2392 "PPC_RELOC_LO14_SECTDIFF",
2393 "PPC_RELOC_LOCAL_SECTDIFF" };
2394
2395 if (RType > 15)
2396 res = "Unknown";
2397 else
2398 res = Table[RType];
2399 break;
2400 }
2402 res = "Unknown";
2403 break;
2404 }
2405 Result.append(res.begin(), res.end());
2406}
2407
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2450 bool &isFramework,
2452 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2453 size_t a, b, c, d, Idx;
2454
2455 isFramework = false;
2457
2458
2459 a = Name.rfind('/');
2460 if (a == Name.npos || a == 0)
2461 goto guess_library;
2462 Foo = Name.substr(a + 1);
2463
2464
2465 Idx = Foo.rfind('_');
2466 if (Idx != Foo.npos && Foo.size() >= 2) {
2467 Suffix = Foo.substr(Idx);
2468 if (Suffix != "_debug" && Suffix != "_profile")
2470 else
2471 Foo = Foo.slice(0, Idx);
2472 }
2473
2474
2475 b = Name.rfind('/', a);
2476 if (b == Name.npos)
2477 Idx = 0;
2478 else
2479 Idx = b+1;
2480 F = Name.substr(Idx, Foo.size());
2481 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);
2482 if (F == Foo && DotFramework == ".framework/") {
2483 isFramework = true;
2484 return Foo;
2485 }
2486
2487
2488 if (b == Name.npos)
2489 goto guess_library;
2490 c = Name.rfind('/', b);
2491 if (c == Name.npos || c == 0)
2492 goto guess_library;
2493 V = Name.substr(c + 1);
2494 if (!V.starts_with("Versions/"))
2495 goto guess_library;
2496 d = Name.rfind('/', c);
2497 if (d == Name.npos)
2498 Idx = 0;
2499 else
2500 Idx = d+1;
2501 F = Name.substr(Idx, Foo.size());
2502 DotFramework = Name.substr(Idx + Foo.size(), sizeof(".framework/") - 1);
2503 if (F == Foo && DotFramework == ".framework/") {
2504 isFramework = true;
2505 return Foo;
2506 }
2507
2508guess_library:
2509
2510 a = Name.rfind('.');
2511 if (a == Name.npos || a == 0)
2513 Dylib = Name.substr(a);
2514 if (Dylib != ".dylib")
2515 goto guess_qtx;
2516
2517
2518 if (a >= 3) {
2519 Dot = Name.substr(a - 2, 1);
2520 if (Dot == ".")
2521 a = a - 2;
2522 }
2523
2524 b = Name.rfind('/', a);
2525 if (b == Name.npos)
2526 b = 0;
2527 else
2528 b = b+1;
2529
2530 Idx = Name.rfind('_');
2531 if (Idx != Name.npos && Idx != b) {
2532 Lib = Name.slice(b, Idx);
2533 Suffix = Name.slice(Idx, a);
2534 if (Suffix != "_debug" && Suffix != "_profile") {
2536 Lib = Name.slice(b, a);
2537 }
2538 }
2539 else
2540 Lib = Name.slice(b, a);
2541
2542
2543 if (Lib.size() >= 3) {
2544 Dot = Lib.substr(Lib.size() - 2, 1);
2545 if (Dot == ".")
2546 Lib = Lib.slice(0, Lib.size()-2);
2547 }
2548 return Lib;
2549
2550guess_qtx:
2551 Qtx = Name.substr(a);
2552 if (Qtx != ".qtx")
2554 b = Name.rfind('/', a);
2555 if (b == Name.npos)
2556 Lib = Name.slice(0, a);
2557 else
2558 Lib = Name.slice(b+1, a);
2559
2560 if (Lib.size() >= 3) {
2561 Dot = Lib.substr(Lib.size() - 2, 1);
2562 if (Dot == ".")
2563 Lib = Lib.slice(0, Lib.size()-2);
2564 }
2565 return Lib;
2566}
2567
2568
2569
2570
2571
2572
2575 if (Index >= Libraries.size())
2577
2578
2579
2580 if (LibrariesShortNames.size() == 0) {
2581 for (unsigned i = 0; i < Libraries.size(); i++) {
2582 auto CommandOrErr =
2584 if (!CommandOrErr)
2587 if (D.dylib.name >= D.cmdsize)
2589 const char *P = (const char *)(Libraries[i]) + D.dylib.name;
2591 if (D.dylib.name+Name.size() >= D.cmdsize)
2594 bool isFramework;
2596 if (shortName.empty())
2597 LibrariesShortNames.push_back(Name);
2598 else
2599 LibrariesShortNames.push_back(shortName);
2600 }
2601 }
2602
2603 Res = LibrariesShortNames[Index];
2604 return std::error_code();
2605}
2606
2608 return Libraries.size();
2609}
2610
2617
2621 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2623
2625}
2626
2630 if (!SymtabLoadCmd || Symtab.nsyms == 0)
2632
2638 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2640}
2641
2644 if (!SymtabLoadCmd || Index >= Symtab.nsyms)
2649 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2652}
2653
2656 if (!SymtabLoadCmd)
2657 report_fatal_error("getSymbolIndex() called with no symbol table symbol");
2661 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff));
2663 return Index;
2664}
2665
2670
2673 DRI.d.a = Sections.size();
2675}
2676
2678 return is64Bit() ? 8 : 4;
2679}
2680
2682 unsigned CPUType = getCPUType(*this);
2684 switch (CPUType) {
2686 return "Mach-O 32-bit i386";
2688 return "Mach-O arm";
2690 return "Mach-O arm64 (ILP32)";
2692 return "Mach-O 32-bit ppc";
2693 default:
2694 return "Mach-O 32-bit unknown";
2695 }
2696 }
2697
2698 switch (CPUType) {
2700 return "Mach-O 64-bit x86-64";
2702 return "Mach-O arm64";
2704 return "Mach-O 64-bit ppc64";
2705 default:
2706 return "Mach-O 64-bit unknown";
2707 }
2708}
2709
2711 switch (CPUType) {
2726 default:
2728 }
2729}
2730
2732 const char **McpuDefault,
2733 const char **ArchFlag) {
2734 if (McpuDefault)
2735 *McpuDefault = nullptr;
2736 if (ArchFlag)
2737 *ArchFlag = nullptr;
2738
2739 switch (CPUType) {
2743 if (ArchFlag)
2744 *ArchFlag = "i386";
2745 return Triple("i386-apple-darwin");
2746 default:
2748 }
2752 if (ArchFlag)
2753 *ArchFlag = "x86_64";
2754 return Triple("x86_64-apple-darwin");
2756 if (ArchFlag)
2757 *ArchFlag = "x86_64h";
2758 return Triple("x86_64h-apple-darwin");
2759 default:
2761 }
2765 if (ArchFlag)
2766 *ArchFlag = "armv4t";
2767 return Triple("armv4t-apple-darwin");
2769 if (ArchFlag)
2770 *ArchFlag = "armv5e";
2771 return Triple("armv5e-apple-darwin");
2773 if (ArchFlag)
2774 *ArchFlag = "xscale";
2775 return Triple("xscale-apple-darwin");
2777 if (ArchFlag)
2778 *ArchFlag = "armv6";
2779 return Triple("armv6-apple-darwin");
2781 if (McpuDefault)
2782 *McpuDefault = "cortex-m0";
2783 if (ArchFlag)
2784 *ArchFlag = "armv6m";
2785 return Triple("armv6m-apple-darwin");
2787 if (ArchFlag)
2788 *ArchFlag = "armv7";
2789 return Triple("armv7-apple-darwin");
2791 if (McpuDefault)
2792 *McpuDefault = "cortex-m4";
2793 if (ArchFlag)
2794 *ArchFlag = "armv7em";
2795 return Triple("thumbv7em-apple-darwin");
2797 if (McpuDefault)
2798 *McpuDefault = "cortex-a7";
2799 if (ArchFlag)
2800 *ArchFlag = "armv7k";
2801 return Triple("armv7k-apple-darwin");
2803 if (McpuDefault)
2804 *McpuDefault = "cortex-m3";
2805 if (ArchFlag)
2806 *ArchFlag = "armv7m";
2807 return Triple("thumbv7m-apple-darwin");
2809 if (McpuDefault)
2810 *McpuDefault = "cortex-a7";
2811 if (ArchFlag)
2812 *ArchFlag = "armv7s";
2813 return Triple("armv7s-apple-darwin");
2814 default:
2816 }
2820 if (McpuDefault)
2821 *McpuDefault = "cyclone";
2822 if (ArchFlag)
2823 *ArchFlag = "arm64";
2824 return Triple("arm64-apple-darwin");
2826 if (McpuDefault)
2827 *McpuDefault = "apple-a12";
2828 if (ArchFlag)
2829 *ArchFlag = "arm64e";
2830 return Triple("arm64e-apple-darwin");
2831 default:
2833 }
2837 if (McpuDefault)
2838 *McpuDefault = "cyclone";
2839 if (ArchFlag)
2840 *ArchFlag = "arm64_32";
2841 return Triple("arm64_32-apple-darwin");
2842 default:
2844 }
2848 if (ArchFlag)
2849 *ArchFlag = "ppc";
2850 return Triple("ppc-apple-darwin");
2851 default:
2853 }
2857 if (ArchFlag)
2858 *ArchFlag = "ppc64";
2859 return Triple("ppc64-apple-darwin");
2860 default:
2862 }
2863 default:
2865 }
2866}
2867
2871
2876
2878 static const std::array<StringRef, 18> ValidArchs = {{
2879 "i386",
2880 "x86_64",
2881 "x86_64h",
2882 "armv4t",
2883 "arm",
2884 "armv5e",
2885 "armv6",
2886 "armv6m",
2887 "armv7",
2888 "armv7em",
2889 "armv7k",
2890 "armv7m",
2891 "armv7s",
2892 "arm64",
2893 "arm64e",
2894 "arm64_32",
2895 "ppc",
2896 "ppc64",
2897 }};
2898
2899 return ValidArchs;
2900}
2901
2905
2909
2914}
2915
2920}
2921
2924 if (!DataInCodeLoadCmd)
2926
2928 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff));
2930}
2931
2934 if (!DataInCodeLoadCmd)
2936
2939 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset));
2941}
2942
2945
2946void ExportEntry::moveToFirst() {
2948 pushNode(0);
2949 if (*E)
2950 return;
2951 pushDownUntilBottom();
2952}
2953
2954void ExportEntry::moveToEnd() {
2956 Done = true;
2957}
2958
2960
2961 if (Done || Other.Done)
2962 return (Done == Other.Done);
2963
2964 if (Stack.size() != Other.Stack.size())
2965 return false;
2966
2967 if (!CumulativeString.equals(Other.CumulativeString))
2968 return false;
2969
2970 for (unsigned i=0; i < Stack.size(); ++i) {
2971 if (Stack[i].Start != Other.Stack[i].Start)
2972 return false;
2973 }
2974 return true;
2975}
2976
2981 if (Ptr > Trie.end())
2982 Ptr = Trie.end();
2983 return Result;
2984}
2985
2987 return CumulativeString;
2988}
2989
2991 return Stack.back().Flags;
2992}
2993
2995 return Stack.back().Address;
2996}
2997
2999 return Stack.back().Other;
3000}
3001
3003 const char* ImportName = Stack.back().ImportName;
3004 if (ImportName)
3007}
3008
3010 return Stack.back().Start - Trie.begin();
3011}
3012
3013ExportEntry::NodeState::NodeState(const uint8_t *Ptr)
3014 : Start(Ptr), Current(Ptr) {}
3015
3016void ExportEntry::pushNode(uint64_t offset) {
3019 NodeState State(Ptr);
3020 const char *error = nullptr;
3024 " in export trie data at node: 0x" +
3026 moveToEnd();
3027 return;
3028 }
3029 State.IsExportNode = (ExportInfoSize != 0);
3030 const uint8_t* Children = State.Current + ExportInfoSize;
3031 if (Children > Trie.end()) {
3034 " in export trie data at node: 0x" + Twine::utohexstr(offset) +
3035 " too big and extends past end of trie data");
3036 moveToEnd();
3037 return;
3038 }
3039 if (State.IsExportNode) {
3040 const uint8_t *ExportStart = State.Current;
3041 State.Flags = readULEB128(State.Current, &error);
3044 " in export trie data at node: 0x" +
3046 moveToEnd();
3047 return;
3048 }
3050 if (State.Flags != 0 &&
3055 "unsupported exported symbol kind: " + Twine((int)Kind) +
3057 " in export trie data at node: 0x" + Twine::utohexstr(offset));
3058 moveToEnd();
3059 return;
3060 }
3062 State.Address = 0;
3063 State.Other = readULEB128(State.Current, &error);
3066 " in export trie data at node: 0x" +
3068 moveToEnd();
3069 return;
3070 }
3071 if (O != nullptr) {
3072
3073
3074 if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
3076 "bad library ordinal: " + Twine((int)State.Other) + " (max " +
3077 Twine((int)O->getLibraryCount()) +
3078 ") in export trie data at node: 0x" + Twine::utohexstr(offset));
3079 moveToEnd();
3080 return;
3081 }
3082 }
3083 State.ImportName = reinterpret_cast<const char*>(State.Current);
3084 if (*State.ImportName == '\0') {
3085 State.Current++;
3086 } else {
3087 const uint8_t *End = State.Current + 1;
3088 if (End >= Trie.end()) {
3089 *E = malformedError("import name of re-export in export trie data at "
3090 "node: 0x" +
3092 " starts past end of trie data");
3093 moveToEnd();
3094 return;
3095 }
3096 while(*End != '\0' && End < Trie.end())
3097 End++;
3098 if (*End != '\0') {
3099 *E = malformedError("import name of re-export in export trie data at "
3100 "node: 0x" +
3102 " extends past end of trie data");
3103 moveToEnd();
3104 return;
3105 }
3106 State.Current = End + 1;
3107 }
3108 } else {
3109 State.Address = readULEB128(State.Current, &error);
3112 " in export trie data at node: 0x" +
3114 moveToEnd();
3115 return;
3116 }
3118 State.Other = readULEB128(State.Current, &error);
3121 " in export trie data at node: 0x" +
3123 moveToEnd();
3124 return;
3125 }
3126 }
3127 }
3128 if (ExportStart + ExportInfoSize < State.Current) {
3130 "inconsistent export info size: 0x" +
3131 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
3133 " in export trie data at node: 0x" + Twine::utohexstr(offset));
3134 moveToEnd();
3135 return;
3136 }
3137 }
3138 State.ChildCount = *Children;
3139 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) {
3140 *E = malformedError("byte for count of children in export trie data at "
3141 "node: 0x" +
3143 " extends past end of trie data");
3144 moveToEnd();
3145 return;
3146 }
3147 State.Current = Children + 1;
3148 State.NextChildIndex = 0;
3149 State.ParentStringLength = CumulativeString.size();
3150 Stack.push_back(State);
3151}
3152
3153void ExportEntry::pushDownUntilBottom() {
3154 ErrorAsOutParameter ErrAsOutParam(E);
3155 const char *error = nullptr;
3156 while (Stack.back().NextChildIndex < Stack.back().ChildCount) {
3157 NodeState &Top = Stack.back();
3158 CumulativeString.resize(Top.ParentStringLength);
3159 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) {
3160 char C = *Top.Current;
3161 CumulativeString.push_back(C);
3162 }
3163 if (Top.Current >= Trie.end()) {
3164 *E = malformedError("edge sub-string in export trie data at node: 0x" +
3166 " for child #" + Twine((int)Top.NextChildIndex) +
3167 " extends past end of trie data");
3168 moveToEnd();
3169 return;
3170 }
3171 Top.Current += 1;
3172 uint64_t childNodeIndex = readULEB128(Top.Current, &error);
3175 " in export trie data at node: 0x" +
3177 moveToEnd();
3178 return;
3179 }
3180 for (const NodeState &node : nodes()) {
3181 if (node.Start == Trie.begin() + childNodeIndex){
3182 *E = malformedError("loop in children in export trie data at node: 0x" +
3184 " back to node: 0x" +
3186 moveToEnd();
3187 return;
3188 }
3189 }
3190 Top.NextChildIndex += 1;
3191 pushNode(childNodeIndex);
3192 if (*E)
3193 return;
3194 }
3195 if (!Stack.back().IsExportNode) {
3196 *E = malformedError("node is not an export node in export trie data at "
3197 "node: 0x" +
3199 moveToEnd();
3200 return;
3201 }
3202}
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3220 assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack");
3221 if (!Stack.back().IsExportNode) {
3222 *E = malformedError("node is not an export node in export trie data at "
3223 "node: 0x" +
3225 moveToEnd();
3226 return;
3227 }
3228
3229 Stack.pop_back();
3230 while (!Stack.empty()) {
3231 NodeState &Top = Stack.back();
3232 if (Top.NextChildIndex < Top.ChildCount) {
3233 pushDownUntilBottom();
3234
3235 return;
3236 } else {
3237 if (Top.IsExportNode) {
3238
3239 CumulativeString.resize(Top.ParentStringLength);
3240 return;
3241 }
3242 Stack.pop_back();
3243 }
3244 }
3245 Done = true;
3246}
3247
3250 const MachOObjectFile *O) {
3252 if (Trie.empty())
3253 Start.moveToEnd();
3254 else
3255 Start.moveToFirst();
3256
3258 Finish.moveToEnd();
3259
3261}
3262
3265 if (DyldInfoLoadCmd)
3267 else if (DyldExportsTrieLoadCmd)
3269
3270 return exports(Err, Trie, this);
3271}
3272
3276
3277 for (const auto &Command : O->load_commands()) {
3278 if (Command.C.cmd == MachO::LC_SEGMENT) {
3279 MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
3280 if (StringRef(SLC.segname) == "__TEXT") {
3281 TextAddress = SLC.vmaddr;
3282 break;
3283 }
3284 } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
3285 MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
3286 if (StringRef(SLC_64.segname) == "__TEXT") {
3287 TextAddress = SLC_64.vmaddr;
3288 break;
3289 }
3290 }
3291 }
3292}
3293
3295
3299
3303
3307
3311
3315
3317
3319
3321
3323
3325
3334
3336
3338
3341 bool Parse)
3344 if (!Parse)
3345 return;
3346
3347 if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets()) {
3348 FixupTargets = *FixupTargetsOrErr;
3349 } else {
3350 *E = FixupTargetsOrErr.takeError();
3351 return;
3352 }
3353
3354 if (auto SegmentsOrErr = O->getChainedFixupsSegments()) {
3355 Segments = std::move(SegmentsOrErr->second);
3356 } else {
3357 *E = SegmentsOrErr.takeError();
3358 return;
3359 }
3360}
3361
3362void MachOChainedFixupEntry::findNextPageWithFixups() {
3363 auto FindInSegment = [this]() {
3365 while (PageIndex < SegInfo.PageStarts.size() &&
3367 ++PageIndex;
3368 return PageIndex < SegInfo.PageStarts.size();
3369 };
3370
3371 while (InfoSegIndex < Segments.size()) {
3372 if (FindInSegment()) {
3373 PageOffset = Segments[InfoSegIndex].PageStarts[PageIndex];
3375 return;
3376 }
3377
3378 InfoSegIndex++;
3379 PageIndex = 0;
3380 }
3381}
3382
3385 if (Segments.empty()) {
3386 Done = true;
3387 return;
3388 }
3389
3390 InfoSegIndex = 0;
3391 PageIndex = 0;
3392
3393 findNextPageWithFixups();
3395}
3396
3400
3403
3404 if (InfoSegIndex == Segments.size()) {
3405 Done = true;
3406 return;
3407 }
3408
3412
3413
3418 " has unsupported chained fixup pointer_format " +
3419 Twine(PointerFormat));
3421 return;
3422 }
3423
3429
3433 " extends past segment's end");
3435 return;
3436 }
3437
3442
3443
3444 assert(O->isLittleEndian() && "big-endian object should have been rejected "
3445 "by getDyldChainedFixupTargets()");
3448 };
3449
3450
3451
3452 bool IsBind = Field(63, 1);
3455 if (IsBind) {
3458
3459 if (ImportOrdinal >= FixupTargets.size()) {
3462 " has out-of range import ordinal " +
3463 Twine(ImportOrdinal));
3465 return;
3466 }
3467
3470 Addend = InlineAddend ? InlineAddend : Target.addend();
3473 } else {
3476
3480 }
3481
3482
3483 if (Next != 0) {
3484 PageOffset += 4 * Next;
3485 } else {
3486 ++PageIndex;
3487 findNextPageWithFixups();
3488 }
3489}
3490
3494 return true;
3496 return false;
3497 return InfoSegIndex == Other.InfoSegIndex && PageIndex == Other.PageIndex &&
3498 PageOffset == Other.PageOffset;
3499}
3500
3503 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3504 PointerSize(is64Bit ? 8 : 4) {}
3505
3506void MachORebaseEntry::moveToFirst() {
3507 Ptr = Opcodes.begin();
3509}
3510
3511void MachORebaseEntry::moveToEnd() {
3512 Ptr = Opcodes.end();
3513 RemainingLoopCount = 0;
3514 Done = true;
3515}
3516
3519
3520 SegmentOffset += AdvanceAmount;
3521 if (RemainingLoopCount) {
3522 --RemainingLoopCount;
3523 return;
3524 }
3525
3526 bool More = true;
3527 while (More) {
3528
3529
3530
3531 if (Ptr == Opcodes.end()) {
3532 Done = true;
3533 return;
3534 }
3535
3536
3537 const uint8_t *OpcodeStart = Ptr;
3542 const char *error = nullptr;
3543 switch (Opcode) {
3545 More = false;
3546 Done = true;
3547 moveToEnd();
3549 break;
3551 RebaseType = ImmValue;
3553 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3554 Twine((int)RebaseType) + " for opcode at: 0x" +
3556 moveToEnd();
3557 return;
3558 }
3560 "mach-o-rebase",
3561 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: "
3562 << "RebaseType=" << (int) RebaseType << "\n");
3563 break;
3565 SegmentIndex = ImmValue;
3566 SegmentOffset = readULEB128(&error);
3568 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3569 Twine(error) + " for opcode at: 0x" +
3571 moveToEnd();
3572 return;
3573 }
3574 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3575 PointerSize);
3577 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3578 Twine(error) + " for opcode at: 0x" +
3580 moveToEnd();
3581 return;
3582 }
3584 "mach-o-rebase",
3585 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
3586 << "SegmentIndex=" << SegmentIndex << ", "
3587 << format("SegmentOffset=0x%06X", SegmentOffset)
3588 << "\n");
3589 break;
3591 SegmentOffset += readULEB128(&error);
3594 " for opcode at: 0x" +
3596 moveToEnd();
3597 return;
3598 }
3599 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3600 PointerSize);
3603 " for opcode at: 0x" +
3605 moveToEnd();
3606 return;
3607 }
3609 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: "
3610 << format("SegmentOffset=0x%06X",
3611 SegmentOffset) << "\n");
3612 break;
3614 SegmentOffset += ImmValue * PointerSize;
3615 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3616 PointerSize);
3618 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " +
3619 Twine(error) + " for opcode at: 0x" +
3621 moveToEnd();
3622 return;
3623 }
3625 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
3626 << format("SegmentOffset=0x%06X",
3627 SegmentOffset) << "\n");
3628 break;
3630 AdvanceAmount = PointerSize;
3631 Skip = 0;
3632 Count = ImmValue;
3633 if (ImmValue != 0)
3634 RemainingLoopCount = ImmValue - 1;
3635 else
3636 RemainingLoopCount = 0;
3637 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3638 PointerSize, Count, Skip);
3640 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " +
3641 Twine(error) + " for opcode at: 0x" +
3643 moveToEnd();
3644 return;
3645 }
3647 "mach-o-rebase",
3648 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: "
3649 << format("SegmentOffset=0x%06X", SegmentOffset)
3650 << ", AdvanceAmount=" << AdvanceAmount
3651 << ", RemainingLoopCount=" << RemainingLoopCount
3652 << "\n");
3653 return;
3655 AdvanceAmount = PointerSize;
3656 Skip = 0;
3659 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3660 Twine(error) + " for opcode at: 0x" +
3662 moveToEnd();
3663 return;
3664 }
3666 RemainingLoopCount = Count - 1;
3667 else
3668 RemainingLoopCount = 0;
3669 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3670 PointerSize, Count, Skip);
3672 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " +
3673 Twine(error) + " for opcode at: 0x" +
3675 moveToEnd();
3676 return;
3677 }
3679 "mach-o-rebase",
3680 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: "
3681 << format("SegmentOffset=0x%06X", SegmentOffset)
3682 << ", AdvanceAmount=" << AdvanceAmount
3683 << ", RemainingLoopCount=" << RemainingLoopCount
3684 << "\n");
3685 return;
3687 Skip = readULEB128(&error);
3689 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3690 Twine(error) + " for opcode at: 0x" +
3692 moveToEnd();
3693 return;
3694 }
3695 AdvanceAmount = Skip + PointerSize;
3697 RemainingLoopCount = 0;
3698 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3699 PointerSize, Count, Skip);
3701 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3702 Twine(error) + " for opcode at: 0x" +
3704 moveToEnd();
3705 return;
3706 }
3708 "mach-o-rebase",
3709 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: "
3710 << format("SegmentOffset=0x%06X", SegmentOffset)
3711 << ", AdvanceAmount=" << AdvanceAmount
3712 << ", RemainingLoopCount=" << RemainingLoopCount
3713 << "\n");
3714 return;
3718 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3719 "ULEB " +
3720 Twine(error) + " for opcode at: 0x" +
3722 moveToEnd();
3723 return;
3724 }
3726 RemainingLoopCount = Count - 1;
3727 else
3728 RemainingLoopCount = 0;
3729 Skip = readULEB128(&error);
3731 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3732 "ULEB " +
3733 Twine(error) + " for opcode at: 0x" +
3735 moveToEnd();
3736 return;
3737 }
3738 AdvanceAmount = Skip + PointerSize;
3739
3740 error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
3741 PointerSize, Count, Skip);
3743 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_"
3744 "ULEB " +
3745 Twine(error) + " for opcode at: 0x" +
3747 moveToEnd();
3748 return;
3749 }
3751 "mach-o-rebase",
3752 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: "
3753 << format("SegmentOffset=0x%06X", SegmentOffset)
3754 << ", AdvanceAmount=" << AdvanceAmount
3755 << ", RemainingLoopCount=" << RemainingLoopCount
3756 << "\n");
3757 return;
3758 default:
3759 *E = malformedError("bad rebase info (bad opcode value 0x" +
3762 moveToEnd();
3763 return;
3764 }
3765 }
3766}
3767
3768uint64_t MachORebaseEntry::readULEB128(const char **error) {
3772 if (Ptr > Opcodes.end())
3773 Ptr = Opcodes.end();
3774 return Result;
3775}
3776
3778
3780
3782 switch (RebaseType) {
3784 return "pointer";
3786 return "text abs32";
3788 return "text rel32";
3789 }
3790 return "unknown";
3791}
3792
3793
3794
3796 return O->BindRebaseSegmentName(SegmentIndex);
3797}
3798
3799
3800
3802 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
3803}
3804
3805
3806
3808 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
3809}
3810
3812#ifdef EXPENSIVE_CHECKS
3813 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
3814#else
3815 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
3816#endif
3817 return (Ptr == Other.Ptr) &&
3818 (RemainingLoopCount == Other.RemainingLoopCount) &&
3819 (Done == Other.Done);
3820}
3821
3825 if (O->BindRebaseSectionTable == nullptr)
3826 O->BindRebaseSectionTable = std::make_unique(O);
3828 Start.moveToFirst();
3829
3831 Finish.moveToEnd();
3832
3834}
3835
3839
3842 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
3843 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3844
3845void MachOBindEntry::moveToFirst() {
3846 Ptr = Opcodes.begin();
3848}
3849
3850void MachOBindEntry::moveToEnd() {
3851 Ptr = Opcodes.end();
3852 RemainingLoopCount = 0;
3853 Done = true;
3854}
3855
3858
3859 SegmentOffset += AdvanceAmount;
3860 if (RemainingLoopCount) {
3861 --RemainingLoopCount;
3862 return;
3863 }
3864
3865 bool More = true;
3866 while (More) {
3867
3868
3869
3870 if (Ptr == Opcodes.end()) {
3871 Done = true;
3872 return;
3873 }
3874
3875
3876 const uint8_t *OpcodeStart = Ptr;
3880 int8_t SignExtended;
3881 const uint8_t *SymStart;
3883 const char *error = nullptr;
3884 switch (Opcode) {
3887
3888
3889 bool NotLastEntry = false;
3890 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
3891 if (*P) {
3892 NotLastEntry = true;
3893 }
3894 }
3895 if (NotLastEntry)
3896 break;
3897 }
3898 More = false;
3899 moveToEnd();
3901 break;
3904 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in "
3905 "weak bind table for opcode at: 0x" +
3907 moveToEnd();
3908 return;
3909 }
3910 Ordinal = ImmValue;
3911 LibraryOrdinalSet = true;
3912 if (ImmValue > O->getLibraryCount()) {
3913 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3914 "library ordinal: " +
3915 Twine((int)ImmValue) + " (max " +
3916 Twine((int)O->getLibraryCount()) +
3917 ") for opcode at: 0x" +
3919 moveToEnd();
3920 return;
3921 }
3923 "mach-o-bind",
3924 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
3925 << "Ordinal=" << Ordinal << "\n");
3926 break;
3929 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in "
3930 "weak bind table for opcode at: 0x" +
3932 moveToEnd();
3933 return;
3934 }
3935 Ordinal = readULEB128(&error);
3936 LibraryOrdinalSet = true;
3938 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " +
3939 Twine(error) + " for opcode at: 0x" +
3941 moveToEnd();
3942 return;
3943 }
3944 if (Ordinal > (int)O->getLibraryCount()) {
3945 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad "
3946 "library ordinal: " +
3947 Twine((int)Ordinal) + " (max " +
3948 Twine((int)O->getLibraryCount()) +
3949 ") for opcode at: 0x" +
3951 moveToEnd();
3952 return;
3953 }
3955 "mach-o-bind",
3956 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
3957 << "Ordinal=" << Ordinal << "\n");
3958 break;
3961 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in "
3962 "weak bind table for opcode at: 0x" +
3964 moveToEnd();
3965 return;
3966 }
3967 if (ImmValue) {
3969 Ordinal = SignExtended;
3971 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown "
3972 "special ordinal: " +
3973 Twine((int)Ordinal) + " for opcode at: 0x" +
3975 moveToEnd();
3976 return;
3977 }
3978 } else
3979 Ordinal = 0;
3980 LibraryOrdinalSet = true;
3982 "mach-o-bind",
3983 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
3984 << "Ordinal=" << Ordinal << "\n");
3985 break;
3987 Flags = ImmValue;
3988 SymStart = Ptr;
3989 while (*Ptr && (Ptr < Opcodes.end())) {
3990 ++Ptr;
3991 }
3992 if (Ptr == Opcodes.end()) {
3994 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM "
3995 "symbol name extends past opcodes for opcode at: 0x" +
3997 moveToEnd();
3998 return;
3999 }
4000 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
4001 Ptr-SymStart);
4002 ++Ptr;
4004 "mach-o-bind",
4005 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
4006 << "SymbolName=" << SymbolName << "\n");
4009 return;
4010 }
4011 break;
4013 BindType = ImmValue;
4015 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
4016 Twine((int)ImmValue) + " for opcode at: 0x" +
4018 moveToEnd();
4019 return;
4020 }
4022 "mach-o-bind",
4023 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
4024 << "BindType=" << (int)BindType << "\n");
4025 break;
4027 Addend = readSLEB128(&error);
4030 " for opcode at: 0x" +
4032 moveToEnd();
4033 return;
4034 }
4036 "mach-o-bind",
4037 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
4038 << "Addend=" << Addend << "\n");
4039 break;
4041 SegmentIndex = ImmValue;
4042 SegmentOffset = readULEB128(&error);
4044 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4045 Twine(error) + " for opcode at: 0x" +
4047 moveToEnd();
4048 return;
4049 }
4050 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4051 PointerSize);
4053 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
4054 Twine(error) + " for opcode at: 0x" +
4056 moveToEnd();
4057 return;
4058 }
4060 "mach-o-bind",
4061 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
4062 << "SegmentIndex=" << SegmentIndex << ", "
4063 << format("SegmentOffset=0x%06X", SegmentOffset)
4064 << "\n");
4065 break;
4067 SegmentOffset += readULEB128(&error);
4070 " for opcode at: 0x" +
4072 moveToEnd();
4073 return;
4074 }
4075 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4076 PointerSize);
4079 " for opcode at: 0x" +
4081 moveToEnd();
4082 return;
4083 }
4085 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
4086 << format("SegmentOffset=0x%06X",
4087 SegmentOffset) << "\n");
4088 break;
4090 AdvanceAmount = PointerSize;
4091 RemainingLoopCount = 0;
4092 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4093 PointerSize);
4096 " for opcode at: 0x" +
4098 moveToEnd();
4099 return;
4100 }
4101 if (SymbolName == StringRef()) {
4103 "for BIND_OPCODE_DO_BIND missing preceding "
4104 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
4106 moveToEnd();
4107 return;
4108 }
4109 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4110 *E =
4111 malformedError("for BIND_OPCODE_DO_BIND missing preceding "
4112 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4114 moveToEnd();
4115 return;
4116 }
4118 dbgs() << "BIND_OPCODE_DO_BIND: "
4119 << format("SegmentOffset=0x%06X",
4120 SegmentOffset) << "\n");
4121 return;
4124 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in "
4125 "lazy bind table for opcode at: 0x" +
4127 moveToEnd();
4128 return;
4129 }
4130 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4131 PointerSize);
4133 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4134 Twine(error) + " for opcode at: 0x" +
4136 moveToEnd();
4137 return;
4138 }
4139 if (SymbolName == StringRef()) {
4141 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4142 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode "
4143 "at: 0x" +
4145 moveToEnd();
4146 return;
4147 }
4148 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4150 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing "
4151 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
4153 moveToEnd();
4154 return;
4155 }
4156 AdvanceAmount = readULEB128(&error) + PointerSize;
4158 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " +
4159 Twine(error) + " for opcode at: 0x" +
4161 moveToEnd();
4162 return;
4163 }
4164
4165
4166
4167 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4168 AdvanceAmount, PointerSize);
4170 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding "
4171 "ULEB) " +
4172 Twine(error) + " for opcode at: 0x" +
4174 moveToEnd();
4175 return;
4176 }
4177 RemainingLoopCount = 0;
4179 "mach-o-bind",
4180 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: "
4181 << format("SegmentOffset=0x%06X", SegmentOffset)
4182 << ", AdvanceAmount=" << AdvanceAmount
4183 << ", RemainingLoopCount=" << RemainingLoopCount
4184 << "\n");
4185 return;
4188 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not "
4189 "allowed in lazy bind table for opcode at: 0x" +
4191 moveToEnd();
4192 return;
4193 }
4194 if (SymbolName == StringRef()) {
4196 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4197 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4198 "opcode at: 0x" +
4200 moveToEnd();
4201 return;
4202 }
4203 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4205 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
4206 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4207 "at: 0x" +
4209 moveToEnd();
4210 return;
4211 }
4212 AdvanceAmount = ImmValue * PointerSize + PointerSize;
4213 RemainingLoopCount = 0;
4214 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
4215 AdvanceAmount, PointerSize);
4217 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
4218 Twine(error) + " for opcode at: 0x" +
4220 moveToEnd();
4221 return;
4222 }
4225 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
4226 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n");
4227 return;
4230 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not "
4231 "allowed in lazy bind table for opcode at: 0x" +
4233 moveToEnd();
4234 return;
4235 }
4238 RemainingLoopCount = Count - 1;
4239 else
4240 RemainingLoopCount = 0;
4242 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4243 " (count value) " +
4244 Twine(error) + " for opcode at: 0x" +
4246 moveToEnd();
4247 return;
4248 }
4249 Skip = readULEB128(&error);
4250 AdvanceAmount = Skip + PointerSize;
4252 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4253 " (skip value) " +
4254 Twine(error) + " for opcode at: 0x" +
4256 moveToEnd();
4257 return;
4258 }
4259 if (SymbolName == StringRef()) {
4261 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4262 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for "
4263 "opcode at: 0x" +
4265 moveToEnd();
4266 return;
4267 }
4268 if (!LibraryOrdinalSet && TableKind != Kind::Weak) {
4270 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB "
4271 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode "
4272 "at: 0x" +
4274 moveToEnd();
4275 return;
4276 }
4277 error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
4278 PointerSize, Count, Skip);
4280 *E =
4281 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
4282 Twine(error) + " for opcode at: 0x" +
4284 moveToEnd();
4285 return;
4286 }
4288 "mach-o-bind",
4289 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
4290 << format("SegmentOffset=0x%06X", SegmentOffset)
4291 << ", AdvanceAmount=" << AdvanceAmount
4292 << ", RemainingLoopCount=" << RemainingLoopCount
4293 << "\n");
4294 return;
4295 default:
4296 *E = malformedError("bad bind info (bad opcode value 0x" +
4299 moveToEnd();
4300 return;
4301 }
4302 }
4303}
4304
4305uint64_t MachOBindEntry::readULEB128(const char **error) {
4309 if (Ptr > Opcodes.end())
4310 Ptr = Opcodes.end();
4311 return Result;
4312}
4313
4314int64_t MachOBindEntry::readSLEB128(const char **error) {
4318 if (Ptr > Opcodes.end())
4319 Ptr = Opcodes.end();
4320 return Result;
4321}
4322
4324
4326
4328 switch (BindType) {
4330 return "pointer";
4332 return "text abs32";
4334 return "text rel32";
4335 }
4336 return "unknown";
4337}
4338
4340
4342
4344
4346
4347
4348
4350 return O->BindRebaseSegmentName(SegmentIndex);
4351}
4352
4353
4354
4356 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
4357}
4358
4359
4360
4362 return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
4363}
4364
4366#ifdef EXPENSIVE_CHECKS
4367 assert(Opcodes == Other.Opcodes && "compare iterators of different files");
4368#else
4369 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files");
4370#endif
4371 return (Ptr == Other.Ptr) &&
4372 (RemainingLoopCount == Other.RemainingLoopCount) &&
4373 (Done == Other.Done);
4374}
4375
4376
4378 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
4381 for (const SectionRef &Section : Obj->sections()) {
4382 SectionInfo Info;
4384 if (!NameOrErr)
4386 else
4387 Info.SectionName = *NameOrErr;
4388 Info.Address = Section.getAddress();
4389 Info.Size = Section.getSize();
4390 Info.SegmentName =
4391 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
4392 if (Info.SegmentName != CurSegName) {
4393 ++CurSegIndex;
4394 CurSegName = Info.SegmentName;
4395 CurSegAddress = Info.Address;
4396 }
4397 Info.SegmentIndex = CurSegIndex - 1;
4398 Info.OffsetInSegment = Info.Address - CurSegAddress;
4399 Info.SegmentStartAddress = CurSegAddress;
4400 Sections.push_back(Info);
4401 }
4402 MaxSegIndex = CurSegIndex;
4403}
4404
4405
4406
4407
4408
4409
4410
4411
4417 if (SegIndex == -1)
4418 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4419 if (SegIndex >= MaxSegIndex)
4420 return "bad segIndex (too large)";
4422 uint64_t Start = SegOffset + i * (PointerSize + Skip);
4423 uint64_t End = Start + PointerSize;
4424 bool Found = false;
4425 for (const SectionInfo &SI : Sections) {
4426 if (SI.SegmentIndex != SegIndex)
4427 continue;
4428 if ((SI.OffsetInSegment<=Start) && (Start<(SI.OffsetInSegment+SI.Size))) {
4429 if (End <= SI.OffsetInSegment + SI.Size) {
4430 Found = true;
4431 break;
4432 }
4433 else
4434 return "bad offset, extends beyond section boundary";
4435 }
4436 }
4437 if (!Found)
4438 return "bad offset, not in section";
4439 }
4440 return nullptr;
4441}
4442
4443
4444
4446 for (const SectionInfo &SI : Sections) {
4447 if (SI.SegmentIndex == SegIndex)
4448 return SI.SegmentName;
4449 }
4451}
4452
4453
4454
4455const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4456 int32_t SegIndex, uint64_t SegOffset) {
4457 for (const SectionInfo &SI : Sections) {
4458 if (SI.SegmentIndex != SegIndex)
4459 continue;
4460 if (SI.OffsetInSegment > SegOffset)
4461 continue;
4462 if (SegOffset >= (SI.OffsetInSegment + SI.Size))
4463 continue;
4464 return SI;
4465 }
4466 llvm_unreachable("SegIndex and SegOffset not in any section");
4467}
4468
4469
4470
4473 return findSection(SegIndex, SegOffset).SectionName;
4474}
4475
4476
4477
4479 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
4480 return SI.SegmentStartAddress + OffsetInSeg;
4481}
4482
4487 if (O->BindRebaseSectionTable == nullptr)
4488 O->BindRebaseSectionTable = std::make_unique(O);
4489 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind);
4490 Start.moveToFirst();
4491
4492 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind);
4493 Finish.moveToEnd();
4494
4496}
4497
4502
4507
4512
4514 if (BindRebaseSectionTable == nullptr)
4515 BindRebaseSectionTable = std::make_unique(this);
4516
4518 Start.moveToFirst();
4519
4522
4524}
4525
4528 return LoadCommands.begin();
4529}
4530
4533 return LoadCommands.end();
4534}
4535
4540
4546
4549 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4550 const section_base *Base =
4551 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4553}
4554
4557 assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
4558 const section_base *Base =
4559 reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
4561}
4562
4563bool
4565 const {
4567 return false;
4569}
4570
4574 return RE.r_word1 & 0xffffff;
4576}
4577
4581 return (RE.r_word1 >> 27) & 1;
4582 return (RE.r_word1 >> 4) & 1;
4583}
4584
4587 return RE.r_word0 >> 31;
4588}
4589
4594
4597 return (RE.r_word0 >> 24) & 0xf;
4598}
4599
4606
4613
4620
4621unsigned
4628
4635 if (SecNum == MachO::R_ABS || SecNum > Sections.size())
4640}
4641
4643 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4645}
4646
4648 assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
4650}
4651
4653 unsigned Index) const {
4654 const char *Sec = getSectionPtr(*this, L, Index);
4656}
4657
4659 unsigned Index) const {
4660 const char *Sec = getSectionPtr(*this, L, Index);
4662}
4663
4666 const char *P = reinterpret_cast<const char *>(DRI.p);
4668}
4669
4672 const char *P = reinterpret_cast<const char *>(DRI.p);
4674}
4675
4680
4685
4690
4695
4700
4705
4710
4715
4720
4725
4730
4735
4740
4745
4750
4755
4760
4765
4770
4775
4780
4785
4790
4795
4800
4810 } else {
4813 }
4814 } else {
4817 Offset = DysymtabLoadCmd.extreloff;
4818 else
4819 Offset = DysymtabLoadCmd.locreloff;
4820 }
4821
4825 *this, reinterpret_cast<const char *>(P));
4826}
4827
4830 const char *P = reinterpret_cast<const char *>(Rel.p);
4832}
4833
4837
4842
4845 unsigned Index) const {
4848}
4849
4852 unsigned Index) const {
4855}
4856
4858 if (SymtabLoadCmd)
4860
4861
4863 Cmd.cmd = MachO::LC_SYMTAB;
4869 return Cmd;
4870}
4871
4873 if (DysymtabLoadCmd)
4875
4876
4878 Cmd.cmd = MachO::LC_DYSYMTAB;
4887 Cmd.ntoc = 0;
4898 return Cmd;
4899}
4900
4903 if (DataInCodeLoadCmd)
4905
4906
4908 Cmd.cmd = MachO::LC_DATA_IN_CODE;
4912 return Cmd;
4913}
4914
4917 if (LinkOptHintsLoadCmd)
4919
4920
4921
4923 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4927 return Cmd;
4928}
4929
4931 if (!DyldInfoLoadCmd)
4932 return {};
4933
4934 auto DyldInfoOrErr =
4936 if (!DyldInfoOrErr)
4937 return {};
4942}
4943
4945 if (!DyldInfoLoadCmd)
4946 return {};
4947
4948 auto DyldInfoOrErr =
4950 if (!DyldInfoOrErr)
4951 return {};
4956}
4957
4959 if (!DyldInfoLoadCmd)
4960 return {};
4961
4962 auto DyldInfoOrErr =
4964 if (!DyldInfoOrErr)
4965 return {};
4970}
4971
4973 if (!DyldInfoLoadCmd)
4974 return {};
4975
4976 auto DyldInfoOrErr =
4978 if (!DyldInfoOrErr)
4979 return {};
4984}
4985
4987 if (!DyldInfoLoadCmd)
4988 return {};
4989
4990 auto DyldInfoOrErr =
4992 if (!DyldInfoOrErr)
4993 return {};
4998}
4999
5002
5003 if (!DyldChainedFixupsLoadCmd)
5004 return std::nullopt;
5006 *this, DyldChainedFixupsLoadCmd);
5007 if (!DyldChainedFixupsOrErr)
5008 return DyldChainedFixupsOrErr.takeError();
5010 *DyldChainedFixupsOrErr;
5011
5012
5013
5014 if (!DyldChainedFixups.dataoff)
5015 return std::nullopt;
5016 return DyldChainedFixups;
5017}
5018
5022 if (!CFOrErr)
5023 return CFOrErr.takeError();
5024 if (!CFOrErr->has_value())
5025 return std::nullopt;
5026
5028
5031
5032
5033 const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
5034 auto CFHeaderOrErr =
5036 if (!CFHeaderOrErr)
5037 return CFHeaderOrErr.takeError();
5039
5040
5046 Twine("bad chained fixups: unknown imports format: ") +
5048
5049
5050
5051
5054 return malformedError(Twine("bad chained fixups: image starts offset ") +
5056 " overlaps with chained fixups header");
5057 }
5058 uint32_t EndOffset = CFHeaderOffset + CFSize;
5060 EndOffset) {
5062 Twine(CFImageStartsOffset +
5064 " extends past end " + Twine(EndOffset));
5065 }
5066
5067 return CFHeader;
5068}
5069
5073 if (!CFOrErr)
5074 return CFOrErr.takeError();
5075
5076 std::vector Segments;
5077 if (!CFOrErr->has_value())
5078 return std::make_pair(0, Segments);
5079
5081
5083 if (!HeaderOrErr)
5084 return HeaderOrErr.takeError();
5085 if (!HeaderOrErr->has_value())
5086 return std::make_pair(0, Segments);
5088
5089 const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);
5090
5092 *this, Contents + Header.starts_offset);
5093 if (!ImageStartsOrErr)
5094 return ImageStartsOrErr.takeError();
5096
5097 const char *SegOffsPtr =
5098 Contents + Header.starts_offset +
5100 const char *SegOffsEnd =
5102 if (SegOffsEnd > Contents + DyldChainedFixups.datasize)
5104 "bad chained fixups: seg_info_offset extends past end");
5105
5106 const char *LastSegEnd = nullptr;
5107 for (size_t I = 0, N = ImageStarts.seg_count; I < N; ++I) {
5108 auto OffOrErr =
5110 if (!OffOrErr)
5111 return OffOrErr.takeError();
5112
5113
5114 if (!*OffOrErr)
5115 continue;
5116
5117 auto Fail = [&](Twine Message) {
5119 " at offset " + Twine(*OffOrErr) + Message);
5120 };
5121
5122 const char *SegPtr = Contents + Header.starts_offset + *OffOrErr;
5123 if (LastSegEnd && SegPtr < LastSegEnd)
5124 return Fail(" overlaps with previous segment info");
5125
5126 auto SegOrErr =
5128 if (!SegOrErr)
5129 return SegOrErr.takeError();
5131
5132 LastSegEnd = SegPtr + Seg.size;
5135
5136 const char *PageStart =
5138 const char *PageEnd = PageStart + Seg.page_count * sizeof(uint16_t);
5139 if (PageEnd > SegPtr + Seg.size)
5140 return Fail(" : page_starts extend past seg_info size");
5141
5142
5143
5144 std::vector<uint16_t> PageStarts;
5145 for (size_t PageIdx = 0; PageIdx < Seg.page_count; ++PageIdx) {
5147 memcpy(&Start, PageStart + PageIdx * sizeof(uint16_t), sizeof(uint16_t));
5150 PageStarts.push_back(Start);
5151 }
5152
5153 Segments.emplace_back(I, *OffOrErr, Seg, std::move(PageStarts));
5154 }
5155
5156 return std::make_pair(ImageStarts.seg_count, Segments);
5157}
5158
5159
5160
5168
5169template <typename T, unsigned N>
5171 std::array<T, N> RawValue;
5172 memcpy(RawValue.data(), Ptr, N * sizeof(T));
5174 for (auto &Element : RawValue)
5176 return RawValue;
5177}
5178
5179Expected<std::vector>
5182 if (!CFOrErr)
5183 return CFOrErr.takeError();
5184
5185 std::vector Targets;
5186 if (!CFOrErr->has_value())
5187 return Targets;
5188
5190
5192 if (!CFHeaderOrErr)
5193 return CFHeaderOrErr.takeError();
5194 if (!(*CFHeaderOrErr))
5195 return Targets;
5197
5198 size_t ImportSize = 0;
5205 else
5206 return malformedError("bad chained fixups: unknown imports format: " +
5208
5209 const char *Contents = getPtr(*this, DyldChainedFixups.dataoff);
5210 const char *Imports = Contents + Header.imports_offset;
5211 size_t ImportsEndOffset =
5212 Header.imports_offset + ImportSize * Header.imports_count;
5213 const char *ImportsEnd = Contents + ImportsEndOffset;
5214 const char *Symbols = Contents + Header.symbols_offset;
5215 const char *SymbolsEnd = Contents + DyldChainedFixups.datasize;
5216
5217 if (ImportsEnd > Symbols)
5218 return malformedError("bad chained fixups: imports end " +
5219 Twine(ImportsEndOffset) + " overlaps with symbols");
5220
5221
5222
5224 return createError("parsing big-endian chained fixups is not implemented");
5225 for (const char *ImportPtr = Imports; ImportPtr < ImportsEnd;
5226 ImportPtr += ImportSize) {
5227 int LibOrdinal;
5228 bool WeakImport;
5234
5236 WeakImport = (RawValue[0] >> 8) & 1;
5237 NameOffset = RawValue[0] >> 9;
5238 Addend = 0;
5240 static_assert(sizeof(uint64_t) ==
5243
5245 WeakImport = (RawValue[0] >> 8) & 1;
5246 NameOffset = RawValue[0] >> 9;
5249 static_assert(2 * sizeof(uint64_t) ==
5252
5254 NameOffset = (RawValue[0] >> 16) & 1;
5255 WeakImport = RawValue[0] >> 17;
5256 Addend = RawValue[1];
5257 } else {
5259 }
5260
5261 const char *Str = Symbols + NameOffset;
5262 if (Str >= SymbolsEnd)
5263 return malformedError("bad chained fixups: symbol offset " +
5264 Twine(NameOffset) + " extends past end " +
5266 Targets.emplace_back(LibOrdinal, NameOffset, Str, Addend, WeakImport);
5267 }
5268
5269 return std::move(Targets);
5270}
5271
5273 if (!DyldExportsTrieLoadCmd)
5274 return {};
5275
5277 *this, DyldExportsTrieLoadCmd);
5278 if (!DyldExportsTrieOrError)
5279 return {};
5284}
5285
5287 if (!FuncStartsLoadCmd)
5288 return {};
5289
5290 auto InfoOrErr =
5292 if (!InfoOrErr)
5293 return {};
5294
5298 return std::move(FunctionStarts);
5299}
5300
5302 if (!UuidLoadCmd)
5303 return {};
5304
5306 return ArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
5307}
5308
5313
5318
5322
5326 data += delta;
5328 }
5329}
5330
5334
5335
5336
5337
5338
5339
5340
5341
5344 size_t MachOFilesetEntryOffset) {
5346 if (Magic == "\xFE\xED\xFA\xCE")
5348 UniversalIndex, MachOFilesetEntryOffset);
5349 if (Magic == "\xCE\xFA\xED\xFE")
5351 UniversalIndex, MachOFilesetEntryOffset);
5352 if (Magic == "\xFE\xED\xFA\xCF")
5354 UniversalIndex, MachOFilesetEntryOffset);
5355 if (Magic == "\xCF\xFA\xED\xFE")
5357 UniversalIndex, MachOFilesetEntryOffset);
5360}
5361
5364 .Case("debug_str_offs", "debug_str_offsets")
5366}
5367
5371
5375 return std::vectorstd::string();
5376 sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
5377 bool IsDir;
5381 EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
5382 Path.str().c_str());
5383 if (EC)
5385
5386 std::vectorstd::string ObjectPaths;
5388 Dir != DirEnd && !EC; Dir.increment(EC)) {
5389 StringRef ObjectPath = Dir->path();
5393 switch (Status.type()) {
5397 ObjectPaths.push_back(ObjectPath.str());
5398 break;
5399 default: ;
5400 }
5401 }
5402 if (EC)
5404 if (ObjectPaths.empty())
5406 "%s: no objects found in dSYM bundle",
5407 Path.str().c_str());
5408 return ObjectPaths;
5409}
5410
5414#define HANDLE_SWIFT_SECTION(KIND, MACHO, ELF, COFF) \
5415 .Case(MACHO, llvm::binaryformat::Swift5ReflectionSectionKind::KIND)
5418#include "llvm/BinaryFormat/Swift.def"
5420#undef HANDLE_SWIFT_SECTION
5421}
5422
5424 switch (Arch) {
5438 default:
5439 return false;
5440 }
5441}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define offsetof(TYPE, MEMBER)
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
Definition MachOObjectFile.cpp:119
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
Definition MachOObjectFile.cpp:819
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
Definition MachOObjectFile.cpp:410
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
Definition MachOObjectFile.cpp:1200
static Error parseBuildVersionCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char * > &BuildTools, uint32_t LoadCommandIndex)
Definition MachOObjectFile.cpp:863
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:174
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
Definition MachOObjectFile.cpp:468
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
Definition MachOObjectFile.cpp:738
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
Definition MachOObjectFile.cpp:84
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
Definition MachOObjectFile.cpp:208
static const char * getPtr(const MachOObjectFile &O, size_t Offset, size_t MachOFilesetEntryOffset=0)
Definition MachOObjectFile.cpp:111
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)
Definition MachOObjectFile.cpp:286
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
Definition MachOObjectFile.cpp:639
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:170
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:162
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)
Definition MachOObjectFile.cpp:982
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
Definition MachOObjectFile.cpp:886
static T getStruct(const MachOObjectFile &O, const char *P)
Definition MachOObjectFile.cpp:71
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:141
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
Definition MachOObjectFile.cpp:97
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
Definition MachOObjectFile.cpp:942
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:150
static std::array< T, N > getArray(const MachOObjectFile &O, const void *Ptr)
Definition MachOObjectFile.cpp:5170
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:146
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
Definition MachOObjectFile.cpp:1009
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)
Definition MachOObjectFile.cpp:601
static Error malformedError(const Twine &Msg)
Definition MachOObjectFile.cpp:63
static bool isLoadCommandObsolete(uint32_t cmd)
Definition MachOObjectFile.cpp:1239
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
Definition MachOObjectFile.cpp:181
static int getEncodedOrdinal(T Value)
Definition MachOObjectFile.cpp:5161
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
Definition MachOObjectFile.cpp:158
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
Definition MachOObjectFile.cpp:253
static StringRef parseSegmentOrSectionName(const char *P)
Definition MachOObjectFile.cpp:124
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
Definition MachOObjectFile.cpp:192
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
Definition MachOObjectFile.cpp:232
static unsigned getCPUType(const MachOObjectFile &O)
Definition MachOObjectFile.cpp:132
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
Definition MachOObjectFile.cpp:787
static Error checkNoteCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, std::list< MachOElement > &Elements)
Definition MachOObjectFile.cpp:834
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
Definition MachOObjectFile.cpp:770
static unsigned getCPUSubType(const MachOObjectFile &O)
Definition MachOObjectFile.cpp:136
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)
Definition MachOObjectFile.cpp:918
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
Definition MachOObjectFile.cpp:219
static Error malformedError(Twine Msg)
OptimizedStructLayoutField Field
static StringRef substr(StringRef Str, uint64_t Len)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
static bool is64Bit(const char *name)
This file implements the C++20 header.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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...
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.
static constexpr size_t npos
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.
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
constexpr size_t size() const
Returns the byte size of the table.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(uint64_t Val)
LLVM Value Representation.
A range adaptor for a pair of iterators.
DataRefImpl getRawDataRefImpl() const
StringRef getData() const
unsigned int getType() const
bool isLittleEndian() const
static unsigned int getMachOType(bool isLE, bool is64Bits)
LLVM_ABI StringRef segmentName(int32_t SegIndex)
Definition MachOObjectFile.cpp:4445
LLVM_ABI StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)
Definition MachOObjectFile.cpp:4471
LLVM_ABI BindRebaseSegInfo(const MachOObjectFile *Obj)
Definition MachOObjectFile.cpp:4377
LLVM_ABI const char * checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, uint8_t PointerSize, uint64_t Count=1, uint64_t Skip=0)
Definition MachOObjectFile.cpp:4412
LLVM_ABI uint64_t address(uint32_t SegIndex, uint64_t SegOffset)
Definition MachOObjectFile.cpp:4478
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...
LLVM_ABI void moveNext()
Definition MachOObjectFile.cpp:3219
LLVM_ABI StringRef name() const
Definition MachOObjectFile.cpp:2986
LLVM_ABI ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Trie)
Definition MachOObjectFile.cpp:2943
LLVM_ABI bool operator==(const ExportEntry &) const
Definition MachOObjectFile.cpp:2959
LLVM_ABI StringRef otherName() const
Definition MachOObjectFile.cpp:3002
LLVM_ABI uint64_t address() const
Definition MachOObjectFile.cpp:2994
LLVM_ABI uint64_t flags() const
Definition MachOObjectFile.cpp:2990
LLVM_ABI uint32_t nodeOffset() const
Definition MachOObjectFile.cpp:3009
friend class MachOObjectFile
LLVM_ABI uint64_t other() const
Definition MachOObjectFile.cpp:2998
LLVM_ABI StringRef sectionName() const
Definition MachOObjectFile.cpp:3308
LLVM_ABI uint64_t segmentAddress() const
Definition MachOObjectFile.cpp:3300
LLVM_ABI int32_t segmentIndex() const
Definition MachOObjectFile.cpp:3294
LLVM_ABI uint64_t address() const
Definition MachOObjectFile.cpp:3312
LLVM_ABI void moveNext()
Definition MachOObjectFile.cpp:3337
LLVM_ABI StringRef typeName() const
Definition MachOObjectFile.cpp:3324
LLVM_ABI int64_t addend() const
Definition MachOObjectFile.cpp:3318
LLVM_ABI MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O)
Definition MachOObjectFile.cpp:3273
uint64_t textAddress() const
LLVM_ABI uint32_t flags() const
Definition MachOObjectFile.cpp:3320
LLVM_ABI StringRef symbolName() const
Definition MachOObjectFile.cpp:3316
LLVM_ABI void moveToFirst()
Definition MachOObjectFile.cpp:3326
LLVM_ABI int ordinal() const
Definition MachOObjectFile.cpp:3322
LLVM_ABI StringRef segmentName() const
Definition MachOObjectFile.cpp:3304
LLVM_ABI void moveToEnd()
Definition MachOObjectFile.cpp:3335
const MachOObjectFile * O
LLVM_ABI uint64_t segmentOffset() const
Definition MachOObjectFile.cpp:3296
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
LLVM_ABI uint32_t flags() const
Definition MachOObjectFile.cpp:4343
LLVM_ABI bool operator==(const MachOBindEntry &) const
Definition MachOObjectFile.cpp:4365
LLVM_ABI void moveNext()
Definition MachOObjectFile.cpp:3856
LLVM_ABI StringRef symbolName() const
Definition MachOObjectFile.cpp:4339
LLVM_ABI int ordinal() const
Definition MachOObjectFile.cpp:4345
LLVM_ABI StringRef sectionName() const
Definition MachOObjectFile.cpp:4355
LLVM_ABI MachOBindEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
Definition MachOObjectFile.cpp:3840
LLVM_ABI StringRef segmentName() const
Definition MachOObjectFile.cpp:4349
LLVM_ABI uint64_t segmentOffset() const
Definition MachOObjectFile.cpp:4325
LLVM_ABI int64_t addend() const
Definition MachOObjectFile.cpp:4341
LLVM_ABI uint64_t address() const
Definition MachOObjectFile.cpp:4361
friend class MachOObjectFile
LLVM_ABI int32_t segmentIndex() const
Definition MachOObjectFile.cpp:4323
LLVM_ABI StringRef typeName() const
Definition MachOObjectFile.cpp:4327
LLVM_ABI void moveNext()
Definition MachOObjectFile.cpp:3401
LLVM_ABI bool operator==(const MachOChainedFixupEntry &) const
Definition MachOObjectFile.cpp:3491
LLVM_ABI MachOChainedFixupEntry(Error *Err, const MachOObjectFile *O, bool Parse)
Definition MachOObjectFile.cpp:3339
LLVM_ABI void moveToEnd()
Definition MachOObjectFile.cpp:3397
LLVM_ABI void moveToFirst()
Definition MachOObjectFile.cpp:3383
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4777
void moveSectionNext(DataRefImpl &Sec) const override
Definition MachOObjectFile.cpp:1933
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
Definition MachOObjectFile.cpp:4556
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
Definition MachOObjectFile.cpp:2677
Triple::ArchType getArch() const override
Definition MachOObjectFile.cpp:2902
MachO::mach_header_64 Header64
bool isSectionData(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2068
const MachO::mach_header_64 & getHeader64() const
Definition MachOObjectFile.cpp:4838
Expected< std::vector< ChainedFixupTarget > > getDyldChainedFixupTargets() const
Definition MachOObjectFile.cpp:5180
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2026
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4595
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Definition MachOObjectFile.cpp:2268
Expected< SectionRef > getSection(unsigned SectionIndex) const
Definition MachOObjectFile.cpp:2039
iterator_range< rebase_iterator > rebaseTable(Error &Err)
For use iterating over all rebase table entries.
Definition MachOObjectFile.cpp:3836
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
Definition MachOObjectFile.cpp:1807
load_command_iterator begin_load_commands() const
Definition MachOObjectFile.cpp:4527
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4757
StringRef getFileFormatName() const override
Definition MachOObjectFile.cpp:2681
dice_iterator begin_dices() const
Definition MachOObjectFile.cpp:2922
basic_symbol_iterator symbol_begin() const override
Definition MachOObjectFile.cpp:2618
Expected< std::optional< MachO::linkedit_data_command > > getChainedFixupsLoadCommand() const
Definition MachOObjectFile.cpp:5001
iterator_range< export_iterator > exports(Error &Err) const
For use iterating over all exported symbols.
Definition MachOObjectFile.cpp:3263
uint64_t getSymbolIndex(DataRefImpl Symb) const
Definition MachOObjectFile.cpp:2654
MachO::build_version_command getBuildVersionLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4707
section_iterator section_end() const override
Definition MachOObjectFile.cpp:2671
MachO::build_tool_version getBuildToolVersion(unsigned index) const
Definition MachOObjectFile.cpp:4712
MachO::linkedit_data_command getDataInCodeLoadCommand() const
Definition MachOObjectFile.cpp:4902
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4782
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
Definition MachOObjectFile.cpp:4665
unsigned getSymbolSectionID(SymbolRef Symb) const
Definition MachOObjectFile.cpp:1927
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...
Definition MachOObjectFile.cpp:5369
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4590
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4692
uint32_t getLibraryCount() const
Definition MachOObjectFile.cpp:2607
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4747
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1912
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition MachOObjectFile.cpp:2259
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
Definition MachOObjectFile.cpp:4972
void moveSymbolNext(DataRefImpl &Symb) const override
Definition MachOObjectFile.cpp:1768
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4630
MachO::dysymtab_command getDysymtabLoadCommand() const
Definition MachOObjectFile.cpp:4872
iterator_range< bind_iterator > bindTable(Error &Err)
For use iterating over all bind table entries.
Definition MachOObjectFile.cpp:4498
MachO::mach_header Header
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1838
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2197
MachO::section_64 getSection64(DataRefImpl DRI) const
Definition MachOObjectFile.cpp:4647
MachO::fileset_entry_command getFilesetEntryLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4797
MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4702
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4792
section_iterator section_begin() const override
Definition MachOObjectFile.cpp:2666
Error checkSymbolTable() const
Definition MachOObjectFile.cpp:1701
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Definition MachOObjectFile.cpp:5331
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4687
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2205
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
Definition MachOObjectFile.cpp:4986
bool isDebugSection(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2084
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
Definition MachOObjectFile.cpp:4671
unsigned getSectionType(SectionRef Sec) const
Definition MachOObjectFile.cpp:1790
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4682
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)
Definition MachOObjectFile.cpp:1254
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
Definition MachOObjectFile.cpp:4542
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
Definition MachOObjectFile.cpp:4916
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4622
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4737
dice_iterator end_dices() const
Definition MachOObjectFile.cpp:2932
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4787
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4762
SmallVector< uint64_t > getFunctionStarts() const
Definition MachOObjectFile.cpp:5286
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4772
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4722
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4767
ArrayRef< uint8_t > getDyldExportsTrie() const
Definition MachOObjectFile.cpp:5272
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1868
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
Definition MachOObjectFile.cpp:2612
bool isSectionBSS(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2076
Expected< std::pair< size_t, std::vector< ChainedFixupsSegment > > > getChainedFixupsSegments() const
Definition MachOObjectFile.cpp:5071
bool isSectionVirtual(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2177
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4585
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1775
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4578
LoadCommandList::const_iterator load_command_iterator
symbol_iterator getSymbolByIndex(unsigned Index) const
Definition MachOObjectFile.cpp:2642
static Triple getHostArch()
Definition MachOObjectFile.cpp:2868
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4752
const MachO::mach_header & getHeader() const
Definition MachOObjectFile.cpp:4834
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4607
iterator_range< bind_iterator > weakBindTable(Error &Err)
For use iterating over all weak bind table entries.
Definition MachOObjectFile.cpp:4508
static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch)
Definition MachOObjectFile.cpp:5423
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
Definition MachOObjectFile.cpp:4930
iterator_range< load_command_iterator > load_commands() const
Definition MachOObjectFile.cpp:4537
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4614
MachO::symtab_command getSymtabLoadCommand() const
Definition MachOObjectFile.cpp:4857
Triple getArchTriple(const char **McpuDefault=nullptr) const
Definition MachOObjectFile.cpp:2906
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4732
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4571
ArrayRef< uint8_t > getUuid() const
Definition MachOObjectFile.cpp:5301
bool is64Bit() const override
Definition MachOObjectFile.cpp:5314
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4697
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
Definition MachOObjectFile.cpp:5362
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4727
uint64_t getRelocationType(DataRefImpl Rel) const override
Definition MachOObjectFile.cpp:2293
relocation_iterator extrel_begin() const
Definition MachOObjectFile.cpp:2221
void moveRelocationNext(DataRefImpl &Rel) const override
Definition MachOObjectFile.cpp:2255
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
Definition MachOObjectFile.cpp:4802
basic_symbol_iterator symbol_end() const override
Definition MachOObjectFile.cpp:2627
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
Definition MachOObjectFile.cpp:4851
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
Definition MachOObjectFile.cpp:4829
bool isSectionStripped(DataRefImpl Sec) const override
When dsymutil generates the companion file, it strips all unnecessary sections (e....
Definition MachOObjectFile.cpp:2191
uint64_t getSectionIndex(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:1948
iterator_range< fixup_iterator > fixupTable(Error &Err)
For iterating over all chained fixups.
Definition MachOObjectFile.cpp:4513
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
Definition MachOObjectFile.cpp:5319
iterator_range< bind_iterator > lazyBindTable(Error &Err)
For use iterating over all lazy bind table entries.
Definition MachOObjectFile.cpp:4503
load_command_iterator end_load_commands() const
Definition MachOObjectFile.cpp:4532
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
Definition MachOObjectFile.cpp:4944
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1843
uint64_t getSectionAddress(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:1942
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:1937
uint8_t getRelocationLength(DataRefImpl Rel) const
Definition MachOObjectFile.cpp:2408
llvm::binaryformat::Swift5ReflectionSectionKind mapReflectionSectionNameToEnumValue(StringRef SectionName) const override
Definition MachOObjectFile.cpp:5412
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
Definition MachOObjectFile.cpp:4958
static bool isValidArch(StringRef ArchFlag)
Definition MachOObjectFile.cpp:2872
bool isSectionText(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2063
bool isSectionCompressed(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2059
static ArrayRef< StringRef > getValidArchs()
Definition MachOObjectFile.cpp:2877
bool isSectionBitcode(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:2184
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4564
relocation_iterator locrel_begin() const
Definition MachOObjectFile.cpp:2238
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.
Definition MachOObjectFile.cpp:5020
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1829
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4742
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
Definition MachOObjectFile.cpp:4600
StringRef getStringTableData() const
Definition MachOObjectFile.cpp:5309
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Definition MachOObjectFile.cpp:2298
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
Definition MachOObjectFile.cpp:4548
uint64_t getNValue(DataRefImpl Sym) const
Definition MachOObjectFile.cpp:1796
ArrayRef< uint8_t > getSegmentContents(StringRef SegmentName) const
Return the raw contents of an entire segment.
Definition MachOObjectFile.cpp:2130
section_iterator getRelocationSection(DataRefImpl Rel) const
Definition MachOObjectFile.cpp:2289
unsigned getSectionID(SectionRef Sec) const
Definition MachOObjectFile.cpp:2173
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4677
ArrayRef< uint8_t > getSectionContents(uint64_t Offset, uint64_t Size) const
Definition MachOObjectFile.cpp:1981
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition MachOObjectFile.cpp:1825
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
Definition MachOObjectFile.cpp:4717
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
Definition MachOObjectFile.cpp:4843
uint64_t getSectionSize(DataRefImpl Sec) const override
Definition MachOObjectFile.cpp:1952
relocation_iterator extrel_end() const
Definition MachOObjectFile.cpp:2229
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
Definition MachOObjectFile.cpp:2449
relocation_iterator locrel_end() const
Definition MachOObjectFile.cpp:2246
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
Definition MachOObjectFile.cpp:2573
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
LLVM_ABI int32_t segmentIndex() const
Definition MachOObjectFile.cpp:3777
LLVM_ABI StringRef segmentName() const
Definition MachOObjectFile.cpp:3795
LLVM_ABI MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)
Definition MachOObjectFile.cpp:3501
LLVM_ABI bool operator==(const MachORebaseEntry &) const
Definition MachOObjectFile.cpp:3811
LLVM_ABI uint64_t address() const
Definition MachOObjectFile.cpp:3807
LLVM_ABI void moveNext()
Definition MachOObjectFile.cpp:3517
LLVM_ABI StringRef sectionName() const
Definition MachOObjectFile.cpp:3801
friend class MachOObjectFile
LLVM_ABI uint64_t segmentOffset() const
Definition MachOObjectFile.cpp:3779
LLVM_ABI StringRef typeName() const
Definition MachOObjectFile.cpp:3781
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.
Definition MachOObjectFile.cpp:5342
section_iterator_range sections() const
symbol_iterator_range symbols() const
Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const
DataRefImpl getRawDataRefImpl() const
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
bool isData() const
Whether this section contains data, not instructions.
bool isBSS() const
Whether this section contains BSS uninitialized data.
directory_iterator - Iterates through the entries in path.
Represents the result of a call to sys::fs::status().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
const uint32_t x86_FLOAT_STATE_COUNT
@ DYLD_CHAINED_IMPORT_ADDEND
@ DYLD_CHAINED_IMPORT_ADDEND64
const uint32_t ARM_THREAD_STATE64_COUNT
@ EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
@ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
@ EXPORT_SYMBOL_FLAGS_KIND_REGULAR
@ BIND_TYPE_TEXT_ABSOLUTE32
const uint32_t x86_EXCEPTION_STATE_COUNT
@ EXPORT_SYMBOL_FLAGS_REEXPORT
@ EXPORT_SYMBOL_FLAGS_KIND_MASK
@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
@ 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
@ BIND_SYMBOL_FLAGS_WEAK_IMPORT
@ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
@ 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
@ DYLD_CHAINED_PTR_64_OFFSET
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)
@ S_ATTR_PURE_INSTRUCTIONS
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
const uint32_t x86_EXCEPTION_STATE64_COUNT
const uint32_t x86_THREAD_STATE64_COUNT
constexpr size_t SymbolTableEntrySize
Swift5ReflectionSectionKind
content_iterator< SectionRef > section_iterator
Error createError(const Twine &Err)
content_iterator< MachOBindEntry > bind_iterator
content_iterator< MachOChainedFixupEntry > fixup_iterator
content_iterator< MachORebaseEntry > rebase_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
content_iterator< ExportEntry > export_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< DiceRef > dice_iterator
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI bool is_directory(const basic_file_status &status)
Does status represent a directory?
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
constexpr bool IsLittleEndianHost
LLVM_ABI std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ no_such_file_or_directory
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
To bit_cast(const From &from) noexcept
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
uint64_t Offset
Definition MachOObjectFile.cpp:248
const char * Name
Definition MachOObjectFile.cpp:250
uint64_t Size
Definition MachOObjectFile.cpp:249
This struct is a compact representation of a valid (non-zero power of two) alignment.
dyld_chained_starts_in_image is embedded in LC_DYLD_CHAINED_FIXUPS payload.
uint16_t page_count
Length of the page_start array.
uint16_t page_size
Page size in bytes (0x1000 or 0x4000)
uint16_t pointer_format
DYLD_CHAINED_PTR*.
uint32_t size
Size of this, including chain_starts entries.
ChainedFixupTarget holds all the information about an external symbol necessary to bind this binary t...
MachO::dyld_chained_starts_in_segment Header
std::vector< uint16_t > PageStarts
struct llvm::object::DataRefImpl::@005117267142344013370254144343227032034000327225 d