File indexing completed on 2026-05-10 08:44:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_OBJECT_OBJECTFILE_H
0014 #define LLVM_OBJECT_OBJECTFILE_H
0015
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/Hashing.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include "llvm/BinaryFormat/Magic.h"
0021 #include "llvm/BinaryFormat/Swift.h"
0022 #include "llvm/Object/Binary.h"
0023 #include "llvm/Object/Error.h"
0024 #include "llvm/Object/SymbolicFile.h"
0025 #include "llvm/Support/Casting.h"
0026 #include "llvm/Support/Error.h"
0027 #include "llvm/Support/MemoryBufferRef.h"
0028 #include "llvm/TargetParser/Triple.h"
0029 #include <cassert>
0030 #include <cstdint>
0031 #include <memory>
0032
0033 namespace llvm {
0034
0035 class SubtargetFeatures;
0036
0037 namespace object {
0038
0039 class COFFObjectFile;
0040 class MachOObjectFile;
0041 class ObjectFile;
0042 class SectionRef;
0043 class SymbolRef;
0044 class symbol_iterator;
0045 class WasmObjectFile;
0046
0047 using section_iterator = content_iterator<SectionRef>;
0048
0049 typedef std::function<bool(const SectionRef &)> SectionFilterPredicate;
0050
0051
0052 class RelocationRef {
0053 DataRefImpl RelocationPimpl;
0054 const ObjectFile *OwningObject = nullptr;
0055
0056 public:
0057 RelocationRef() = default;
0058 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
0059
0060 bool operator==(const RelocationRef &Other) const;
0061
0062 void moveNext();
0063
0064 uint64_t getOffset() const;
0065 symbol_iterator getSymbol() const;
0066 uint64_t getType() const;
0067
0068
0069
0070
0071 void getTypeName(SmallVectorImpl<char> &Result) const;
0072
0073 DataRefImpl getRawDataRefImpl() const;
0074 const ObjectFile *getObject() const;
0075 };
0076
0077 using relocation_iterator = content_iterator<RelocationRef>;
0078
0079
0080
0081 class SectionRef {
0082 friend class SymbolRef;
0083
0084 DataRefImpl SectionPimpl;
0085 const ObjectFile *OwningObject = nullptr;
0086
0087 public:
0088 SectionRef() = default;
0089 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
0090
0091 bool operator==(const SectionRef &Other) const;
0092 bool operator!=(const SectionRef &Other) const;
0093 bool operator<(const SectionRef &Other) const;
0094
0095 void moveNext();
0096
0097 Expected<StringRef> getName() const;
0098 uint64_t getAddress() const;
0099 uint64_t getIndex() const;
0100 uint64_t getSize() const;
0101 Expected<StringRef> getContents() const;
0102
0103
0104 Align getAlignment() const;
0105
0106 bool isCompressed() const;
0107
0108 bool isText() const;
0109
0110 bool isData() const;
0111
0112 bool isBSS() const;
0113 bool isVirtual() const;
0114 bool isBitcode() const;
0115 bool isStripped() const;
0116
0117
0118
0119
0120 bool isBerkeleyText() const;
0121
0122
0123
0124 bool isBerkeleyData() const;
0125
0126
0127 bool isDebugSection() const;
0128
0129 bool containsSymbol(SymbolRef S) const;
0130
0131 relocation_iterator relocation_begin() const;
0132 relocation_iterator relocation_end() const;
0133 iterator_range<relocation_iterator> relocations() const {
0134 return make_range(relocation_begin(), relocation_end());
0135 }
0136
0137
0138
0139 Expected<section_iterator> getRelocatedSection() const;
0140
0141 DataRefImpl getRawDataRefImpl() const;
0142 const ObjectFile *getObject() const;
0143 };
0144
0145 struct SectionedAddress {
0146 const static uint64_t UndefSection = UINT64_MAX;
0147
0148 uint64_t Address = 0;
0149 uint64_t SectionIndex = UndefSection;
0150 };
0151
0152 inline bool operator<(const SectionedAddress &LHS,
0153 const SectionedAddress &RHS) {
0154 return std::tie(LHS.SectionIndex, LHS.Address) <
0155 std::tie(RHS.SectionIndex, RHS.Address);
0156 }
0157
0158 inline bool operator==(const SectionedAddress &LHS,
0159 const SectionedAddress &RHS) {
0160 return std::tie(LHS.SectionIndex, LHS.Address) ==
0161 std::tie(RHS.SectionIndex, RHS.Address);
0162 }
0163
0164 raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
0165
0166
0167
0168 class SymbolRef : public BasicSymbolRef {
0169 friend class SectionRef;
0170
0171 public:
0172 enum Type {
0173 ST_Unknown,
0174 ST_Other,
0175 ST_Data,
0176 ST_Debug,
0177 ST_File,
0178 ST_Function,
0179 };
0180
0181 SymbolRef() = default;
0182 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
0183 SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
0184 assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
0185 }
0186
0187 Expected<StringRef> getName() const;
0188
0189
0190 Expected<uint64_t> getAddress() const;
0191
0192
0193
0194 Expected<uint64_t> getValue() const;
0195
0196
0197 uint32_t getAlignment() const;
0198 uint64_t getCommonSize() const;
0199 Expected<SymbolRef::Type> getType() const;
0200
0201
0202
0203 Expected<section_iterator> getSection() const;
0204
0205 const ObjectFile *getObject() const;
0206 };
0207
0208 class symbol_iterator : public basic_symbol_iterator {
0209 public:
0210 symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
0211 symbol_iterator(const basic_symbol_iterator &B)
0212 : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
0213 cast<ObjectFile>(B->getObject()))) {}
0214
0215 const SymbolRef *operator->() const {
0216 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
0217 return static_cast<const SymbolRef*>(&P);
0218 }
0219
0220 const SymbolRef &operator*() const {
0221 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
0222 return static_cast<const SymbolRef&>(P);
0223 }
0224 };
0225
0226
0227
0228
0229 class ObjectFile : public SymbolicFile {
0230 virtual void anchor();
0231
0232 protected:
0233 ObjectFile(unsigned int Type, MemoryBufferRef Source);
0234
0235 const uint8_t *base() const {
0236 return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 friend class SymbolRef;
0248
0249 virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
0250 Error printSymbolName(raw_ostream &OS,
0251 DataRefImpl Symb) const override;
0252 virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
0253 virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
0254 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
0255 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
0256 virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
0257 virtual Expected<section_iterator>
0258 getSymbolSection(DataRefImpl Symb) const = 0;
0259
0260
0261 friend class SectionRef;
0262
0263 virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
0264 virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
0265 virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
0266 virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
0267 virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
0268 virtual Expected<ArrayRef<uint8_t>>
0269 getSectionContents(DataRefImpl Sec) const = 0;
0270 virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
0271 virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
0272 virtual bool isSectionText(DataRefImpl Sec) const = 0;
0273 virtual bool isSectionData(DataRefImpl Sec) const = 0;
0274 virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
0275
0276 virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
0277 virtual bool isSectionBitcode(DataRefImpl Sec) const;
0278 virtual bool isSectionStripped(DataRefImpl Sec) const;
0279 virtual bool isBerkeleyText(DataRefImpl Sec) const;
0280 virtual bool isBerkeleyData(DataRefImpl Sec) const;
0281 virtual bool isDebugSection(DataRefImpl Sec) const;
0282 virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
0283 virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
0284 virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
0285
0286
0287 friend class RelocationRef;
0288 virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
0289 virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
0290 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
0291 virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
0292 virtual void getRelocationTypeName(DataRefImpl Rel,
0293 SmallVectorImpl<char> &Result) const = 0;
0294
0295 virtual llvm::binaryformat::Swift5ReflectionSectionKind
0296 mapReflectionSectionNameToEnumValue(StringRef SectionName) const {
0297 return llvm::binaryformat::Swift5ReflectionSectionKind::unknown;
0298 };
0299
0300 Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
0301
0302 public:
0303 ObjectFile() = delete;
0304 ObjectFile(const ObjectFile &other) = delete;
0305 ObjectFile &operator=(const ObjectFile &other) = delete;
0306
0307 uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
0308 Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
0309 if (!SymbolFlagsOrErr)
0310
0311 report_fatal_error(SymbolFlagsOrErr.takeError());
0312 assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
0313 return getCommonSymbolSizeImpl(Symb);
0314 }
0315
0316 virtual std::vector<SectionRef> dynamic_relocation_sections() const {
0317 return std::vector<SectionRef>();
0318 }
0319
0320 using symbol_iterator_range = iterator_range<symbol_iterator>;
0321 symbol_iterator_range symbols() const {
0322 return symbol_iterator_range(symbol_begin(), symbol_end());
0323 }
0324
0325 virtual section_iterator section_begin() const = 0;
0326 virtual section_iterator section_end() const = 0;
0327
0328 using section_iterator_range = iterator_range<section_iterator>;
0329 section_iterator_range sections() const {
0330 return section_iterator_range(section_begin(), section_end());
0331 }
0332
0333 virtual bool hasDebugInfo() const;
0334
0335
0336
0337 virtual uint8_t getBytesInAddress() const = 0;
0338
0339 virtual StringRef getFileFormatName() const = 0;
0340 virtual Triple::ArchType getArch() const = 0;
0341 virtual Triple::OSType getOS() const { return Triple::UnknownOS; }
0342 virtual Expected<SubtargetFeatures> getFeatures() const = 0;
0343 virtual std::optional<StringRef> tryGetCPUName() const {
0344 return std::nullopt;
0345 };
0346 virtual void setARMSubArch(Triple &TheTriple) const { }
0347 virtual Expected<uint64_t> getStartAddress() const {
0348 return errorCodeToError(object_error::parse_failed);
0349 };
0350
0351
0352 Triple makeTriple() const;
0353
0354
0355 virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
0356
0357
0358 virtual bool isRelocatableObject() const = 0;
0359
0360
0361 bool isReflectionSectionStrippable(
0362 llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
0363 const;
0364
0365
0366
0367
0368
0369 static Expected<OwningBinary<ObjectFile>>
0370 createObjectFile(StringRef ObjectPath);
0371
0372 static Expected<std::unique_ptr<ObjectFile>>
0373 createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
0374 bool InitContent = true);
0375 static Expected<std::unique_ptr<ObjectFile>>
0376 createObjectFile(MemoryBufferRef Object) {
0377 return createObjectFile(Object, llvm::file_magic::unknown);
0378 }
0379
0380 static bool classof(const Binary *v) {
0381 return v->isObject();
0382 }
0383
0384 static Expected<std::unique_ptr<COFFObjectFile>>
0385 createCOFFObjectFile(MemoryBufferRef Object);
0386
0387 static Expected<std::unique_ptr<ObjectFile>>
0388 createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
0389
0390 static Expected<std::unique_ptr<ObjectFile>>
0391 createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
0392
0393 static Expected<std::unique_ptr<MachOObjectFile>>
0394 createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype = 0,
0395 uint32_t UniversalIndex = 0,
0396 size_t MachOFilesetEntryOffset = 0);
0397
0398 static Expected<std::unique_ptr<ObjectFile>>
0399 createGOFFObjectFile(MemoryBufferRef Object);
0400
0401 static Expected<std::unique_ptr<WasmObjectFile>>
0402 createWasmObjectFile(MemoryBufferRef Object);
0403 };
0404
0405
0406
0407 class SectionFilterIterator {
0408 public:
0409 SectionFilterIterator(SectionFilterPredicate Pred,
0410 const section_iterator &Begin,
0411 const section_iterator &End)
0412 : Predicate(std::move(Pred)), Iterator(Begin), End(End) {
0413 scanPredicate();
0414 }
0415 const SectionRef &operator*() const { return *Iterator; }
0416 SectionFilterIterator &operator++() {
0417 ++Iterator;
0418 scanPredicate();
0419 return *this;
0420 }
0421 bool operator!=(const SectionFilterIterator &Other) const {
0422 return Iterator != Other.Iterator;
0423 }
0424
0425 private:
0426 void scanPredicate() {
0427 while (Iterator != End && !Predicate(*Iterator)) {
0428 ++Iterator;
0429 }
0430 }
0431 SectionFilterPredicate Predicate;
0432 section_iterator Iterator;
0433 section_iterator End;
0434 };
0435
0436
0437
0438 class SectionFilter {
0439 public:
0440 SectionFilter(SectionFilterPredicate Pred, const ObjectFile &Obj)
0441 : Predicate(std::move(Pred)), Object(Obj) {}
0442 SectionFilterIterator begin() {
0443 return SectionFilterIterator(Predicate, Object.section_begin(),
0444 Object.section_end());
0445 }
0446 SectionFilterIterator end() {
0447 return SectionFilterIterator(Predicate, Object.section_end(),
0448 Object.section_end());
0449 }
0450
0451 private:
0452 SectionFilterPredicate Predicate;
0453 const ObjectFile &Object;
0454 };
0455
0456
0457 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
0458 : BasicSymbolRef(SymbolP, Owner) {}
0459
0460 inline Expected<StringRef> SymbolRef::getName() const {
0461 return getObject()->getSymbolName(getRawDataRefImpl());
0462 }
0463
0464 inline Expected<uint64_t> SymbolRef::getAddress() const {
0465 return getObject()->getSymbolAddress(getRawDataRefImpl());
0466 }
0467
0468 inline Expected<uint64_t> SymbolRef::getValue() const {
0469 return getObject()->getSymbolValue(getRawDataRefImpl());
0470 }
0471
0472 inline uint32_t SymbolRef::getAlignment() const {
0473 return getObject()->getSymbolAlignment(getRawDataRefImpl());
0474 }
0475
0476 inline uint64_t SymbolRef::getCommonSize() const {
0477 return getObject()->getCommonSymbolSize(getRawDataRefImpl());
0478 }
0479
0480 inline Expected<section_iterator> SymbolRef::getSection() const {
0481 return getObject()->getSymbolSection(getRawDataRefImpl());
0482 }
0483
0484 inline Expected<SymbolRef::Type> SymbolRef::getType() const {
0485 return getObject()->getSymbolType(getRawDataRefImpl());
0486 }
0487
0488 inline const ObjectFile *SymbolRef::getObject() const {
0489 const SymbolicFile *O = BasicSymbolRef::getObject();
0490 return cast<ObjectFile>(O);
0491 }
0492
0493
0494 inline SectionRef::SectionRef(DataRefImpl SectionP,
0495 const ObjectFile *Owner)
0496 : SectionPimpl(SectionP)
0497 , OwningObject(Owner) {}
0498
0499 inline bool SectionRef::operator==(const SectionRef &Other) const {
0500 return OwningObject == Other.OwningObject &&
0501 SectionPimpl == Other.SectionPimpl;
0502 }
0503
0504 inline bool SectionRef::operator!=(const SectionRef &Other) const {
0505 return !(*this == Other);
0506 }
0507
0508 inline bool SectionRef::operator<(const SectionRef &Other) const {
0509 assert(OwningObject == Other.OwningObject);
0510 return SectionPimpl < Other.SectionPimpl;
0511 }
0512
0513 inline void SectionRef::moveNext() {
0514 return OwningObject->moveSectionNext(SectionPimpl);
0515 }
0516
0517 inline Expected<StringRef> SectionRef::getName() const {
0518 return OwningObject->getSectionName(SectionPimpl);
0519 }
0520
0521 inline uint64_t SectionRef::getAddress() const {
0522 return OwningObject->getSectionAddress(SectionPimpl);
0523 }
0524
0525 inline uint64_t SectionRef::getIndex() const {
0526 return OwningObject->getSectionIndex(SectionPimpl);
0527 }
0528
0529 inline uint64_t SectionRef::getSize() const {
0530 return OwningObject->getSectionSize(SectionPimpl);
0531 }
0532
0533 inline Expected<StringRef> SectionRef::getContents() const {
0534 Expected<ArrayRef<uint8_t>> Res =
0535 OwningObject->getSectionContents(SectionPimpl);
0536 if (!Res)
0537 return Res.takeError();
0538 return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
0539 }
0540
0541 inline Align SectionRef::getAlignment() const {
0542 return MaybeAlign(OwningObject->getSectionAlignment(SectionPimpl))
0543 .valueOrOne();
0544 }
0545
0546 inline bool SectionRef::isCompressed() const {
0547 return OwningObject->isSectionCompressed(SectionPimpl);
0548 }
0549
0550 inline bool SectionRef::isText() const {
0551 return OwningObject->isSectionText(SectionPimpl);
0552 }
0553
0554 inline bool SectionRef::isData() const {
0555 return OwningObject->isSectionData(SectionPimpl);
0556 }
0557
0558 inline bool SectionRef::isBSS() const {
0559 return OwningObject->isSectionBSS(SectionPimpl);
0560 }
0561
0562 inline bool SectionRef::isVirtual() const {
0563 return OwningObject->isSectionVirtual(SectionPimpl);
0564 }
0565
0566 inline bool SectionRef::isBitcode() const {
0567 return OwningObject->isSectionBitcode(SectionPimpl);
0568 }
0569
0570 inline bool SectionRef::isStripped() const {
0571 return OwningObject->isSectionStripped(SectionPimpl);
0572 }
0573
0574 inline bool SectionRef::isBerkeleyText() const {
0575 return OwningObject->isBerkeleyText(SectionPimpl);
0576 }
0577
0578 inline bool SectionRef::isBerkeleyData() const {
0579 return OwningObject->isBerkeleyData(SectionPimpl);
0580 }
0581
0582 inline bool SectionRef::isDebugSection() const {
0583 return OwningObject->isDebugSection(SectionPimpl);
0584 }
0585
0586 inline relocation_iterator SectionRef::relocation_begin() const {
0587 return OwningObject->section_rel_begin(SectionPimpl);
0588 }
0589
0590 inline relocation_iterator SectionRef::relocation_end() const {
0591 return OwningObject->section_rel_end(SectionPimpl);
0592 }
0593
0594 inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
0595 return OwningObject->getRelocatedSection(SectionPimpl);
0596 }
0597
0598 inline DataRefImpl SectionRef::getRawDataRefImpl() const {
0599 return SectionPimpl;
0600 }
0601
0602 inline const ObjectFile *SectionRef::getObject() const {
0603 return OwningObject;
0604 }
0605
0606
0607 inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
0608 const ObjectFile *Owner)
0609 : RelocationPimpl(RelocationP)
0610 , OwningObject(Owner) {}
0611
0612 inline bool RelocationRef::operator==(const RelocationRef &Other) const {
0613 return RelocationPimpl == Other.RelocationPimpl;
0614 }
0615
0616 inline void RelocationRef::moveNext() {
0617 return OwningObject->moveRelocationNext(RelocationPimpl);
0618 }
0619
0620 inline uint64_t RelocationRef::getOffset() const {
0621 return OwningObject->getRelocationOffset(RelocationPimpl);
0622 }
0623
0624 inline symbol_iterator RelocationRef::getSymbol() const {
0625 return OwningObject->getRelocationSymbol(RelocationPimpl);
0626 }
0627
0628 inline uint64_t RelocationRef::getType() const {
0629 return OwningObject->getRelocationType(RelocationPimpl);
0630 }
0631
0632 inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
0633 return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
0634 }
0635
0636 inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
0637 return RelocationPimpl;
0638 }
0639
0640 inline const ObjectFile *RelocationRef::getObject() const {
0641 return OwningObject;
0642 }
0643
0644 }
0645
0646 template <> struct DenseMapInfo<object::SectionRef> {
0647 static bool isEqual(const object::SectionRef &A,
0648 const object::SectionRef &B) {
0649 return A == B;
0650 }
0651 static object::SectionRef getEmptyKey() {
0652 return object::SectionRef({}, nullptr);
0653 }
0654 static object::SectionRef getTombstoneKey() {
0655 object::DataRefImpl TS;
0656 TS.p = (uintptr_t)-1;
0657 return object::SectionRef(TS, nullptr);
0658 }
0659 static unsigned getHashValue(const object::SectionRef &Sec) {
0660 object::DataRefImpl Raw = Sec.getRawDataRefImpl();
0661 return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
0662 }
0663 };
0664
0665 }
0666
0667 #endif