1 | //===- BTFParser.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 | // BTFParser reads .BTF and .BTF.ext ELF sections generated by LLVM |
10 | // BPF backend and provides introspection for the stored information. |
11 | // Currently the following information is accessible: |
12 | // - string table; |
13 | // - instruction offset to line information mapping; |
14 | // - types table; |
15 | // - CO-RE relocations table. |
16 | // |
17 | // See llvm/DebugInfo/BTF/BTF.h for some details about binary format |
18 | // and links to Linux Kernel documentation. |
19 | // |
20 | //===----------------------------------------------------------------------===// |
21 | |
22 | #ifndef LLVM_DEBUGINFO_BTF_BTFPARSER_H |
23 | #define LLVM_DEBUGINFO_BTF_BTFPARSER_H |
24 | |
25 | #include "llvm/ADT/DenseMap.h" |
26 | #include "llvm/DebugInfo/BTF/BTF.h" |
27 | #include "llvm/Object/ObjectFile.h" |
28 | #include "llvm/Support/DataExtractor.h" |
29 | |
30 | namespace llvm { |
31 | using object::ObjectFile; |
32 | using object::SectionedAddress; |
33 | using object::SectionRef; |
34 | |
35 | class BTFParser { |
36 | using BTFLinesVector = SmallVector<BTF::BPFLineInfo, 0>; |
37 | using BTFRelocVector = SmallVector<BTF::BPFFieldReloc, 0>; |
38 | |
39 | // In BTF strings are stored as a continuous memory region with |
40 | // individual strings separated by 0 bytes. Strings are identified |
41 | // by an offset in such region. |
42 | // The `StringsTable` points to this region in the parsed ObjectFile. |
43 | StringRef StringsTable; |
44 | |
45 | // A copy of types table from the object file but using native byte |
46 | // order. Should not be too big in practice, e.g. for ~250MiB vmlinux |
47 | // image it is ~4MiB. |
48 | OwningArrayRef<uint8_t> TypesBuffer; |
49 | |
50 | // Maps ELF section number to instruction line number information. |
51 | // Each BTFLinesVector is sorted by `InsnOffset` to allow fast lookups. |
52 | DenseMap<uint64_t, BTFLinesVector> SectionLines; |
53 | |
54 | // Maps ELF section number to CO-RE relocation information. |
55 | // Each BTFRelocVector is sorted by `InsnOffset` to allow fast lookups. |
56 | DenseMap<uint64_t, BTFRelocVector> SectionRelocs; |
57 | |
58 | // Vector of pointers to all known types, index in this vector |
59 | // equals to logical type BTF id. |
60 | // Pointers point to memory owned by `TypesBuffer` |
61 | // (except pointer at index 0, which is statically allocated). |
62 | std::vector<const BTF::CommonType *> Types; |
63 | |
64 | struct ParseContext; |
65 | Error parseBTF(ParseContext &Ctx, SectionRef BTF); |
66 | Error parseBTFExt(ParseContext &Ctx, SectionRef BTFExt); |
67 | Error (ParseContext &Ctx, DataExtractor &, |
68 | uint64_t LineInfoStart, uint64_t LineInfoEnd); |
69 | Error (ParseContext &Ctx, DataExtractor &, |
70 | uint64_t RelocInfoStart, uint64_t RelocInfoEnd); |
71 | Error parseTypesInfo(ParseContext &Ctx, uint64_t TypesInfoStart, |
72 | StringRef RawData); |
73 | |
74 | public: |
75 | // Looks-up a string in the .BTF section's string table. |
76 | // Offset is relative to string table start. |
77 | StringRef findString(uint32_t Offset) const; |
78 | |
79 | // Search for line information for a specific address, |
80 | // address match is exact (contrary to DWARFContext). |
81 | // Return nullptr if no information found. |
82 | // If information is present, return a pointer to object |
83 | // owned by this class. |
84 | const BTF::BPFLineInfo *findLineInfo(SectionedAddress Address) const; |
85 | |
86 | // Search for CO-RE relocation information for a specific address. |
87 | // Return nullptr if no information found. |
88 | // If information is present, return a pointer to object |
89 | // owned by this class. |
90 | const BTF::BPFFieldReloc *findFieldReloc(SectionedAddress Address) const; |
91 | |
92 | // Return a human readable representation of the CO-RE relocation |
93 | // record, this is for display purpose only. |
94 | // See implementation for details. |
95 | void symbolize(const BTF::BPFFieldReloc *Reloc, |
96 | SmallVectorImpl<char> &Result) const; |
97 | |
98 | // Lookup BTF type definition with a specific index. |
99 | // Return nullptr if no information found. |
100 | // If information is present, return a pointer to object |
101 | // owned by this class. |
102 | const BTF::CommonType *findType(uint32_t Id) const; |
103 | |
104 | // Return total number of known BTF types. |
105 | size_t typesCount() const { return Types.size(); } |
106 | |
107 | // Allow to selectively load BTF information. |
108 | struct ParseOptions { |
109 | bool LoadLines = false; |
110 | bool LoadTypes = false; |
111 | bool LoadRelocs = false; |
112 | }; |
113 | |
114 | // Fills instance of BTFParser with information stored in .BTF and |
115 | // .BTF.ext sections of the `Obj`. If this instance was already |
116 | // filled, old data is discarded. |
117 | // |
118 | // If information cannot be parsed: |
119 | // - return an error describing the failure; |
120 | // - state of the BTFParser might be incomplete but is not invalid, |
121 | // queries might be run against it, but some (or all) information |
122 | // might be unavailable; |
123 | Error parse(const ObjectFile &Obj, const ParseOptions &Opts); |
124 | Error parse(const ObjectFile &Obj) { return parse(Obj, Opts: {.LoadLines: true, .LoadTypes: true, .LoadRelocs: true}); } |
125 | |
126 | // Return true if `Obj` has .BTF and .BTF.ext sections. |
127 | static bool hasBTFSections(const ObjectFile &Obj); |
128 | }; |
129 | |
130 | } // namespace llvm |
131 | |
132 | #endif // LLVM_DEBUGINFO_BTF_BTFPARSER_H |
133 | |