//===- 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"
#include "llvm/Support/FormatVariadic.h"

#define DEBUG_TYPE "debug-info-btf-parser"

using namespace llvm;
using object::ObjectFile;
using object::SectionedAddress;
using object::SectionRef;

const char BTFSectionName[] = ".BTF";
const char BTFExtSectionName[] = ".BTF.ext";

// 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 {
  std::string Buffer;
  raw_string_ostream Stream;

public:
  Err(const char *InitialMsg) : Buffer(InitialMsg), Stream(Buffer) {}
  Err(const char *SectionName, DataExtractor::Cursor &C)
      : Buffer(), Stream(Buffer) {
    *this << "error while reading " << SectionName
          << " section: " << C.takeError();
  };

  template <typename T> Err &operator<<(T Val) {
    Stream << Val;
    return *this;
  }

  Err &write_hex(unsigned long long Val) {
    Stream.write_hex(Val);
    return *this;
  }

  Err &operator<<(Error Val) {
    handleAllErrors(std::move(Val),
                    [=](ErrorInfoBase &Info) { Stream << Info.message(); });
    return *this;
  }

  operator Error() const {
    return make_error<StringError>(Buffer, errc::invalid_argument);
  }
};
} // 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 {
  const ObjectFile &Obj;
  const ParseOptions &Opts;
  // Map from ELF section name to SectionRef
  DenseMap<StringRef, SectionRef> Sections;

public:
  ParseContext(const ObjectFile &Obj, const ParseOptions &Opts)
      : Obj(Obj), Opts(Opts) {}

  Expected<DataExtractor> makeExtractor(SectionRef Sec) {
    Expected<StringRef> Contents = Sec.getContents();
    if (!Contents)
      return Contents.takeError();
    return DataExtractor(Contents.get(), Obj.isLittleEndian());
  }

  std::optional<SectionRef> findSection(StringRef Name) const {
    auto It = Sections.find(Name);
    if (It != Sections.end())
      return It->second;
    return std::nullopt;
  }
};

Error BTFParser::parseBTF(ParseContext &Ctx, SectionRef BTF) {
  Expected<DataExtractor> MaybeExtractor = Ctx.makeExtractor(BTF);
  if (!MaybeExtractor)
    return MaybeExtractor.takeError();

  DataExtractor &Extractor = MaybeExtractor.get();
  DataExtractor::Cursor C = DataExtractor::Cursor(0);
  uint16_t Magic = Extractor.getU16(C);
  if (!C)
    return Err(".BTF", C);
  if (Magic != BTF::MAGIC)
    return Err("invalid .BTF magic: ").write_hex(Magic);
  uint8_t Version = Extractor.getU8(C);
  if (!C)
    return Err(".BTF", C);
  if (Version != 1)
    return Err("unsupported .BTF version: ") << (unsigned)Version;
  (void)Extractor.getU8(C); // flags
  uint32_t HdrLen = Extractor.getU32(C);
  if (!C)
    return Err(".BTF", C);
  if (HdrLen < 8)
    return Err("unexpected .BTF header length: ") << HdrLen;
  uint32_t TypeOff = Extractor.getU32(C);
  uint32_t TypeLen = Extractor.getU32(C);
  uint32_t StrOff = Extractor.getU32(C);
  uint32_t StrLen = Extractor.getU32(C);
  uint32_t StrStart = HdrLen + StrOff;
  uint32_t StrEnd = StrStart + StrLen;
  uint32_t TypesInfoStart = HdrLen + TypeOff;
  uint32_t TypesInfoEnd = TypesInfoStart + TypeLen;
  uint32_t BytesExpected = std::max(StrEnd, TypesInfoEnd);
  if (!C)
    return Err(".BTF", C);
  if (Extractor.getData().size() < BytesExpected)
    return Err("invalid .BTF section size, expecting at-least ")
           << BytesExpected << " bytes";

  StringsTable = Extractor.getData().slice(StrStart, StrEnd);

  if (TypeLen > 0 && Ctx.Opts.LoadTypes) {
    StringRef RawData = Extractor.getData().slice(TypesInfoStart, TypesInfoEnd);
    if (Error E = parseTypesInfo(Ctx, TypesInfoStart, RawData))
      return E;
  }

  return Error::success();
}

