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 parseLineInfo(ParseContext &Ctx, DataExtractor &Extractor,
68                       uint64_t LineInfoStart, uint64_t LineInfoEnd);
69   Error parseRelocInfo(ParseContext &Ctx, DataExtractor &Extractor,
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.
typesCount()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);
parse(const ObjectFile & Obj)124   Error parse(const ObjectFile &Obj) { return parse(Obj, {true, true, 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