//===- 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.
//
// 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>;

  // 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;

  // Maps ELF section number to instruction line number information.
  // Each BTFLinesVector is sorted by `InsnOffset` to allow fast lookups.
  DenseMap<uint64_t, BTFLinesVector> SectionLines;

  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);

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;

  // 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);

  // Return true if `Obj` has .BTF and .BTF.ext sections.
  static bool hasBTFSections(const ObjectFile &Obj);
};

} // namespace llvm

#endif // LLVM_DEBUGINFO_BTF_BTFPARSER_H