// Compute record size for each BTF::CommonType sub-type
// (including entries in the tail position).
static size_t byteSize(BTF::CommonType *Type) {
  size_t Size = sizeof(BTF::CommonType);
  switch (Type->getKind()) {
  case BTF::BTF_KIND_INT:
    Size += sizeof(uint32_t);
    break;
  case BTF::BTF_KIND_ARRAY:
    Size += sizeof(BTF::BTFArray);
    break;
  case BTF::BTF_KIND_VAR:
    Size += sizeof(uint32_t);
    break;
  case BTF::BTF_KIND_DECL_TAG:
    Size += sizeof(uint32_t);
    break;
  case BTF::BTF_KIND_STRUCT:
  case BTF::BTF_KIND_UNION:
    Size += sizeof(BTF::BTFMember) * Type->getVlen();
    break;
  case BTF::BTF_KIND_ENUM:
    Size += sizeof(BTF::BTFEnum) * Type->getVlen();
    break;
  case BTF::BTF_KIND_ENUM64:
    Size += sizeof(BTF::BTFEnum64) * Type->getVlen();
    break;
  case BTF::BTF_KIND_FUNC_PROTO:
    Size += sizeof(BTF::BTFParam) * Type->getVlen();
    break;
  case BTF::BTF_KIND_DATASEC:
    Size += sizeof(BTF::BTFDataSec) * Type->getVlen();
    break;
  }
  return Size;
}

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

// 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) {
  using support::endian::byte_swap;

  TypesBuffer.assign(arrayRefFromStringRef(RawData));
  // Switch endianness if necessary.
  endianness Endianness = Ctx.Obj.isLittleEndian() ? llvm::endianness::little
                                                   : llvm::endianness::big;
  uint32_t *TypesBuffer32 = (uint32_t *)TypesBuffer.data();
  for (uint64_t I = 0; I < TypesBuffer.size() / 4; ++I)
    TypesBuffer32[I] = byte_swap(TypesBuffer32[I], Endianness);

  // The type id 0 is reserved for void type.
  Types.push_back(&VoidTypeInst);

  uint64_t Pos = 0;
  while (Pos < RawData.size()) {
    uint64_t BytesLeft = RawData.size() - Pos;
    uint64_t Offset = TypesInfoStart + Pos;
    BTF::CommonType *Type = (BTF::CommonType *)&TypesBuffer[Pos];
    if (BytesLeft < sizeof(*Type))
      return Err("incomplete type definition in .BTF section:")
             << " offset " << Offset << ", index " << Types.size();

    uint64_t Size = byteSize(Type);
    if (BytesLeft < Size)
      return Err("incomplete type definition in .BTF section:")
             << " offset=" << Offset << ", index=" << Types.size()
             << ", vlen=" << Type->getVlen();

    LLVM_DEBUG({
      llvm::dbgs() << "Adding BTF type:\n"
                   << "  Id = " << Types.size() << "\n"
                   << "  Kind = " << Type->getKind() << "\n"
                   << "  Name = " << findString(Type->NameOff) << "\n"
                   << "  Record Size = " << Size << "\n";
    });
    Types.push_back(Type);
    Pos += Size;
  }

  return Error::success();
}

