1 | //===-- llvm/BinaryFormat/XCOFF.h - The XCOFF file format -------*- 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 defines manifest constants for the XCOFF object file format. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_BINARYFORMAT_XCOFF_H |
14 | #define LLVM_BINARYFORMAT_XCOFF_H |
15 | |
16 | #include <stddef.h> |
17 | #include <stdint.h> |
18 | |
19 | namespace llvm { |
20 | class StringRef; |
21 | template <unsigned> class SmallString; |
22 | |
23 | namespace XCOFF { |
24 | |
25 | // Constants used in the XCOFF definition. |
26 | |
27 | constexpr size_t FileNamePadSize = 6; |
28 | constexpr size_t NameSize = 8; |
29 | constexpr size_t SymbolTableEntrySize = 18; |
30 | constexpr size_t RelocationSerializationSize32 = 10; |
31 | constexpr uint16_t RelocOverflow = 65535; |
32 | constexpr uint8_t AllocRegNo = 31; |
33 | |
34 | enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 }; |
35 | |
36 | // x_smclas field of x_csect from system header: /usr/include/syms.h |
37 | /// Storage Mapping Class definitions. |
38 | enum StorageMappingClass : uint8_t { |
39 | // READ ONLY CLASSES |
40 | XMC_PR = 0, ///< Program Code |
41 | XMC_RO = 1, ///< Read Only Constant |
42 | XMC_DB = 2, ///< Debug Dictionary Table |
43 | XMC_GL = 6, ///< Global Linkage (Interfile Interface Code) |
44 | XMC_XO = 7, ///< Extended Operation (Pseudo Machine Instruction) |
45 | XMC_SV = 8, ///< Supervisor Call (32-bit process only) |
46 | XMC_SV64 = 17, ///< Supervisor Call for 64-bit process |
47 | XMC_SV3264 = 18, ///< Supervisor Call for both 32- and 64-bit processes |
48 | XMC_TI = 12, ///< Traceback Index csect |
49 | XMC_TB = 13, ///< Traceback Table csect |
50 | |
51 | // READ WRITE CLASSES |
52 | XMC_RW = 5, ///< Read Write Data |
53 | XMC_TC0 = 15, ///< TOC Anchor for TOC Addressability |
54 | XMC_TC = 3, ///< General TOC item |
55 | XMC_TD = 16, ///< Scalar data item in the TOC |
56 | XMC_DS = 10, ///< Descriptor csect |
57 | XMC_UA = 4, ///< Unclassified - Treated as Read Write |
58 | XMC_BS = 9, ///< BSS class (uninitialized static internal) |
59 | XMC_UC = 11, ///< Un-named Fortran Common |
60 | |
61 | XMC_TL = 20, ///< Initialized thread-local variable |
62 | XMC_UL = 21, ///< Uninitialized thread-local variable |
63 | XMC_TE = 22 ///< Symbol mapped at the end of TOC |
64 | }; |
65 | |
66 | // Flags for defining the section type. Masks for use with the (signed, 32-bit) |
67 | // s_flags field of the section header structure, selecting for values in the |
68 | // lower 16 bits. Defined in the system header `scnhdr.h`. |
69 | enum SectionTypeFlags : int32_t { |
70 | STYP_PAD = 0x0008, |
71 | STYP_DWARF = 0x0010, |
72 | STYP_TEXT = 0x0020, |
73 | STYP_DATA = 0x0040, |
74 | STYP_BSS = 0x0080, |
75 | STYP_EXCEPT = 0x0100, |
76 | STYP_INFO = 0x0200, |
77 | STYP_TDATA = 0x0400, |
78 | STYP_TBSS = 0x0800, |
79 | STYP_LOADER = 0x1000, |
80 | STYP_DEBUG = 0x2000, |
81 | STYP_TYPCHK = 0x4000, |
82 | STYP_OVRFLO = 0x8000 |
83 | }; |
84 | |
85 | /// Values for defining the section subtype of sections of type STYP_DWARF as |
86 | /// they would appear in the (signed, 32-bit) s_flags field of the section |
87 | /// header structure, contributing to the 16 most significant bits. Defined in |
88 | /// the system header `scnhdr.h`. |
89 | enum DwarfSectionSubtypeFlags : int32_t { |
90 | SSUBTYP_DWINFO = 0x1'0000, ///< DWARF info section |
91 | SSUBTYP_DWLINE = 0x2'0000, ///< DWARF line section |
92 | SSUBTYP_DWPBNMS = 0x3'0000, ///< DWARF pubnames section |
93 | SSUBTYP_DWPBTYP = 0x4'0000, ///< DWARF pubtypes section |
94 | SSUBTYP_DWARNGE = 0x5'0000, ///< DWARF aranges section |
95 | SSUBTYP_DWABREV = 0x6'0000, ///< DWARF abbrev section |
96 | SSUBTYP_DWSTR = 0x7'0000, ///< DWARF str section |
97 | SSUBTYP_DWRNGES = 0x8'0000, ///< DWARF ranges section |
98 | SSUBTYP_DWLOC = 0x9'0000, ///< DWARF loc section |
99 | SSUBTYP_DWFRAME = 0xA'0000, ///< DWARF frame section |
100 | SSUBTYP_DWMAC = 0xB'0000 ///< DWARF macinfo section |
101 | }; |
102 | |
103 | // STORAGE CLASSES, n_sclass field of syment. |
104 | // The values come from `storclass.h` and `dbxstclass.h`. |
105 | enum StorageClass : uint8_t { |
106 | // Storage classes used for symbolic debugging symbols. |
107 | C_FILE = 103, // File name |
108 | C_BINCL = 108, // Beginning of include file |
109 | C_EINCL = 109, // Ending of include file |
110 | C_GSYM = 128, // Global variable |
111 | C_STSYM = 133, // Statically allocated symbol |
112 | C_BCOMM = 135, // Beginning of common block |
113 | C_ECOMM = 137, // End of common block |
114 | C_ENTRY = 141, // Alternate entry |
115 | C_BSTAT = 143, // Beginning of static block |
116 | C_ESTAT = 144, // End of static block |
117 | C_GTLS = 145, // Global thread-local variable |
118 | C_STTLS = 146, // Static thread-local variable |
119 | |
120 | // Storage classes used for DWARF symbols. |
121 | C_DWARF = 112, // DWARF section symbol |
122 | |
123 | // Storage classes used for absolute symbols. |
124 | C_LSYM = 129, // Automatic variable allocated on stack |
125 | C_PSYM = 130, // Argument to subroutine allocated on stack |
126 | C_RSYM = 131, // Register variable |
127 | C_RPSYM = 132, // Argument to function or procedure stored in register |
128 | C_ECOML = 136, // Local member of common block |
129 | C_FUN = 142, // Function or procedure |
130 | |
131 | // Storage classes used for undefined external symbols or |
132 | // symbols of general sections. |
133 | C_EXT = 2, // External symbol |
134 | C_WEAKEXT = 111, // Weak external symbol |
135 | |
136 | // Storage classes used for symbols of general sections. |
137 | C_NULL = 0, |
138 | C_STAT = 3, // Static |
139 | C_BLOCK = 100, // ".bb" or ".eb" |
140 | C_FCN = 101, // ".bf" or ".ef" |
141 | C_HIDEXT = 107, // Un-named external symbol |
142 | C_INFO = 110, // Comment string in .info section |
143 | C_DECL = 140, // Declaration of object (type) |
144 | |
145 | // Storage classes - Obsolete/Undocumented. |
146 | C_AUTO = 1, // Automatic variable |
147 | C_REG = 4, // Register variable |
148 | C_EXTDEF = 5, // External definition |
149 | C_LABEL = 6, // Label |
150 | C_ULABEL = 7, // Undefined label |
151 | C_MOS = 8, // Member of structure |
152 | C_ARG = 9, // Function argument |
153 | C_STRTAG = 10, // Structure tag |
154 | C_MOU = 11, // Member of union |
155 | C_UNTAG = 12, // Union tag |
156 | C_TPDEF = 13, // Type definition |
157 | C_USTATIC = 14, // Undefined static |
158 | C_ENTAG = 15, // Enumeration tag |
159 | C_MOE = 16, // Member of enumeration |
160 | C_REGPARM = 17, // Register parameter |
161 | C_FIELD = 18, // Bit field |
162 | C_EOS = 102, // End of structure |
163 | C_LINE = 104, |
164 | C_ALIAS = 105, // Duplicate tag |
165 | C_HIDDEN = 106, // Special storage class for external |
166 | C_EFCN = 255, // Physical end of function |
167 | |
168 | // Storage classes - reserved |
169 | C_TCSYM = 134 // Reserved |
170 | }; |
171 | |
172 | // Flags for defining the symbol type. Values to be encoded into the lower 3 |
173 | // bits of the (unsigned, 8-bit) x_smtyp field of csect auxiliary symbol table |
174 | // entries. Defined in the system header `syms.h`. |
175 | enum SymbolType : uint8_t { |
176 | XTY_ER = 0, ///< External reference. |
177 | XTY_SD = 1, ///< Csect definition for initialized storage. |
178 | XTY_LD = 2, ///< Label definition. |
179 | ///< Defines an entry point to an initialized csect. |
180 | XTY_CM = 3 ///< Common csect definition. For uninitialized storage. |
181 | }; |
182 | |
183 | /// Values for visibility as they would appear when encoded in the high 4 bits |
184 | /// of the 16-bit unsigned n_type field of symbol table entries. Valid for |
185 | /// 32-bit XCOFF only when the vstamp in the auxiliary header is greater than 1. |
186 | enum VisibilityType : uint16_t { |
187 | SYM_V_UNSPECIFIED = 0x0000, |
188 | SYM_V_INTERNAL = 0x1000, |
189 | SYM_V_HIDDEN = 0x2000, |
190 | SYM_V_PROTECTED = 0x3000, |
191 | SYM_V_EXPORTED = 0x4000 |
192 | }; |
193 | |
194 | // Relocation types, defined in `/usr/include/reloc.h`. |
195 | enum RelocationType : uint8_t { |
196 | R_POS = 0x00, ///< Positive relocation. Provides the address of the referenced |
197 | ///< symbol. |
198 | R_RL = 0x0c, ///< Positive indirect load relocation. Modifiable instruction. |
199 | R_RLA = 0x0d, ///< Positive load address relocation. Modifiable instruction. |
200 | |
201 | R_NEG = 0x01, ///< Negative relocation. Provides the negative of the address |
202 | ///< of the referenced symbol. |
203 | R_REL = 0x02, ///< Relative to self relocation. Provides a displacement value |
204 | ///< between the address of the referenced symbol and the |
205 | ///< address being relocated. |
206 | |
207 | R_TOC = 0x03, ///< Relative to the TOC relocation. Provides a displacement |
208 | ///< that is the difference between the address of the |
209 | ///< referenced symbol and the TOC anchor csect. |
210 | R_TRL = 0x12, ///< TOC relative indirect load relocation. Similar to R_TOC, |
211 | ///< but not modifiable instruction. |
212 | |
213 | R_TRLA = |
214 | 0x13, ///< Relative to the TOC or to the thread-local storage base |
215 | ///< relocation. Compilers are not permitted to generate this |
216 | ///< relocation type. It is the result of a reversible |
217 | ///< transformation by the linker of an R_TOC relation that turned a |
218 | ///< load instruction into an add-immediate instruction. |
219 | |
220 | R_GL = 0x05, ///< Global linkage-external TOC address relocation. Provides the |
221 | ///< address of the external TOC associated with a defined |
222 | ///< external symbol. |
223 | R_TCL = 0x06, ///< Local object TOC address relocation. Provides the address |
224 | ///< of the local TOC entry of a defined external symbol. |
225 | |
226 | R_REF = 0x0f, ///< A non-relocating relocation. Used to prevent the binder |
227 | ///< from garbage collecting a csect (such as code used for |
228 | ///< dynamic initialization of non-local statics) for which |
229 | ///< another csect has an implicit dependency. |
230 | |
231 | R_BA = 0x08, ///< Branch absolute relocation. Provides the address of the |
232 | ///< referenced symbol. References a non-modifiable instruction. |
233 | R_BR = 0x0a, ///< Branch relative to self relocation. Provides the |
234 | ///< displacement that is the difference between the address of |
235 | ///< the referenced symbol and the address of the referenced |
236 | ///< branch instruction. References a non-modifiable instruction. |
237 | R_RBA = 0x18, ///< Branch absolute relocation. Similar to R_BA but |
238 | ///< references a modifiable instruction. |
239 | R_RBR = 0x1a, ///< Branch relative to self relocation. Similar to the R_BR |
240 | ///< relocation type, but references a modifiable instruction. |
241 | |
242 | R_TLS = 0x20, ///< General-dynamic reference to TLS symbol. |
243 | R_TLS_IE = 0x21, ///< Initial-exec reference to TLS symbol. |
244 | R_TLS_LD = 0x22, ///< Local-dynamic reference to TLS symbol. |
245 | R_TLS_LE = 0x23, ///< Local-exec reference to TLS symbol. |
246 | R_TLSM = 0x24, ///< Module reference to TLS. Provides a handle for the module |
247 | ///< containing the referenced symbol. |
248 | R_TLSML = 0x25, ///< Module reference to the local TLS storage. |
249 | |
250 | R_TOCU = 0x30, ///< Relative to TOC upper. Specifies the high-order 16 bits of |
251 | ///< a large code model TOC-relative relocation. |
252 | R_TOCL = 0x31 ///< Relative to TOC lower. Specifies the low-order 16 bits of a |
253 | ///< large code model TOC-relative relocation. |
254 | }; |
255 | |
256 | struct { |
257 | uint16_t ; |
258 | uint16_t ; |
259 | int32_t ; |
260 | uint32_t ; |
261 | int32_t ; |
262 | uint16_t ; |
263 | uint16_t ; |
264 | }; |
265 | |
266 | struct { |
267 | char [XCOFF::NameSize]; |
268 | uint32_t ; |
269 | uint32_t ; |
270 | uint32_t ; |
271 | uint32_t ; |
272 | uint32_t ; |
273 | uint32_t ; |
274 | uint16_t ; |
275 | uint16_t ; |
276 | int32_t ; |
277 | }; |
278 | |
279 | enum CFileStringType : uint8_t { |
280 | XFT_FN = 0, ///< Specifies the source-file name. |
281 | XFT_CT = 1, ///< Specifies the compiler time stamp. |
282 | XFT_CV = 2, ///< Specifies the compiler version number. |
283 | XFT_CD = 128 ///< Specifies compiler-defined information. |
284 | }; |
285 | |
286 | enum CFileLangId : uint8_t { |
287 | TB_C = 0, ///< C language. |
288 | TB_CPLUSPLUS = 9 ///< C++ language. |
289 | }; |
290 | |
291 | enum CFileCpuId : uint8_t { |
292 | TCPU_PPC64 = 2, ///< PowerPC common architecture 64-bit mode. |
293 | TCPU_COM = 3, ///< POWER and PowerPC architecture common. |
294 | TCPU_970 = 19 ///< PPC970 - PowerPC 64-bit architecture. |
295 | }; |
296 | |
297 | StringRef getMappingClassString(XCOFF::StorageMappingClass SMC); |
298 | StringRef getRelocationTypeString(XCOFF::RelocationType Type); |
299 | SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum); |
300 | |
301 | struct TracebackTable { |
302 | enum LanguageID : uint8_t { |
303 | C, |
304 | Fortran, |
305 | Pascal, |
306 | Ada, |
307 | PL1, |
308 | Basic, |
309 | Lisp, |
310 | Cobol, |
311 | Modula2, |
312 | CPlusPlus, |
313 | Rpg, |
314 | PL8, |
315 | PLIX = PL8, |
316 | Assembly, |
317 | Java, |
318 | ObjectiveC |
319 | }; |
320 | // Byte 1 |
321 | static constexpr uint32_t VersionMask = 0xFF00'0000; |
322 | static constexpr uint8_t VersionShift = 24; |
323 | |
324 | // Byte 2 |
325 | static constexpr uint32_t LanguageIdMask = 0x00FF'0000; |
326 | static constexpr uint8_t LanguageIdShift = 16; |
327 | |
328 | // Byte 3 |
329 | static constexpr uint32_t IsGlobaLinkageMask = 0x0000'8000; |
330 | static constexpr uint32_t IsOutOfLineEpilogOrPrologueMask = 0x0000'4000; |
331 | static constexpr uint32_t HasTraceBackTableOffsetMask = 0x0000'2000; |
332 | static constexpr uint32_t IsInternalProcedureMask = 0x0000'1000; |
333 | static constexpr uint32_t HasControlledStorageMask = 0x0000'0800; |
334 | static constexpr uint32_t IsTOClessMask = 0x0000'0400; |
335 | static constexpr uint32_t IsFloatingPointPresentMask = 0x0000'0200; |
336 | static constexpr uint32_t IsFloatingPointOperationLogOrAbortEnabledMask = |
337 | 0x0000'0100; |
338 | |
339 | // Byte 4 |
340 | static constexpr uint32_t IsInterruptHandlerMask = 0x0000'0080; |
341 | static constexpr uint32_t IsFunctionNamePresentMask = 0x0000'0040; |
342 | static constexpr uint32_t IsAllocaUsedMask = 0x0000'0020; |
343 | static constexpr uint32_t OnConditionDirectiveMask = 0x0000'001C; |
344 | static constexpr uint32_t IsCRSavedMask = 0x0000'0002; |
345 | static constexpr uint32_t IsLRSavedMask = 0x0000'0001; |
346 | static constexpr uint8_t OnConditionDirectiveShift = 2; |
347 | |
348 | // Byte 5 |
349 | static constexpr uint32_t IsBackChainStoredMask = 0x8000'0000; |
350 | static constexpr uint32_t IsFixupMask = 0x4000'0000; |
351 | static constexpr uint32_t FPRSavedMask = 0x3F00'0000; |
352 | static constexpr uint32_t FPRSavedShift = 24; |
353 | |
354 | // Byte 6 |
355 | static constexpr uint32_t HasVectorInfoMask = 0x0080'0000; |
356 | static constexpr uint32_t HasExtensionTableMask = 0x0040'0000; |
357 | static constexpr uint32_t GPRSavedMask = 0x003F'0000; |
358 | static constexpr uint32_t GPRSavedShift = 16; |
359 | |
360 | // Byte 7 |
361 | static constexpr uint32_t NumberOfFixedParmsMask = 0x0000'FF00; |
362 | static constexpr uint8_t NumberOfFixedParmsShift = 8; |
363 | |
364 | // Byte 8 |
365 | static constexpr uint32_t NumberOfFloatingPointParmsMask = 0x0000'00FE; |
366 | static constexpr uint32_t HasParmsOnStackMask = 0x0000'0001; |
367 | static constexpr uint8_t NumberOfFloatingPointParmsShift = 1; |
368 | |
369 | // Masks to select leftmost bits for decoding parameter type information. |
370 | // Bit to use when vector info is not presented. |
371 | static constexpr uint32_t ParmTypeIsFloatingBit = 0x8000'0000; |
372 | static constexpr uint32_t ParmTypeFloatingIsDoubleBit = 0x4000'0000; |
373 | // Bits to use when vector info is presented. |
374 | static constexpr uint32_t ParmTypeIsFixedBits = 0x0000'0000; |
375 | static constexpr uint32_t ParmTypeIsVectorBits = 0x4000'0000; |
376 | static constexpr uint32_t ParmTypeIsFloatingBits = 0x8000'0000; |
377 | static constexpr uint32_t ParmTypeIsDoubleBits = 0xC000'0000; |
378 | static constexpr uint32_t ParmTypeMask = 0xC000'0000; |
379 | |
380 | // Vector extension |
381 | static constexpr uint16_t NumberOfVRSavedMask = 0xFC00; |
382 | static constexpr uint16_t IsVRSavedOnStackMask = 0x0200; |
383 | static constexpr uint16_t HasVarArgsMask = 0x0100; |
384 | static constexpr uint8_t NumberOfVRSavedShift = 10; |
385 | |
386 | static constexpr uint16_t NumberOfVectorParmsMask = 0x00FE; |
387 | static constexpr uint16_t HasVMXInstructionMask = 0x0001; |
388 | static constexpr uint8_t NumberOfVectorParmsShift = 1; |
389 | |
390 | static constexpr uint32_t ParmTypeIsVectorCharBit = 0x0000'0000; |
391 | static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000; |
392 | static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000; |
393 | static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000; |
394 | }; |
395 | |
396 | // Extended Traceback table flags. |
397 | enum ExtendedTBTableFlag : uint8_t { |
398 | TB_OS1 = 0x80, ///< Reserved for OS use. |
399 | TB_RESERVED = 0x40, ///< Reserved for compiler. |
400 | TB_SSP_CANARY = 0x20, ///< stack smasher canary present on stack. |
401 | TB_OS2 = 0x10, ///< Reserved for OS use. |
402 | TB_EH_INFO = 0x08, ///< Exception handling info present. |
403 | TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists. |
404 | }; |
405 | |
406 | StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId); |
407 | SmallString<32> getExtendedTBTableFlagString(uint8_t Flag); |
408 | |
409 | struct CsectProperties { |
410 | CsectProperties(StorageMappingClass SMC, SymbolType ST) |
411 | : MappingClass(SMC), Type(ST) {} |
412 | StorageMappingClass MappingClass; |
413 | SymbolType Type; |
414 | }; |
415 | |
416 | } // end namespace XCOFF |
417 | } // end namespace llvm |
418 | |
419 | #endif |
420 | |