1 //===- GOFFObjectFile.h - GOFF object file implementation -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares the GOFFObjectFile class. 10 // Record classes and derivatives are also declared and implemented. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OBJECT_GOFFOBJECTFILE_H 15 #define LLVM_OBJECT_GOFFOBJECTFILE_H 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/IndexedMap.h" 19 #include "llvm/BinaryFormat/GOFF.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include "llvm/Support/ConvertEBCDIC.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include "llvm/TargetParser/SubtargetFeature.h" 25 #include "llvm/TargetParser/Triple.h" 26 27 namespace llvm { 28 29 namespace object { 30 31 class GOFFObjectFile : public ObjectFile { 32 friend class GOFFSymbolRef; 33 34 IndexedMap<const uint8_t *> EsdPtrs; // Indexed by EsdId. 35 SmallVector<const uint8_t *, 256> TextPtrs; 36 37 mutable DenseMap<uint32_t, std::pair<size_t, std::unique_ptr<char[]>>> 38 EsdNamesCache; 39 40 typedef DataRefImpl SectionEntryImpl; 41 // (EDID, 0) code, r/o data section 42 // (EDID,PRID) r/w data section 43 SmallVector<SectionEntryImpl, 256> SectionList; 44 mutable DenseMap<uint32_t, SmallVector<uint8_t>> SectionDataCache; 45 46 public: 47 Expected<StringRef> getSymbolName(SymbolRef Symbol) const; 48 49 GOFFObjectFile(MemoryBufferRef Object, Error &Err); classof(const Binary * V)50 static inline bool classof(const Binary *V) { return V->isGOFF(); } 51 section_iterator section_begin() const override; 52 section_iterator section_end() const override; 53 getBytesInAddress()54 uint8_t getBytesInAddress() const override { return 8; } 55 getFileFormatName()56 StringRef getFileFormatName() const override { return "GOFF-SystemZ"; } 57 getArch()58 Triple::ArchType getArch() const override { return Triple::systemz; } 59 getFeatures()60 Expected<SubtargetFeatures> getFeatures() const override { return SubtargetFeatures(); } 61 isRelocatableObject()62 bool isRelocatableObject() const override { return true; } 63 64 void moveSymbolNext(DataRefImpl &Symb) const override; 65 basic_symbol_iterator symbol_begin() const override; 66 basic_symbol_iterator symbol_end() const override; 67 is64Bit()68 bool is64Bit() const override { 69 return true; 70 } 71 72 bool isSectionNoLoad(DataRefImpl Sec) const; 73 bool isSectionReadOnlyData(DataRefImpl Sec) const; 74 bool isSectionZeroInit(DataRefImpl Sec) const; 75 76 private: 77 // SymbolRef. 78 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 79 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 80 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 81 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 82 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override; 83 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 84 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 85 uint64_t getSymbolSize(DataRefImpl Symb) const; 86 87 const uint8_t *getSymbolEsdRecord(DataRefImpl Symb) const; 88 bool isSymbolUnresolved(DataRefImpl Symb) const; 89 bool isSymbolIndirect(DataRefImpl Symb) const; 90 91 // SectionRef. 92 void moveSectionNext(DataRefImpl &Sec) const override; 93 virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const override; 94 uint64_t getSectionAddress(DataRefImpl Sec) const override; 95 uint64_t getSectionSize(DataRefImpl Sec) const override; 96 virtual Expected<ArrayRef<uint8_t>> 97 getSectionContents(DataRefImpl Sec) const override; getSectionIndex(DataRefImpl Sec)98 uint64_t getSectionIndex(DataRefImpl Sec) const override { return Sec.d.a; } 99 uint64_t getSectionAlignment(DataRefImpl Sec) const override; isSectionCompressed(DataRefImpl Sec)100 bool isSectionCompressed(DataRefImpl Sec) const override { return false; } 101 bool isSectionText(DataRefImpl Sec) const override; 102 bool isSectionData(DataRefImpl Sec) const override; isSectionBSS(DataRefImpl Sec)103 bool isSectionBSS(DataRefImpl Sec) const override { return false; } isSectionVirtual(DataRefImpl Sec)104 bool isSectionVirtual(DataRefImpl Sec) const override { return false; } section_rel_begin(DataRefImpl Sec)105 relocation_iterator section_rel_begin(DataRefImpl Sec) const override { 106 return relocation_iterator(RelocationRef(Sec, this)); 107 } section_rel_end(DataRefImpl Sec)108 relocation_iterator section_rel_end(DataRefImpl Sec) const override { 109 return relocation_iterator(RelocationRef(Sec, this)); 110 } 111 112 const uint8_t *getSectionEdEsdRecord(DataRefImpl &Sec) const; 113 const uint8_t *getSectionPrEsdRecord(DataRefImpl &Sec) const; 114 const uint8_t *getSectionEdEsdRecord(uint32_t SectionIndex) const; 115 const uint8_t *getSectionPrEsdRecord(uint32_t SectionIndex) const; 116 uint32_t getSectionDefEsdId(DataRefImpl &Sec) const; 117 118 // RelocationRef. moveRelocationNext(DataRefImpl & Rel)119 void moveRelocationNext(DataRefImpl &Rel) const override {} getRelocationOffset(DataRefImpl Rel)120 uint64_t getRelocationOffset(DataRefImpl Rel) const override { return 0; } getRelocationSymbol(DataRefImpl Rel)121 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override { 122 DataRefImpl Temp; 123 return basic_symbol_iterator(SymbolRef(Temp, this)); 124 } getRelocationType(DataRefImpl Rel)125 uint64_t getRelocationType(DataRefImpl Rel) const override { return 0; } getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result)126 void getRelocationTypeName(DataRefImpl Rel, 127 SmallVectorImpl<char> &Result) const override {} 128 }; 129 130 class GOFFSymbolRef : public SymbolRef { 131 public: GOFFSymbolRef(const SymbolRef & B)132 GOFFSymbolRef(const SymbolRef &B) : SymbolRef(B) { 133 assert(isa<GOFFObjectFile>(SymbolRef::getObject())); 134 } 135 getObject()136 const GOFFObjectFile *getObject() const { 137 return cast<GOFFObjectFile>(BasicSymbolRef::getObject()); 138 } 139 getSymbolGOFFFlags()140 Expected<uint32_t> getSymbolGOFFFlags() const { 141 return getObject()->getSymbolFlags(getRawDataRefImpl()); 142 } 143 getSymbolGOFFType()144 Expected<SymbolRef::Type> getSymbolGOFFType() const { 145 return getObject()->getSymbolType(getRawDataRefImpl()); 146 } 147 getSize()148 uint64_t getSize() const { 149 return getObject()->getSymbolSize(getRawDataRefImpl()); 150 } 151 }; 152 153 } // namespace object 154 155 } // namespace llvm 156 157 #endif 158