Error BTFParser::parseBTFExt(ParseContext &Ctx, SectionRef BTFExt) {
  Expected<DataExtractor> MaybeExtractor = Ctx.makeExtractor(BTFExt);
  if (!MaybeExtractor)
    return MaybeExtractor.takeError();

  DataExtractor &Extractor = MaybeExtractor.get();
  DataExtractor::Cursor C = DataExtractor::Cursor(0);
  uint16_t Magic = Extractor.getU16(C);
  if (!C)
    return Err(".BTF.ext", C);
  if (Magic != BTF::MAGIC)
    return Err("invalid .BTF.ext magic: ").write_hex(Magic);
  uint8_t Version = Extractor.getU8(C);
  if (!C)
    return Err(".BTF", C);
  if (Version != 1)
    return Err("unsupported .BTF.ext version: ") << (unsigned)Version;
  (void)Extractor.getU8(C); // flags
  uint32_t HdrLen = Extractor.getU32(C);
  if (!C)
    return Err(".BTF.ext", C);
  if (HdrLen < 8)
    return Err("unexpected .BTF.ext header length: ") << HdrLen;
  (void)Extractor.getU32(C); // func_info_off
  (void)Extractor.getU32(C); // func_info_len
  uint32_t LineInfoOff = Extractor.getU32(C);
  uint32_t LineInfoLen = Extractor.getU32(C);
  uint32_t RelocInfoOff = Extractor.getU32(C);
  uint32_t RelocInfoLen = Extractor.getU32(C);
  if (!C)
    return Err(".BTF.ext", C);

  if (LineInfoLen > 0 && Ctx.Opts.LoadLines) {
    uint32_t LineInfoStart = HdrLen + LineInfoOff;
    uint32_t LineInfoEnd = LineInfoStart + LineInfoLen;
    if (Error E = parseLineInfo(Ctx, Extractor, LineInfoStart, LineInfoEnd))
      return E;
  }

  if (RelocInfoLen > 0 && Ctx.Opts.LoadRelocs) {
    uint32_t RelocInfoStart = HdrLen + RelocInfoOff;
    uint32_t RelocInfoEnd = RelocInfoStart + RelocInfoLen;
    if (Error E = parseRelocInfo(Ctx, Extractor, RelocInfoStart, RelocInfoEnd))
      return E;
  }

  return Error::success();
}

Error BTFParser::parseLineInfo(ParseContext &Ctx, DataExtractor &Extractor,
                               uint64_t LineInfoStart, uint64_t LineInfoEnd) {
  DataExtractor::Cursor C = DataExtractor::Cursor(LineInfoStart);
  uint32_t RecSize = Extractor.getU32(C);
  if (!C)
    return Err(".BTF.ext", C);
  if (RecSize < 16)
    return Err("unexpected .BTF.ext line info record length: ") << RecSize;

  while (C && C.tell() < LineInfoEnd) {
    uint32_t SecNameOff = Extractor.getU32(C);
    uint32_t NumInfo = Extractor.getU32(C);
    StringRef SecName = findString(SecNameOff);
    std::optional<SectionRef> Sec = Ctx.findSection(SecName);
    if (!C)
      return Err(".BTF.ext", C);
    if (!Sec)
      return Err("") << "can't find section '" << SecName
                     << "' while parsing .BTF.ext line info";
    BTFLinesVector &Lines = SectionLines[Sec->getIndex()];
    for (uint32_t I = 0; C && I < NumInfo; ++I) {
      uint64_t RecStart = C.tell();
      uint32_t InsnOff = Extractor.getU32(C);
      uint32_t FileNameOff = Extractor.getU32(C);
      uint32_t LineOff = Extractor.getU32(C);
      uint32_t LineCol = Extractor.getU32(C);
      if (!C)
        return Err(".BTF.ext", C);
      Lines.push_back({InsnOff, FileNameOff, LineOff, LineCol});
      C.seek(RecStart + RecSize);
    }
    llvm::stable_sort(Lines,
                      [](const BTF::BPFLineInfo &L, const BTF::BPFLineInfo &R) {
                        return L.InsnOffset < R.InsnOffset;
                      });
  }
  if (!C)
    return Err(".BTF.ext", C);

  return Error::success();
}

