xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Object/GOFF.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
24 namespace llvm {
25 namespace 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.
31 class Record {
32 public:
33   static Error getContinuousData(const uint8_t *Record, uint16_t DataLength,
34                                  int DataIndex, SmallString<256> &CompleteData);
35 
isContinued(const uint8_t * Record)36   static bool isContinued(const uint8_t *Record) {
37     uint8_t IsContinued;
38     getBits(Record, 1, 7, 1, IsContinued);
39     return IsContinued;
40   }
41 
isContinuation(const uint8_t * Record)42   static bool isContinuation(const uint8_t *Record) {
43     uint8_t IsContinuation;
44     getBits(Record, 1, 6, 1, IsContinuation);
45     return IsContinuation;
46   }
47 
48 protected:
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.
getBits(const uint8_t * Bytes,uint8_t ByteIndex,uint8_t BitIndex,uint8_t Length,uint8_t & Value)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>
get(const uint8_t * Bytes,uint8_t ByteIndex,T & Value)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 
76 class TXTRecord : public Record {
77 public:
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 
getElementEsdId(const uint8_t * Record,uint32_t & EsdId)83   static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId) {
84     get<uint32_t>(Record, 4, EsdId);
85   }
86 
getOffset(const uint8_t * Record,uint32_t & Offset)87   static void getOffset(const uint8_t *Record, uint32_t &Offset) {
88     get<uint32_t>(Record, 12, Offset);
89   }
90 
getDataLength(const uint8_t * Record,uint16_t & Length)91   static void getDataLength(const uint8_t *Record, uint16_t &Length) {
92     get<uint16_t>(Record, 22, Length);
93   }
94 };
95 
96 class HDRRecord : public Record {
97 public:
98   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
99 
getPropertyModuleLength(const uint8_t * Record)100   static uint16_t getPropertyModuleLength(const uint8_t *Record) {
101     uint16_t Length;
102     get<uint16_t>(Record, 52, Length);
103     return Length;
104   }
105 };
106 
107 class ESDRecord : public Record {
108 public:
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 
120 public:
121   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
122 
123   // ESD Get routines.
getSymbolType(const uint8_t * Record,GOFF::ESDSymbolType & SymbolType)124   static void getSymbolType(const uint8_t *Record,
125                             GOFF::ESDSymbolType &SymbolType) {
126     uint8_t Value;
127     get<uint8_t>(Record, 3, Value);
128     SymbolType = (GOFF::ESDSymbolType)Value;
129   }
130 
getEsdId(const uint8_t * Record,uint32_t & EsdId)131   static void getEsdId(const uint8_t *Record, uint32_t &EsdId) {
132     get<uint32_t>(Record, 4, EsdId);
133   }
134 
getParentEsdId(const uint8_t * Record,uint32_t & EsdId)135   static void getParentEsdId(const uint8_t *Record, uint32_t &EsdId) {
136     get<uint32_t>(Record, 8, EsdId);
137   }
138 
getOffset(const uint8_t * Record,uint32_t & Offset)139   static void getOffset(const uint8_t *Record, uint32_t &Offset) {
140     get<uint32_t>(Record, 16, Offset);
141   }
142 
getLength(const uint8_t * Record,uint32_t & Length)143   static void getLength(const uint8_t *Record, uint32_t &Length) {
144     get<uint32_t>(Record, 24, Length);
145   }
146 
getNameSpaceId(const uint8_t * Record,GOFF::ESDNameSpaceId & Id)147   static void getNameSpaceId(const uint8_t *Record, GOFF::ESDNameSpaceId &Id) {
148     uint8_t Value;
149     get<uint8_t>(Record, 40, Value);
150     Id = (GOFF::ESDNameSpaceId)Value;
151   }
152 
getFillBytePresent(const uint8_t * Record,bool & Present)153   static void getFillBytePresent(const uint8_t *Record, bool &Present) {
154     uint8_t Value;
155     getBits(Record, 41, 0, 1, Value);
156     Present = (bool)Value;
157   }
158 
getNameMangled(const uint8_t * Record,bool & Mangled)159   static void getNameMangled(const uint8_t *Record, bool &Mangled) {
160     uint8_t Value;
161     getBits(Record, 41, 1, 1, Value);
162     Mangled = (bool)Value;
163   }
164 
getRenamable(const uint8_t * Record,bool & Renamable)165   static void getRenamable(const uint8_t *Record, bool &Renamable) {
166     uint8_t Value;
167     getBits(Record, 41, 2, 1, Value);
168     Renamable = (bool)Value;
169   }
170 
getRemovable(const uint8_t * Record,bool & Removable)171   static void getRemovable(const uint8_t *Record, bool &Removable) {
172     uint8_t Value;
173     getBits(Record, 41, 3, 1, Value);
174     Removable = (bool)Value;
175   }
176 
getFillByteValue(const uint8_t * Record,uint8_t & Fill)177   static void getFillByteValue(const uint8_t *Record, uint8_t &Fill) {
178     get<uint8_t>(Record, 42, Fill);
179   }
180 
getAdaEsdId(const uint8_t * Record,uint32_t & EsdId)181   static void getAdaEsdId(const uint8_t *Record, uint32_t &EsdId) {
182     get<uint32_t>(Record, 44, EsdId);
183   }
184 
getSortPriority(const uint8_t * Record,uint32_t & Priority)185   static void getSortPriority(const uint8_t *Record, uint32_t &Priority) {
186     get<uint32_t>(Record, 48, Priority);
187   }
188 
getAmode(const uint8_t * Record,GOFF::ESDAmode & Amode)189   static void getAmode(const uint8_t *Record, GOFF::ESDAmode &Amode) {
190     uint8_t Value;
191     get<uint8_t>(Record, 60, Value);
192     Amode = (GOFF::ESDAmode)Value;
193   }
194 
getRmode(const uint8_t * Record,GOFF::ESDRmode & Rmode)195   static void getRmode(const uint8_t *Record, GOFF::ESDRmode &Rmode) {
196     uint8_t Value;
197     get<uint8_t>(Record, 61, Value);
198     Rmode = (GOFF::ESDRmode)Value;
199   }
200 
getTextStyle(const uint8_t * Record,GOFF::ESDTextStyle & Style)201   static void getTextStyle(const uint8_t *Record, GOFF::ESDTextStyle &Style) {
202     uint8_t Value;
203     getBits(Record, 62, 0, 4, Value);
204     Style = (GOFF::ESDTextStyle)Value;
205   }
206 
getBindingAlgorithm(const uint8_t * Record,GOFF::ESDBindingAlgorithm & Algorithm)207   static void getBindingAlgorithm(const uint8_t *Record,
208                                   GOFF::ESDBindingAlgorithm &Algorithm) {
209     uint8_t Value;
210     getBits(Record, 62, 4, 4, Value);
211     Algorithm = (GOFF::ESDBindingAlgorithm)Value;
212   }
213 
getTaskingBehavior(const uint8_t * Record,GOFF::ESDTaskingBehavior & TaskingBehavior)214   static void getTaskingBehavior(const uint8_t *Record,
215                                  GOFF::ESDTaskingBehavior &TaskingBehavior) {
216     uint8_t Value;
217     getBits(Record, 63, 0, 3, Value);
218     TaskingBehavior = (GOFF::ESDTaskingBehavior)Value;
219   }
220 
getReadOnly(const uint8_t * Record,bool & ReadOnly)221   static void getReadOnly(const uint8_t *Record, bool &ReadOnly) {
222     uint8_t Value;
223     getBits(Record, 63, 4, 1, Value);
224     ReadOnly = (bool)Value;
225   }
226 
getExecutable(const uint8_t * Record,GOFF::ESDExecutable & Executable)227   static void getExecutable(const uint8_t *Record,
228                             GOFF::ESDExecutable &Executable) {
229     uint8_t Value;
230     getBits(Record, 63, 5, 3, Value);
231     Executable = (GOFF::ESDExecutable)Value;
232   }
233 
getDuplicateSeverity(const uint8_t * Record,GOFF::ESDDuplicateSymbolSeverity & DSS)234   static void getDuplicateSeverity(const uint8_t *Record,
235                                    GOFF::ESDDuplicateSymbolSeverity &DSS) {
236     uint8_t Value;
237     getBits(Record, 64, 2, 2, Value);
238     DSS = (GOFF::ESDDuplicateSymbolSeverity)Value;
239   }
240 
getBindingStrength(const uint8_t * Record,GOFF::ESDBindingStrength & Strength)241   static void getBindingStrength(const uint8_t *Record,
242                                  GOFF::ESDBindingStrength &Strength) {
243     uint8_t Value;
244     getBits(Record, 64, 4, 4, Value);
245     Strength = (GOFF::ESDBindingStrength)Value;
246   }
247 
getLoadingBehavior(const uint8_t * Record,GOFF::ESDLoadingBehavior & Behavior)248   static void getLoadingBehavior(const uint8_t *Record,
249                                  GOFF::ESDLoadingBehavior &Behavior) {
250     uint8_t Value;
251     getBits(Record, 65, 0, 2, Value);
252     Behavior = (GOFF::ESDLoadingBehavior)Value;
253   }
254 
getIndirectReference(const uint8_t * Record,bool & Indirect)255   static void getIndirectReference(const uint8_t *Record, bool &Indirect) {
256     uint8_t Value;
257     getBits(Record, 65, 3, 1, Value);
258     Indirect = (bool)Value;
259   }
260 
getBindingScope(const uint8_t * Record,GOFF::ESDBindingScope & Scope)261   static void getBindingScope(const uint8_t *Record,
262                               GOFF::ESDBindingScope &Scope) {
263     uint8_t Value;
264     getBits(Record, 65, 4, 4, Value);
265     Scope = (GOFF::ESDBindingScope)Value;
266   }
267 
getLinkageType(const uint8_t * Record,GOFF::ESDLinkageType & Type)268   static void getLinkageType(const uint8_t *Record,
269                              GOFF::ESDLinkageType &Type) {
270     uint8_t Value;
271     getBits(Record, 66, 2, 1, Value);
272     Type = (GOFF::ESDLinkageType)Value;
273   }
274 
getAlignment(const uint8_t * Record,GOFF::ESDAlignment & Alignment)275   static void getAlignment(const uint8_t *Record,
276                            GOFF::ESDAlignment &Alignment) {
277     uint8_t Value;
278     getBits(Record, 66, 3, 5, Value);
279     Alignment = (GOFF::ESDAlignment)Value;
280   }
281 
getNameLength(const uint8_t * Record)282   static uint16_t getNameLength(const uint8_t *Record) {
283     uint16_t Length;
284     get<uint16_t>(Record, 70, Length);
285     return Length;
286   }
287 };
288 
289 class ENDRecord : public Record {
290 public:
291   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
292 
getNameLength(const uint8_t * Record)293   static uint16_t getNameLength(const uint8_t *Record) {
294     uint16_t Length;
295     get<uint16_t>(Record, 24, Length);
296     return Length;
297   }
298 };
299 
300 } // end namespace object
301 } // end namespace llvm
302 
303 #endif
304