llvm/llvm/lib/DebugInfo/BTF/BTFParser.cpp

//===- BTFParser.cpp ------------------------------------------------------===//
//
// 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/interprets .BTF and .BTF.ext ELF sections.
// Refer to BTFParser.h for API description.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/BTF/BTFParser.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Errc.h"

#define DEBUG_TYPE

usingnamespacellvm;
ObjectFile;
SectionedAddress;
SectionRef;

const char BTFSectionName[] =;
const char BTFExtSectionName[] =;

// Utility class with API similar to raw_ostream but can be cast
// to Error, e.g.:
//
// Error foo(...) {
//   ...
//   if (Error E = bar(...))
//     return Err("error while foo(): ") << E;
//   ...
// }
//
namespace {
class Err {};
} // anonymous namespace

// ParseContext wraps information that is only necessary while parsing
// ObjectFile and can be discarded once parsing is done.
// Used by BTFParser::parse* auxiliary functions.
struct BTFParser::ParseContext {};

Error BTFParser::parseBTF(ParseContext &Ctx, SectionRef BTF) {}

// Compute record size for each BTF::CommonType sub-type
// (including entries in the tail position).
static size_t byteSize(BTF::CommonType *Type) {}

// Guard value for voids, simplifies code a bit, but NameOff is not
// actually valid.
const BTF::CommonType VoidTypeInst =;

// Type information "parsing" is very primitive:
// - The `RawData` is copied to a buffer owned by `BTFParser` instance.
// - The buffer is treated as an array of `uint32_t` values, each value
//   is swapped to use native endianness. This is possible, because
//   according to BTF spec all buffer elements are structures comprised
//   of `uint32_t` fields.
// - `BTFParser::Types` vector is filled with pointers to buffer
//   elements, using `byteSize()` function to slice the buffer at type
//   record boundaries.
// - If at some point a type definition with incorrect size (logical size
//   exceeding buffer boundaries) is reached it is not added to the
//   `BTFParser::Types` vector and the process stops.
Error BTFParser::parseTypesInfo(ParseContext &Ctx, uint64_t TypesInfoStart,
                                StringRef RawData) {}

Error BTFParser::parseBTFExt(ParseContext &Ctx, SectionRef BTFExt) {}

Error BTFParser::parseLineInfo(ParseContext &Ctx, DataExtractor &Extractor,
                               uint64_t LineInfoStart, uint64_t LineInfoEnd) {}

Error BTFParser::parseRelocInfo(ParseContext &Ctx, DataExtractor &Extractor,
                                uint64_t RelocInfoStart,
                                uint64_t RelocInfoEnd) {}

Error BTFParser::parse(const ObjectFile &Obj, const ParseOptions &Opts) {}

bool BTFParser::hasBTFSections(const ObjectFile &Obj) {}

StringRef BTFParser::findString(uint32_t Offset) const {}

template <typename T>
static const T *findInfo(const DenseMap<uint64_t, SmallVector<T, 0>> &SecMap,
                         SectionedAddress Address) {}

const BTF::BPFLineInfo *
BTFParser::findLineInfo(SectionedAddress Address) const {}

const BTF::BPFFieldReloc *
BTFParser::findFieldReloc(SectionedAddress Address) const {}

const BTF::CommonType *BTFParser::findType(uint32_t Id) const {}

enum RelocKindGroup {};

static RelocKindGroup relocKindGroup(const BTF::BPFFieldReloc *Reloc) {}

static bool isMod(const BTF::CommonType *Type) {}

static bool printMod(const BTFParser &BTF, const BTF::CommonType *Type,
                     raw_ostream &Stream) {}

static const BTF::CommonType *skipModsAndTypedefs(const BTFParser &BTF,
                                                  const BTF::CommonType *Type) {}

namespace {
struct StrOrAnon {};

static raw_ostream &operator<<(raw_ostream &Stream, const StrOrAnon &S) {}
} // anonymous namespace

static void relocKindName(uint32_t X, raw_ostream &Out) {}

// Produces a human readable description of a CO-RE relocation.
// Such relocations are generated by BPF backend, and processed
// by libbpf's BPF program loader [1].
//
// Each relocation record has the following information:
// - Relocation kind;
// - BTF type ID;
// - Access string offset in string table.
//
// There are different kinds of relocations, these kinds could be split
// in three groups:
// - load-time information about types (size, existence),
//   `BTFParser::symbolize()` output for such relocations uses the template:
//
//     <relocation-kind> [<id>] <type-name>
//
//   For example:
//   - "<type_exists> [7] struct foo"
//   - "<type_size> [7] struct foo"
//
// - load-time information about enums (literal existence, literal value),
//   `BTFParser::symbolize()` output for such relocations uses the template:
//
//     <relocation-kind> [<id>] <type-name>::<literal-name> = <original-value>
//
//   For example:
//   - "<enumval_exists> [5] enum foo::U = 1"
//   - "<enumval_value> [5] enum foo::V = 2"
//
// - load-time information about fields (e.g. field offset),
//   `BTFParser::symbolize()` output for such relocations uses the template:
//
//     <relocation-kind> [<id>] \
//       <type-name>::[N].<field-1-name>...<field-M-name> \
//       (<access string>)
//
//   For example:
//   - "<byte_off> [8] struct bar::[7].v (7:1)"
//   - "<field_exists> [8] struct bar::v (0:1)"
//
// If relocation description is not valid output follows the following pattern:
//
//     <relocation-kind> <type-id>::<unprocessedaccess-string> <<error-msg>>
//
// For example:
//
// - "<type_sz> [42] '' <unknown type id: 42>"
// - "<byte_off> [4] '0:' <field spec too short>"
//
// Additional examples could be found in unit tests, see
// llvm/unittests/DebugInfo/BTF/BTFParserTest.cpp.
//
// [1] https://www.kernel.org/doc/html/latest/bpf/libbpf/index.html
void BTFParser::symbolize(const BTF::BPFFieldReloc *Reloc,
                          SmallVectorImpl<char> &Result) const {}