Error BTFParser::parseRelocInfo(ParseContext &Ctx, DataExtractor &Extractor,
                                uint64_t RelocInfoStart,
                                uint64_t RelocInfoEnd) {
  DataExtractor::Cursor C = DataExtractor::Cursor(RelocInfoStart);
  uint32_t RecSize = Extractor.getU32(C);
  if (!C)
    return Err(".BTF.ext", C);
  if (RecSize < 16)
    return Err("unexpected .BTF.ext field reloc info record length: ")
           << RecSize;
  while (C && C.tell() < RelocInfoEnd) {
    uint32_t SecNameOff = Extractor.getU32(C);
    uint32_t NumInfo = Extractor.getU32(C);
    StringRef SecName = findString(SecNameOff);
    std::optional<SectionRef> Sec = Ctx.findSection(SecName);
    BTFRelocVector &Relocs = SectionRelocs[Sec->getIndex()];
    for (uint32_t I = 0; C && I < NumInfo; ++I) {
      uint64_t RecStart = C.tell();
      uint32_t InsnOff = Extractor.getU32(C);
      uint32_t TypeID = Extractor.getU32(C);
      uint32_t OffsetNameOff = Extractor.getU32(C);
      uint32_t RelocKind = Extractor.getU32(C);
      if (!C)
        return Err(".BTF.ext", C);
      Relocs.push_back({InsnOff, TypeID, OffsetNameOff, RelocKind});
      C.seek(RecStart + RecSize);
    }
    llvm::stable_sort(
        Relocs, [](const BTF::BPFFieldReloc &L, const BTF::BPFFieldReloc &R) {
          return L.InsnOffset < R.InsnOffset;
        });
  }
  if (!C)
    return Err(".BTF.ext", C);

  return Error::success();
}

Error BTFParser::parse(const ObjectFile &Obj, const ParseOptions &Opts) {
  StringsTable = StringRef();
  SectionLines.clear();
  SectionRelocs.clear();
  Types.clear();
  TypesBuffer.clear();

  ParseContext Ctx(Obj, Opts);
  std::optional<SectionRef> BTF;
  std::optional<SectionRef> BTFExt;
  for (SectionRef Sec : Obj.sections()) {
    Expected<StringRef> MaybeName = Sec.getName();
    if (!MaybeName)
      return Err("error while reading section name: ") << MaybeName.takeError();
    Ctx.Sections[*MaybeName] = Sec;
    if (*MaybeName == BTFSectionName)
      BTF = Sec;
    if (*MaybeName == BTFExtSectionName)
      BTFExt = Sec;
  }
  if (!BTF)
    return Err("can't find .BTF section");
  if (!BTFExt)
    return Err("can't find .BTF.ext section");
  if (Error E = parseBTF(Ctx, *BTF))
    return E;
  if (Error E = parseBTFExt(Ctx, *BTFExt))
    return E;

  return Error::success();
}

bool BTFParser::hasBTFSections(const ObjectFile &Obj) {
  bool HasBTF = false;
  bool HasBTFExt = false;
  for (SectionRef Sec : Obj.sections()) {
    Expected<StringRef> Name = Sec.getName();
    if (Error E = Name.takeError()) {
      logAllUnhandledErrors(std::move(E), errs());
      continue;
    }
    HasBTF |= *Name == BTFSectionName;
    HasBTFExt |= *Name == BTFExtSectionName;
    if (HasBTF && HasBTFExt)
      return true;
  }
  return false;
}

StringRef BTFParser::findString(uint32_t Offset) const {
  return StringsTable.slice(Offset, StringsTable.find(0, Offset));
}

template <typename T>
static const T *findInfo(const DenseMap<uint64_t, SmallVector<T, 0>> &SecMap,
                         SectionedAddress Address) {
  auto MaybeSecInfo = SecMap.find(Address.SectionIndex);
  if (MaybeSecInfo == SecMap.end())
    return nullptr;

  const SmallVector<T, 0> &SecInfo = MaybeSecInfo->second;
  const uint64_t TargetOffset = Address.Address;
  typename SmallVector<T, 0>::const_iterator MaybeInfo = llvm::partition_point(
      SecInfo, [=](const T &Entry) { return Entry.InsnOffset < TargetOffset; });
  if (MaybeInfo == SecInfo.end() || MaybeInfo->InsnOffset != Address.Address)
    return nullptr;

  return &*MaybeInfo;
}

const BTF::BPFLineInfo *
BTFParser::findLineInfo(SectionedAddress Address) const {
  return findInfo(SectionLines, Address);
}

