xref: /freebsd/contrib/llvm-project/llvm/include/llvm/BinaryFormat/GOFF.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- llvm/BinaryFormat/GOFF.h - GOFF definitions --------------*- 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 header contains common, non-processor-specific data structures and
10 // constants for the GOFF file format.
11 //
12 // GOFF specifics can be found in MVS Program Management: Advanced Facilities.
13 // See
14 // https://www.ibm.com/docs/en/zos/3.1.0?topic=facilities-generalized-object-file-format-goff
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_BINARYFORMAT_GOFF_H
19 #define LLVM_BINARYFORMAT_GOFF_H
20 
21 #include "llvm/Support/DataTypes.h"
22 
23 namespace llvm {
24 
25 namespace GOFF {
26 
27 /// \brief Length of the parts of a physical GOFF record.
28 constexpr uint8_t RecordLength = 80;
29 constexpr uint8_t RecordPrefixLength = 3;
30 constexpr uint8_t PayloadLength = 77;
31 constexpr uint8_t RecordContentLength = RecordLength - RecordPrefixLength;
32 
33 /// \brief Maximum data length before starting a new card for RLD and TXT data.
34 ///
35 /// The maximum number of bytes that can be included in an RLD or TXT record and
36 /// their continuations is a SIGNED 16 bit int despite what the spec says. The
37 /// number of bytes we allow ourselves to attach to a card is thus arbitrarily
38 /// limited to 32K-1 bytes.
39 constexpr uint16_t MaxDataLength = 32 * 1024 - 1;
40 
41 /// \brief Prefix byte on every record. This indicates GOFF format.
42 constexpr uint8_t PTVPrefix = 0x03;
43 
44 enum RecordType : uint8_t {
45   RT_ESD = 0,
46   RT_TXT = 1,
47   RT_RLD = 2,
48   RT_LEN = 3,
49   RT_END = 4,
50   RT_HDR = 15,
51 };
52 
53 enum ESDSymbolType : uint8_t {
54   ESD_ST_SectionDefinition = 0,
55   ESD_ST_ElementDefinition = 1,
56   ESD_ST_LabelDefinition = 2,
57   ESD_ST_PartReference = 3,
58   ESD_ST_ExternalReference = 4,
59 };
60 
61 enum ESDNameSpaceId : uint8_t {
62   ESD_NS_ProgramManagementBinder = 0,
63   ESD_NS_NormalName = 1,
64   ESD_NS_PseudoRegister = 2,
65   ESD_NS_Parts = 3
66 };
67 
68 enum ESDReserveQwords : uint8_t {
69   ESD_RQ_0 = 0,
70   ESD_RQ_1 = 1,
71   ESD_RQ_2 = 2,
72   ESD_RQ_3 = 3
73 };
74 
75 enum ESDAmode : uint8_t {
76   ESD_AMODE_None = 0,
77   ESD_AMODE_24 = 1,
78   ESD_AMODE_31 = 2,
79   ESD_AMODE_ANY = 3,
80   ESD_AMODE_64 = 4,
81   ESD_AMODE_MIN = 16,
82 };
83 
84 enum ESDRmode : uint8_t {
85   ESD_RMODE_None = 0,
86   ESD_RMODE_24 = 1,
87   ESD_RMODE_31 = 3,
88   ESD_RMODE_64 = 4,
89 };
90 
91 enum ESDTextStyle : uint8_t {
92   ESD_TS_ByteOriented = 0,
93   ESD_TS_Structured = 1,
94   ESD_TS_Unstructured = 2,
95 };
96 
97 enum ESDBindingAlgorithm : uint8_t {
98   ESD_BA_Concatenate = 0,
99   ESD_BA_Merge = 1,
100 };
101 
102 enum ESDTaskingBehavior : uint8_t {
103   ESD_TA_Unspecified = 0,
104   ESD_TA_NonReus = 1,
105   ESD_TA_Reus = 2,
106   ESD_TA_Rent = 3,
107 };
108 
109 enum ESDExecutable : uint8_t {
110   ESD_EXE_Unspecified = 0,
111   ESD_EXE_DATA = 1,
112   ESD_EXE_CODE = 2,
113 };
114 
115 enum ESDDuplicateSymbolSeverity : uint8_t {
116   ESD_DSS_NoWarning = 0,
117   ESD_DSS_Warning = 1,
118   ESD_DSS_Error = 2,
119   ESD_DSS_Reserved = 3,
120 };
121 
122 enum ESDBindingStrength : uint8_t {
123   ESD_BST_Strong = 0,
124   ESD_BST_Weak = 1,
125 };
126 
127 enum ESDLoadingBehavior : uint8_t {
128   ESD_LB_Initial = 0,
129   ESD_LB_Deferred = 1,
130   ESD_LB_NoLoad = 2,
131   ESD_LB_Reserved = 3,
132 };
133 
134 enum ESDBindingScope : uint8_t {
135   ESD_BSC_Unspecified = 0,
136   ESD_BSC_Section = 1,
137   ESD_BSC_Module = 2,
138   ESD_BSC_Library = 3,
139   ESD_BSC_ImportExport = 4,
140 };
141 
142 enum ESDLinkageType : uint8_t { ESD_LT_OS = 0, ESD_LT_XPLink = 1 };
143 
144 enum ESDAlignment : uint8_t {
145   ESD_ALIGN_Byte = 0,
146   ESD_ALIGN_Halfword = 1,
147   ESD_ALIGN_Fullword = 2,
148   ESD_ALIGN_Doubleword = 3,
149   ESD_ALIGN_Quadword = 4,
150   ESD_ALIGN_32byte = 5,
151   ESD_ALIGN_64byte = 6,
152   ESD_ALIGN_128byte = 7,
153   ESD_ALIGN_256byte = 8,
154   ESD_ALIGN_512byte = 9,
155   ESD_ALIGN_1024byte = 10,
156   ESD_ALIGN_2Kpage = 11,
157   ESD_ALIGN_4Kpage = 12,
158 };
159 
160 enum ENDEntryPointRequest : uint8_t {
161   END_EPR_None = 0,
162   END_EPR_EsdidOffset = 1,
163   END_EPR_ExternalName = 2,
164   END_EPR_Reserved = 3,
165 };
166 
167 // \brief Subsections of the primary C_CODE section in the object file.
168 enum SubsectionKind : uint8_t {
169   SK_PPA1 = 2,
170   SK_PPA2 = 4,
171 };
172 
173 // The standard System/390 convention is to name the high-order (leftmost) bit
174 // in a byte as bit zero. The Flags type helps to set bits in byte according
175 // to this numeration order.
176 class Flags {
177   uint8_t Val = 0;
178 
bits(uint8_t BitIndex,uint8_t Length,uint8_t Value,uint8_t OldValue)179   constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value,
180                                 uint8_t OldValue) {
181     uint8_t Pos = 8 - BitIndex - Length;
182     uint8_t Mask = ((1 << Length) - 1) << Pos;
183     Value = Value << Pos;
184     return (OldValue & ~Mask) | Value;
185   }
186 
187 public:
188   constexpr Flags() = default;
Flags(uint8_t BitIndex,uint8_t Length,uint8_t Value)189   constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value)
190       : Val(bits(BitIndex, Length, Value, 0)) {}
191 
192   template <typename T>
set(uint8_t BitIndex,uint8_t Length,T NewValue)193   constexpr void set(uint8_t BitIndex, uint8_t Length, T NewValue) {
194     Val = bits(BitIndex, Length, static_cast<uint8_t>(NewValue), Val);
195   }
196 
197   template <typename T>
get(uint8_t BitIndex,uint8_t Length)198   constexpr T get(uint8_t BitIndex, uint8_t Length) const {
199     return static_cast<T>((Val >> (8 - BitIndex - Length)) &
200                           ((1 << Length) - 1));
201   }
202 
uint8_t()203   constexpr operator uint8_t() const { return Val; }
204 };
205 
206 // Structure for the flag field of a symbol. See
207 // https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record
208 // at offset 41 for the definition.
209 struct SymbolFlags {
210   Flags SymFlags;
211 
212 #define GOFF_SYMBOL_FLAG(NAME, TYPE, BITINDEX, LENGTH)                         \
213   void set##NAME(TYPE Val) { SymFlags.set<TYPE>(BITINDEX, LENGTH, Val); }      \
214   TYPE get##NAME() const { return SymFlags.get<TYPE>(BITINDEX, LENGTH); }
215 
216   GOFF_SYMBOL_FLAG(FillBytePresence, bool, 0, 1)
217   GOFF_SYMBOL_FLAG(Mangled, bool, 1, 1)
218   GOFF_SYMBOL_FLAG(Renameable, bool, 2, 1)
219   GOFF_SYMBOL_FLAG(RemovableClass, bool, 3, 1)
220   GOFF_SYMBOL_FLAG(ReservedQwords, ESDReserveQwords, 5, 3)
221 
222 #undef GOFF_SYMBOL_FLAG
223 
uint8_tSymbolFlags224   constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); }
225 };
226 
227 // Structure for the behavioral attributes. See
228 // https://www.ibm.com/docs/en/zos/3.1.0?topic=record-external-symbol-definition-behavioral-attributes
229 // for the definition.
230 struct BehavioralAttributes {
231   Flags Attr[10];
232 
233 #define GOFF_BEHAVIORAL_ATTRIBUTE(NAME, TYPE, ATTRIDX, BITINDEX, LENGTH)       \
234   void set##NAME(TYPE Val) { Attr[ATTRIDX].set<TYPE>(BITINDEX, LENGTH, Val); } \
235   TYPE get##NAME() const { return Attr[ATTRIDX].get<TYPE>(BITINDEX, LENGTH); }
236 
237   GOFF_BEHAVIORAL_ATTRIBUTE(Amode, GOFF::ESDAmode, 0, 0, 8)
238   GOFF_BEHAVIORAL_ATTRIBUTE(Rmode, GOFF::ESDRmode, 1, 0, 8)
239   GOFF_BEHAVIORAL_ATTRIBUTE(TextStyle, GOFF::ESDTextStyle, 2, 0, 4)
240   GOFF_BEHAVIORAL_ATTRIBUTE(BindingAlgorithm, GOFF::ESDBindingAlgorithm, 2, 4,
241                             4)
242   GOFF_BEHAVIORAL_ATTRIBUTE(TaskingBehavior, GOFF::ESDTaskingBehavior, 3, 0, 3)
243   GOFF_BEHAVIORAL_ATTRIBUTE(ReadOnly, bool, 3, 4, 1)
244   GOFF_BEHAVIORAL_ATTRIBUTE(Executable, GOFF::ESDExecutable, 3, 5, 3)
245   GOFF_BEHAVIORAL_ATTRIBUTE(DuplicateSymbolSeverity,
246                             GOFF::ESDDuplicateSymbolSeverity, 4, 2, 2)
247   GOFF_BEHAVIORAL_ATTRIBUTE(BindingStrength, GOFF::ESDBindingStrength, 4, 4, 4)
248   GOFF_BEHAVIORAL_ATTRIBUTE(LoadingBehavior, GOFF::ESDLoadingBehavior, 5, 0, 2)
249   GOFF_BEHAVIORAL_ATTRIBUTE(COMMON, bool, 5, 2, 1)
250   GOFF_BEHAVIORAL_ATTRIBUTE(IndirectReference, bool, 5, 3, 1)
251   GOFF_BEHAVIORAL_ATTRIBUTE(BindingScope, GOFF::ESDBindingScope, 5, 4, 4)
252   GOFF_BEHAVIORAL_ATTRIBUTE(LinkageType, GOFF::ESDLinkageType, 6, 2, 1)
253   GOFF_BEHAVIORAL_ATTRIBUTE(Alignment, GOFF::ESDAlignment, 6, 3, 5)
254 
255 #undef GOFF_BEHAVIORAL_ATTRIBUTE
256 };
257 } // end namespace GOFF
258 
259 } // end namespace llvm
260 
261 #endif // LLVM_BINARYFORMAT_GOFF_H
262