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