106c3fb27SDimitry Andric //===- GOFFObjectFile.h - GOFF object file implementation -------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric // 906c3fb27SDimitry Andric // This file declares the GOFFObjectFile class. 1006c3fb27SDimitry Andric // Record classes and derivatives are also declared and implemented. 1106c3fb27SDimitry Andric // 1206c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1306c3fb27SDimitry Andric 1406c3fb27SDimitry Andric #ifndef LLVM_OBJECT_GOFFOBJECTFILE_H 1506c3fb27SDimitry Andric #define LLVM_OBJECT_GOFFOBJECTFILE_H 1606c3fb27SDimitry Andric 1706c3fb27SDimitry Andric #include "llvm/ADT/DenseMap.h" 1806c3fb27SDimitry Andric #include "llvm/ADT/IndexedMap.h" 1906c3fb27SDimitry Andric #include "llvm/BinaryFormat/GOFF.h" 2006c3fb27SDimitry Andric #include "llvm/Object/ObjectFile.h" 2106c3fb27SDimitry Andric #include "llvm/Support/ConvertEBCDIC.h" 2206c3fb27SDimitry Andric #include "llvm/Support/Debug.h" 2306c3fb27SDimitry Andric #include "llvm/Support/raw_ostream.h" 2406c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 2506c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 2606c3fb27SDimitry Andric 2706c3fb27SDimitry Andric namespace llvm { 2806c3fb27SDimitry Andric 2906c3fb27SDimitry Andric namespace object { 3006c3fb27SDimitry Andric 3106c3fb27SDimitry Andric class GOFFObjectFile : public ObjectFile { 32*0fca6ea1SDimitry Andric friend class GOFFSymbolRef; 33*0fca6ea1SDimitry Andric 3406c3fb27SDimitry Andric IndexedMap<const uint8_t *> EsdPtrs; // Indexed by EsdId. 35*0fca6ea1SDimitry Andric SmallVector<const uint8_t *, 256> TextPtrs; 3606c3fb27SDimitry Andric 3706c3fb27SDimitry Andric mutable DenseMap<uint32_t, std::pair<size_t, std::unique_ptr<char[]>>> 3806c3fb27SDimitry Andric EsdNamesCache; 3906c3fb27SDimitry Andric 4006c3fb27SDimitry Andric typedef DataRefImpl SectionEntryImpl; 4106c3fb27SDimitry Andric // (EDID, 0) code, r/o data section 4206c3fb27SDimitry Andric // (EDID,PRID) r/w data section 4306c3fb27SDimitry Andric SmallVector<SectionEntryImpl, 256> SectionList; 44*0fca6ea1SDimitry Andric mutable DenseMap<uint32_t, SmallVector<uint8_t>> SectionDataCache; 4506c3fb27SDimitry Andric 4606c3fb27SDimitry Andric public: 4706c3fb27SDimitry Andric Expected<StringRef> getSymbolName(SymbolRef Symbol) const; 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric GOFFObjectFile(MemoryBufferRef Object, Error &Err); 5006c3fb27SDimitry Andric static inline bool classof(const Binary *V) { return V->isGOFF(); } 5106c3fb27SDimitry Andric section_iterator section_begin() const override; 5206c3fb27SDimitry Andric section_iterator section_end() const override; 5306c3fb27SDimitry Andric 5406c3fb27SDimitry Andric uint8_t getBytesInAddress() const override { return 8; } 5506c3fb27SDimitry Andric 5606c3fb27SDimitry Andric StringRef getFileFormatName() const override { return "GOFF-SystemZ"; } 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric Triple::ArchType getArch() const override { return Triple::systemz; } 5906c3fb27SDimitry Andric 6006c3fb27SDimitry Andric Expected<SubtargetFeatures> getFeatures() const override { return SubtargetFeatures(); } 6106c3fb27SDimitry Andric 6206c3fb27SDimitry Andric bool isRelocatableObject() const override { return true; } 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric void moveSymbolNext(DataRefImpl &Symb) const override; 6506c3fb27SDimitry Andric basic_symbol_iterator symbol_begin() const override; 6606c3fb27SDimitry Andric basic_symbol_iterator symbol_end() const override; 6706c3fb27SDimitry Andric 6806c3fb27SDimitry Andric bool is64Bit() const override { 6906c3fb27SDimitry Andric return true; 7006c3fb27SDimitry Andric } 7106c3fb27SDimitry Andric 72*0fca6ea1SDimitry Andric bool isSectionNoLoad(DataRefImpl Sec) const; 73*0fca6ea1SDimitry Andric bool isSectionReadOnlyData(DataRefImpl Sec) const; 74*0fca6ea1SDimitry Andric bool isSectionZeroInit(DataRefImpl Sec) const; 75*0fca6ea1SDimitry Andric 7606c3fb27SDimitry Andric private: 7706c3fb27SDimitry Andric // SymbolRef. 7806c3fb27SDimitry Andric Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 7906c3fb27SDimitry Andric Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 8006c3fb27SDimitry Andric uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 8106c3fb27SDimitry Andric uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 8206c3fb27SDimitry Andric Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override; 8306c3fb27SDimitry Andric Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 8406c3fb27SDimitry Andric Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 85*0fca6ea1SDimitry Andric uint64_t getSymbolSize(DataRefImpl Symb) const; 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric const uint8_t *getSymbolEsdRecord(DataRefImpl Symb) const; 8806c3fb27SDimitry Andric bool isSymbolUnresolved(DataRefImpl Symb) const; 8906c3fb27SDimitry Andric bool isSymbolIndirect(DataRefImpl Symb) const; 9006c3fb27SDimitry Andric 9106c3fb27SDimitry Andric // SectionRef. 92*0fca6ea1SDimitry Andric void moveSectionNext(DataRefImpl &Sec) const override; 93*0fca6ea1SDimitry Andric virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const override; 94*0fca6ea1SDimitry Andric uint64_t getSectionAddress(DataRefImpl Sec) const override; 95*0fca6ea1SDimitry Andric uint64_t getSectionSize(DataRefImpl Sec) const override; 9606c3fb27SDimitry Andric virtual Expected<ArrayRef<uint8_t>> 97*0fca6ea1SDimitry Andric getSectionContents(DataRefImpl Sec) const override; 98*0fca6ea1SDimitry Andric uint64_t getSectionIndex(DataRefImpl Sec) const override { return Sec.d.a; } 99*0fca6ea1SDimitry Andric uint64_t getSectionAlignment(DataRefImpl Sec) const override; 10006c3fb27SDimitry Andric bool isSectionCompressed(DataRefImpl Sec) const override { return false; } 101*0fca6ea1SDimitry Andric bool isSectionText(DataRefImpl Sec) const override; 102*0fca6ea1SDimitry Andric bool isSectionData(DataRefImpl Sec) const override; 10306c3fb27SDimitry Andric bool isSectionBSS(DataRefImpl Sec) const override { return false; } 10406c3fb27SDimitry Andric bool isSectionVirtual(DataRefImpl Sec) const override { return false; } 10506c3fb27SDimitry Andric relocation_iterator section_rel_begin(DataRefImpl Sec) const override { 10606c3fb27SDimitry Andric return relocation_iterator(RelocationRef(Sec, this)); 10706c3fb27SDimitry Andric } 10806c3fb27SDimitry Andric relocation_iterator section_rel_end(DataRefImpl Sec) const override { 10906c3fb27SDimitry Andric return relocation_iterator(RelocationRef(Sec, this)); 11006c3fb27SDimitry Andric } 11106c3fb27SDimitry Andric 11206c3fb27SDimitry Andric const uint8_t *getSectionEdEsdRecord(DataRefImpl &Sec) const; 11306c3fb27SDimitry Andric const uint8_t *getSectionPrEsdRecord(DataRefImpl &Sec) const; 11406c3fb27SDimitry Andric const uint8_t *getSectionEdEsdRecord(uint32_t SectionIndex) const; 11506c3fb27SDimitry Andric const uint8_t *getSectionPrEsdRecord(uint32_t SectionIndex) const; 116*0fca6ea1SDimitry Andric uint32_t getSectionDefEsdId(DataRefImpl &Sec) const; 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric // RelocationRef. 11906c3fb27SDimitry Andric void moveRelocationNext(DataRefImpl &Rel) const override {} 12006c3fb27SDimitry Andric uint64_t getRelocationOffset(DataRefImpl Rel) const override { return 0; } 12106c3fb27SDimitry Andric symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override { 12206c3fb27SDimitry Andric DataRefImpl Temp; 12306c3fb27SDimitry Andric return basic_symbol_iterator(SymbolRef(Temp, this)); 12406c3fb27SDimitry Andric } 12506c3fb27SDimitry Andric uint64_t getRelocationType(DataRefImpl Rel) const override { return 0; } 12606c3fb27SDimitry Andric void getRelocationTypeName(DataRefImpl Rel, 12706c3fb27SDimitry Andric SmallVectorImpl<char> &Result) const override {} 12806c3fb27SDimitry Andric }; 12906c3fb27SDimitry Andric 130*0fca6ea1SDimitry Andric class GOFFSymbolRef : public SymbolRef { 131*0fca6ea1SDimitry Andric public: 132*0fca6ea1SDimitry Andric GOFFSymbolRef(const SymbolRef &B) : SymbolRef(B) { 133*0fca6ea1SDimitry Andric assert(isa<GOFFObjectFile>(SymbolRef::getObject())); 134*0fca6ea1SDimitry Andric } 135*0fca6ea1SDimitry Andric 136*0fca6ea1SDimitry Andric const GOFFObjectFile *getObject() const { 137*0fca6ea1SDimitry Andric return cast<GOFFObjectFile>(BasicSymbolRef::getObject()); 138*0fca6ea1SDimitry Andric } 139*0fca6ea1SDimitry Andric 140*0fca6ea1SDimitry Andric Expected<uint32_t> getSymbolGOFFFlags() const { 141*0fca6ea1SDimitry Andric return getObject()->getSymbolFlags(getRawDataRefImpl()); 142*0fca6ea1SDimitry Andric } 143*0fca6ea1SDimitry Andric 144*0fca6ea1SDimitry Andric Expected<SymbolRef::Type> getSymbolGOFFType() const { 145*0fca6ea1SDimitry Andric return getObject()->getSymbolType(getRawDataRefImpl()); 146*0fca6ea1SDimitry Andric } 147*0fca6ea1SDimitry Andric 148*0fca6ea1SDimitry Andric uint64_t getSize() const { 149*0fca6ea1SDimitry Andric return getObject()->getSymbolSize(getRawDataRefImpl()); 150*0fca6ea1SDimitry Andric } 151*0fca6ea1SDimitry Andric }; 152*0fca6ea1SDimitry Andric 15306c3fb27SDimitry Andric } // namespace object 15406c3fb27SDimitry Andric 15506c3fb27SDimitry Andric } // namespace llvm 15606c3fb27SDimitry Andric 15706c3fb27SDimitry Andric #endif 158