30#define DEBUG_TYPE "DWARFReader" 
   32void LVDWARFReader::processOneAttribute(
const DWARFDie &Die,
 
   42  auto GetAsUnsignedConstant = [&]() -> int64_t {
 
   54  auto GetBoundValue = [&AttrSpec](
const DWARFFormValue &FormValue) -> int64_t {
 
   56    case dwarf::DW_FORM_ref_addr:
 
   57    case dwarf::DW_FORM_ref1:
 
   58    case dwarf::DW_FORM_ref2:
 
   59    case dwarf::DW_FORM_ref4:
 
   60    case dwarf::DW_FORM_ref8:
 
   61    case dwarf::DW_FORM_ref_udata:
 
   62    case dwarf::DW_FORM_ref_sig8:
 
   64    case dwarf::DW_FORM_data1:
 
   65    case dwarf::DW_FORM_flag:
 
   66    case dwarf::DW_FORM_data2:
 
   67    case dwarf::DW_FORM_data4:
 
   68    case dwarf::DW_FORM_data8:
 
   69    case dwarf::DW_FORM_udata:
 
   70    case dwarf::DW_FORM_ref_sup4:
 
   71    case dwarf::DW_FORM_ref_sup8:
 
   73    case dwarf::DW_FORM_sdata:
 
   75    case dwarf::DW_FORM_implicit_const:
 
   87  switch (AttrSpec.
Attr) {
 
   88  case dwarf::DW_AT_accessibility:
 
   91  case dwarf::DW_AT_artificial:
 
   94  case dwarf::DW_AT_bit_size:
 
   97  case dwarf::DW_AT_byte_size:
 
  100  case dwarf::DW_AT_call_file:
 
  102                                             ? GetAsUnsignedConstant() + 1
 
  103                                             : GetAsUnsignedConstant());
 
  105  case dwarf::DW_AT_call_line:
 
  108  case dwarf::DW_AT_comp_dir:
 
  111  case dwarf::DW_AT_const_value:
 
  120      if (FormValue.
getForm() == dwarf::DW_FORM_sdata) {
 
  121        std::stringstream Stream;
 
  134  case dwarf::DW_AT_count:
 
  137  case dwarf::DW_AT_decl_line:
 
  140  case dwarf::DW_AT_decl_file:
 
  142                                         ? GetAsUnsignedConstant() + 1
 
  143                                         : GetAsUnsignedConstant());
 
  145  case dwarf::DW_AT_enum_class:
 
  146    if (GetFlag(FormValue))
 
  149  case dwarf::DW_AT_external:
 
  150    if (GetFlag(FormValue))
 
  153  case dwarf::DW_AT_GNU_discriminator:
 
  156  case dwarf::DW_AT_inline:
 
  159  case dwarf::DW_AT_lower_bound:
 
  162  case dwarf::DW_AT_name:
 
  165  case dwarf::DW_AT_GNU_template_name:
 
  168  case dwarf::DW_AT_linkage_name:
 
  169  case dwarf::DW_AT_MIPS_linkage_name:
 
  172  case dwarf::DW_AT_producer:
 
  173    if (
options().getAttributeProducer())
 
  176  case dwarf::DW_AT_language:
 
  177    if (
options().getAttributeLanguage())
 
  181  case dwarf::DW_AT_upper_bound:
 
  184  case dwarf::DW_AT_virtuality:
 
  188  case dwarf::DW_AT_abstract_origin:
 
  189  case dwarf::DW_AT_call_origin:
 
  190  case dwarf::DW_AT_extension:
 
  191  case dwarf::DW_AT_import:
 
  192  case dwarf::DW_AT_specification:
 
  193  case dwarf::DW_AT_type:
 
  194    updateReference(AttrSpec.
Attr, FormValue);
 
  197  case dwarf::DW_AT_low_pc:
 
  198    if (
options().getGeneralCollectRanges()) {
 
  204        CurrentLowPC = *
Value;
 
  207        if (U->getAddrOffsetSectionItem(UValue)) {
 
  229  case dwarf::DW_AT_high_pc:
 
  230    if (
options().getGeneralCollectRanges()) {
 
  232      if (std::optional<uint64_t> Address = FormValue.
getAsAddress())
 
  234        CurrentHighPC = *Address;
 
  253  case dwarf::DW_AT_ranges:
 
  254    if (RangesDataAvailable && 
options().getGeneralCollectRanges()) {
 
  257        if (FormValue.
getForm() == dwarf::DW_FORM_rnglistx)
 
  262          GetRanges(FormValue, U);
 
  263      if (!RangesOrError) {
 
  266          dbgs() << 
format(
"error decoding address ranges = ",
 
  295  case dwarf::DW_AT_data_member_location:
 
  296    if (
options().getAttributeAnyLocation())
 
  297      processLocationMember(AttrSpec.
Attr, FormValue, Die, OffsetOnEntry);
 
  301  case dwarf::DW_AT_location:
 
  302  case dwarf::DW_AT_string_length:
 
  303  case dwarf::DW_AT_use_location:
 
  305      processLocationList(AttrSpec.
Attr, FormValue, Die, OffsetOnEntry);
 
  308  case dwarf::DW_AT_call_data_value:
 
  309  case dwarf::DW_AT_call_value:
 
  310  case dwarf::DW_AT_GNU_call_site_data_value:
 
  311  case dwarf::DW_AT_GNU_call_site_value:
 
  313      processLocationList(AttrSpec.
Attr, FormValue, Die, OffsetOnEntry,
 
  322LVScope *LVDWARFReader::processOneDie(
const DWARFDie &InputDIE, 
LVScope *Parent,
 
  323                                      DWARFDie &SkeletonDie) {
 
  328  const DWARFDie &DIE = SkeletonDie.
isValid() ? SkeletonDie : InputDIE;
 
  329  DWARFDataExtractor DebugInfoData =
 
  337  CurrentEndOffset = 0;
 
  372      for (LVElement *Target : 
Reference.References)
 
  374      for (LVElement *Target : 
Reference.Types)
 
  391    auto ProcessAttributes = [&](
const DWARFDie &TheDIE,
 
  392                                 DWARFDataExtractor &DebugData) {
 
  393      CurrentEndOffset = 
Offset;
 
  394      uint32_t abbrCode = DebugData.getULEB128(&CurrentEndOffset);
 
  396        if (
const DWARFAbbreviationDeclaration *AbbrevDecl =
 
  399            for (
const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
 
  400                 AbbrevDecl->attributes())
 
  401              processOneAttribute(TheDIE, &CurrentEndOffset, AttrSpec);
 
  405    ProcessAttributes(DIE, DebugInfoData);
 
  410      DWARFDataExtractor DebugInfoData =
 
  414        ProcessAttributes(InputDIE, DebugInfoData);
 
  423      if (FoundLowPC && FoundHighPC) {
 
  427          if ((
options().getAttributePublics() ||
 
  428               options().getPrintAnyLine()) &&
 
  443        std::optional<DWARFFormValue> LinkageDIE =
 
  445        if (LinkageDIE.has_value()) {
 
  472                          CurrentHighPC > CurrentLowPC
 
  479    if (Parent->getIsAggregate())
 
  490    Parent->setIsTemplate();
 
  495void LVDWARFReader::traverseDieAndChildren(DWARFDie &DIE, 
LVScope *Parent,
 
  496                                           DWARFDie &SkeletonDie) {
 
  498  LVScope *
Scope = processOneDie(DIE, Parent, SkeletonDie);
 
  506      traverseDieAndChildren(Child, Scope, DummyDie);
 
  516void LVDWARFReader::processLocationGaps() {
 
  517  if (
options().getAttributeAnyLocation())
 
  518    for (LVSymbol *Symbol : SymbolsWithLocations)
 
  519      Symbol->fillLocationGaps();
 
  522void LVDWARFReader::createLineAndFileRecords(
 
  523    const DWARFDebugLine::LineTable *
Lines) {
 
  528  if (!Lines->Prologue.FileNames.empty())
 
  529    for (
const DWARFDebugLine::FileNameEntry &Entry :
 
  530         Lines->Prologue.FileNames) {
 
  531      std::string Directory;
 
  532      if (Lines->getDirectoryForEntry(Entry, Directory))
 
  534      if (Directory.empty())
 
  535        Directory = std::string(
CompileUnit->getCompilationDirectory());
 
  538      raw_string_ostream(
String) << Directory << 
"/" << 
File;
 
  543  bool IncrementIndex = Lines->Prologue.getVersion() >= 5;
 
  546  if (
options().getPrintLines() && Lines->Rows.size())
 
  547    for (
const DWARFDebugLine::Row &Row : Lines->Rows) {
 
  552      LVLineDebug *
Line = createLineDebug();
 
  557          CompileUnit->getFilename(IncrementIndex ? Row.File + 1 : Row.File));
 
  558      Line->setLineNumber(Row.Line);
 
  559      if (Row.Discriminator)
 
  560        Line->setDiscriminator(Row.Discriminator);
 
  562        Line->setIsNewStatement();
 
  564        Line->setIsBasicBlock();
 
  566        Line->setIsEndSequence();
 
  567      if (Row.EpilogueBegin)
 
  568        Line->setIsEpilogueBegin();
 
  570        Line->setIsPrologueEnd();
 
  573               << 
" Line: " << 
Line->lineNumberAsString(
true)
 
  585  if (Opcode == dwarf::DW_OP_regval_type)
 
  591  auto *MCRegInfo = 
MRI.get();
 
  595    if (std::optional<MCRegister> LLVMRegNum =
 
  596            MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
 
  597      if (
const char *
RegName = MCRegInfo->getName(*LLVMRegNum))
 
 
  608    W.startLine() << 
"\n";
 
  609    W.printString(
"File", Obj.getFileName().str());
 
  622                             "Could not create DWARF information: %s",
 
  625  if (
Error Err = loadTargetInfo(Obj))
 
  634      DwarfContext->getNumCompileUnits() ? DwarfContext->compile_units()
 
  635                                         : DwarfContext->dwo_compile_units();
 
  636  for (
const std::unique_ptr<DWARFUnit> &
CU : CompileUnits) {
 
  694    auto DeduceIncrementFileIndex = [&]() -> 
bool {
 
  695      if (
CU->getVersion() < 5)
 
  700              CU->getContext().getLineTableForUnit(
CU.get())) {
 
  702        if (LT->hasFileAtIndex(0) && LT->hasFileAtIndex(1)) {
 
  704              LT->Prologue.getFileNameEntry(0);
 
  706              LT->Prologue.getFileNameEntry(1);
 
  712          std::string FileZero;
 
  715          LT->getFileNameByIndex(
 
  718          LT->getFileNameByIndex(
 
  721          return FileZero != FileOne;
 
  729    IncrementFileIndex = DeduceIncrementFileIndex();
 
  734      std::optional<const char *> DWOFileName =
 
  735          CU->getVersion() >= 5
 
  738      StringRef From(DWOFileName.value_or(
""));
 
  747        DWOAlternativeLocation);
 
  759    RangesDataAvailable =
 
  764    traverseDieAndChildren(CUDie, 
Root, SkeletonDie);
 
  766    createLineAndFileRecords(DwarfContext->getLineTableForUnit(
CU.get()));
 
  776    ScopesWithRanges->
sort();
 
  779    processLocationGaps();
 
  782    ScopesWithRanges->
clear();
 
  783    SymbolsWithLocations.clear();
 
 
  795                                        bool CallSiteLocation) {
 
  812                               U->getFormParams().Format);
 
  825    if (FormValue.
getForm() == dwarf::DW_FORM_loclistx) {
 
  826      std::optional<uint64_t> LoclistOffset = U->getLoclistOffset(
Offset);
 
  832    if (std::optional<SectionedAddress> BA = 
U->getBaseAddress())
 
  837    auto ProcessLocationEntry = [&](
const DWARFLocationEntry &
Entry) {
 
  838      if (
Entry.Kind == dwarf::DW_LLE_base_address) {
 
  842      if (
Entry.Kind == dwarf::DW_LLE_offset_pair) {
 
  845        DWARFAddressRange 
Range{LowPC, HighPC, 
Entry.SectionIndex};
 
  848        DWARFLocationExpression Loc{
Range, 
Entry.Loc};
 
  849        DWARFDataExtractor 
Data(Loc.
Expr, IsLittleEndian,
 
  850                                U->getAddressByteSize());
 
  851        DWARFExpression Expression(
Data, 
U->getAddressByteSize());
 
  859        ProcessLocationExpression(Expression);
 
  862    Error E = 
U->getLocationTable().visitLocationList(
 
  863        &
Offset, [&](
const DWARFLocationEntry &
E) {
 
  864          ProcessLocationEntry(
E);
 
  873                                          const DWARFFormValue &FormValue,
 
  875                                          uint64_t OffsetOnEntry) {
 
  883    processLocationList(Attr, FormValue, Die, OffsetOnEntry);
 
  888                                    const DWARFFormValue &FormValue) {
 
  901  LVElement *
Target = getElementForOffset(
 
  903      Attr == dwarf::DW_AT_import || Attr == dwarf::DW_AT_type);
 
  905  if (FormValue.
getForm() == dwarf::DW_FORM_ref_addr) {
 
  908      Target->setIsGlobalReference();
 
  910      removeGlobalOffset(
Offset);
 
  924  case dwarf::DW_AT_abstract_origin:
 
  925  case dwarf::DW_AT_call_origin:
 
  929  case dwarf::DW_AT_extension:
 
  933  case dwarf::DW_AT_specification:
 
  937  case dwarf::DW_AT_import:
 
  938  case dwarf::DW_AT_type:
 
  951  if (!
Entry.Element) {
 
  953      Entry.Types.insert(Element);
 
  955      Entry.References.insert(Element);
 
  957  return Entry.Element;
 
  963  Triple 
TT = Obj.makeTriple();
 
  966  Expected<SubtargetFeatures> Features = Obj.getFeatures();
 
  967  SubtargetFeatures FeaturesValue;
 
  970    FeaturesValue = SubtargetFeatures();
 
  972  FeaturesValue = *Features;
 
  975  if (
auto OptCPU = Obj.tryGetCPUName())
 
  981void LVDWARFReader::mapRangeAddress(
const ObjectFile &Obj) {
 
  982  for (
auto Iter = Obj.symbol_begin(); Iter != Obj.symbol_end(); ++Iter) {
 
  983    const SymbolRef &
Symbol = *Iter;
 
  985    Expected<SymbolRef::Type> TypeOrErr = 
Symbol.getType();
 
 1001    bool IsSTAB = 
false;
 
 1003      DataRefImpl SymDRI = 
Symbol.getRawDataRefImpl();
 
 1011    Expected<section_iterator> IterOrErr = 
Symbol.getSection();
 
 1017    if (Section == Obj.section_end())
 
 1021    Expected<uint64_t> AddressOrErr = 
Symbol.getAddress();
 
 1022    if (!AddressOrErr) {
 
 1026    uint64_t 
Address = *AddressOrErr;
 
 1030    Expected<StringRef> NameOrErr = 
Symbol.getName();
 
 1038    Expected<uint32_t> FlagsOrErr = 
Symbol.getFlags();
 
 1043    uint32_t 
Flags = *FlagsOrErr;
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
 
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
 
size_t size() const
size - Get the array size.
 
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
 
DWARFUnitVector::compile_unit_range compile_unit_range
 
bool isLittleEndian() const
 
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
 
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
 
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
 
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
 
DWARFUnit * getDwarfUnit() const
 
LLVM_ABI DWARFDie getSibling() const
Get the sibling of this DIE object.
 
LLVM_ABI std::optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const
Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...
 
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
 
LLVM_ABI DWARFDie getFirstChild() const
Get the first child of this DIE object.
 
dwarf::Tag getTag() const
 
This class represents an Operation in the Expression.
 
DWARFDataExtractor getDebugInfoExtractor() const
 
uint64_t getOffset() const
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
reference get()
Returns a reference to the stored T value.
 
Class representing an expression and its matching format.
 
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
 
StringRef - Represent a constant reference to a string, i.e.
 
LLVM_ABI std::string getString() const
Returns features as a string.
 
LLVM Value Representation.
 
Stores all information relating to a compile unit, be it in its original instance in the object file ...
 
LVSectionIndex updateSymbolTable(LVScope *Function)
 
LVSectionIndex getSectionIndex(LVScope *Scope) override
 
Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures, StringRef TheCPU)
 
void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)
 
void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex)
 
void mapVirtualAddress(const object::ObjectFile &Obj)
 
std::unique_ptr< const MCRegisterInfo > MRI
 
Error createInstructions()
 
LVAddress WasmCodeSectionOffset
 
LVAddress getTombstoneAddress() const
 
void setCUHighAddress(LVAddress Address)
 
void setTombstoneAddress(LVAddress Address)
 
void print(raw_ostream &OS) const
 
std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands) override
 
void sortScopes() override
 
void setCUBaseAddress(LVAddress Address)
 
Error createScopes() override
 
virtual void setCount(int64_t Value)
 
virtual void setCallLineNumber(uint32_t Number)
 
virtual void setBitSize(uint32_t Size)
 
virtual void setLinkageName(StringRef LinkageName)
 
virtual void setProducer(StringRef ProducerName)
 
virtual void setUpperBound(int64_t Value)
 
virtual void setDiscriminator(uint32_t Value)
 
virtual void setLowerBound(int64_t Value)
 
virtual void setValue(StringRef Value)
 
void setInlineCode(uint32_t Code)
 
void setName(StringRef ElementName) override
 
virtual bool isCompileUnit() const
 
void setAccessibilityCode(uint32_t Access)
 
void setVirtualityCode(uint32_t Virtuality)
 
void setFilenameIndex(size_t Index)
 
virtual void setSourceLanguage(LVSourceLanguage SL)
 
virtual void setCallFilenameIndex(size_t Index)
 
void setLineNumber(uint32_t Number)
 
LVRange * getSectionRanges(LVSectionIndex SectionIndex)
 
void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit)
 
std::vector< LVAddressRange > CurrentRanges
 
std::string FileFormatName
 
std::string createAlternativePath(StringRef From)
 
LVElement * CurrentElement
 
LVElement * createElement(dwarf::Tag Tag)
 
StringRef getFilename() const
 
LVScopeCompileUnit * CompileUnit
 
LVSectionIndex DotTextSectionIndex
 
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope)
 
virtual Error createScopes()
 
void addElement(LVElement *Element)
 
void addObject(LVLocation *Location)
 
void addLocation(dwarf::Attribute Attr, LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset, bool CallSiteLocation=false)
 
void addLocationOperands(LVSmall Opcode, ArrayRef< uint64_t > Operands)
 
MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const
 
MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const
 
bool is64Bit() const override
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
A raw_ostream that writes to an std::string.
 
std::string & str()
Returns the string's reference.
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
 
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
 
uint64_t computeTombstoneAddress(uint8_t AddressByteSize)
 
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
 
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
 
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
 
constexpr unsigned int DWARF_CHAR_BIT
 
LLVM_ABI std::string transformPath(StringRef Path)
 
std::pair< LVAddress, LVAddress > LVAddressRange
 
constexpr bool UpdateHighAddress
 
DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec
 
content_iterator< SectionRef > section_iterator
 
This is an optimization pass for GlobalISel generic memory operations.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Data
 
DWARFExpression::Operation Op
 
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
 
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
 
LLVM_ABI bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, ArrayRef< uint64_t > Operands)
Pretty print a register opcode and operands.
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
 
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
 
Container for dump options that control which debug information will be dumped.
 
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
 
bool isImplicitConst() const
 
int64_t getImplicitConstValue() const
 
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
 
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
 
SmallVector< uint8_t, 4 > Expr
The expression itself.
 
static const uint64_t UndefSection
 
A source language supported by any of the debug info representations.