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); |
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 | |
54 | uint8_t getBytesInAddress() const override { return 8; } |
55 | |
56 | StringRef getFileFormatName() const override { return "GOFF-SystemZ" ; } |
57 | |
58 | Triple::ArchType getArch() const override { return Triple::systemz; } |
59 | |
60 | Expected<SubtargetFeatures> getFeatures() const override { return SubtargetFeatures(); } |
61 | |
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 | |
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; |
98 | uint64_t getSectionIndex(DataRefImpl Sec) const override { return Sec.d.a; } |
99 | uint64_t getSectionAlignment(DataRefImpl Sec) const override; |
100 | bool isSectionCompressed(DataRefImpl Sec) const override { return false; } |
101 | bool isSectionText(DataRefImpl Sec) const override; |
102 | bool isSectionData(DataRefImpl Sec) const override; |
103 | bool isSectionBSS(DataRefImpl Sec) const override { return false; } |
104 | bool isSectionVirtual(DataRefImpl Sec) const override { return false; } |
105 | relocation_iterator section_rel_begin(DataRefImpl Sec) const override { |
106 | return relocation_iterator(RelocationRef(Sec, this)); |
107 | } |
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. |
119 | void moveRelocationNext(DataRefImpl &Rel) const override {} |
120 | uint64_t getRelocationOffset(DataRefImpl Rel) const override { return 0; } |
121 | symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override { |
122 | DataRefImpl Temp; |
123 | return basic_symbol_iterator(SymbolRef(Temp, this)); |
124 | } |
125 | uint64_t getRelocationType(DataRefImpl Rel) const override { return 0; } |
126 | void getRelocationTypeName(DataRefImpl Rel, |
127 | SmallVectorImpl<char> &Result) const override {} |
128 | }; |
129 | |
130 | class GOFFSymbolRef : public SymbolRef { |
131 | public: |
132 | GOFFSymbolRef(const SymbolRef &B) : SymbolRef(B) { |
133 | assert(isa<GOFFObjectFile>(SymbolRef::getObject())); |
134 | } |
135 | |
136 | const GOFFObjectFile *getObject() const { |
137 | return cast<GOFFObjectFile>(Val: BasicSymbolRef::getObject()); |
138 | } |
139 | |
140 | Expected<uint32_t> getSymbolGOFFFlags() const { |
141 | return getObject()->getSymbolFlags(Symb: getRawDataRefImpl()); |
142 | } |
143 | |
144 | Expected<SymbolRef::Type> getSymbolGOFFType() const { |
145 | return getObject()->getSymbolType(Symb: getRawDataRefImpl()); |
146 | } |
147 | |
148 | uint64_t getSize() const { |
149 | return getObject()->getSymbolSize(Symb: getRawDataRefImpl()); |
150 | } |
151 | }; |
152 | |
153 | } // namespace object |
154 | |
155 | } // namespace llvm |
156 | |
157 | #endif |
158 | |