const BTF::BPFFieldReloc *
BTFParser::findFieldReloc(SectionedAddress Address) const {
  return findInfo(SectionRelocs, Address);
}

const BTF::CommonType *BTFParser::findType(uint32_t Id) const {
  if (Id < Types.size())
    return Types[Id];
  return nullptr;
}

enum RelocKindGroup {
  RKG_FIELD,
  RKG_TYPE,
  RKG_ENUMVAL,
  RKG_UNKNOWN,
};

static RelocKindGroup relocKindGroup(const BTF::BPFFieldReloc *Reloc) {
  switch (Reloc->RelocKind) {
  case BTF::FIELD_BYTE_OFFSET:
  case BTF::FIELD_BYTE_SIZE:
  case BTF::FIELD_EXISTENCE:
  case BTF::FIELD_SIGNEDNESS:
  case BTF::FIELD_LSHIFT_U64:
  case BTF::FIELD_RSHIFT_U64:
    return RKG_FIELD;
  case BTF::BTF_TYPE_ID_LOCAL:
  case BTF::BTF_TYPE_ID_REMOTE:
  case BTF::TYPE_EXISTENCE:
  case BTF::TYPE_MATCH:
  case BTF::TYPE_SIZE:
    return RKG_TYPE;
  case BTF::ENUM_VALUE_EXISTENCE:
  case BTF::ENUM_VALUE:
    return RKG_ENUMVAL;
  default:
    return RKG_UNKNOWN;
  }
}

static bool isMod(const BTF::CommonType *Type) {
  switch (Type->getKind()) {
  case BTF::BTF_KIND_VOLATILE:
  case BTF::BTF_KIND_CONST:
  case BTF::BTF_KIND_RESTRICT:
  case BTF::BTF_KIND_TYPE_TAG:
    return true;
  default:
    return false;
  }
}

static bool printMod(const BTFParser &BTF, const BTF::CommonType *Type,
                     raw_ostream &Stream) {
  switch (Type->getKind()) {
  case BTF::BTF_KIND_CONST:
    Stream << " const";
    break;
  case BTF::BTF_KIND_VOLATILE:
    Stream << " volatile";
    break;
  case BTF::BTF_KIND_RESTRICT:
    Stream << " restrict";
    break;
  case BTF::BTF_KIND_TYPE_TAG:
    Stream << " type_tag(\"" << BTF.findString(Type->NameOff) << "\")";
    break;
  default:
    return false;
  }
  return true;
}

static const BTF::CommonType *skipModsAndTypedefs(const BTFParser &BTF,
                                                  const BTF::CommonType *Type) {
  while (isMod(Type) || Type->getKind() == BTF::BTF_KIND_TYPEDEF) {
    auto *Base = BTF.findType(Type->Type);
    if (!Base)
      break;
    Type = Base;
  }
  return Type;
}

namespace {
struct StrOrAnon {
  const BTFParser &BTF;
  uint32_t Offset;
  uint32_t Idx;
};

static raw_ostream &operator<<(raw_ostream &Stream, const StrOrAnon &S) {
  StringRef Str = S.BTF.findString(S.Offset);
  if (Str.empty())
    Stream << "<anon " << S.Idx << ">";
  else
    Stream << Str;
  return Stream;
}
} // anonymous namespace

