xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/Object/GOFFObjectFile.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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