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