static void relocKindName(uint32_t X, raw_ostream &Out) {
  Out << "<";
  switch (X) {
  default:
    Out << "reloc kind #" << X;
    break;
  case BTF::FIELD_BYTE_OFFSET:
    Out << "byte_off";
    break;
  case BTF::FIELD_BYTE_SIZE:
    Out << "byte_sz";
    break;
  case BTF::FIELD_EXISTENCE:
    Out << "field_exists";
    break;
  case BTF::FIELD_SIGNEDNESS:
    Out << "signed";
    break;
  case BTF::FIELD_LSHIFT_U64:
    Out << "lshift_u64";
    break;
  case BTF::FIELD_RSHIFT_U64:
    Out << "rshift_u64";
    break;
  case BTF::BTF_TYPE_ID_LOCAL:
    Out << "local_type_id";
    break;
  case BTF::BTF_TYPE_ID_REMOTE:
    Out << "target_type_id";
    break;
  case BTF::TYPE_EXISTENCE:
    Out << "type_exists";
    break;
  case BTF::TYPE_MATCH:
    Out << "type_matches";
    break;
  case BTF::TYPE_SIZE:
    Out << "type_size";
    break;
  case BTF::ENUM_VALUE_EXISTENCE:
    Out << "enumval_exists";
    break;
  case BTF::ENUM_VALUE:
    Out << "enumval_value";
    break;
  }
  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 {
  raw_svector_ostream Stream(Result);
  StringRef FullSpecStr = findString(Reloc->OffsetNameOff);
  SmallVector<uint32_t, 8> RawSpec;

  auto Fail = [&](auto Msg) {
    Result.resize(0);
    relocKindName(Reloc->RelocKind, Stream);
    Stream << " [" << Reloc->TypeID << "] '" << FullSpecStr << "'"
           << " <" << Msg << ">";
  };

  // Relocation access string follows pattern [0-9]+(:[0-9]+)*,
  // e.g.: 12:22:3. Code below splits `SpecStr` by ':', parses
  // numbers, and pushes them to `RawSpec`.
  StringRef SpecStr = FullSpecStr;
  while (SpecStr.size()) {
    unsigned long long Val;
    if (consumeUnsignedInteger(SpecStr, 10, Val))
      return Fail("spec string is not a number");
    RawSpec.push_back(Val);
    if (SpecStr.empty())
      break;
    if (SpecStr[0] != ':')
      return Fail(
          formatv("unexpected spec string delimiter: '{0}'", SpecStr[0]));
    SpecStr = SpecStr.substr(1);
  }

  // Print relocation kind to `Stream`.
  relocKindName(Reloc->RelocKind, Stream);

  uint32_t CurId = Reloc->TypeID;
  const BTF::CommonType *Type = findType(CurId);
  if (!Type)
    return Fail(formatv("unknown type id: {0:d}", CurId));

  Stream << " [" << CurId << "]";

  // `Type` might have modifiers, e.g. for type 'const int' the `Type`
  // would refer to BTF type of kind BTF_KIND_CONST.
  // Print all these modifiers to `Stream`.
  for (uint32_t ChainLen = 0; printMod(*this, Type, Stream); ++ChainLen) {
    if (ChainLen >= 32)
      return Fail("modifiers chain is too long");

    CurId = Type->Type;
    const BTF::CommonType *NextType = findType(CurId);
    if (!NextType)
      return Fail(formatv("unknown type id: {0:d} in modifiers chain", CurId));
    Type = NextType;
  }
  // Print the type name to `Stream`.
  if (CurId == 0) {
    Stream << " void";
  } else {
    switch (Type->getKind()) {
    case BTF::BTF_KIND_TYPEDEF:
      Stream << " typedef";
      break;
    case BTF::BTF_KIND_STRUCT:
      Stream << " struct";
      break;
    case BTF::BTF_KIND_UNION:
      Stream << " union";
      break;
    case BTF::BTF_KIND_ENUM:
      Stream << " enum";
      break;
    case BTF::BTF_KIND_ENUM64:
      Stream << " enum";
      break;
    case BTF::BTF_KIND_FWD:
      if (Type->Info & BTF::FWD_UNION_FLAG)
        Stream << " fwd union";
      else
        Stream << " fwd struct";
      break;
    default:
      break;
    }
    Stream << " " << StrOrAnon({*this, Type->NameOff, CurId});
  }

  RelocKindGroup Group = relocKindGroup(Reloc);
  // Type-based relocations don't use access string but clang backend
  // generates '0' and libbpf checks it's value, do the same here.
  if (Group == RKG_TYPE) {
    if (RawSpec.size() != 1 || RawSpec[0] != 0)
      return Fail("unexpected type-based relocation spec: should be '0'");
    return;
  }

  Stream << "::";

  // For enum-based relocations access string is a single number,
  // corresponding to the enum literal sequential number.
  // E.g. for `enum E { U, V }`, relocation requesting value of `V`
  // would look as follows:
  // - kind: BTF::ENUM_VALUE
  // - BTF id: id for `E`
  // - access string: "1"
  if (Group == RKG_ENUMVAL) {
    Type = skipModsAndTypedefs(*this, Type);

    if (RawSpec.size() != 1)
      return Fail("unexpected enumval relocation spec size");

    uint32_t NameOff;
    uint64_t Val;
    uint32_t Idx = RawSpec[0];
    if (auto *T = dyn_cast<BTF::EnumType>(Type)) {
      if (T->values().size() <= Idx)
        return Fail(formatv("bad value index: {0:d}", Idx));
      const BTF::BTFEnum &E = T->values()[Idx];
      NameOff = E.NameOff;
      Val = E.Val;
    } else if (auto *T = dyn_cast<BTF::Enum64Type>(Type)) {
      if (T->values().size() <= Idx)
        return Fail(formatv("bad value index: {0:d}", Idx));
      const BTF::BTFEnum64 &E = T->values()[Idx];
      NameOff = E.NameOff;
      Val = (uint64_t)E.Val_Hi32 << 32u | E.Val_Lo32;
    } else {
      return Fail(formatv("unexpected type kind for enum relocation: {0:d}",
                          Type->getKind()));
    }

    Stream << StrOrAnon({*this, NameOff, Idx});
    if (Type->Info & BTF::ENUM_SIGNED_FLAG)
      Stream << " = " << (int64_t)Val;
    else
      Stream << " = " << (uint64_t)Val;
    return;
  }

  // For type-based relocations access string is an array of numbers,
  // which resemble index parameters for `getelementptr` LLVM IR instruction.
  // E.g. for the following types:
  //
  //   struct foo {
  //     int a;
  //     int b;
  //   };
  //   struct bar {
  //     int u;
  //     struct foo v[7];
  //   };
  //
  // Relocation requesting `offsetof(struct bar, v[2].b)` will have
  // the following access string: 0:1:2:1
  //                              ^ ^ ^ ^
  //                              | | | |
  //                  initial index | | field 'b' is a field #1
  //                                | | (counting from 0)
  //                                | array index #2
  //           field 'v' is a field #1
  //              (counting from 0)
  if (Group == RKG_FIELD) {
    if (RawSpec.size() < 1)
      return Fail("field spec too short");

    if (RawSpec[0] != 0)
      Stream << "[" << RawSpec[0] << "]";
    for (uint32_t I = 1; I < RawSpec.size(); ++I) {
      Type = skipModsAndTypedefs(*this, Type);
      uint32_t Idx = RawSpec[I];

      if (auto *T = dyn_cast<BTF::StructType>(Type)) {
        if (T->getVlen() <= Idx)
          return Fail(formatv(
              "member index {0:d} for spec sub-string {1:d} is out of range",
              Idx, I));

        const BTF::BTFMember &Member = T->members()[Idx];
        if (I != 1 || RawSpec[0] != 0)
          Stream << ".";
        Stream << StrOrAnon({*this, Member.NameOff, Idx});
        Type = findType(Member.Type);
        if (!Type)
          return Fail(
              formatv("unknown member type id {0:d} for spec sub-string {1:d}",
                      Member.Type, I));
      } else if (auto *T = dyn_cast<BTF::ArrayType>(Type)) {
        Stream << "[" << Idx << "]";
        Type = findType(T->getArray().ElemType);
        if (!Type)
          return Fail(
              formatv("unknown element type id {0:d} for spec sub-string {1:d}",
                      T->getArray().ElemType, I));
      } else {
        return Fail(
            formatv("unexpected type kind {0:d} for spec sub-string {1:d}",
                    Type->getKind(), I));
      }
    }

    Stream << " (" << FullSpecStr << ")";
    return;
  }

  return Fail(formatv("unknown relocation kind: {0:d}", Reloc->RelocKind));
}
