File indexing completed on 2026-05-10 08:44:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_OBJECT_MACHO_H
0015 #define LLVM_OBJECT_MACHO_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/SmallString.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringExtras.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include "llvm/ADT/iterator_range.h"
0023 #include "llvm/BinaryFormat/MachO.h"
0024 #include "llvm/BinaryFormat/Swift.h"
0025 #include "llvm/Object/Binary.h"
0026 #include "llvm/Object/ObjectFile.h"
0027 #include "llvm/Object/SymbolicFile.h"
0028 #include "llvm/Support/Error.h"
0029 #include "llvm/Support/Format.h"
0030 #include "llvm/Support/MemoryBuffer.h"
0031 #include "llvm/Support/raw_ostream.h"
0032 #include "llvm/TargetParser/SubtargetFeature.h"
0033 #include "llvm/TargetParser/Triple.h"
0034 #include <cstdint>
0035 #include <memory>
0036 #include <string>
0037 #include <system_error>
0038
0039 namespace llvm {
0040 namespace object {
0041
0042
0043
0044 class DiceRef {
0045 DataRefImpl DicePimpl;
0046 const ObjectFile *OwningObject = nullptr;
0047
0048 public:
0049 DiceRef() = default;
0050 DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
0051
0052 bool operator==(const DiceRef &Other) const;
0053 bool operator<(const DiceRef &Other) const;
0054
0055 void moveNext();
0056
0057 std::error_code getOffset(uint32_t &Result) const;
0058 std::error_code getLength(uint16_t &Result) const;
0059 std::error_code getKind(uint16_t &Result) const;
0060
0061 DataRefImpl getRawDataRefImpl() const;
0062 const ObjectFile *getObjectFile() const;
0063 };
0064 using dice_iterator = content_iterator<DiceRef>;
0065
0066
0067
0068
0069
0070
0071
0072
0073 class ExportEntry {
0074 public:
0075 ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie);
0076
0077 StringRef name() const;
0078 uint64_t flags() const;
0079 uint64_t address() const;
0080 uint64_t other() const;
0081 StringRef otherName() const;
0082 uint32_t nodeOffset() const;
0083
0084 bool operator==(const ExportEntry &) const;
0085
0086 void moveNext();
0087
0088 private:
0089 friend class MachOObjectFile;
0090
0091 void moveToFirst();
0092 void moveToEnd();
0093 uint64_t readULEB128(const uint8_t *&p, const char **error);
0094 void pushDownUntilBottom();
0095 void pushNode(uint64_t Offset);
0096
0097
0098 struct NodeState {
0099 NodeState(const uint8_t *Ptr);
0100
0101 const uint8_t *Start;
0102 const uint8_t *Current;
0103 uint64_t Flags = 0;
0104 uint64_t Address = 0;
0105 uint64_t Other = 0;
0106 const char *ImportName = nullptr;
0107 unsigned ChildCount = 0;
0108 unsigned NextChildIndex = 0;
0109 unsigned ParentStringLength = 0;
0110 bool IsExportNode = false;
0111 };
0112 using NodeList = SmallVector<NodeState, 16>;
0113 using node_iterator = NodeList::const_iterator;
0114
0115 Error *E;
0116 const MachOObjectFile *O;
0117 ArrayRef<uint8_t> Trie;
0118 SmallString<256> CumulativeString;
0119 NodeList Stack;
0120 bool Done = false;
0121
0122 iterator_range<node_iterator> nodes() const {
0123 return make_range(Stack.begin(), Stack.end());
0124 }
0125 };
0126 using export_iterator = content_iterator<ExportEntry>;
0127
0128
0129
0130
0131
0132 class BindRebaseSegInfo {
0133 public:
0134 BindRebaseSegInfo(const MachOObjectFile *Obj);
0135
0136
0137 const char *checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
0138 uint8_t PointerSize, uint64_t Count = 1,
0139 uint64_t Skip = 0);
0140
0141 StringRef segmentName(int32_t SegIndex);
0142 StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
0143 uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
0144
0145 private:
0146 struct SectionInfo {
0147 uint64_t Address;
0148 uint64_t Size;
0149 StringRef SectionName;
0150 StringRef SegmentName;
0151 uint64_t OffsetInSegment;
0152 uint64_t SegmentStartAddress;
0153 int32_t SegmentIndex;
0154 };
0155 const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
0156
0157 SmallVector<SectionInfo, 32> Sections;
0158 int32_t MaxSegIndex;
0159 };
0160
0161
0162
0163
0164
0165
0166
0167
0168 class MachORebaseEntry {
0169 public:
0170 MachORebaseEntry(Error *Err, const MachOObjectFile *O,
0171 ArrayRef<uint8_t> opcodes, bool is64Bit);
0172
0173 int32_t segmentIndex() const;
0174 uint64_t segmentOffset() const;
0175 StringRef typeName() const;
0176 StringRef segmentName() const;
0177 StringRef sectionName() const;
0178 uint64_t address() const;
0179
0180 bool operator==(const MachORebaseEntry &) const;
0181
0182 void moveNext();
0183
0184 private:
0185 friend class MachOObjectFile;
0186
0187 void moveToFirst();
0188 void moveToEnd();
0189 uint64_t readULEB128(const char **error);
0190
0191 Error *E;
0192 const MachOObjectFile *O;
0193 ArrayRef<uint8_t> Opcodes;
0194 const uint8_t *Ptr;
0195 uint64_t SegmentOffset = 0;
0196 int32_t SegmentIndex = -1;
0197 uint64_t RemainingLoopCount = 0;
0198 uint64_t AdvanceAmount = 0;
0199 uint8_t RebaseType = 0;
0200 uint8_t PointerSize;
0201 bool Done = false;
0202 };
0203 using rebase_iterator = content_iterator<MachORebaseEntry>;
0204
0205
0206
0207
0208
0209
0210
0211
0212 class MachOBindEntry {
0213 public:
0214 enum class Kind { Regular, Lazy, Weak };
0215
0216 MachOBindEntry(Error *Err, const MachOObjectFile *O,
0217 ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
0218
0219 int32_t segmentIndex() const;
0220 uint64_t segmentOffset() const;
0221 StringRef typeName() const;
0222 StringRef symbolName() const;
0223 uint32_t flags() const;
0224 int64_t addend() const;
0225 int ordinal() const;
0226
0227 StringRef segmentName() const;
0228 StringRef sectionName() const;
0229 uint64_t address() const;
0230
0231 bool operator==(const MachOBindEntry &) const;
0232
0233 void moveNext();
0234
0235 private:
0236 friend class MachOObjectFile;
0237
0238 void moveToFirst();
0239 void moveToEnd();
0240 uint64_t readULEB128(const char **error);
0241 int64_t readSLEB128(const char **error);
0242
0243 Error *E;
0244 const MachOObjectFile *O;
0245 ArrayRef<uint8_t> Opcodes;
0246 const uint8_t *Ptr;
0247 uint64_t SegmentOffset = 0;
0248 int32_t SegmentIndex = -1;
0249 StringRef SymbolName;
0250 bool LibraryOrdinalSet = false;
0251 int Ordinal = 0;
0252 uint32_t Flags = 0;
0253 int64_t Addend = 0;
0254 uint64_t RemainingLoopCount = 0;
0255 uint64_t AdvanceAmount = 0;
0256 uint8_t BindType = 0;
0257 uint8_t PointerSize;
0258 Kind TableKind;
0259 bool Done = false;
0260 };
0261 using bind_iterator = content_iterator<MachOBindEntry>;
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 struct ChainedFixupTarget {
0276 public:
0277 ChainedFixupTarget(int LibOrdinal, uint32_t NameOffset, StringRef Symbol,
0278 uint64_t Addend, bool WeakImport)
0279 : LibOrdinal(LibOrdinal), NameOffset(NameOffset), SymbolName(Symbol),
0280 Addend(Addend), WeakImport(WeakImport) {}
0281
0282 int libOrdinal() { return LibOrdinal; }
0283 uint32_t nameOffset() { return NameOffset; }
0284 StringRef symbolName() { return SymbolName; }
0285 uint64_t addend() { return Addend; }
0286 bool weakImport() { return WeakImport; }
0287 bool weakBind() {
0288 return LibOrdinal == MachO::BIND_SPECIAL_DYLIB_WEAK_LOOKUP;
0289 }
0290
0291 private:
0292 int LibOrdinal;
0293 uint32_t NameOffset;
0294 StringRef SymbolName;
0295 uint64_t Addend;
0296 bool WeakImport;
0297 };
0298
0299 struct ChainedFixupsSegment {
0300 ChainedFixupsSegment(uint8_t SegIdx, uint32_t Offset,
0301 const MachO::dyld_chained_starts_in_segment &Header,
0302 std::vector<uint16_t> &&PageStarts)
0303 : SegIdx(SegIdx), Offset(Offset), Header(Header),
0304 PageStarts(PageStarts){};
0305
0306 uint32_t SegIdx;
0307 uint32_t Offset;
0308 MachO::dyld_chained_starts_in_segment Header;
0309 std::vector<uint16_t> PageStarts;
0310 };
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 class MachOAbstractFixupEntry {
0323 public:
0324 MachOAbstractFixupEntry(Error *Err, const MachOObjectFile *O);
0325
0326 int32_t segmentIndex() const;
0327 uint64_t segmentOffset() const;
0328 uint64_t segmentAddress() const;
0329 StringRef segmentName() const;
0330 StringRef sectionName() const;
0331 StringRef typeName() const;
0332 StringRef symbolName() const;
0333 uint32_t flags() const;
0334 int64_t addend() const;
0335 int ordinal() const;
0336
0337
0338
0339 uint64_t address() const;
0340
0341
0342
0343
0344 uint64_t pointerValue() const { return PointerValue; }
0345
0346
0347
0348
0349
0350
0351 uint64_t rawValue() const { return RawValue; }
0352
0353 void moveNext();
0354
0355 protected:
0356 Error *E;
0357 const MachOObjectFile *O;
0358 uint64_t SegmentOffset = 0;
0359 int32_t SegmentIndex = -1;
0360 StringRef SymbolName;
0361 int32_t Ordinal = 0;
0362 uint32_t Flags = 0;
0363 int64_t Addend = 0;
0364 uint64_t PointerValue = 0;
0365 uint64_t RawValue = 0;
0366 bool Done = false;
0367
0368 void moveToFirst();
0369 void moveToEnd();
0370
0371
0372 uint64_t textAddress() const { return TextAddress; }
0373
0374 private:
0375 uint64_t TextAddress;
0376 };
0377
0378 class MachOChainedFixupEntry : public MachOAbstractFixupEntry {
0379 public:
0380 enum class FixupKind { Bind, Rebase };
0381
0382 MachOChainedFixupEntry(Error *Err, const MachOObjectFile *O, bool Parse);
0383
0384 bool operator==(const MachOChainedFixupEntry &) const;
0385
0386 bool isBind() const { return Kind == FixupKind::Bind; }
0387 bool isRebase() const { return Kind == FixupKind::Rebase; }
0388
0389 void moveNext();
0390 void moveToFirst();
0391 void moveToEnd();
0392
0393 private:
0394 void findNextPageWithFixups();
0395
0396 std::vector<ChainedFixupTarget> FixupTargets;
0397 std::vector<ChainedFixupsSegment> Segments;
0398 ArrayRef<uint8_t> SegmentData;
0399 FixupKind Kind;
0400 uint32_t InfoSegIndex = 0;
0401 uint32_t PageIndex = 0;
0402 uint32_t PageOffset = 0;
0403 };
0404 using fixup_iterator = content_iterator<MachOChainedFixupEntry>;
0405
0406 class MachOObjectFile : public ObjectFile {
0407 public:
0408 struct LoadCommandInfo {
0409 const char *Ptr;
0410 MachO::load_command C;
0411 };
0412 using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
0413 using load_command_iterator = LoadCommandList::const_iterator;
0414
0415 static Expected<std::unique_ptr<MachOObjectFile>>
0416 create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
0417 uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0,
0418 size_t MachOFilesetEntryOffset = 0);
0419
0420 static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch);
0421
0422 void moveSymbolNext(DataRefImpl &Symb) const override;
0423
0424 uint64_t getNValue(DataRefImpl Sym) const;
0425 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
0426
0427
0428 Error checkSymbolTable() const;
0429
0430 std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
0431 unsigned getSectionType(SectionRef Sec) const;
0432
0433 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
0434 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
0435 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
0436 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
0437 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
0438 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
0439 unsigned getSymbolSectionID(SymbolRef Symb) const;
0440 unsigned getSectionID(SectionRef Sec) const;
0441
0442 void moveSectionNext(DataRefImpl &Sec) const override;
0443 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
0444 uint64_t getSectionAddress(DataRefImpl Sec) const override;
0445 uint64_t getSectionIndex(DataRefImpl Sec) const override;
0446 uint64_t getSectionSize(DataRefImpl Sec) const override;
0447 ArrayRef<uint8_t> getSectionContents(uint32_t Offset, uint64_t Size) const;
0448 Expected<ArrayRef<uint8_t>>
0449 getSectionContents(DataRefImpl Sec) const override;
0450 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
0451 Expected<SectionRef> getSection(unsigned SectionIndex) const;
0452 Expected<SectionRef> getSection(StringRef SectionName) const;
0453 bool isSectionCompressed(DataRefImpl Sec) const override;
0454 bool isSectionText(DataRefImpl Sec) const override;
0455 bool isSectionData(DataRefImpl Sec) const override;
0456 bool isSectionBSS(DataRefImpl Sec) const override;
0457 bool isSectionVirtual(DataRefImpl Sec) const override;
0458 bool isSectionBitcode(DataRefImpl Sec) const override;
0459 bool isDebugSection(DataRefImpl Sec) const override;
0460
0461
0462 ArrayRef<uint8_t> getSegmentContents(StringRef SegmentName) const;
0463 ArrayRef<uint8_t> getSegmentContents(size_t SegmentIndex) const;
0464
0465
0466
0467
0468
0469
0470
0471
0472 bool isSectionStripped(DataRefImpl Sec) const override;
0473
0474 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
0475 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
0476
0477 relocation_iterator extrel_begin() const;
0478 relocation_iterator extrel_end() const;
0479 iterator_range<relocation_iterator> external_relocations() const {
0480 return make_range(extrel_begin(), extrel_end());
0481 }
0482
0483 relocation_iterator locrel_begin() const;
0484 relocation_iterator locrel_end() const;
0485
0486 void moveRelocationNext(DataRefImpl &Rel) const override;
0487 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
0488 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
0489 section_iterator getRelocationSection(DataRefImpl Rel) const;
0490 uint64_t getRelocationType(DataRefImpl Rel) const override;
0491 void getRelocationTypeName(DataRefImpl Rel,
0492 SmallVectorImpl<char> &Result) const override;
0493 uint8_t getRelocationLength(DataRefImpl Rel) const;
0494
0495
0496 std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
0497 uint32_t getLibraryCount() const;
0498
0499 section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
0500
0501
0502
0503
0504 basic_symbol_iterator symbol_begin() const override;
0505 basic_symbol_iterator symbol_end() const override;
0506
0507 bool is64Bit() const override;
0508
0509
0510 symbol_iterator getSymbolByIndex(unsigned Index) const;
0511 uint64_t getSymbolIndex(DataRefImpl Symb) const;
0512
0513 section_iterator section_begin() const override;
0514 section_iterator section_end() const override;
0515
0516 uint8_t getBytesInAddress() const override;
0517
0518 StringRef getFileFormatName() const override;
0519 Triple::ArchType getArch() const override;
0520 Expected<SubtargetFeatures> getFeatures() const override {
0521 return SubtargetFeatures();
0522 }
0523 Triple getArchTriple(const char **McpuDefault = nullptr) const;
0524
0525 relocation_iterator section_rel_begin(unsigned Index) const;
0526 relocation_iterator section_rel_end(unsigned Index) const;
0527
0528 dice_iterator begin_dices() const;
0529 dice_iterator end_dices() const;
0530
0531 load_command_iterator begin_load_commands() const;
0532 load_command_iterator end_load_commands() const;
0533 iterator_range<load_command_iterator> load_commands() const;
0534
0535
0536 iterator_range<export_iterator> exports(Error &Err) const;
0537
0538
0539 static iterator_range<export_iterator> exports(Error &Err,
0540 ArrayRef<uint8_t> Trie,
0541 const MachOObjectFile *O =
0542 nullptr);
0543
0544
0545 iterator_range<rebase_iterator> rebaseTable(Error &Err);
0546
0547
0548 static iterator_range<rebase_iterator> rebaseTable(Error &Err,
0549 MachOObjectFile *O,
0550 ArrayRef<uint8_t> Opcodes,
0551 bool is64);
0552
0553
0554 iterator_range<bind_iterator> bindTable(Error &Err);
0555
0556
0557 iterator_range<fixup_iterator> fixupTable(Error &Err);
0558
0559
0560 iterator_range<bind_iterator> lazyBindTable(Error &Err);
0561
0562
0563 iterator_range<bind_iterator> weakBindTable(Error &Err);
0564
0565
0566 static iterator_range<bind_iterator> bindTable(Error &Err,
0567 MachOObjectFile *O,
0568 ArrayRef<uint8_t> Opcodes,
0569 bool is64,
0570 MachOBindEntry::Kind);
0571
0572
0573
0574
0575
0576
0577
0578 const char *BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
0579 uint8_t PointerSize,
0580 uint64_t Count = 1,
0581 uint64_t Skip = 0) const {
0582 return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
0583 PointerSize, Count, Skip);
0584 }
0585
0586
0587
0588
0589
0590
0591
0592 const char *RebaseEntryCheckSegAndOffsets(int32_t SegIndex,
0593 uint64_t SegOffset,
0594 uint8_t PointerSize,
0595 uint64_t Count = 1,
0596 uint64_t Skip = 0) const {
0597 return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
0598 PointerSize, Count, Skip);
0599 }
0600
0601
0602
0603 StringRef BindRebaseSegmentName(int32_t SegIndex) const {
0604 return BindRebaseSectionTable->segmentName(SegIndex);
0605 }
0606
0607
0608
0609 StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
0610 return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
0611 }
0612
0613
0614
0615 uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
0616 return BindRebaseSectionTable->address(SegIndex, SegOffset);
0617 }
0618
0619
0620
0621
0622 StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
0623
0624
0625
0626 ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
0627 ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
0628
0629
0630 bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
0631 unsigned getPlainRelocationSymbolNum(
0632 const MachO::any_relocation_info &RE) const;
0633 bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
0634 bool getScatteredRelocationScattered(
0635 const MachO::any_relocation_info &RE) const;
0636 uint32_t getScatteredRelocationValue(
0637 const MachO::any_relocation_info &RE) const;
0638 uint32_t getScatteredRelocationType(
0639 const MachO::any_relocation_info &RE) const;
0640 unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
0641 unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
0642 unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
0643 unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
0644 SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
0645
0646
0647 MachO::section getSection(DataRefImpl DRI) const;
0648 MachO::section_64 getSection64(DataRefImpl DRI) const;
0649 MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
0650 MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
0651 MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
0652 MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
0653
0654 MachO::linkedit_data_command
0655 getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
0656 MachO::segment_command
0657 getSegmentLoadCommand(const LoadCommandInfo &L) const;
0658 MachO::segment_command_64
0659 getSegment64LoadCommand(const LoadCommandInfo &L) const;
0660 MachO::linker_option_command
0661 getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
0662 MachO::version_min_command
0663 getVersionMinLoadCommand(const LoadCommandInfo &L) const;
0664 MachO::note_command
0665 getNoteLoadCommand(const LoadCommandInfo &L) const;
0666 MachO::build_version_command
0667 getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
0668 MachO::build_tool_version
0669 getBuildToolVersion(unsigned index) const;
0670 MachO::dylib_command
0671 getDylibIDLoadCommand(const LoadCommandInfo &L) const;
0672 MachO::dyld_info_command
0673 getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
0674 MachO::dylinker_command
0675 getDylinkerCommand(const LoadCommandInfo &L) const;
0676 MachO::uuid_command
0677 getUuidCommand(const LoadCommandInfo &L) const;
0678 MachO::rpath_command
0679 getRpathCommand(const LoadCommandInfo &L) const;
0680 MachO::source_version_command
0681 getSourceVersionCommand(const LoadCommandInfo &L) const;
0682 MachO::entry_point_command
0683 getEntryPointCommand(const LoadCommandInfo &L) const;
0684 MachO::encryption_info_command
0685 getEncryptionInfoCommand(const LoadCommandInfo &L) const;
0686 MachO::encryption_info_command_64
0687 getEncryptionInfoCommand64(const LoadCommandInfo &L) const;
0688 MachO::sub_framework_command
0689 getSubFrameworkCommand(const LoadCommandInfo &L) const;
0690 MachO::sub_umbrella_command
0691 getSubUmbrellaCommand(const LoadCommandInfo &L) const;
0692 MachO::sub_library_command
0693 getSubLibraryCommand(const LoadCommandInfo &L) const;
0694 MachO::sub_client_command
0695 getSubClientCommand(const LoadCommandInfo &L) const;
0696 MachO::routines_command
0697 getRoutinesCommand(const LoadCommandInfo &L) const;
0698 MachO::routines_command_64
0699 getRoutinesCommand64(const LoadCommandInfo &L) const;
0700 MachO::thread_command
0701 getThreadCommand(const LoadCommandInfo &L) const;
0702 MachO::fileset_entry_command
0703 getFilesetEntryLoadCommand(const LoadCommandInfo &L) const;
0704
0705 MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
0706 MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
0707 const MachO::mach_header &getHeader() const;
0708 const MachO::mach_header_64 &getHeader64() const;
0709 uint32_t
0710 getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
0711 unsigned Index) const;
0712 MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
0713 unsigned Index) const;
0714 MachO::symtab_command getSymtabLoadCommand() const;
0715 MachO::dysymtab_command getDysymtabLoadCommand() const;
0716 MachO::linkedit_data_command getDataInCodeLoadCommand() const;
0717 MachO::linkedit_data_command getLinkOptHintsLoadCommand() const;
0718 ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const;
0719 ArrayRef<uint8_t> getDyldInfoBindOpcodes() const;
0720 ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
0721 ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
0722 ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
0723
0724
0725
0726 Expected<std::optional<MachO::dyld_chained_fixups_header>>
0727 getChainedFixupsHeader() const;
0728 Expected<std::vector<ChainedFixupTarget>> getDyldChainedFixupTargets() const;
0729
0730
0731
0732 Expected<std::optional<MachO::linkedit_data_command>>
0733 getChainedFixupsLoadCommand() const;
0734
0735
0736 Expected<std::pair<size_t, std::vector<ChainedFixupsSegment>>>
0737 getChainedFixupsSegments() const;
0738 ArrayRef<uint8_t> getDyldExportsTrie() const;
0739
0740 SmallVector<uint64_t> getFunctionStarts() const;
0741 ArrayRef<uint8_t> getUuid() const;
0742
0743 StringRef getStringTableData() const;
0744
0745 void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
0746
0747 static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
0748 StringRef &Suffix);
0749
0750 static Triple::ArchType getArch(uint32_t CPUType, uint32_t CPUSubType);
0751 static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
0752 const char **McpuDefault = nullptr,
0753 const char **ArchFlag = nullptr);
0754 static bool isValidArch(StringRef ArchFlag);
0755 static ArrayRef<StringRef> getValidArchs();
0756 static Triple getHostArch();
0757
0758 bool isRelocatableObject() const override;
0759
0760 StringRef mapDebugSectionName(StringRef Name) const override;
0761
0762 llvm::binaryformat::Swift5ReflectionSectionKind
0763 mapReflectionSectionNameToEnumValue(StringRef SectionName) const override;
0764
0765 bool hasPageZeroSegment() const { return HasPageZeroSegment; }
0766
0767 size_t getMachOFilesetEntryOffset() const { return MachOFilesetEntryOffset; }
0768
0769 static bool classof(const Binary *v) {
0770 return v->isMachO();
0771 }
0772
0773 static uint32_t
0774 getVersionMinMajor(MachO::version_min_command &C, bool SDK) {
0775 uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
0776 return (VersionOrSDK >> 16) & 0xffff;
0777 }
0778
0779 static uint32_t
0780 getVersionMinMinor(MachO::version_min_command &C, bool SDK) {
0781 uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
0782 return (VersionOrSDK >> 8) & 0xff;
0783 }
0784
0785 static uint32_t
0786 getVersionMinUpdate(MachO::version_min_command &C, bool SDK) {
0787 uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
0788 return VersionOrSDK & 0xff;
0789 }
0790
0791 static std::string getBuildPlatform(uint32_t platform) {
0792 switch (platform) {
0793 #define PLATFORM(platform, id, name, build_name, target, tapi_target, \
0794 marketing) \
0795 case MachO::PLATFORM_##platform: \
0796 return #name;
0797 #include "llvm/BinaryFormat/MachO.def"
0798 default:
0799 std::string ret;
0800 raw_string_ostream ss(ret);
0801 ss << format_hex(platform, 8, true);
0802 return ret;
0803 }
0804 }
0805
0806 static std::string getBuildTool(uint32_t tools) {
0807 switch (tools) {
0808 case MachO::TOOL_CLANG: return "clang";
0809 case MachO::TOOL_SWIFT: return "swift";
0810 case MachO::TOOL_LD: return "ld";
0811 case MachO::TOOL_LLD:
0812 return "lld";
0813 default:
0814 std::string ret;
0815 raw_string_ostream ss(ret);
0816 ss << format_hex(tools, 8, true);
0817 return ret;
0818 }
0819 }
0820
0821 static std::string getVersionString(uint32_t version) {
0822 uint32_t major = (version >> 16) & 0xffff;
0823 uint32_t minor = (version >> 8) & 0xff;
0824 uint32_t update = version & 0xff;
0825
0826 SmallString<32> Version;
0827 Version = utostr(major) + "." + utostr(minor);
0828 if (update != 0)
0829 Version += "." + utostr(update);
0830 return std::string(std::string(Version));
0831 }
0832
0833
0834
0835
0836
0837 static Expected<std::vector<std::string>>
0838 findDsymObjectMembers(StringRef Path);
0839
0840 private:
0841 MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
0842 Error &Err, uint32_t UniversalCputype = 0,
0843 uint32_t UniversalIndex = 0,
0844 size_t MachOFilesetEntryOffset = 0);
0845
0846 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
0847
0848 union {
0849 MachO::mach_header_64 Header64;
0850 MachO::mach_header Header;
0851 };
0852 using SectionList = SmallVector<const char*, 1>;
0853 SectionList Sections;
0854 using LibraryList = SmallVector<const char*, 1>;
0855 LibraryList Libraries;
0856 LoadCommandList LoadCommands;
0857 using LibraryShortName = SmallVector<StringRef, 1>;
0858 using BuildToolList = SmallVector<const char*, 1>;
0859 BuildToolList BuildTools;
0860 mutable LibraryShortName LibrariesShortNames;
0861 std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
0862 const char *SymtabLoadCmd = nullptr;
0863 const char *DysymtabLoadCmd = nullptr;
0864 const char *DataInCodeLoadCmd = nullptr;
0865 const char *LinkOptHintsLoadCmd = nullptr;
0866 const char *DyldInfoLoadCmd = nullptr;
0867 const char *FuncStartsLoadCmd = nullptr;
0868 const char *DyldChainedFixupsLoadCmd = nullptr;
0869 const char *DyldExportsTrieLoadCmd = nullptr;
0870 const char *UuidLoadCmd = nullptr;
0871 bool HasPageZeroSegment = false;
0872 size_t MachOFilesetEntryOffset = 0;
0873 };
0874
0875
0876 inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
0877 : DicePimpl(DiceP) , OwningObject(Owner) {}
0878
0879 inline bool DiceRef::operator==(const DiceRef &Other) const {
0880 return DicePimpl == Other.DicePimpl;
0881 }
0882
0883 inline bool DiceRef::operator<(const DiceRef &Other) const {
0884 return DicePimpl < Other.DicePimpl;
0885 }
0886
0887 inline void DiceRef::moveNext() {
0888 const MachO::data_in_code_entry *P =
0889 reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
0890 DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
0891 }
0892
0893
0894
0895
0896
0897 inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
0898 const MachOObjectFile *MachOOF =
0899 static_cast<const MachOObjectFile *>(OwningObject);
0900 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
0901 Result = Dice.offset;
0902 return std::error_code();
0903 }
0904
0905 inline std::error_code DiceRef::getLength(uint16_t &Result) const {
0906 const MachOObjectFile *MachOOF =
0907 static_cast<const MachOObjectFile *>(OwningObject);
0908 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
0909 Result = Dice.length;
0910 return std::error_code();
0911 }
0912
0913 inline std::error_code DiceRef::getKind(uint16_t &Result) const {
0914 const MachOObjectFile *MachOOF =
0915 static_cast<const MachOObjectFile *>(OwningObject);
0916 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
0917 Result = Dice.kind;
0918 return std::error_code();
0919 }
0920
0921 inline DataRefImpl DiceRef::getRawDataRefImpl() const {
0922 return DicePimpl;
0923 }
0924
0925 inline const ObjectFile *DiceRef::getObjectFile() const {
0926 return OwningObject;
0927 }
0928
0929 }
0930 }
0931
0932 #endif