1//===- GOFF.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_GOFF_H
15#define LLVM_OBJECT_GOFF_H
16
17#include "llvm/ADT/SmallString.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/BinaryFormat/GOFF.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/Endian.h"
22#include "llvm/Support/raw_ostream.h"
23
24namespace llvm {
25namespace object {
26
27/// \brief Represents a GOFF physical record.
28///
29/// Specifies protected member functions to manipulate the record. These should
30/// be called from deriving classes to change values as that record specifies.
31class Record {
32public:
33 static Error getContinuousData(const uint8_t *Record, uint16_t DataLength,
34 int DataIndex, SmallString<256> &CompleteData);
35
36 static bool isContinued(const uint8_t *Record) {
37 uint8_t IsContinued;
38 getBits(Bytes: Record, ByteIndex: 1, BitIndex: 7, Length: 1, Value&: IsContinued);
39 return IsContinued;
40 }
41
42 static bool isContinuation(const uint8_t *Record) {
43 uint8_t IsContinuation;
44 getBits(Bytes: Record, ByteIndex: 1, BitIndex: 6, Length: 1, Value&: IsContinuation);
45 return IsContinuation;
46 }
47
48protected:
49 /// \brief Get bit field of specified byte.
50 ///
51 /// Used to pack bit fields into one byte. Fields are packed left to right.
52 /// Bit index zero is the most significant bit of the byte.
53 ///
54 /// \param ByteIndex index of byte the field is in.
55 /// \param BitIndex index of first bit of field.
56 /// \param Length length of bit field.
57 /// \param Value value of bit field.
58 static void getBits(const uint8_t *Bytes, uint8_t ByteIndex, uint8_t BitIndex,
59 uint8_t Length, uint8_t &Value) {
60 assert(ByteIndex < GOFF::RecordLength && "Byte index out of bounds!");
61 assert(BitIndex < 8 && "Bit index out of bounds!");
62 assert(Length + BitIndex <= 8 && "Bit length too long!");
63
64 get<uint8_t>(Bytes, ByteIndex, Value);
65 Value = (Value >> (8 - BitIndex - Length)) & ((1 << Length) - 1);
66 }
67
68 template <class T>
69 static void get(const uint8_t *Bytes, uint8_t ByteIndex, T &Value) {
70 assert(ByteIndex + sizeof(T) <= GOFF::RecordLength &&
71 "Byte index out of bounds!");
72 Value = support::endian::read<T, llvm::endianness::big>(&Bytes[ByteIndex]);
73 }
74};
75
76class TXTRecord : public Record {
77public:
78 /// \brief Maximum length of data; any more must go in continuation.
79 static const uint8_t TXTMaxDataLength = 56;
80
81 static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
82
83 static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId) {
84 get<uint32_t>(Bytes: Record, ByteIndex: 4, Value&: EsdId);
85 }
86
87 static void getOffset(const uint8_t *Record, uint32_t &Offset) {
88 get<uint32_t>(Bytes: Record, ByteIndex: 12, Value&: Offset);
89 }
90
91 static void getDataLength(const uint8_t *Record, uint16_t &Length) {
92 get<uint16_t>(Bytes: Record, ByteIndex: 22, Value&: Length);
93 }
94};
95
96class HDRRecord : public Record {
97public:
98 static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
99
100 static uint16_t getPropertyModuleLength(const uint8_t *Record) {
101 uint16_t Length;
102 get<uint16_t>(Bytes: Record, ByteIndex: 52, Value&: Length);
103 return Length;
104 }
105};
106
107class ESDRecord : public Record {
108public:
109 /// \brief Number of bytes for name; any more must go in continuation.
110 /// This is the number of bytes that can fit into the data field of an ESD
111 /// record.
112 static const uint8_t ESDMaxUncontinuedNameLength = 8;
113
114 /// \brief Maximum name length for ESD records and continuations.
115 /// This is the number of bytes that can fit into the data field of an ESD
116 /// record AND following continuations. This is limited fundamentally by the
117 /// 16 bit SIGNED length field.
118 static const uint16_t MaxNameLength = 32 * 1024;
119
120public:
121 static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
122
123 // ESD Get routines.
124 static void getSymbolType(const uint8_t *Record,
125 GOFF::ESDSymbolType &SymbolType) {
126 uint8_t Value;
127 get<uint8_t>(Bytes: Record, ByteIndex: 3, Value);
128 SymbolType = (GOFF::ESDSymbolType)Value;
129 }
130
131 static void getEsdId(const uint8_t *Record, uint32_t &EsdId) {
132 get<uint32_t>(Bytes: Record, ByteIndex: 4, Value&: EsdId);
133 }
134
135 static void getParentEsdId(const uint8_t *Record, uint32_t &EsdId) {
136 get<uint32_t>(Bytes: Record, ByteIndex: 8, Value&: EsdId);
137 }
138
139 static void getOffset(const uint8_t *Record, uint32_t &Offset) {
140 get<uint32_t>(Bytes: Record, ByteIndex: 16, Value&: Offset);
141 }
142
143 static void getLength(const uint8_t *Record, uint32_t &Length) {
144 get<uint32_t>(Bytes: Record, ByteIndex: 24, Value&: Length);
145 }
146
147 static void getNameSpaceId(const uint8_t *Record, GOFF::ESDNameSpaceId &Id) {
148 uint8_t Value;
149 get<uint8_t>(Bytes: Record, ByteIndex: 40, Value);
150 Id = (GOFF::ESDNameSpaceId)Value;
151 }
152
153 static void getFillBytePresent(const uint8_t *Record, bool &Present) {
154 uint8_t Value;
155 getBits(Bytes: Record, ByteIndex: 41, BitIndex: 0, Length: 1, Value);
156 Present = (bool)Value;
157 }
158
159 static void getNameMangled(const uint8_t *Record, bool &Mangled) {
160 uint8_t Value;
161 getBits(Bytes: Record, ByteIndex: 41, BitIndex: 1, Length: 1, Value);
162 Mangled = (bool)Value;
163 }
164
165 static void getRenamable(const uint8_t *Record, bool &Renamable) {
166 uint8_t Value;
167 getBits(Bytes: Record, ByteIndex: 41, BitIndex: 2, Length: 1, Value);
168 Renamable = (bool)Value;
169 }
170
171 static void getRemovable(const uint8_t *Record, bool &Removable) {
172 uint8_t Value;
173 getBits(Bytes: Record, ByteIndex: 41, BitIndex: 3, Length: 1, Value);
174 Removable = (bool)Value;
175 }
176
177 static void getFillByteValue(const uint8_t *Record, uint8_t &Fill) {
178 get<uint8_t>(Bytes: Record, ByteIndex: 42, Value&: Fill);
179 }
180
181 static void getAdaEsdId(const uint8_t *Record, uint32_t &EsdId) {
182 get<uint32_t>(Bytes: Record, ByteIndex: 44, Value&: EsdId);
183 }
184
185 static void getSortPriority(const uint8_t *Record, uint32_t &Priority) {
186 get<uint32_t>(Bytes: Record, ByteIndex: 48, Value&: Priority);
187 }
188
189 static void getAmode(const uint8_t *Record, GOFF::ESDAmode &Amode) {
190 uint8_t Value;
191 get<uint8_t>(Bytes: Record, ByteIndex: 60, Value);
192 Amode = (GOFF::ESDAmode)Value;
193 }
194
195 static void getRmode(const uint8_t *Record, GOFF::ESDRmode &Rmode) {
196 uint8_t Value;
197 get<uint8_t>(Bytes: Record, ByteIndex: 61, Value);
198 Rmode = (GOFF::ESDRmode)Value;
199 }
200
201 static void getTextStyle(const uint8_t *Record, GOFF::ESDTextStyle &Style) {
202 uint8_t Value;
203 getBits(Bytes: Record, ByteIndex: 62, BitIndex: 0, Length: 4, Value);
204 Style = (GOFF::ESDTextStyle)Value;
205 }
206
207 static void getBindingAlgorithm(const uint8_t *Record,
208 GOFF::ESDBindingAlgorithm &Algorithm) {
209 uint8_t Value;
210 getBits(Bytes: Record, ByteIndex: 62, BitIndex: 4, Length: 4, Value);
211 Algorithm = (GOFF::ESDBindingAlgorithm)Value;
212 }
213
214 static void getTaskingBehavior(const uint8_t *Record,
215 GOFF::ESDTaskingBehavior &TaskingBehavior) {
216 uint8_t Value;
217 getBits(Bytes: Record, ByteIndex: 63, BitIndex: 0, Length: 3, Value);
218 TaskingBehavior = (GOFF::ESDTaskingBehavior)Value;
219 }
220
221 static void getReadOnly(const uint8_t *Record, bool &ReadOnly) {
222 uint8_t Value;
223 getBits(Bytes: Record, ByteIndex: 63, BitIndex: 4, Length: 1, Value);
224 ReadOnly = (bool)Value;
225 }
226
227 static void getExecutable(const uint8_t *Record,
228 GOFF::ESDExecutable &Executable) {
229 uint8_t Value;
230 getBits(Bytes: Record, ByteIndex: 63, BitIndex: 5, Length: 3, Value);
231 Executable = (GOFF::ESDExecutable)Value;
232 }
233
234 static void getDuplicateSeverity(const uint8_t *Record,
235 GOFF::ESDDuplicateSymbolSeverity &DSS) {
236 uint8_t Value;
237 getBits(Bytes: Record, ByteIndex: 64, BitIndex: 2, Length: 2, Value);
238 DSS = (GOFF::ESDDuplicateSymbolSeverity)Value;
239 }
240
241 static void getBindingStrength(const uint8_t *Record,
242 GOFF::ESDBindingStrength &Strength) {
243 uint8_t Value;
244 getBits(Bytes: Record, ByteIndex: 64, BitIndex: 4, Length: 4, Value);
245 Strength = (GOFF::ESDBindingStrength)Value;
246 }
247
248 static void getLoadingBehavior(const uint8_t *Record,
249 GOFF::ESDLoadingBehavior &Behavior) {
250 uint8_t Value;
251 getBits(Bytes: Record, ByteIndex: 65, BitIndex: 0, Length: 2, Value);
252 Behavior = (GOFF::ESDLoadingBehavior)Value;
253 }
254
255 static void getIndirectReference(const uint8_t *Record, bool &Indirect) {
256 uint8_t Value;
257 getBits(Bytes: Record, ByteIndex: 65, BitIndex: 3, Length: 1, Value);
258 Indirect = (bool)Value;
259 }
260
261 static void getBindingScope(const uint8_t *Record,
262 GOFF::ESDBindingScope &Scope) {
263 uint8_t Value;
264 getBits(Bytes: Record, ByteIndex: 65, BitIndex: 4, Length: 4, Value);
265 Scope = (GOFF::ESDBindingScope)Value;
266 }
267
268 static void getLinkageType(const uint8_t *Record,
269 GOFF::ESDLinkageType &Type) {
270 uint8_t Value;
271 getBits(Bytes: Record, ByteIndex: 66, BitIndex: 2, Length: 1, Value);
272 Type = (GOFF::ESDLinkageType)Value;
273 }
274
275 static void getAlignment(const uint8_t *Record,
276 GOFF::ESDAlignment &Alignment) {
277 uint8_t Value;
278 getBits(Bytes: Record, ByteIndex: 66, BitIndex: 3, Length: 5, Value);
279 Alignment = (GOFF::ESDAlignment)Value;
280 }
281
282 static uint16_t getNameLength(const uint8_t *Record) {
283 uint16_t Length;
284 get<uint16_t>(Bytes: Record, ByteIndex: 70, Value&: Length);
285 return Length;
286 }
287};
288
289class ENDRecord : public Record {
290public:
291 static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
292
293 static uint16_t getNameLength(const uint8_t *Record) {
294 uint16_t Length;
295 get<uint16_t>(Bytes: Record, ByteIndex: 24, Value&: Length);
296 return Length;
297 }
298};
299
300} // end namespace object
301} // end namespace llvm
302
303#endif
304

source code of llvm/include/llvm/Object/GOFF.h