47 #include <system_error> 62 return make_error<GenericBinaryError>(
"truncated or malformed object (" +
71 if (P < O.getData().begin() || P +
sizeof(
T) > O.getData().end())
84 if (P < O.getData().begin() || P +
sizeof(
T) > O.getData().end())
97 uintptr_t CommandAddr =
reinterpret_cast<uintptr_t
>(L.Ptr);
99 bool Is64 = O.is64Bit();
105 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec *
SectionSize;
106 return reinterpret_cast<const char*
>(SectionAddr);
110 assert(Offset <= O.getData().size());
111 return O.getData().data() +
Offset;
116 const char *
P =
reinterpret_cast<const char *
>(DRI.p);
117 return getStruct<MachO::nlist_base>(
O,
P);
129 return O.getHeader().cputype;
144 if (O.isLittleEndian())
156 if (O.isLittleEndian())
168 if (O.isLittleEndian())
186 if (
auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
187 if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())
189 " extends past end of file");
190 if (CmdOrErr->cmdsize < 8)
192 " with size less than 8 bytes");
193 return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
195 return CmdOrErr.takeError();
203 return malformedError(
"load command 0 extends past the end all load " 204 "commands in the file");
210 const MachOObjectFile::LoadCommandInfo &L) {
214 Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
216 " extends past the end all load commands in the file");
220 template <
typename T>
223 if (
sizeof(
T) > Obj.getData().size()) {
224 Err =
malformedError(
"the mach header extends past the end of the " 228 if (
auto HeaderOrErr = getStructOrErr<T>(Obj,
getPtr(Obj, 0)))
229 Header = *HeaderOrErr;
231 Err = HeaderOrErr.takeError();
247 for (
auto it=Elements.begin() ; it != Elements.end(); ++it) {
249 if ((Offset >=
E.Offset && Offset <
E.Offset +
E.Size) ||
250 (Offset + Size >
E.Offset && Offset + Size <
E.Offset +
E.Size) ||
251 (Offset <= E.Offset && Offset + Size >=
E.Offset +
E.Size))
253 " with a size of " +
Twine(Size) +
", overlaps " +
254 E.Name +
" at offset " +
Twine(
E.Offset) +
" with " 255 "a size of " +
Twine(
E.Size));
258 if (nt != Elements.end()) {
260 if (Offset + Size <=
N.Offset) {
273 template <
typename Segment,
typename Section>
275 const MachOObjectFile &Obj,
const MachOObjectFile::LoadCommandInfo &
Load,
277 uint32_t LoadCommandIndex,
const char *CmdName, uint64_t SizeOfHeaders,
278 std::list<MachOElement> &Elements) {
279 const unsigned SegmentLoadSize =
sizeof(Segment);
280 if (Load.C.cmdsize < SegmentLoadSize)
282 " " + CmdName +
" cmdsize too small");
283 if (
auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) {
284 Segment S = SegOrErr.get();
286 uint64_t FileSize = Obj.getData().size();
288 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
290 " inconsistent cmdsize in " + CmdName +
291 " for the number of sections");
292 for (
unsigned J = 0; J < S.nsects; ++J) {
295 Section s = getStruct<Section>(Obj, Sec);
302 CmdName +
" command " +
Twine(LoadCommandIndex) +
303 " extends past the end of the file");
308 s.offset < SizeOfHeaders && s.size != 0)
310 CmdName +
" command " +
Twine(LoadCommandIndex) +
311 " not past the headers of the file");
312 uint64_t BigSize = s.offset;
319 return malformedError(
"offset field plus size field of section " +
320 Twine(J) +
" in " + CmdName +
" command " +
321 Twine(LoadCommandIndex) +
322 " extends past the end of the file");
329 Twine(J) +
" in " + CmdName +
" command " +
330 Twine(LoadCommandIndex) +
331 " greater than the segment");
336 CmdName +
" command " +
Twine(LoadCommandIndex) +
337 " less than the segment's vmaddr");
340 uint64_t BigEnd = S.vmaddr;
342 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd)
344 " in " + CmdName +
" command " +
345 Twine(LoadCommandIndex) +
346 " greater than than " 347 "the segment's vmaddr plus vmsize");
355 if (s.reloff > FileSize)
357 CmdName +
" command " +
Twine(LoadCommandIndex) +
358 " extends past the end of the file");
362 if (BigSize > FileSize)
363 return malformedError(
"reloff field plus nreloc field times sizeof(" 364 "struct relocation_info) of section " +
365 Twine(J) +
" in " + CmdName +
" command " +
366 Twine(LoadCommandIndex) +
367 " extends past the end of the file");
371 "section relocation entries"))
374 if (S.fileoff > FileSize)
376 " fileoff field in " + CmdName +
377 " extends past the end of the file");
378 uint64_t BigSize = S.fileoff;
379 BigSize += S.filesize;
380 if (BigSize > FileSize)
382 " fileoff field plus filesize field in " +
383 CmdName +
" extends past the end of the file");
384 if (S.vmsize != 0 && S.filesize > S.vmsize)
386 " filesize field in " + CmdName +
387 " greater than vmsize field");
390 return SegOrErr.takeError();
396 const MachOObjectFile::LoadCommandInfo &
Load,
398 const char **SymtabLoadCmd,
399 std::list<MachOElement> &Elements) {
402 " LC_SYMTAB cmdsize too small");
403 if (*SymtabLoadCmd !=
nullptr)
406 getStruct<MachO::symtab_command>(Obj, Load.Ptr);
409 " has incorrect cmdsize");
410 uint64_t FileSize = Obj.getData().size();
411 if (Symtab.
symoff > FileSize)
413 Twine(LoadCommandIndex) +
" extends past the end " 415 uint64_t SymtabSize = Symtab.
nsyms;
416 const char *struct_nlist_name;
419 struct_nlist_name =
"struct nlist_64";
422 struct_nlist_name =
"struct nlist";
424 uint64_t BigSize = SymtabSize;
426 if (BigSize > FileSize)
427 return malformedError(
"symoff field plus nsyms field times sizeof(" +
428 Twine(struct_nlist_name) +
") of LC_SYMTAB command " +
429 Twine(LoadCommandIndex) +
" extends past the end " 434 if (Symtab.
stroff > FileSize)
436 Twine(LoadCommandIndex) +
" extends past the end " 440 if (BigSize > FileSize)
441 return malformedError(
"stroff field plus strsize field of LC_SYMTAB " 442 "command " +
Twine(LoadCommandIndex) +
" extends " 443 "past the end of the file");
445 Symtab.
strsize,
"string table"))
447 *SymtabLoadCmd = Load.Ptr;
452 const MachOObjectFile::LoadCommandInfo &
Load,
454 const char **DysymtabLoadCmd,
455 std::list<MachOElement> &Elements) {
458 " LC_DYSYMTAB cmdsize too small");
459 if (*DysymtabLoadCmd !=
nullptr)
462 getStruct<MachO::dysymtab_command>(Obj, Load.Ptr);
465 " has incorrect cmdsize");
466 uint64_t FileSize = Obj.getData().size();
467 if (Dysymtab.
tocoff > FileSize)
469 Twine(LoadCommandIndex) +
" extends past the end of " 471 uint64_t BigSize = Dysymtab.
ntoc;
473 BigSize += Dysymtab.
tocoff;
474 if (BigSize > FileSize)
475 return malformedError(
"tocoff field plus ntoc field times sizeof(struct " 476 "dylib_table_of_contents) of LC_DYSYMTAB command " +
477 Twine(LoadCommandIndex) +
" extends past the end of " 480 Dysymtab.
ntoc *
sizeof(
struct 482 "table of contents"))
486 Twine(LoadCommandIndex) +
" extends past the end of " 489 const char *struct_dylib_module_name;
490 uint64_t sizeof_modtab;
493 struct_dylib_module_name =
"struct dylib_module_64";
496 struct_dylib_module_name =
"struct dylib_module";
498 BigSize *= sizeof_modtab;
500 if (BigSize > FileSize)
501 return malformedError(
"modtaboff field plus nmodtab field times sizeof(" +
502 Twine(struct_dylib_module_name) +
") of LC_DYSYMTAB " 503 "command " +
Twine(LoadCommandIndex) +
" extends " 504 "past the end of the file");
506 Dysymtab.
nmodtab * sizeof_modtab,
510 return malformedError(
"extrefsymoff field of LC_DYSYMTAB command " +
511 Twine(LoadCommandIndex) +
" extends past the end of " 516 if (BigSize > FileSize)
517 return malformedError(
"extrefsymoff field plus nextrefsyms field times " 518 "sizeof(struct dylib_reference) of LC_DYSYMTAB " 519 "command " +
Twine(LoadCommandIndex) +
" extends " 520 "past the end of the file");
527 return malformedError(
"indirectsymoff field of LC_DYSYMTAB command " +
528 Twine(LoadCommandIndex) +
" extends past the end of " 533 if (BigSize > FileSize)
534 return malformedError(
"indirectsymoff field plus nindirectsyms field times " 535 "sizeof(uint32_t) of LC_DYSYMTAB command " +
536 Twine(LoadCommandIndex) +
" extends past the end of " 545 Twine(LoadCommandIndex) +
" extends past the end of " 550 if (BigSize > FileSize)
551 return malformedError(
"extreloff field plus nextrel field times sizeof" 552 "(struct relocation_info) of LC_DYSYMTAB command " +
553 Twine(LoadCommandIndex) +
" extends past the end of " 558 "external relocation table"))
562 Twine(LoadCommandIndex) +
" extends past the end of " 567 if (BigSize > FileSize)
568 return malformedError(
"locreloff field plus nlocrel field times sizeof" 569 "(struct relocation_info) of LC_DYSYMTAB command " +
570 Twine(LoadCommandIndex) +
" extends past the end of " 575 "local relocation table"))
577 *DysymtabLoadCmd = Load.Ptr;
582 const MachOObjectFile::LoadCommandInfo &
Load,
584 const char **LoadCmd,
const char *CmdName,
585 std::list<MachOElement> &Elements,
586 const char *ElementName) {
589 CmdName +
" cmdsize too small");
590 if (*LoadCmd !=
nullptr)
593 getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr);
596 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
597 uint64_t FileSize = Obj.getData().size();
598 if (LinkData.
dataoff > FileSize)
600 Twine(LoadCommandIndex) +
" extends past the end of " 602 uint64_t BigSize = LinkData.
dataoff;
604 if (BigSize > FileSize)
606 Twine(CmdName) +
" command " +
607 Twine(LoadCommandIndex) +
" extends past the end of " 617 const MachOObjectFile::LoadCommandInfo &
Load,
619 const char **LoadCmd,
const char *CmdName,
620 std::list<MachOElement> &Elements) {
623 CmdName +
" cmdsize too small");
624 if (*LoadCmd !=
nullptr)
625 return malformedError(
"more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY " 628 getStruct<MachO::dyld_info_command>(Obj, Load.Ptr);
631 Twine(LoadCommandIndex) +
" has incorrect cmdsize");
632 uint64_t FileSize = Obj.getData().size();
635 " command " +
Twine(LoadCommandIndex) +
" extends " 636 "past the end of the file");
639 if (BigSize > FileSize)
640 return malformedError(
"rebase_off field plus rebase_size field of " +
641 Twine(CmdName) +
" command " +
642 Twine(LoadCommandIndex) +
" extends past the end of " 650 " command " +
Twine(LoadCommandIndex) +
" extends " 651 "past the end of the file");
654 if (BigSize > FileSize)
656 Twine(CmdName) +
" command " +
657 Twine(LoadCommandIndex) +
" extends past the end of " 665 " command " +
Twine(LoadCommandIndex) +
" extends " 666 "past the end of the file");
669 if (BigSize > FileSize)
670 return malformedError(
"weak_bind_off field plus weak_bind_size field of " +
671 Twine(CmdName) +
" command " +
672 Twine(LoadCommandIndex) +
" extends past the end of " 676 "dyld weak bind info"))
680 " command " +
Twine(LoadCommandIndex) +
" extends " 681 "past the end of the file");
684 if (BigSize > FileSize)
685 return malformedError(
"lazy_bind_off field plus lazy_bind_size field of " +
686 Twine(CmdName) +
" command " +
687 Twine(LoadCommandIndex) +
" extends past the end of " 691 "dyld lazy bind info"))
695 " command " +
Twine(LoadCommandIndex) +
" extends " 696 "past the end of the file");
699 if (BigSize > FileSize)
700 return malformedError(
"export_off field plus export_size field of " +
701 Twine(CmdName) +
" command " +
702 Twine(LoadCommandIndex) +
" extends past the end of " 713 const MachOObjectFile::LoadCommandInfo &
Load,
714 uint32_t LoadCommandIndex,
const char *CmdName) {
717 CmdName +
" cmdsize too small");
721 CmdName +
" name.offset field too small, not past " 722 "the end of the dylib_command struct");
725 CmdName +
" name.offset field extends past the end " 726 "of the load command");
730 const char *
P = (
const char *)Load.Ptr;
736 CmdName +
" library name extends past the end of the " 742 const MachOObjectFile::LoadCommandInfo &
Load,
744 const char **LoadCmd) {
748 if (*LoadCmd !=
nullptr)
752 return malformedError(
"LC_ID_DYLIB load command in non-dynamic library " 759 const MachOObjectFile::LoadCommandInfo &
Load,
760 uint32_t LoadCommandIndex,
const char *CmdName) {
763 CmdName +
" cmdsize too small");
767 CmdName +
" name.offset field too small, not past " 768 "the end of the dylinker_command struct");
771 CmdName +
" name.offset field extends past the end " 772 "of the load command");
776 const char *
P = (
const char *)Load.Ptr;
782 CmdName +
" dyld name extends past the end of the " 788 const MachOObjectFile::LoadCommandInfo &
Load,
790 const char **LoadCmd,
const char *CmdName) {
793 CmdName +
" has incorrect cmdsize");
794 if (*LoadCmd !=
nullptr)
796 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or " 797 "LC_VERSION_MIN_WATCHOS command");
803 const MachOObjectFile::LoadCommandInfo &
Load,
805 std::list<MachOElement> &Elements) {
808 " LC_NOTE has incorrect cmdsize");
810 uint64_t FileSize = Obj.getData().
size();
813 Twine(LoadCommandIndex) +
" extends " 814 "past the end of the file");
815 uint64_t BigSize = Nt.
offset;
817 if (BigSize > FileSize)
818 return malformedError(
"size field plus offset field of LC_NOTE command " +
819 Twine(LoadCommandIndex) +
" extends past the end of " 829 const MachOObjectFile::LoadCommandInfo &
Load,
833 getStruct<MachO::build_version_command>(Obj, Load.Ptr);
834 if (Load.C.cmdsize !=
838 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize");
842 for (
unsigned i = 0; i < BVC.
ntools; ++i)
849 const MachOObjectFile::LoadCommandInfo &
Load,
853 " LC_RPATH cmdsize too small");
857 " LC_RPATH path.offset field too small, not past " 858 "the end of the rpath_command struct");
861 " LC_RPATH path.offset field extends past the end " 862 "of the load command");
866 const char *
P = (
const char *)Load.Ptr;
872 " LC_RPATH library name extends past the end of the " 878 const MachOObjectFile::LoadCommandInfo &
Load,
880 uint64_t cryptoff, uint64_t cryptsize,
881 const char **LoadCmd,
const char *CmdName) {
882 if (*LoadCmd !=
nullptr)
884 "LC_ENCRYPTION_INFO_64 command");
885 uint64_t FileSize = Obj.getData().size();
886 if (cryptoff > FileSize)
888 " command " +
Twine(LoadCommandIndex) +
" extends " 889 "past the end of the file");
890 uint64_t BigSize = cryptoff;
891 BigSize += cryptsize;
892 if (BigSize > FileSize)
894 Twine(CmdName) +
" command " +
895 Twine(LoadCommandIndex) +
" extends past the end of " 902 const MachOObjectFile::LoadCommandInfo &
Load,
906 " LC_LINKER_OPTION cmdsize too small");
908 getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
910 const char *
string = (
const char *)Load.Ptr +
915 while (*
string ==
'\0' && left > 0) {
922 uint32_t len = std::min(NullPos, left) + 1;
929 " LC_LINKER_OPTION string count " +
Twine(L.
count) +
930 " does not match number of strings");
935 const MachOObjectFile::LoadCommandInfo &
Load,
936 uint32_t LoadCommandIndex,
const char *CmdName,
937 size_t SizeOfCmd,
const char *CmdStructName,
938 uint32_t PathOffset,
const char *PathFieldName) {
939 if (PathOffset < SizeOfCmd)
941 CmdName +
" " + PathFieldName +
".offset field too " 942 "small, not past the end of the " + CmdStructName);
943 if (PathOffset >= Load.C.cmdsize)
945 CmdName +
" " + PathFieldName +
".offset field " 946 "extends past the end of the load command");
950 const char *
P = (
const char *)Load.Ptr;
951 for (i = PathOffset; i < Load.C.cmdsize; i++)
954 if (i >= Load.C.cmdsize)
956 CmdName +
" " + PathFieldName +
" name extends past " 957 "the end of the load command");
962 const MachOObjectFile::LoadCommandInfo &
Load,
964 const char *CmdName) {
967 CmdName +
" cmdsize too small");
969 getStruct<MachO::thread_command>(Obj, Load.Ptr);
974 while (state < end) {
977 "flavor in " + CmdName +
" extends past end of " 987 " count in " + CmdName +
" extends past end of " 999 " count not x86_THREAD_STATE32_COUNT for " 1000 "flavor number " +
Twine(nflavor) +
" which is " 1001 "a x86_THREAD_STATE32 flavor in " + CmdName +
1005 " x86_THREAD_STATE32 extends past end of " 1006 "command in " + CmdName +
" command");
1010 " unknown flavor (" +
Twine(flavor) +
") for " 1011 "flavor number " +
Twine(nflavor) +
" in " +
1012 CmdName +
" command");
1018 " count not x86_THREAD_STATE_COUNT for " 1019 "flavor number " +
Twine(nflavor) +
" which is " 1020 "a x86_THREAD_STATE flavor in " + CmdName +
1024 " x86_THREAD_STATE extends past end of " 1025 "command in " + CmdName +
" command");
1030 " count not x86_FLOAT_STATE_COUNT for " 1031 "flavor number " +
Twine(nflavor) +
" which is " 1032 "a x86_FLOAT_STATE flavor in " + CmdName +
1036 " x86_FLOAT_STATE extends past end of " 1037 "command in " + CmdName +
" command");
1042 " count not x86_EXCEPTION_STATE_COUNT for " 1043 "flavor number " +
Twine(nflavor) +
" which is " 1044 "a x86_EXCEPTION_STATE flavor in " + CmdName +
1048 " x86_EXCEPTION_STATE extends past end of " 1049 "command in " + CmdName +
" command");
1054 " count not x86_THREAD_STATE64_COUNT for " 1055 "flavor number " +
Twine(nflavor) +
" which is " 1056 "a x86_THREAD_STATE64 flavor in " + CmdName +
1060 " x86_THREAD_STATE64 extends past end of " 1061 "command in " + CmdName +
" command");
1066 " count not x86_EXCEPTION_STATE64_COUNT for " 1067 "flavor number " +
Twine(nflavor) +
" which is " 1068 "a x86_EXCEPTION_STATE64 flavor in " + CmdName +
1072 " x86_EXCEPTION_STATE64 extends past end of " 1073 "command in " + CmdName +
" command");
1077 " unknown flavor (" +
Twine(flavor) +
") for " 1078 "flavor number " +
Twine(nflavor) +
" in " +
1079 CmdName +
" command");
1085 " count not ARM_THREAD_STATE_COUNT for " 1086 "flavor number " +
Twine(nflavor) +
" which is " 1087 "a ARM_THREAD_STATE flavor in " + CmdName +
1091 " ARM_THREAD_STATE extends past end of " 1092 "command in " + CmdName +
" command");
1096 " unknown flavor (" +
Twine(flavor) +
") for " 1097 "flavor number " +
Twine(nflavor) +
" in " +
1098 CmdName +
" command");
1104 " count not ARM_THREAD_STATE64_COUNT for " 1105 "flavor number " +
Twine(nflavor) +
" which is " 1106 "a ARM_THREAD_STATE64 flavor in " + CmdName +
1110 " ARM_THREAD_STATE64 extends past end of " 1111 "command in " + CmdName +
" command");
1115 " unknown flavor (" +
Twine(flavor) +
") for " 1116 "flavor number " +
Twine(nflavor) +
" in " +
1117 CmdName +
" command");
1123 " count not PPC_THREAD_STATE_COUNT for " 1124 "flavor number " +
Twine(nflavor) +
" which is " 1125 "a PPC_THREAD_STATE flavor in " + CmdName +
1129 " PPC_THREAD_STATE extends past end of " 1130 "command in " + CmdName +
" command");
1134 " unknown flavor (" +
Twine(flavor) +
") for " 1135 "flavor number " +
Twine(nflavor) +
" in " +
1136 CmdName +
" command");
1140 "command " +
Twine(LoadCommandIndex) +
" for " +
1141 CmdName +
" command can't be checked");
1149 const MachOObjectFile::LoadCommandInfo
1152 const char **LoadCmd,
1153 std::list<MachOElement> &Elements) {
1156 " LC_TWOLEVEL_HINTS has incorrect cmdsize");
1157 if (*LoadCmd !=
nullptr)
1158 return malformedError(
"more than one LC_TWOLEVEL_HINTS command");
1160 getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
1161 uint64_t FileSize = Obj.getData().size();
1162 if (Hints.
offset > FileSize)
1163 return malformedError(
"offset field of LC_TWOLEVEL_HINTS command " +
1164 Twine(LoadCommandIndex) +
" extends past the end of " 1166 uint64_t BigSize = Hints.
nhints;
1169 if (BigSize > FileSize)
1170 return malformedError(
"offset field plus nhints times sizeof(struct " 1171 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
1172 Twine(LoadCommandIndex) +
" extends past the end of " 1178 *LoadCmd = Load.Ptr;
1186 if (cmd == MachO::LC_SYMSEG ||
1187 cmd == MachO::LC_LOADFVMLIB ||
1188 cmd == MachO::LC_IDFVMLIB ||
1189 cmd == MachO::LC_IDENT ||
1190 cmd == MachO::LC_FVMFILE ||
1191 cmd == MachO::LC_PREPAGE ||
1192 cmd == MachO::LC_PREBOUND_DYLIB ||
1193 cmd == MachO::LC_TWOLEVEL_HINTS ||
1194 cmd == MachO::LC_PREBIND_CKSUM)
1201 bool Is64Bits,
uint32_t UniversalCputype,
1204 std::unique_ptr<MachOObjectFile> Obj(
1206 Is64Bits, Err, UniversalCputype,
1209 return std::move(Err);
1210 return std::move(Obj);
1213 MachOObjectFile::MachOObjectFile(
MemoryBufferRef Object,
bool IsLittleEndian,
1214 bool Is64bits,
Error &Err,
1217 :
ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
1219 uint64_t SizeOfHeaders;
1224 cputype = Header64.cputype;
1228 cputype = Header.cputype;
1232 SizeOfHeaders += getHeader().sizeofcmds;
1233 if (getData().data() + SizeOfHeaders > getData().
end()) {
1234 Err =
malformedError(
"load commands extend past the end of the file");
1237 if (UniversalCputype != 0 && cputype != UniversalCputype) {
1239 Twine(UniversalIndex) +
"'s cputype does not match " 1240 "object file's mach header");
1243 std::list<MachOElement> Elements;
1244 Elements.push_back({0, SizeOfHeaders,
"Mach-O headers"});
1246 uint32_t LoadCommandCount = getHeader().ncmds;
1248 if (LoadCommandCount != 0) {
1252 Err = LoadOrErr.takeError();
1257 const char *DyldIdLoadCmd =
nullptr;
1258 const char *FuncStartsLoadCmd =
nullptr;
1259 const char *SplitInfoLoadCmd =
nullptr;
1260 const char *CodeSignDrsLoadCmd =
nullptr;
1261 const char *CodeSignLoadCmd =
nullptr;
1262 const char *VersLoadCmd =
nullptr;
1263 const char *SourceLoadCmd =
nullptr;
1264 const char *EntryPointLoadCmd =
nullptr;
1265 const char *EncryptLoadCmd =
nullptr;
1266 const char *RoutinesLoadCmd =
nullptr;
1267 const char *UnixThreadLoadCmd =
nullptr;
1268 const char *TwoLevelHintsLoadCmd =
nullptr;
1269 for (
unsigned I = 0;
I < LoadCommandCount; ++
I) {
1276 Load.
C.
cmd != MachO::LC_THREAD || Load.
C.
cmdsize % 4) {
1289 LoadCommands.push_back(Load);
1290 if (Load.
C.
cmd == MachO::LC_SYMTAB) {
1293 }
else if (Load.
C.
cmd == MachO::LC_DYSYMTAB) {
1297 }
else if (Load.
C.
cmd == MachO::LC_DATA_IN_CODE) {
1299 "LC_DATA_IN_CODE", Elements,
1300 "data in code info")))
1302 }
else if (Load.
C.
cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
1304 "LC_LINKER_OPTIMIZATION_HINT",
1305 Elements,
"linker optimization " 1308 }
else if (Load.
C.
cmd == MachO::LC_FUNCTION_STARTS) {
1310 "LC_FUNCTION_STARTS", Elements,
1311 "function starts data")))
1313 }
else if (Load.
C.
cmd == MachO::LC_SEGMENT_SPLIT_INFO) {
1315 "LC_SEGMENT_SPLIT_INFO", Elements,
1316 "split info data")))
1318 }
else if (Load.
C.
cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) {
1320 "LC_DYLIB_CODE_SIGN_DRS", Elements,
1321 "code signing RDs data")))
1323 }
else if (Load.
C.
cmd == MachO::LC_CODE_SIGNATURE) {
1325 "LC_CODE_SIGNATURE", Elements,
1326 "code signature data")))
1328 }
else if (Load.
C.
cmd == MachO::LC_DYLD_INFO) {
1330 "LC_DYLD_INFO", Elements)))
1332 }
else if (Load.
C.
cmd == MachO::LC_DYLD_INFO_ONLY) {
1334 "LC_DYLD_INFO_ONLY", Elements)))
1336 }
else if (Load.
C.
cmd == MachO::LC_UUID) {
1346 UuidLoadCmd = Load.
Ptr;
1347 }
else if (Load.
C.
cmd == MachO::LC_SEGMENT_64) {
1350 *
this, Load, Sections, HasPageZeroSegment,
I,
1351 "LC_SEGMENT_64", SizeOfHeaders, Elements)))
1353 }
else if (Load.
C.
cmd == MachO::LC_SEGMENT) {
1356 *
this, Load, Sections, HasPageZeroSegment,
I,
1357 "LC_SEGMENT", SizeOfHeaders, Elements)))
1359 }
else if (Load.
C.
cmd == MachO::LC_ID_DYLIB) {
1362 }
else if (Load.
C.
cmd == MachO::LC_LOAD_DYLIB) {
1365 Libraries.push_back(Load.
Ptr);
1366 }
else if (Load.
C.
cmd == MachO::LC_LOAD_WEAK_DYLIB) {
1369 Libraries.push_back(Load.
Ptr);
1370 }
else if (Load.
C.
cmd == MachO::LC_LAZY_LOAD_DYLIB) {
1373 Libraries.push_back(Load.
Ptr);
1374 }
else if (Load.
C.
cmd == MachO::LC_REEXPORT_DYLIB) {
1377 Libraries.push_back(Load.
Ptr);
1378 }
else if (Load.
C.
cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
1381 Libraries.push_back(Load.
Ptr);
1382 }
else if (Load.
C.
cmd == MachO::LC_ID_DYLINKER) {
1385 }
else if (Load.
C.
cmd == MachO::LC_LOAD_DYLINKER) {
1388 }
else if (Load.
C.
cmd == MachO::LC_DYLD_ENVIRONMENT) {
1391 }
else if (Load.
C.
cmd == MachO::LC_VERSION_MIN_MACOSX) {
1393 "LC_VERSION_MIN_MACOSX")))
1395 }
else if (Load.
C.
cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
1397 "LC_VERSION_MIN_IPHONEOS")))
1399 }
else if (Load.
C.
cmd == MachO::LC_VERSION_MIN_TVOS) {
1401 "LC_VERSION_MIN_TVOS")))
1403 }
else if (Load.
C.
cmd == MachO::LC_VERSION_MIN_WATCHOS) {
1405 "LC_VERSION_MIN_WATCHOS")))
1407 }
else if (Load.
C.
cmd == MachO::LC_NOTE) {
1410 }
else if (Load.
C.
cmd == MachO::LC_BUILD_VERSION) {
1413 }
else if (Load.
C.
cmd == MachO::LC_RPATH) {
1416 }
else if (Load.
C.
cmd == MachO::LC_SOURCE_VERSION) {
1419 " has incorrect cmdsize");
1422 if (SourceLoadCmd) {
1426 SourceLoadCmd = Load.
Ptr;
1427 }
else if (Load.
C.
cmd == MachO::LC_MAIN) {
1430 " has incorrect cmdsize");
1433 if (EntryPointLoadCmd) {
1437 EntryPointLoadCmd = Load.
Ptr;
1438 }
else if (Load.
C.
cmd == MachO::LC_ENCRYPTION_INFO) {
1441 " has incorrect cmdsize");
1445 getStruct<MachO::encryption_info_command>(*
this, Load.
Ptr);
1447 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO")))
1449 }
else if (Load.
C.
cmd == MachO::LC_ENCRYPTION_INFO_64) {
1452 " has incorrect cmdsize");
1456 getStruct<MachO::encryption_info_command_64>(*
this, Load.
Ptr);
1458 &EncryptLoadCmd,
"LC_ENCRYPTION_INFO_64")))
1460 }
else if (Load.
C.
cmd == MachO::LC_LINKER_OPTION) {
1463 }
else if (Load.
C.
cmd == MachO::LC_SUB_FRAMEWORK) {
1466 " LC_SUB_FRAMEWORK cmdsize too small");
1470 getStruct<MachO::sub_framework_command>(*
this, Load.
Ptr);
1473 "sub_framework_command", S.
umbrella,
1476 }
else if (Load.
C.
cmd == MachO::LC_SUB_UMBRELLA) {
1479 " LC_SUB_UMBRELLA cmdsize too small");
1483 getStruct<MachO::sub_umbrella_command>(*
this, Load.
Ptr);
1489 }
else if (Load.
C.
cmd == MachO::LC_SUB_LIBRARY) {
1492 " LC_SUB_LIBRARY cmdsize too small");
1496 getStruct<MachO::sub_library_command>(*
this, Load.
Ptr);
1502 }
else if (Load.
C.
cmd == MachO::LC_SUB_CLIENT) {
1505 " LC_SUB_CLIENT cmdsize too small");
1509 getStruct<MachO::sub_client_command>(*
this, Load.
Ptr);
1512 "sub_client_command", S.
client,
"client")))
1514 }
else if (Load.
C.
cmd == MachO::LC_ROUTINES) {
1517 " has incorrect cmdsize");
1520 if (RoutinesLoadCmd) {
1521 Err =
malformedError(
"more than one LC_ROUTINES and or LC_ROUTINES_64 " 1525 RoutinesLoadCmd = Load.
Ptr;
1526 }
else if (Load.
C.
cmd == MachO::LC_ROUTINES_64) {
1529 " has incorrect cmdsize");
1532 if (RoutinesLoadCmd) {
1533 Err =
malformedError(
"more than one LC_ROUTINES_64 and or LC_ROUTINES " 1537 RoutinesLoadCmd = Load.
Ptr;
1538 }
else if (Load.
C.
cmd == MachO::LC_UNIXTHREAD) {
1541 if (UnixThreadLoadCmd) {
1545 UnixThreadLoadCmd = Load.
Ptr;
1546 }
else if (Load.
C.
cmd == MachO::LC_THREAD) {
1550 }
else if (Load.
C.
cmd == MachO::LC_TWOLEVEL_HINTS) {
1552 &TwoLevelHintsLoadCmd, Elements)))
1556 Twine(Load.
C.
cmd) +
" is obsolete and not " 1563 if (
I < LoadCommandCount - 1) {
1567 Err = LoadOrErr.takeError();
1572 if (!SymtabLoadCmd) {
1573 if (DysymtabLoadCmd) {
1574 Err =
malformedError(
"contains LC_DYSYMTAB load command without a " 1575 "LC_SYMTAB load command");
1578 }
else if (DysymtabLoadCmd) {
1580 getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
1582 getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
1583 if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.
nsyms) {
1585 "extends past the end of the symbol table");
1588 uint64_t BigSize = Dysymtab.ilocalsym;
1589 BigSize += Dysymtab.nlocalsym;
1590 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.
nsyms) {
1591 Err =
malformedError(
"ilocalsym plus nlocalsym in LC_DYSYMTAB load " 1592 "command extends past the end of the symbol table");
1595 if (Dysymtab.nextdefsym != 0 && Dysymtab.iextdefsym > Symtab.
nsyms) {
1597 "extends past the end of the symbol table");
1600 BigSize = Dysymtab.iextdefsym;
1601 BigSize += Dysymtab.nextdefsym;
1602 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.
nsyms) {
1603 Err =
malformedError(
"iextdefsym plus nextdefsym in LC_DYSYMTAB " 1604 "load command extends past the end of the symbol " 1608 if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.
nsyms) {
1610 "extends past the end of the symbol table");
1613 BigSize = Dysymtab.iundefsym;
1614 BigSize += Dysymtab.nundefsym;
1615 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.
nsyms) {
1616 Err =
malformedError(
"iundefsym plus nundefsym in LC_DYSYMTAB load " 1617 " command extends past the end of the symbol table");
1623 DyldIdLoadCmd ==
nullptr) {
1624 Err =
malformedError(
"no LC_ID_DYLIB load command in dynamic library " 1628 assert(LoadCommands.size() == LoadCommandCount);
1646 uint64_t NValue = 0;
1669 if (NSect == 0 || NSect > Sections.size())
1671 " for symbol at index " +
Twine(SymbolIndex));
1673 if ((NType & MachO::N_STAB) == 0 &&
1677 "the end of string table, for N_INDR symbol at " 1678 "index " +
Twine(SymbolIndex));
1681 (((NType & MachO::N_TYPE) ==
MachO::N_UNDF && NValue == 0) ||
1684 if (LibraryOrdinal != 0 &&
1687 LibraryOrdinal - 1 >= Libraries.size() ) {
1689 " for symbol at index " +
Twine(SymbolIndex));
1694 " past the end of string table, for symbol at " 1695 "index " +
Twine(SymbolIndex));
1702 unsigned SymbolTableEntrySize =
is64Bit() ?
1705 Symb.
p += SymbolTableEntrySize;
1709 StringRef StringTable = getStringTableData();
1715 const char *Start = &StringTable.
data()[Entry.
n_strx];
1716 if (Start < getData().
begin() || Start >= getData().
end()) {
1718 " for symbol at index " +
Twine(getSymbolIndex(Symb)));
1742 StringRef StringTable = getStringTableData();
1746 uint64_t NValue = getNValue(Symb);
1747 if (NValue >= StringTable.
size())
1749 const char *Start = &StringTable.
data()[NValue];
1751 return std::error_code();
1754 uint64_t MachOObjectFile::getSymbolValueImpl(
DataRefImpl Sym)
const {
1755 return getNValue(Sym);
1763 uint32_t flags = getSymbolFlags(DRI);
1772 return getNValue(DRI);
1778 uint8_t n_type = Entry.
n_type;
1792 if (Sec->isData() || Sec->isBSS())
1802 uint8_t MachOType = Entry.
n_type;
1803 uint16_t MachOFlags = Entry.
n_desc;
1841 uint8_t index = Entry.
n_sect;
1844 return section_end();
1846 DRI.
d.
a = index - 1;
1847 if (DRI.
d.
a >= Sections.size()){
1849 " for symbol at index " +
Twine(getSymbolIndex(Symb)));
1868 return std::error_code();
1873 return getSection64(Sec).addr;
1891 SectOffset = Sect.
offset;
1892 SectSize = Sect.
size;
1896 SectOffset = Sect.
offset;
1897 SectSize = Sect.
size;
1902 uint64_t FileSize = getData().size();
1903 if (SectOffset > FileSize)
1905 if (FileSize - SectOffset < SectSize)
1906 return FileSize - SectOffset;
1925 Res = this->getData().
substr(Offset, Size);
1926 return std::error_code();
1939 return uint64_t(1) <<
Align;
1943 if (SectionIndex < 1 || SectionIndex > Sections.size())
1947 DRI.
d.
a = SectionIndex - 1;
1954 if (std::error_code
E =
Section.getName(SecName))
1956 if (SecName == SectionName) {
2000 StringRef SegmentName = getSectionFinalSegmentName(Sec);
2002 if (!getSectionName(Sec, SectName))
2003 return (SegmentName ==
"__LLVM" && SectName ==
"__bitcode");
2009 return getSection64(Sec).offset == 0;
2078 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
2080 return getAnyRelocationAddress(RE);
2086 if (isRelocationScattered(RE))
2087 return symbol_end();
2089 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
2090 bool isExtern = getPlainRelocationExternal(RE);
2092 return symbol_end();
2095 unsigned SymbolTableEntrySize =
is64Bit() ?
2098 uint64_t
Offset = S.
symoff + SymbolIdx * SymbolTableEntrySize;
2100 Sym.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
2111 return getAnyRelocationType(RE);
2117 uint64_t RType = getRelocationType(Rel);
2119 unsigned Arch = this->getArch();
2123 static const char *
const Table[] = {
2124 "GENERIC_RELOC_VANILLA",
2125 "GENERIC_RELOC_PAIR",
2126 "GENERIC_RELOC_SECTDIFF",
2127 "GENERIC_RELOC_PB_LA_PTR",
2128 "GENERIC_RELOC_LOCAL_SECTDIFF",
2129 "GENERIC_RELOC_TLV" };
2138 static const char *
const Table[] = {
2139 "X86_64_RELOC_UNSIGNED",
2140 "X86_64_RELOC_SIGNED",
2141 "X86_64_RELOC_BRANCH",
2142 "X86_64_RELOC_GOT_LOAD",
2144 "X86_64_RELOC_SUBTRACTOR",
2145 "X86_64_RELOC_SIGNED_1",
2146 "X86_64_RELOC_SIGNED_2",
2147 "X86_64_RELOC_SIGNED_4",
2148 "X86_64_RELOC_TLV" };
2157 static const char *
const Table[] = {
2158 "ARM_RELOC_VANILLA",
2160 "ARM_RELOC_SECTDIFF",
2161 "ARM_RELOC_LOCAL_SECTDIFF",
2162 "ARM_RELOC_PB_LA_PTR",
2164 "ARM_THUMB_RELOC_BR22",
2165 "ARM_THUMB_32BIT_BRANCH",
2167 "ARM_RELOC_HALF_SECTDIFF" };
2176 static const char *
const Table[] = {
2177 "ARM64_RELOC_UNSIGNED",
"ARM64_RELOC_SUBTRACTOR",
2178 "ARM64_RELOC_BRANCH26",
"ARM64_RELOC_PAGE21",
2179 "ARM64_RELOC_PAGEOFF12",
"ARM64_RELOC_GOT_LOAD_PAGE21",
2180 "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_POINTER_TO_GOT",
2181 "ARM64_RELOC_TLVP_LOAD_PAGE21",
"ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2182 "ARM64_RELOC_ADDEND" 2192 static const char *
const Table[] = {
2193 "PPC_RELOC_VANILLA",
2201 "PPC_RELOC_SECTDIFF",
2202 "PPC_RELOC_PB_LA_PTR",
2203 "PPC_RELOC_HI16_SECTDIFF",
2204 "PPC_RELOC_LO16_SECTDIFF",
2205 "PPC_RELOC_HA16_SECTDIFF",
2207 "PPC_RELOC_LO14_SECTDIFF",
2208 "PPC_RELOC_LOCAL_SECTDIFF" };
2225 return getAnyRelocationLength(RE);
2259 StringRef Foo,
F, DotFramework, V, Dylib, Lib, Dot, Qtx;
2260 size_t a, b, c, d, Idx;
2262 isFramework =
false;
2266 a = Name.
rfind(
'/');
2267 if (a == Name.
npos || a == 0)
2272 Idx = Foo.
rfind(
'_');
2273 if (Idx != Foo.
npos && Foo.
size() >= 2) {
2275 Foo = Foo.
slice(0, Idx);
2279 b = Name.
rfind(
'/', a);
2285 DotFramework = Name.
slice(Idx + Foo.
size(),
2286 Idx + Foo.
size() +
sizeof(
".framework/")-1);
2287 if (F == Foo && DotFramework ==
".framework/") {
2295 c = Name.
rfind(
'/', b);
2296 if (c == Name.
npos || c == 0)
2301 d = Name.
rfind(
'/', c);
2307 DotFramework = Name.
slice(Idx + Foo.
size(),
2308 Idx + Foo.
size() +
sizeof(
".framework/")-1);
2309 if (F == Foo && DotFramework ==
".framework/") {
2316 a = Name.
rfind(
'.');
2317 if (a == Name.
npos || a == 0)
2320 if (Dylib !=
".dylib")
2325 Dot = Name.
slice(a-2, a-1);
2330 b = Name.
rfind(
'/', a);
2336 Idx = Name.
find(
'_', b);
2337 if (Idx != Name.
npos && Idx != b) {
2338 Lib = Name.
slice(b, Idx);
2339 Suffix = Name.
slice(Idx, a);
2342 Lib = Name.
slice(b, a);
2345 if (Lib.
size() >= 3) {
2356 b = Name.
rfind(
'/', a);
2358 Lib = Name.
slice(0, a);
2360 Lib = Name.
slice(b+1, a);
2362 if (Lib.
size() >= 3) {
2377 if (Index >= Libraries.size())
2382 if (LibrariesShortNames.size() == 0) {
2383 for (
unsigned i = 0; i < Libraries.size(); i++) {
2385 getStruct<MachO::dylib_command>(*
this, Libraries[i]);
2388 const char *
P = (
const char *)(Libraries[i]) + D.
dylib.
name;
2394 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
2395 if (shortName.
empty())
2396 LibrariesShortNames.push_back(Name);
2398 LibrariesShortNames.push_back(shortName);
2402 Res = LibrariesShortNames[
Index];
2403 return std::error_code();
2407 return Libraries.size();
2413 Sec.
d.
a = Rel->getRawDataRefImpl().d.a;
2420 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2423 return getSymbolByIndex(0);
2429 if (!SymtabLoadCmd || Symtab.
nsyms == 0)
2432 unsigned SymbolTableEntrySize =
is64Bit() ?
2436 Symtab.
nsyms * SymbolTableEntrySize;
2437 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
2443 if (!SymtabLoadCmd || Index >= Symtab.
nsyms)
2445 unsigned SymbolTableEntrySize =
2448 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2449 DRI.
p += Index * SymbolTableEntrySize;
2457 unsigned SymbolTableEntrySize =
2460 DRIstart.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Symtab.
symoff));
2461 uint64_t
Index = (Symb.
p - DRIstart.
p) / SymbolTableEntrySize;
2472 DRI.
d.
a = Sections.size();
2485 return "Mach-O 32-bit i386";
2487 return "Mach-O arm";
2489 return "Mach-O 32-bit ppc";
2491 return "Mach-O 32-bit unknown";
2497 return "Mach-O 64-bit x86-64";
2499 return "Mach-O arm64";
2501 return "Mach-O 64-bit ppc64";
2503 return "Mach-O 64-bit unknown";
2527 const char **McpuDefault,
2528 const char **ArchFlag) {
2530 *McpuDefault =
nullptr;
2532 *ArchFlag =
nullptr;
2540 return Triple(
"i386-apple-darwin");
2548 *ArchFlag =
"x86_64";
2549 return Triple(
"x86_64-apple-darwin");
2552 *ArchFlag =
"x86_64h";
2553 return Triple(
"x86_64h-apple-darwin");
2561 *ArchFlag =
"armv4t";
2562 return Triple(
"armv4t-apple-darwin");
2565 *ArchFlag =
"armv5e";
2566 return Triple(
"armv5e-apple-darwin");
2569 *ArchFlag =
"xscale";
2570 return Triple(
"xscale-apple-darwin");
2573 *ArchFlag =
"armv6";
2574 return Triple(
"armv6-apple-darwin");
2577 *McpuDefault =
"cortex-m0";
2579 *ArchFlag =
"armv6m";
2580 return Triple(
"armv6m-apple-darwin");
2583 *ArchFlag =
"armv7";
2584 return Triple(
"armv7-apple-darwin");
2587 *McpuDefault =
"cortex-m4";
2589 *ArchFlag =
"armv7em";
2590 return Triple(
"thumbv7em-apple-darwin");
2593 *McpuDefault =
"cortex-a7";
2595 *ArchFlag =
"armv7k";
2596 return Triple(
"armv7k-apple-darwin");
2599 *McpuDefault =
"cortex-m3";
2601 *ArchFlag =
"armv7m";
2602 return Triple(
"thumbv7m-apple-darwin");
2605 *McpuDefault =
"cortex-a7";
2607 *ArchFlag =
"armv7s";
2608 return Triple(
"armv7s-apple-darwin");
2616 *McpuDefault =
"cyclone";
2618 *ArchFlag =
"arm64";
2619 return Triple(
"arm64-apple-darwin");
2628 return Triple(
"ppc-apple-darwin");
2636 *ArchFlag =
"ppc64";
2637 return Triple(
"ppc64-apple-darwin");
2653 .
Case(
"x86_64",
true)
2654 .
Case(
"x86_64h",
true)
2655 .
Case(
"armv4t",
true)
2657 .
Case(
"armv5e",
true)
2658 .
Case(
"armv6",
true)
2659 .
Case(
"armv6m",
true)
2660 .
Case(
"armv7",
true)
2661 .
Case(
"armv7em",
true)
2662 .
Case(
"armv7k",
true)
2663 .
Case(
"armv7m",
true)
2664 .
Case(
"armv7s",
true)
2665 .
Case(
"arm64",
true)
2667 .
Case(
"ppc64",
true)
2676 return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
2682 return section_rel_begin(DRI);
2688 return section_rel_end(DRI);
2693 if (!DataInCodeLoadCmd)
2697 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, DicLC.
dataoff));
2703 if (!DataInCodeLoadCmd)
2708 DRI.
p =
reinterpret_cast<uintptr_t
>(
getPtr(*
this, Offset));
2715 void ExportEntry::moveToFirst() {
2720 pushDownUntilBottom();
2723 void ExportEntry::moveToEnd() {
2730 if (Done || Other.Done)
2731 return (Done == Other.Done);
2733 if (Stack.
size() != Other.Stack.
size())
2736 if (!CumulativeString.
equals(Other.CumulativeString))
2739 for (
unsigned i=0; i < Stack.
size(); ++i) {
2740 if (Stack[i].Start != Other.Stack[i].Start)
2750 if (Ptr > Trie.
end())
2756 return CumulativeString;
2760 return Stack.
back().Flags;
2764 return Stack.
back().Address;
2768 return Stack.
back().Other;
2772 const char* ImportName = Stack.
back().ImportName;
2779 return Stack.
back().Start - Trie.
begin();
2782 ExportEntry::NodeState::NodeState(
const uint8_t *Ptr)
2783 : Start(Ptr), Current(Ptr) {}
2785 void ExportEntry::pushNode(uint64_t offset) {
2787 const uint8_t *Ptr = Trie.
begin() + offset;
2788 NodeState State(Ptr);
2790 uint64_t ExportInfoSize =
readULEB128(State.Current, &error);
2793 " in export trie data at node: 0x" +
2798 State.IsExportNode = (ExportInfoSize != 0);
2799 const uint8_t* Children = State.Current + ExportInfoSize;
2800 if (Children > Trie.
end()) {
2804 " too big and extends past end of trie data");
2808 if (State.IsExportNode) {
2809 const uint8_t *ExportStart = State.Current;
2813 " in export trie data at node: 0x" +
2819 if (State.Flags != 0 &&
2824 "unsupported exported symbol kind: " +
Twine((
int)Kind) +
2835 " in export trie data at node: 0x" +
2841 if (State.Other >
O->getLibraryCount()) {
2843 "bad library ordinal: " +
Twine((
int)State.Other) +
" (max " +
2844 Twine((
int)
O->getLibraryCount()) +
2850 State.ImportName =
reinterpret_cast<const char*
>(State.Current);
2851 if (*State.ImportName ==
'\0') {
2854 const uint8_t *End = State.Current + 1;
2855 if (End >= Trie.
end()) {
2856 *
E =
malformedError(
"import name of re-export in export trie data at " 2859 " starts past end of trie data");
2863 while(*End !=
'\0' && End < Trie.
end())
2866 *
E =
malformedError(
"import name of re-export in export trie data at " 2869 " extends past end of trie data");
2873 State.Current = End + 1;
2876 State.Address =
readULEB128(State.Current, &error);
2879 " in export trie data at node: 0x" +
2888 " in export trie data at node: 0x" +
2895 if(ExportStart + ExportInfoSize != State.Current) {
2897 "inconsistant export info size: 0x" +
2905 State.ChildCount = *Children;
2906 if (State.ChildCount != 0 && Children + 1 >= Trie.
end()) {
2907 *
E =
malformedError(
"byte for count of childern in export trie data at " 2910 " extends past end of trie data");
2914 State.Current = Children + 1;
2915 State.NextChildIndex = 0;
2916 State.ParentStringLength = CumulativeString.
size();
2920 void ExportEntry::pushDownUntilBottom() {
2923 while (Stack.
back().NextChildIndex < Stack.
back().ChildCount) {
2924 NodeState &Top = Stack.
back();
2925 CumulativeString.
resize(Top.ParentStringLength);
2926 for (;*Top.Current != 0 && Top.Current < Trie.
end(); Top.Current++) {
2927 char C = *Top.Current;
2930 if (Top.Current >= Trie.
end()) {
2931 *
E =
malformedError(
"edge sub-string in export trie data at node: 0x" +
2933 " for child #" +
Twine((
int)Top.NextChildIndex) +
2934 " extends past end of trie data");
2939 uint64_t childNodeIndex =
readULEB128(Top.Current, &error);
2942 " in export trie data at node: 0x" +
2947 for (
const NodeState &node :
nodes()) {
2948 if (node.Start == Trie.
begin() + childNodeIndex){
2949 *
E =
malformedError(
"loop in childern in export trie data at node: 0x" +
2951 " back to node: 0x" +
2957 Top.NextChildIndex += 1;
2958 pushNode(childNodeIndex);
2962 if (!Stack.
back().IsExportNode) {
2963 *
E =
malformedError(
"node is not an export node in export trie data at " 2987 assert(!Stack.
empty() &&
"ExportEntry::moveNext() with empty node stack");
2988 if (!Stack.
back().IsExportNode) {
2989 *
E =
malformedError(
"node is not an export node in export trie data at " 2997 while (!Stack.
empty()) {
2998 NodeState &Top = Stack.
back();
2999 if (Top.NextChildIndex < Top.ChildCount) {
3000 pushDownUntilBottom();
3004 if (Top.IsExportNode) {
3006 CumulativeString.
resize(Top.ParentStringLength);
3022 Start.moveToFirst();
3031 return exports(Err, getDyldInfoExportsTrie(),
this);
3036 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.
begin()),
3037 PointerSize(is64Bit ? 8 : 4) {}
3039 void MachORebaseEntry::moveToFirst() {
3040 Ptr = Opcodes.
begin();
3044 void MachORebaseEntry::moveToEnd() {
3045 Ptr = Opcodes.
end();
3046 RemainingLoopCount = 0;
3054 if (RemainingLoopCount) {
3055 --RemainingLoopCount;
3061 if (Ptr == Opcodes.
end()) {
3068 const uint8_t *OpcodeStart = Ptr;
3069 uint8_t Byte = *Ptr++;
3073 const char *error =
nullptr;
3084 *E =
malformedError(
"for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " +
3092 dbgs() <<
"REBASE_OPCODE_SET_TYPE_IMM: " 3093 <<
"RebaseType=" << (
int)
RebaseType <<
"\n");
3096 SegmentIndex = ImmValue;
3099 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3100 Twine(error) +
" for opcode at: 0x" +
3108 *E =
malformedError(
"for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3109 Twine(error) +
" for opcode at: 0x" +
3116 dbgs() <<
"REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3117 <<
"SegmentIndex=" << SegmentIndex <<
", " 3125 " for opcode at: 0x" +
3134 " for opcode at: 0x" +
3140 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_ULEB: " 3141 <<
format(
"SegmentOffset=0x%06X",
3149 Twine(error) +
" for opcode at: 0x" +
3160 " (after adding immediate times the pointer size) " +
3161 Twine(error) +
" for opcode at: 0x" +
3167 dbgs() <<
"REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 3168 <<
format(
"SegmentOffset=0x%06X",
3176 Twine(error) +
" for opcode at: 0x" +
3181 AdvanceAmount = PointerSize;
3185 RemainingLoopCount = ImmValue - 1;
3187 RemainingLoopCount = 0;
3192 Twine(error) +
" for opcode at: 0x" +
3199 dbgs() <<
"REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 3201 <<
", AdvanceAmount=" << AdvanceAmount
3202 <<
", RemainingLoopCount=" << RemainingLoopCount
3210 Twine(error) +
" for opcode at: 0x" +
3215 AdvanceAmount = PointerSize;
3220 Twine(error) +
" for opcode at: 0x" +
3226 RemainingLoopCount = Count - 1;
3228 RemainingLoopCount = 0;
3233 Twine(error) +
" for opcode at: 0x" +
3240 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 3242 <<
", AdvanceAmount=" << AdvanceAmount
3243 <<
", RemainingLoopCount=" << RemainingLoopCount
3250 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3251 Twine(error) +
" for opcode at: 0x" +
3258 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3259 Twine(error) +
" for opcode at: 0x" +
3264 AdvanceAmount = Skip + PointerSize;
3266 RemainingLoopCount = 0;
3270 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " +
3271 Twine(error) +
" for opcode at: 0x" +
3278 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 3280 <<
", AdvanceAmount=" << AdvanceAmount
3281 <<
", RemainingLoopCount=" << RemainingLoopCount
3288 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3290 Twine(error) +
" for opcode at: 0x" +
3297 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3299 Twine(error) +
" for opcode at: 0x" +
3305 RemainingLoopCount = Count - 1;
3307 RemainingLoopCount = 0;
3310 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3312 Twine(error) +
" for opcode at: 0x" +
3317 AdvanceAmount = Skip + PointerSize;
3322 *E =
malformedError(
"for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3324 Twine(error) +
" for opcode at: 0x" +
3331 dbgs() <<
"REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 3333 <<
", AdvanceAmount=" << AdvanceAmount
3334 <<
", RemainingLoopCount=" << RemainingLoopCount
3351 if (Ptr > Opcodes.
end())
3352 Ptr = Opcodes.
end();
3365 return "text abs32";
3367 return "text rel32";
3391 #ifdef EXPENSIVE_CHECKS 3392 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
3394 assert(Opcodes.
data() == Other.Opcodes.
data() &&
"compare iterators of different files");
3396 return (Ptr == Other.Ptr) &&
3397 (RemainingLoopCount == Other.RemainingLoopCount) &&
3398 (Done == Other.Done);
3404 if (O->BindRebaseSectionTable ==
nullptr)
3405 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(
O);
3407 Start.moveToFirst();
3416 return rebaseTable(Err,
this, getDyldInfoRebaseOpcodes(),
is64Bit());
3421 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.
begin()),
3422 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {}
3424 void MachOBindEntry::moveToFirst() {
3425 Ptr = Opcodes.
begin();
3429 void MachOBindEntry::moveToEnd() {
3430 Ptr = Opcodes.
end();
3431 RemainingLoopCount = 0;
3439 if (RemainingLoopCount) {
3440 --RemainingLoopCount;
3446 if (Ptr == Opcodes.
end()) {
3453 const uint8_t *OpcodeStart = Ptr;
3454 uint8_t Byte = *Ptr++;
3457 int8_t SignExtended;
3458 const uint8_t *SymStart;
3460 const char *error =
nullptr;
3466 bool NotLastEntry =
false;
3467 for (
const uint8_t *
P = Ptr;
P < Opcodes.
end(); ++
P) {
3469 NotLastEntry =
true;
3481 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in " 3482 "weak bind table for opcode at: 0x" +
3488 LibraryOrdinalSet =
true;
3490 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3491 "library ordinal: " +
3492 Twine((
int)ImmValue) +
" (max " +
3494 ") for opcode at: 0x" +
3501 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 3502 <<
"Ordinal=" << Ordinal <<
"\n");
3506 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in " 3507 "weak bind table for opcode at: 0x" +
3513 LibraryOrdinalSet =
true;
3516 Twine(error) +
" for opcode at: 0x" +
3522 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3523 "library ordinal: " +
3524 Twine((
int)Ordinal) +
" (max " +
3526 ") for opcode at: 0x" +
3533 dbgs() <<
"BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 3534 <<
"Ordinal=" << Ordinal <<
"\n");
3538 *E =
malformedError(
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in " 3539 "weak bind table for opcode at: 0x" +
3545 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
3546 Ordinal = SignExtended;
3548 *E =
malformedError(
"for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown " 3549 "special ordinal: " +
3550 Twine((
int)Ordinal) +
" for opcode at: 0x" +
3557 LibraryOrdinalSet =
true;
3560 dbgs() <<
"BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 3561 <<
"Ordinal=" << Ordinal <<
"\n");
3566 while (*Ptr && (Ptr < Opcodes.
end())) {
3569 if (Ptr == Opcodes.
end()) {
3571 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM " 3572 "symbol name extends past opcodes for opcode at: 0x" +
3582 dbgs() <<
"BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 3592 *E =
malformedError(
"for BIND_OPCODE_SET_TYPE_IMM bad bind type: " +
3593 Twine((
int)ImmValue) +
" for opcode at: 0x" +
3600 dbgs() <<
"BIND_OPCODE_SET_TYPE_IMM: " 3601 <<
"BindType=" << (
int)
BindType <<
"\n");
3604 Addend = readSLEB128(&error);
3607 " for opcode at: 0x" +
3614 dbgs() <<
"BIND_OPCODE_SET_ADDEND_SLEB: " 3615 <<
"Addend=" << Addend <<
"\n");
3618 SegmentIndex = ImmValue;
3621 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3622 Twine(error) +
" for opcode at: 0x" +
3629 *E =
malformedError(
"for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " +
3630 Twine(error) +
" for opcode at: 0x" +
3637 dbgs() <<
"BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3638 <<
"SegmentIndex=" << SegmentIndex <<
", " 3646 " for opcode at: 0x" +
3654 " for opcode at: 0x" +
3660 dbgs() <<
"BIND_OPCODE_ADD_ADDR_ULEB: " 3661 <<
format(
"SegmentOffset=0x%06X",
3665 AdvanceAmount = PointerSize;
3666 RemainingLoopCount = 0;
3670 " for opcode at: 0x" +
3677 "for BIND_OPCODE_DO_BIND missing preceding " 3678 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" +
3683 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
3686 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3692 dbgs() <<
"BIND_OPCODE_DO_BIND: " 3693 <<
format(
"SegmentOffset=0x%06X",
3698 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in " 3699 "lazy bind table for opcode at: 0x" +
3707 Twine(error) +
" for opcode at: 0x" +
3714 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3715 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode " 3721 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
3723 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3724 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" +
3729 AdvanceAmount =
readULEB128(&error) + PointerSize;
3732 Twine(error) +
" for opcode at: 0x" +
3741 AdvanceAmount,
false);
3743 *E =
malformedError(
"for BIND_OPCODE_ADD_ADDR_ULEB (after adding " 3745 Twine(error) +
" for opcode at: 0x" +
3750 RemainingLoopCount = 0;
3753 dbgs() <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 3755 <<
", AdvanceAmount=" << AdvanceAmount
3756 <<
", RemainingLoopCount=" << RemainingLoopCount
3761 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not " 3762 "allowed in lazy bind table for opcode at: 0x" +
3769 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
3770 Twine(error) +
" for opcode at: 0x" +
3777 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3778 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3784 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
3786 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3787 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3793 AdvanceAmount = ImmValue * PointerSize + PointerSize;
3794 RemainingLoopCount = 0;
3796 AdvanceAmount,
false);
3800 " (after adding immediate times the pointer size) " +
3801 Twine(error) +
" for opcode at: 0x" +
3808 <<
"BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 3813 *E =
malformedError(
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not " 3814 "allowed in lazy bind table for opcode at: 0x" +
3821 RemainingLoopCount = Count - 1;
3823 RemainingLoopCount = 0;
3825 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3827 Twine(error) +
" for opcode at: 0x" +
3833 AdvanceAmount = Skip + PointerSize;
3835 *E =
malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3837 Twine(error) +
" for opcode at: 0x" +
3845 malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3846 Twine(error) +
" for opcode at: 0x" +
3853 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3854 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3860 if (!LibraryOrdinalSet && TableKind !=
Kind::Weak) {
3862 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3863 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3873 malformedError(
"for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " +
3874 Twine(error) +
" for opcode at: 0x" +
3881 dbgs() <<
"BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 3883 <<
", AdvanceAmount=" << AdvanceAmount
3884 <<
", RemainingLoopCount=" << RemainingLoopCount
3901 if (Ptr > Opcodes.
end())
3902 Ptr = Opcodes.
end();
3906 int64_t MachOBindEntry::readSLEB128(
const char **error) {
3910 if (Ptr > Opcodes.
end())
3911 Ptr = Opcodes.
end();
3924 return "text abs32";
3926 return "text rel32";
3958 #ifdef EXPENSIVE_CHECKS 3959 assert(Opcodes == Other.Opcodes &&
"compare iterators of different files");
3961 assert(Opcodes.
data() == Other.Opcodes.
data() &&
"compare iterators of different files");
3963 return (Ptr == Other.Ptr) &&
3964 (RemainingLoopCount == Other.RemainingLoopCount) &&
3965 (Done == Other.Done);
3972 uint64_t CurSegAddress;
3975 Section.getName(Info.SectionName);
3976 Info.Address =
Section.getAddress();
3977 Info.Size =
Section.getSize();
3980 if (!Info.SegmentName.equals(CurSegName)) {
3982 CurSegName = Info.SegmentName;
3983 CurSegAddress = Info.Address;
3985 Info.SegmentIndex = CurSegIndex - 1;
3986 Info.OffsetInSegment = Info.Address - CurSegAddress;
3987 Info.SegmentStartAddress = CurSegAddress;
3988 Sections.push_back(Info);
3990 MaxSegIndex = CurSegIndex;
3999 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
4000 if (SegIndex >= MaxSegIndex)
4001 return "bad segIndex (too large)";
4002 for (
const SectionInfo &
SI : Sections) {
4003 if (
SI.SegmentIndex != SegIndex)
4005 if (
SI.OffsetInSegment > SegOffset)
4007 if (SegOffset > (
SI.OffsetInSegment +
SI.Size))
4009 if (endInvalid && SegOffset >= (
SI.OffsetInSegment +
SI.Size))
4013 return "bad segOffset, too large";
4022 uint8_t PointerSize,
4024 uint64_t SegOffset) {
4025 const SectionInfo &
SI = findSection(SegIndex, SegOffset);
4026 uint64_t addr = SI.SegmentStartAddress + SegOffset;
4027 if (addr >= SI.Address + SI.Size)
4028 return "bad segOffset, too large";
4031 i = (Skip + PointerSize) * (Count - 1);
4032 else if (Count == 1)
4033 i = Skip + PointerSize;
4034 if (addr + i >= SI.Address + SI.Size) {
4036 uint64_t TrailingSegOffset = (addr + i) - SI.SegmentStartAddress;
4037 const char *error = checkSegAndOffset(SegIndex, TrailingSegOffset,
false);
4039 return "bad count and skip, too large";
4047 for (
const SectionInfo &
SI : Sections) {
4048 if (
SI.SegmentIndex == SegIndex)
4049 return SI.SegmentName;
4056 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection(
4057 int32_t SegIndex, uint64_t SegOffset) {
4058 for (
const SectionInfo &
SI : Sections) {
4059 if (
SI.SegmentIndex != SegIndex)
4061 if (
SI.OffsetInSegment > SegOffset)
4063 if (SegOffset >= (
SI.OffsetInSegment +
SI.Size))
4073 uint64_t SegOffset) {
4074 return findSection(SegIndex, SegOffset).SectionName;
4080 const SectionInfo &
SI = findSection(SegIndex, OffsetInSeg);
4081 return SI.SegmentStartAddress + OffsetInSeg;
4088 if (O->BindRebaseSectionTable ==
nullptr)
4089 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(
O);
4091 Start.moveToFirst();
4100 return bindTable(Err,
this, getDyldInfoBindOpcodes(),
is64Bit(),
4105 return bindTable(Err,
this, getDyldInfoLazyBindOpcodes(),
is64Bit(),
4110 return bindTable(Err,
this, getDyldInfoWeakBindOpcodes(),
is64Bit(),
4116 return LoadCommands.begin();
4121 return LoadCommands.end();
4126 return make_range(begin_load_commands(), end_load_commands());
4137 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4138 const section_base *
Base =
4139 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4145 assert(Sec.
d.
a < Sections.size() &&
"Should have detected this earlier");
4146 const section_base *
Base =
4147 reinterpret_cast<const section_base *
>(Sections[Sec.
d.
a]);
4161 if (isLittleEndian())
4168 if (isLittleEndian())
4169 return (RE.
r_word1 >> 27) & 1;
4185 return (RE.
r_word0 >> 24) & 0xf;
4190 if (isRelocationScattered(RE))
4197 if (isRelocationScattered(RE))
4204 if (isRelocationScattered(RE))
4212 if (isRelocationScattered(RE))
4213 return getScatteredRelocationType(RE);
4220 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
4221 return *section_end();
4222 unsigned SecNum = getPlainRelocationSymbolNum(RE);
4223 if (SecNum ==
MachO::R_ABS || SecNum > Sections.size())
4224 return *section_end();
4226 DRI.
d.
a = SecNum - 1;
4231 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4232 return getStruct<MachO::section>(*
this, Sections[DRI.
d.
a]);
4236 assert(DRI.
d.
a < Sections.size() &&
"Should have detected this earlier");
4237 return getStruct<MachO::section_64>(*
this, Sections[DRI.
d.
a]);
4241 unsigned Index)
const {
4243 return getStruct<MachO::section>(*
this, Sec);
4247 unsigned Index)
const {
4249 return getStruct<MachO::section_64>(*
this, Sec);
4254 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4255 return getStruct<MachO::nlist>(*
this,
P);
4260 const char *
P =
reinterpret_cast<const char *
>(DRI.
p);
4261 return getStruct<MachO::nlist_64>(*
this,
P);
4266 return getStruct<MachO::linkedit_data_command>(*
this, L.
Ptr);
4271 return getStruct<MachO::segment_command>(*
this, L.
Ptr);
4276 return getStruct<MachO::segment_command_64>(*
this, L.
Ptr);
4281 return getStruct<MachO::linker_option_command>(*
this, L.
Ptr);
4286 return getStruct<MachO::version_min_command>(*
this, L.
Ptr);
4291 return getStruct<MachO::note_command>(*
this, L.
Ptr);
4296 return getStruct<MachO::build_version_command>(*
this, L.
Ptr);
4301 return getStruct<MachO::build_tool_version>(*
this, BuildTools[index]);
4306 return getStruct<MachO::dylib_command>(*
this, L.
Ptr);
4311 return getStruct<MachO::dyld_info_command>(*
this, L.
Ptr);
4316 return getStruct<MachO::dylinker_command>(*
this, L.
Ptr);
4321 return getStruct<MachO::uuid_command>(*
this, L.
Ptr);
4326 return getStruct<MachO::rpath_command>(*
this, L.
Ptr);
4331 return getStruct<MachO::source_version_command>(*
this, L.
Ptr);
4336 return getStruct<MachO::entry_point_command>(*
this, L.
Ptr);
4341 return getStruct<MachO::encryption_info_command>(*
this, L.
Ptr);
4346 return getStruct<MachO::encryption_info_command_64>(*
this, L.
Ptr);
4351 return getStruct<MachO::sub_framework_command>(*
this, L.
Ptr);
4356 return getStruct<MachO::sub_umbrella_command>(*
this, L.
Ptr);
4361 return getStruct<MachO::sub_library_command>(*
this, L.
Ptr);
4366 return getStruct<MachO::sub_client_command>(*
this, L.
Ptr);
4371 return getStruct<MachO::routines_command>(*
this, L.
Ptr);
4376 return getStruct<MachO::routines_command_64>(*
this, L.
Ptr);
4381 return getStruct<MachO::thread_command>(*
this, L.
Ptr);
4407 return getStruct<MachO::any_relocation_info>(
4408 *
this, reinterpret_cast<const char *>(
P));
4413 const char *
P =
reinterpret_cast<const char *
>(Rel.
p);
4414 return getStruct<MachO::data_in_code_entry>(*
this,
P);
4428 unsigned Index)
const {
4430 return getStruct<uint32_t>(*
this,
getPtr(*
this, Offset));
4435 unsigned Index)
const {
4437 return getStruct<MachO::data_in_code_entry>(*
this,
getPtr(*
this, Offset));
4442 return getStruct<MachO::symtab_command>(*
this, SymtabLoadCmd);
4446 Cmd.
cmd = MachO::LC_SYMTAB;
4456 if (DysymtabLoadCmd)
4457 return getStruct<MachO::dysymtab_command>(*
this, DysymtabLoadCmd);
4461 Cmd.
cmd = MachO::LC_DYSYMTAB;
4473 Cmd.extrefsymoff = 0;
4474 Cmd.nextrefsyms = 0;
4475 Cmd.indirectsymoff = 0;
4476 Cmd.nindirectsyms = 0;
4486 if (DataInCodeLoadCmd)
4487 return getStruct<MachO::linkedit_data_command>(*
this, DataInCodeLoadCmd);
4491 Cmd.
cmd = MachO::LC_DATA_IN_CODE;
4500 if (LinkOptHintsLoadCmd)
4501 return getStruct<MachO::linkedit_data_command>(*
this, LinkOptHintsLoadCmd);
4506 Cmd.
cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
4514 if (!DyldInfoLoadCmd)
4518 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4519 const uint8_t *Ptr =
4525 if (!DyldInfoLoadCmd)
4529 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4530 const uint8_t *Ptr =
4531 reinterpret_cast<const uint8_t *
>(
getPtr(*
this, DyldInfo.
bind_off));
4536 if (!DyldInfoLoadCmd)
4540 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4541 const uint8_t *Ptr =
4547 if (!DyldInfoLoadCmd)
4551 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4552 const uint8_t *Ptr =
4558 if (!DyldInfoLoadCmd)
4562 getStruct<MachO::dyld_info_command>(*
this, DyldInfoLoadCmd);
4563 const uint8_t *Ptr =
4573 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16);
4582 return getType() == getMachOType(
false,
true) ||
4583 getType() == getMachOType(
true,
true);
4592 while (uint64_t delta = extractor.
getULEB128(&offset)) {
4607 if (Magic ==
"\xFE\xED\xFA\xCE")
4609 UniversalCputype, UniversalIndex);
4610 if (Magic ==
"\xCE\xFA\xED\xFE")
4612 UniversalCputype, UniversalIndex);
4613 if (Magic ==
"\xFE\xED\xFA\xCF")
4615 UniversalCputype, UniversalIndex);
4616 if (Magic ==
"\xCF\xFA\xED\xFE")
4618 UniversalCputype, UniversalIndex);
4619 return make_error<GenericBinaryError>(
"Unrecognized MachO magic number",
4625 .Case(
"debug_str_offs",
"debug_str_offsets")
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
content_iterator< ExportEntry > export_iterator
relocation_iterator locrel_end() const
const char * BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset, bool endInvalid) const
For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to validate a MachOBindEntry...
static unsigned getScatteredRelocationLength(const MachO::any_relocation_info &RE)
MachO::linkedit_data_command getLinkeditDataLoadCommand(const LoadCommandInfo &L) const
MachO::segment_command getSegmentLoadCommand(const LoadCommandInfo &L) const
const_iterator end(StringRef path)
Get end iterator over path.
void swapStruct(fat_header &mh)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
const uint32_t x86_FLOAT_STATE_COUNT
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout)
static bool getScatteredRelocationPCRel(const MachO::any_relocation_info &RE)
MachO::symtab_command getSymtabLoadCommand() const
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static const char * getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, unsigned Sec)
void swapByteOrder(T &Value)
StringRef BindRebaseSegmentName(int32_t SegIndex) const
For use with the SegIndex of a checked Mach-O Bind or Rebase entry to get the segment name...
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const uint32_t x86_EXCEPTION_STATE64_COUNT
static Error parseSegmentLoadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char *> &Sections, bool &IsPageZeroSegment, uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders, std::list< MachOElement > &Elements)
static Error parseBuildVersionCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, SmallVectorImpl< const char *> &BuildTools, uint32_t LoadCommandIndex)
StringRef sectionName() const
int32_t segmentIndex() const
MachO::encryption_info_command getEncryptionInfoCommand(const LoadCommandInfo &L) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
StringRef getFileFormatName() const override
uint64_t getRelocationOffset(DataRefImpl Rel) const override
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
bool isSectionVirtual(DataRefImpl Sec) const override
const MachO::mach_header_64 & getHeader64() const
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
void moveRelocationNext(DataRefImpl &Rel) const override
ExportEntry encapsulates the current-state-of-the-walk used when doing a non-recursive walk of the tr...
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
const char * BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip, uint8_t PointerSize, int32_t SegIndex, uint64_t SegOffset) const
For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for the BIND_OPCODE_DO_BIND_ULEB_T...
void push_back(const T &Elt)
static Error checkOverlappingElement(std::list< MachOElement > &Elements, uint64_t Offset, uint64_t Size, const char *Name)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
MachORebaseEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > opcodes, bool is64Bit)
uint32_t getLibraryCount() const
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static const char * getPtr(const MachOObjectFile &O, size_t Offset)
const char * checkCountAndSkip(uint32_t Count, uint32_t Skip, uint8_t PointerSize, int32_t SegIndex, uint64_t SegOffset)
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
bool hasPageZeroSegment() const
Expected< SectionRef > getSection(unsigned SectionIndex) const
static Triple getHostArch()
const char * RebaseEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset, bool endInvalid) const
For use with a SegIndex,SegOffset pair in MachORebaseEntry::moveNext() to validate a MachORebaseEntry...
This class is the base class for all object file types.
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
uint64_t getRelocationType(DataRefImpl Rel) const override
static StringRef parseSegmentOrSectionName(const char *P)
unsigned getSectionType(SectionRef Sec) const
static uint32_t getSectionFlags(const MachOObjectFile &O, DataRefImpl Sec)
uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
MachORebaseEntry encapsulates the current state in the decompression of rebasing opcodes.
uint64_t getSectionAlignment(DataRefImpl Sec) const override
MachO::linkedit_data_command getLinkOptHintsLoadCommand() const
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
Error takeError()
Take ownership of the stored error.
MachO::dylinker_command getDylinkerCommand(const LoadCommandInfo &L) const
MachO::uuid_command getUuidCommand(const LoadCommandInfo &L) const
bool operator==(const MachOBindEntry &) const
static uint32_t getPlainRelocationAddress(const MachO::any_relocation_info &RE)
uint8_t GET_COMM_ALIGN(uint16_t n_desc)
dice_iterator begin_dices() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool isSectionBitcode(DataRefImpl Sec) const override
static unsigned getPlainRelocationLength(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
MachO::thread_command getThreadCommand(const LoadCommandInfo &L) const
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
uint64_t getSectionAddress(DataRefImpl Sec) const override
StringRef segmentName() const
static Expected< MachOObjectFile::LoadCommandInfo > getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, const MachOObjectFile::LoadCommandInfo &L)
basic_symbol_iterator symbol_begin() const override
static Error checkRpathCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
const uint32_t ARM_THREAD_STATE_COUNT
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool isSectionText(DataRefImpl Sec) const override
const uint32_t x86_THREAD_STATE32_COUNT
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
DataRefImpl getRawDataRefImpl() const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
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.
StringRef getBuffer() const
MachO::sub_library_command getSubLibraryCommand(const LoadCommandInfo &L) const
This is a value type class that represents a single relocation in the list of relocations in the obje...
int32_t segmentIndex() const
MachO::linker_option_command getLinkerOptionLoadCommand(const LoadCommandInfo &L) const
Error checkSymbolTable() const
Tagged union holding either a T or a Error.
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
static void parseHeader(const MachOObjectFile &Obj, T &Header, Error &Err)
MachOBindEntry encapsulates the current state in the decompression of binding opcodes.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
MachO::dyld_info_command getDyldInfoLoadCommand(const LoadCommandInfo &L) const
static Error checkDyldInfoCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements)
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Triple::ArchType getArch() const override
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
load_command_iterator begin_load_commands() const
content_iterator< SectionRef > section_iterator
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static const bool IsLittleEndianHost
StringRef getStringTableData() const
MachO::build_version_command getBuildVersionLoadCommand(const LoadCommandInfo &L) const
content_iterator< DiceRef > dice_iterator
SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const
static unsigned getCPUType(const MachOObjectFile &O)
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
symbol_iterator getSymbolByIndex(unsigned Index) const
iterator_range< rebase_iterator > rebaseTable(Error &Err)
For use iterating over all rebase table entries.
static Error checkDylibCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
unsigned getSectionID(SectionRef Sec) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static bool getPlainRelocationPCRel(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
iterator_range< export_iterator > exports(Error &Err) const
For use iterating over all exported symbols.
section_iterator_range sections() const
MachO::encryption_info_command_64 getEncryptionInfoCommand64(const LoadCommandInfo &L) const
content_iterator< MachOBindEntry > bind_iterator
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
basic_symbol_iterator symbol_end() const override
struct llvm::object::DataRefImpl::@282 d
uint64_t segmentOffset() const
Analysis containing CSE Info
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const
static bool isLoadCommandObsolete(uint32_t cmd)
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
MachO::sub_framework_command getSubFrameworkCommand(const LoadCommandInfo &L) const
static Error checkDylibIdCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd)
void moveSectionNext(DataRefImpl &Sec) const override
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
MachO::rpath_command getRpathCommand(const LoadCommandInfo &L) const
StringRef otherName() const
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
static Error checkDyldCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
StringRef typeName() const
A switch()-like statement whose cases are string literals.
bool isSectionCompressed(DataRefImpl Sec) const override
Unify divergent function exit nodes
static Error checkSymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **SymtabLoadCmd, std::list< MachOElement > &Elements)
iterator_range< bind_iterator > weakBindTable(Error &Err)
For use iterating over all weak bind table entries.
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
static Constant * SegmentOffset(IRBuilder<> &IRB, unsigned Offset, unsigned AddressSpace)
relocation_iterator locrel_begin() const
uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the address...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
ArrayRef< uint8_t > getDyldInfoRebaseOpcodes() const
static bool is64Bit(const char *name)
const uint32_t x86_THREAD_STATE64_COUNT
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
static Error checkEncryptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, uint64_t cryptoff, uint64_t cryptsize, const char **LoadCmd, const char *CmdName)
static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI)
#define offsetof(TYPE, MEMBER)
unsigned getSymbolSectionID(SymbolRef Symb) const
MachO::sub_client_command getSubClientCommand(const LoadCommandInfo &L) const
static Error checkSubCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName, size_t SizeOfCmd, const char *CmdStructName, uint32_t PathOffset, const char *PathFieldName)
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.
static T getStruct(const MachOObjectFile &O, const char *P)
MachO::linkedit_data_command getDataInCodeLoadCommand() const
section_iterator getRelocationSection(DataRefImpl Rel) const
DiceRef - This is a value type class that represents a single data in code entry in the table in a Ma...
DataRefImpl getRawDataRefImpl() const
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
const char * RebaseEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip, uint8_t PointerSize, int32_t SegIndex, uint64_t SegOffset) const
For use in MachORebaseEntry::moveNext() to validate a MachORebaseEntry for the REBASE_OPCODE_DO_*_TIM...
bool equals(StringRef RHS) const
Check for string equality.
static wasm::ValType getType(const TargetRegisterClass *RC)
MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const
static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName, std::list< MachOElement > &Elements, const char *ElementName)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static Error checkThreadCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char *CmdName)
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
Triple - Helper class for working with autoconf configuration names.
StringRef typeName() const
static const char *const Magic
relocation_iterator extrel_end() const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
MachO::version_min_command getVersionMinLoadCommand(const LoadCommandInfo &L) const
void moveSymbolNext(DataRefImpl &Symb) const override
static ErrorSuccess success()
Create a success value.
static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, std::list< MachOElement > &Elements)
bool isSectionData(DataRefImpl Sec) const override
uint32_t nodeOffset() const
static Expected< MachOObjectFile::LoadCommandInfo > getFirstLoadCommandInfo(const MachOObjectFile &Obj)
static Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
static Expected< T > getStructOrErr(const MachOObjectFile &O, const char *P)
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
MachO::build_tool_version getBuildToolVersion(unsigned index) const
ArrayRef< uint8_t > getUuid() const
ArrayRef< uint8_t > getDyldInfoLazyBindOpcodes() const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
BindRebaseSegInfo(const MachOObjectFile *Obj)
static Twine utohexstr(const uint64_t &Val)
uint64_t getNValue(DataRefImpl Sym) const
load_command_iterator end_load_commands() const
const uint32_t x86_THREAD_STATE_COUNT
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
MachO::data_in_code_entry getDice(DataRefImpl Rel) const
Triple getArchTriple(const char **McpuDefault=nullptr) const
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
static Error checkLinkerOptCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex)
content_iterator< BasicSymbolRef > basic_symbol_iterator
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint32_t getSymbolFlags(DataRefImpl Symb) const override
A range adaptor for a pair of iterators.
const uint32_t x86_EXCEPTION_STATE_COUNT
static unsigned getScatteredRelocationAddress(const MachO::any_relocation_info &RE)
bool operator==(const MachORebaseEntry &) const
uint64_t segmentOffset() const
iterator_range< bind_iterator > bindTable(Error &Err)
For use iterating over all bind table entries.
Helper for Errors used as out-parameters.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
const char * checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset, bool endInvalid)
This is a value type class that represents a single symbol in the list of symbols in the object file...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
static Error checkVersCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **LoadCmd, const char *CmdName)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static Expected< std::unique_ptr< MachOObjectFile > > create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
StringRef sectionName() const
static Error checkNoteCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, std::list< MachOElement > &Elements)
ArrayRef< uint8_t > getDyldInfoBindOpcodes() const
MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, unsigned Index) const
MachO::source_version_command getSourceVersionCommand(const LoadCommandInfo &L) const
relocation_iterator extrel_begin() const
static Expected< MachOObjectFile::LoadCommandInfo > getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, uint32_t LoadCommandIndex)
ArrayRef< char > getSectionRawFinalSegmentName(DataRefImpl Sec) const
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
dice_iterator end_dices() const
uint8_t getRelocationLength(DataRefImpl Rel) const
MachO::section_64 getSection64(DataRefImpl DRI) const
static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix)
uint64_t address(uint32_t SegIndex, uint64_t SegOffset)
ArrayRef< uint8_t > getDyldInfoWeakBindOpcodes() const
static Error checkDysymtabCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, uint32_t LoadCommandIndex, const char **DysymtabLoadCmd, std::list< MachOElement > &Elements)
bool isSectionBSS(DataRefImpl Sec) const override
uint64_t getSectionIndex(DataRefImpl Sec) const override
void ReadULEB128s(uint64_t Index, SmallVectorImpl< uint64_t > &Out) const
LLVM_NODISCARD bool empty() const
MachO::entry_point_command getEntryPointCommand(const LoadCommandInfo &L) const
StringRef segmentName(int32_t SegIndex)
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
content_iterator< MachORebaseEntry > rebase_iterator
const MachO::mach_header & getHeader() const
StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const
For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase entry to get the section ...
MachO::note_command getNoteLoadCommand(const LoadCommandInfo &L) const
ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Trie)
StringRef symbolName() const
MachO::routines_command getRoutinesCommand(const LoadCommandInfo &L) const
section_iterator section_begin() const override
iterator_range< bind_iterator > lazyBindTable(Error &Err)
For use iterating over all lazy bind table entries.
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
static bool isValidArch(StringRef ArchFlag)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
iterator_range< load_command_iterator > load_commands() const
MachO::routines_command_64 getRoutinesCommand64(const LoadCommandInfo &L) const
ArrayRef< char > getSectionRawName(DataRefImpl Sec) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachO::segment_command_64 getSegment64LoadCommand(const LoadCommandInfo &L) const
StringRef mapDebugSectionName(StringRef Name) const override
Maps a debug section name to a standard DWARF section name.
MachO::sub_umbrella_command getSubUmbrellaCommand(const LoadCommandInfo &L) const
LoadCommandList::const_iterator load_command_iterator
bool isSectionStripped(DataRefImpl Sec) const override
When dsymutil generates the companion file, it strips all unnecessary sections (e.g.
Lightweight error class with error context and mandatory checking.
const uint32_t ARM_THREAD_STATE64_COUNT
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const
section_iterator section_end() const override
content_iterator< RelocationRef > relocation_iterator
MachOBindEntry(Error *Err, const MachOObjectFile *O, ArrayRef< uint8_t > Opcodes, bool is64Bit, MachOBindEntry::Kind)
StringRef segmentName() const
StringRef - Represent a constant reference to a string, i.e.
uint64_t getSymbolIndex(DataRefImpl Symb) const
S_ZEROFILL - Zero fill on demand section.
bool getScatteredRelocationScattered(const MachO::any_relocation_info &RE) const
StringRef sectionName(int32_t SegIndex, uint64_t SegOffset)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
SectionType
These are the section type and attributes fields.
ArrayRef< uint8_t > getDyldInfoExportsTrie() const
uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const
static Error malformedError(const Twine &Msg)
StringRef getData() const
uint32_t getScatteredRelocationValue(const MachO::any_relocation_info &RE) const
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
const uint32_t PPC_THREAD_STATE_COUNT
bool operator==(const ExportEntry &) const
bool empty() const
empty - Check if the array is empty.
This is a value type class that represents a single section in the list of sections in the object fil...
static unsigned getPlainRelocationType(const MachOObjectFile &O, const MachO::any_relocation_info &RE)
MachO::dysymtab_command getDysymtabLoadCommand() const
uint64_t getSectionSize(DataRefImpl Sec) const override
uint32_t getScatteredRelocationType(const MachO::any_relocation_info &RE) const