#pragma once
#include <variant>
#include <folly/Function.h>
#include <folly/Range.h>
#include <folly/debugging/symbolizer/DwarfLineNumberVM.h>
#include <folly/debugging/symbolizer/DwarfSection.h>
#include <folly/debugging/symbolizer/DwarfUtil.h>
#include <folly/experimental/symbolizer/Elf.h>
#include <folly/experimental/symbolizer/ElfCache.h>
#include <folly/experimental/symbolizer/SymbolizedFrame.h>
namespace folly {
namespace symbolizer {
#if FOLLY_HAVE_DWARF && FOLLY_HAVE_ELF
struct CallLocation;
class DwarfImpl {
public:
explicit DwarfImpl(
ElfCacheBase* elfCache, CompilationUnits& cu, LocationInfoMode mode);
bool findLocation(
uintptr_t address,
SymbolizedFrame& frame,
folly::Range<SymbolizedFrame*> inlineFrames,
folly::FunctionRef<void(folly::StringPiece)> eachParameterName,
bool checkAddress = true) const;
private:
using AttributeValue = std::variant<uint64_t, folly::StringPiece>;
bool findSubProgramDieForAddress(
const CompilationUnit& cu,
const Die& die,
uint64_t address,
folly::Optional<uint64_t> baseAddrCU,
Die& subprogram) const;
void findInlinedSubroutineDieForAddress(
const CompilationUnit& cu,
const Die& die,
const DwarfLineNumberVM& lineVM,
uint64_t address,
folly::Optional<uint64_t> baseAddrCU,
folly::Range<CallLocation*> locations,
size_t& numFound) const;
CompilationUnit findCompilationUnit(
const CompilationUnit& cu, uint64_t targetOffset) const;
Die findDefinitionDie(const CompilationUnit& cu, const Die& die) const;
size_t forEachChild(
const CompilationUnit& cu,
const Die& die,
folly::FunctionRef<bool(const Die& die)> f) const;
bool isAddrInRangeList(
const CompilationUnit& cu,
uint64_t address,
folly::Optional<uint64_t> baseAddr,
size_t offset,
uint8_t addrSize) const;
void fillInlineFrames(
uintptr_t address,
SymbolizedFrame& frame,
folly::Range<CallLocation*> inlineLocations,
folly::Range<SymbolizedFrame*> inlineFrames) const;
ElfCacheBase* elfCache_;
CompilationUnits& cu_;
const LocationInfoMode mode_;
};
#endif
}
}