1 | //===-- BTF.h --------------------------------------------------*- 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 | /// \file |
10 | /// This file contains the layout of .BTF and .BTF.ext ELF sections. |
11 | /// |
12 | /// The binary layout for .BTF section: |
13 | /// struct Header |
14 | /// Type and Str subsections |
15 | /// The Type subsection is a collection of types with type id starting with 1. |
16 | /// The Str subsection is simply a collection of strings. |
17 | /// |
18 | /// The binary layout for .BTF.ext section: |
19 | /// struct ExtHeader |
20 | /// FuncInfo, LineInfo, FieldReloc and ExternReloc subsections |
21 | /// The FuncInfo subsection is defined as below: |
22 | /// BTFFuncInfo Size |
23 | /// struct SecFuncInfo for ELF section #1 |
24 | /// A number of struct BPFFuncInfo for ELF section #1 |
25 | /// struct SecFuncInfo for ELF section #2 |
26 | /// A number of struct BPFFuncInfo for ELF section #2 |
27 | /// ... |
28 | /// The LineInfo subsection is defined as below: |
29 | /// BPFLineInfo Size |
30 | /// struct SecLineInfo for ELF section #1 |
31 | /// A number of struct BPFLineInfo for ELF section #1 |
32 | /// struct SecLineInfo for ELF section #2 |
33 | /// A number of struct BPFLineInfo for ELF section #2 |
34 | /// ... |
35 | /// The FieldReloc subsection is defined as below: |
36 | /// BPFFieldReloc Size |
37 | /// struct SecFieldReloc for ELF section #1 |
38 | /// A number of struct BPFFieldReloc for ELF section #1 |
39 | /// struct SecFieldReloc for ELF section #2 |
40 | /// A number of struct BPFFieldReloc for ELF section #2 |
41 | /// ... |
42 | /// |
43 | /// The section formats are also defined at |
44 | /// https://github.com/torvalds/linux/blob/master/include/uapi/linux/btf.h |
45 | /// |
46 | //===----------------------------------------------------------------------===// |
47 | |
48 | #ifndef LLVM_LIB_TARGET_BPF_BTF_H |
49 | #define LLVM_LIB_TARGET_BPF_BTF_H |
50 | |
51 | #include "llvm/ADT/ArrayRef.h" |
52 | #include "llvm/Support/TrailingObjects.h" |
53 | |
54 | namespace llvm { |
55 | namespace BTF { |
56 | |
57 | enum : uint32_t { MAGIC = 0xeB9F, VERSION = 1 }; |
58 | |
59 | /// Sizes in bytes of various things in the BTF format. |
60 | enum { |
61 | = 24, |
62 | = 32, |
63 | CommonTypeSize = 12, |
64 | BTFArraySize = 12, |
65 | BTFEnumSize = 8, |
66 | BTFEnum64Size = 12, |
67 | BTFMemberSize = 12, |
68 | BTFParamSize = 8, |
69 | BTFDataSecVarSize = 12, |
70 | SecFuncInfoSize = 8, |
71 | SecLineInfoSize = 8, |
72 | SecFieldRelocSize = 8, |
73 | BPFFuncInfoSize = 8, |
74 | BPFLineInfoSize = 16, |
75 | BPFFieldRelocSize = 16, |
76 | }; |
77 | |
78 | /// The .BTF section header definition. |
79 | struct { |
80 | uint16_t ; ///< Magic value |
81 | uint8_t ; ///< Version number |
82 | uint8_t ; ///< Extra flags |
83 | uint32_t ; ///< Length of this header |
84 | |
85 | /// All offsets are in bytes relative to the end of this header. |
86 | uint32_t ; ///< Offset of type section |
87 | uint32_t ; ///< Length of type section |
88 | uint32_t ; ///< Offset of string section |
89 | uint32_t ; ///< Length of string section |
90 | }; |
91 | |
92 | enum : uint32_t { |
93 | MAX_VLEN = 0xffff ///< Max # of struct/union/enum members or func args |
94 | }; |
95 | |
96 | enum TypeKinds : uint8_t { |
97 | #define HANDLE_BTF_KIND(ID, NAME) BTF_KIND_##NAME = ID, |
98 | #include "BTF.def" |
99 | }; |
100 | |
101 | // Constants for CommonType::Info field. |
102 | constexpr uint32_t FWD_UNION_FLAG = 1u << 31; |
103 | constexpr uint32_t ENUM_SIGNED_FLAG = 1u << 31; |
104 | |
105 | /// The BTF common type definition. Different kinds may have |
106 | /// additional information after this structure data. |
107 | struct CommonType { |
108 | /// Type name offset in the string table. |
109 | uint32_t NameOff; |
110 | |
111 | /// "Info" bits arrangement: |
112 | /// Bits 0-15: vlen (e.g. # of struct's members) |
113 | /// Bits 16-23: unused |
114 | /// Bits 24-28: kind (e.g. int, ptr, array...etc) |
115 | /// Bits 29-30: unused |
116 | /// Bit 31: kind_flag, currently used by |
117 | /// struct, union and fwd |
118 | uint32_t Info; |
119 | |
120 | /// "Size" is used by INT, ENUM, STRUCT and UNION. |
121 | /// "Size" tells the size of the type it is describing. |
122 | /// |
123 | /// "Type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, |
124 | /// FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG. |
125 | /// "Type" is a type_id referring to another type. |
126 | union { |
127 | uint32_t Size; |
128 | uint32_t Type; |
129 | }; |
130 | |
131 | uint32_t getKind() const { return Info >> 24 & 0x1f; } |
132 | uint32_t getVlen() const { return Info & 0xffff; } |
133 | }; |
134 | |
135 | // For some specific BTF_KIND, "struct CommonType" is immediately |
136 | // followed by extra data. |
137 | |
138 | // BTF_KIND_INT is followed by a u32 and the following |
139 | // is the 32 bits arrangement: |
140 | // BTF_INT_ENCODING(VAL) : (((VAL) & 0x0f000000) >> 24) |
141 | // BTF_INT_OFFSET(VAL) : (((VAL & 0x00ff0000)) >> 16) |
142 | // BTF_INT_BITS(VAL) : ((VAL) & 0x000000ff) |
143 | |
144 | /// Attributes stored in the INT_ENCODING. |
145 | enum : uint8_t { |
146 | INT_SIGNED = (1 << 0), |
147 | INT_CHAR = (1 << 1), |
148 | INT_BOOL = (1 << 2) |
149 | }; |
150 | |
151 | /// BTF_KIND_ENUM is followed by multiple "struct BTFEnum". |
152 | /// The exact number of btf_enum is stored in the vlen (of the |
153 | /// info in "struct CommonType"). |
154 | struct BTFEnum { |
155 | uint32_t NameOff; ///< Enum name offset in the string table |
156 | int32_t Val; ///< Enum member value |
157 | }; |
158 | |
159 | /// BTF_KIND_ENUM64 is followed by multiple "struct BTFEnum64". |
160 | /// The exact number of BTFEnum64 is stored in the vlen (of the |
161 | /// info in "struct CommonType"). |
162 | struct BTFEnum64 { |
163 | uint32_t NameOff; ///< Enum name offset in the string table |
164 | uint32_t Val_Lo32; ///< Enum member lo32 value |
165 | uint32_t Val_Hi32; ///< Enum member hi32 value |
166 | }; |
167 | |
168 | /// BTF_KIND_ARRAY is followed by one "struct BTFArray". |
169 | struct BTFArray { |
170 | uint32_t ElemType; ///< Element type |
171 | uint32_t IndexType; ///< Index type |
172 | uint32_t Nelems; ///< Number of elements for this array |
173 | }; |
174 | |
175 | /// BTF_KIND_STRUCT and BTF_KIND_UNION are followed |
176 | /// by multiple "struct BTFMember". The exact number |
177 | /// of BTFMember is stored in the vlen (of the info in |
178 | /// "struct CommonType"). |
179 | /// |
180 | /// If the struct/union contains any bitfield member, |
181 | /// the Offset below represents BitOffset (bits 0 - 23) |
182 | /// and BitFieldSize(bits 24 - 31) with BitFieldSize = 0 |
183 | /// for non bitfield members. Otherwise, the Offset |
184 | /// represents the BitOffset. |
185 | struct BTFMember { |
186 | uint32_t NameOff; ///< Member name offset in the string table |
187 | uint32_t Type; ///< Member type |
188 | uint32_t Offset; ///< BitOffset or BitFieldSize+BitOffset |
189 | }; |
190 | |
191 | /// BTF_KIND_FUNC_PROTO are followed by multiple "struct BTFParam". |
192 | /// The exist number of BTFParam is stored in the vlen (of the info |
193 | /// in "struct CommonType"). |
194 | struct BTFParam { |
195 | uint32_t NameOff; |
196 | uint32_t Type; |
197 | }; |
198 | |
199 | /// BTF_KIND_FUNC can be global, static or extern. |
200 | enum : uint8_t { |
201 | FUNC_STATIC = 0, |
202 | FUNC_GLOBAL = 1, |
203 | FUNC_EXTERN = 2, |
204 | }; |
205 | |
206 | /// Variable scoping information. |
207 | enum : uint8_t { |
208 | VAR_STATIC = 0, ///< Linkage: InternalLinkage |
209 | VAR_GLOBAL_ALLOCATED = 1, ///< Linkage: ExternalLinkage |
210 | VAR_GLOBAL_EXTERNAL = 2, ///< Linkage: ExternalLinkage |
211 | }; |
212 | |
213 | /// BTF_KIND_DATASEC are followed by multiple "struct BTFDataSecVar". |
214 | /// The exist number of BTFDataSec is stored in the vlen (of the info |
215 | /// in "struct CommonType"). |
216 | struct BTFDataSec { |
217 | uint32_t Type; ///< A BTF_KIND_VAR type |
218 | uint32_t Offset; ///< In-section offset |
219 | uint32_t Size; ///< Occupied memory size |
220 | }; |
221 | |
222 | /// The .BTF.ext section header definition. |
223 | struct { |
224 | uint16_t ; |
225 | uint8_t ; |
226 | uint8_t ; |
227 | uint32_t ; |
228 | |
229 | uint32_t ; ///< Offset of func info section |
230 | uint32_t ; ///< Length of func info section |
231 | uint32_t ; ///< Offset of line info section |
232 | uint32_t ; ///< Length of line info section |
233 | uint32_t ; ///< Offset of offset reloc section |
234 | uint32_t ; ///< Length of offset reloc section |
235 | }; |
236 | |
237 | /// Specifying one function info. |
238 | struct BPFFuncInfo { |
239 | uint32_t InsnOffset; ///< Byte offset in the section |
240 | uint32_t TypeId; ///< Type id referring to .BTF type section |
241 | }; |
242 | |
243 | /// Specifying function info's in one section. |
244 | struct SecFuncInfo { |
245 | uint32_t SecNameOff; ///< Section name index in the .BTF string table |
246 | uint32_t NumFuncInfo; ///< Number of func info's in this section |
247 | }; |
248 | |
249 | /// Specifying one line info. |
250 | struct BPFLineInfo { |
251 | uint32_t InsnOffset; ///< Byte offset in this section |
252 | uint32_t FileNameOff; ///< File name index in the .BTF string table |
253 | uint32_t LineOff; ///< Line index in the .BTF string table |
254 | uint32_t LineCol; ///< Line num: line_col >> 10, |
255 | /// col num: line_col & 0x3ff |
256 | uint32_t getLine() const { return LineCol >> 10; } |
257 | uint32_t getCol() const { return LineCol & 0x3ff; } |
258 | }; |
259 | |
260 | /// Specifying line info's in one section. |
261 | struct SecLineInfo { |
262 | uint32_t SecNameOff; ///< Section name index in the .BTF string table |
263 | uint32_t NumLineInfo; ///< Number of line info's in this section |
264 | }; |
265 | |
266 | /// Specifying one offset relocation. |
267 | struct BPFFieldReloc { |
268 | uint32_t InsnOffset; ///< Byte offset in this section |
269 | uint32_t TypeID; ///< TypeID for the relocation |
270 | uint32_t OffsetNameOff; ///< The string to traverse types |
271 | uint32_t RelocKind; ///< What to patch the instruction |
272 | }; |
273 | |
274 | /// Specifying offset relocation's in one section. |
275 | struct SecFieldReloc { |
276 | uint32_t SecNameOff; ///< Section name index in the .BTF string table |
277 | uint32_t NumFieldReloc; ///< Number of offset reloc's in this section |
278 | }; |
279 | |
280 | /// CO-RE relocation kind codes used in .BTF.ext section. |
281 | enum PatchableRelocKind : uint32_t { |
282 | FIELD_BYTE_OFFSET = 0, |
283 | FIELD_BYTE_SIZE, |
284 | FIELD_EXISTENCE, |
285 | FIELD_SIGNEDNESS, |
286 | FIELD_LSHIFT_U64, |
287 | FIELD_RSHIFT_U64, |
288 | BTF_TYPE_ID_LOCAL, |
289 | BTF_TYPE_ID_REMOTE, |
290 | TYPE_EXISTENCE, |
291 | TYPE_SIZE, |
292 | ENUM_VALUE_EXISTENCE, |
293 | ENUM_VALUE, |
294 | TYPE_MATCH, |
295 | MAX_FIELD_RELOC_KIND, |
296 | }; |
297 | |
298 | // Define a number of sub-types for CommonType, each with: |
299 | // - An accessor for a relevant "tail" information (data fields that |
300 | // follow the CommonType record in binary format). |
301 | // - A classof() definition based on CommonType::getKind() value to |
302 | // allow use with dyn_cast<>() function. |
303 | |
304 | // For CommonType sub-types that are followed by a single entry of |
305 | // some type in the binary format. |
306 | #define BTF_DEFINE_TAIL(Type, Accessor) \ |
307 | const Type &Accessor() const { return *getTrailingObjects<Type>(); } |
308 | |
309 | // For CommonType sub-types that are followed by CommonType::getVlen() |
310 | // number of entries of some type in the binary format. |
311 | #define BTF_DEFINE_TAIL_ARR(Type, Accessor) \ |
312 | ArrayRef<Type> Accessor() const { \ |
313 | return ArrayRef<Type>(getTrailingObjects<Type>(), getVlen()); \ |
314 | } |
315 | |
316 | struct ArrayType final : CommonType, |
317 | private TrailingObjects<ArrayType, BTFArray> { |
318 | friend TrailingObjects; |
319 | BTF_DEFINE_TAIL(BTFArray, getArray) |
320 | |
321 | static bool classof(const CommonType *V) { |
322 | return V->getKind() == BTF_KIND_ARRAY; |
323 | } |
324 | }; |
325 | |
326 | struct StructType final : CommonType, |
327 | private TrailingObjects<StructType, BTFMember> { |
328 | friend TrailingObjects; |
329 | BTF_DEFINE_TAIL_ARR(BTFMember, members) |
330 | |
331 | static bool classof(const CommonType *V) { |
332 | return V->getKind() == BTF_KIND_STRUCT || V->getKind() == BTF_KIND_UNION; |
333 | } |
334 | }; |
335 | |
336 | struct EnumType final : CommonType, private TrailingObjects<EnumType, BTFEnum> { |
337 | friend TrailingObjects; |
338 | BTF_DEFINE_TAIL_ARR(BTFEnum, values) |
339 | |
340 | static bool classof(const CommonType *V) { |
341 | return V->getKind() == BTF_KIND_ENUM; |
342 | } |
343 | }; |
344 | |
345 | struct Enum64Type final : CommonType, |
346 | private TrailingObjects<Enum64Type, BTFEnum64> { |
347 | friend TrailingObjects; |
348 | BTF_DEFINE_TAIL_ARR(BTFEnum64, values) |
349 | |
350 | static bool classof(const CommonType *V) { |
351 | return V->getKind() == BTF_KIND_ENUM64; |
352 | } |
353 | }; |
354 | |
355 | #undef BTF_DEFINE_TAIL |
356 | #undef BTF_DEFINE_TAIL_ARR |
357 | |
358 | } // End namespace BTF. |
359 | } // End namespace llvm. |
360 | |
361 | #endif |
362 | |