blob: 4ab17eca5f92ba73711a452c7fd560162b8a86ac [file] [log] [blame]
//===-- LVELFReader.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
//
//===----------------------------------------------------------------------===//
//
// This file defines the LVELFReader class, which is used to describe a
// debug information (DWARF) reader.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H
#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"
#include <unordered_set>
namespace llvm {
namespace logicalview {
class LVElement;
class LVLine;
class LVScopeCompileUnit;
class LVSymbol;
class LVType;
using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
class LVELFReader final : public LVBinaryReader {
object::ObjectFile &Obj;
// Indicates if ranges data are available; in the case of split DWARF any
// reference to ranges is valid only if the skeleton DIE has been loaded.
bool RangesDataAvailable = false;
LVAddress CUBaseAddress = 0;
LVAddress CUHighAddress = 0;
// Current elements during the processing of a DIE.
LVElement *CurrentElement = nullptr;
LVScope *CurrentScope = nullptr;
LVSymbol *CurrentSymbol = nullptr;
LVType *CurrentType = nullptr;
LVOffset CurrentOffset = 0;
LVOffset CurrentEndOffset = 0;
// In DWARF v4, the files are 1-indexed.
// In DWARF v5, the files are 0-indexed.
// The ELF reader expects the indexes as 1-indexed.
bool IncrementFileIndex = false;
// Address ranges collected for current DIE.
std::vector<LVAddressRange> CurrentRanges;
// Symbols with locations for current compile unit.
LVSymbols SymbolsWithLocations;
// Global Offsets (Offset, Element).
LVOffsetElementMap GlobalOffsets;
// Low PC and High PC values for DIE being processed.
LVAddress CurrentLowPC = 0;
LVAddress CurrentHighPC = 0;
bool FoundLowPC = false;
bool FoundHighPC = false;
// Cross references (Elements).
using LVElementSet = std::unordered_set<LVElement *>;
using LVElementEntry = std::pair<LVElement *, LVElementSet>;
using LVElementReference = std::unordered_map<LVOffset, LVElementEntry>;
LVElementReference ElementTable;
Error loadTargetInfo(const object::ObjectFile &Obj);
void mapRangeAddress(const object::ObjectFile &Obj) override;
LVElement *createElement(dwarf::Tag Tag);
void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent,
DWARFDie &SkeletonDie);
// Process the attributes for the given DIE.
LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent,
DWARFDie &SkeletonDie);
void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr,
const AttributeSpec &AttrSpec);
void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines);
void processLocationGaps();
// Add offset to global map.
void addGlobalOffset(LVOffset Offset) {
if (GlobalOffsets.find(Offset) == GlobalOffsets.end())
// Just associate the DIE offset with a null element, as we do not
// know if the referenced element has been created.
GlobalOffsets.emplace(Offset, nullptr);
}
// Remove offset from global map.
void removeGlobalOffset(LVOffset Offset) {
LVOffsetElementMap::iterator Iter = GlobalOffsets.find(Offset);
if (Iter != GlobalOffsets.end())
GlobalOffsets.erase(Iter);
}
// Get the location information for DW_AT_data_member_location.
void processLocationMember(dwarf::Attribute Attr,
const DWARFFormValue &FormValue,
const DWARFDie &Die, uint64_t OffsetOnEntry);
void processLocationList(dwarf::Attribute Attr,
const DWARFFormValue &FormValue, const DWARFDie &Die,
uint64_t OffsetOnEntry,
bool CallSiteLocation = false);
void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue);
// Get an element given the DIE offset.
LVElement *getElementForOffset(LVOffset offset, LVElement *Element);
protected:
Error createScopes() override;
void sortScopes() override;
public:
LVELFReader() = delete;
LVELFReader(StringRef Filename, StringRef FileFormatName,
object::ObjectFile &Obj, ScopedPrinter &W)
: LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF),
Obj(Obj) {}
LVELFReader(const LVELFReader &) = delete;
LVELFReader &operator=(const LVELFReader &) = delete;
~LVELFReader() = default;
LVAddress getCUBaseAddress() const { return CUBaseAddress; }
void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; }
LVAddress getCUHighAddress() const { return CUHighAddress; }
void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; }
const LVSymbols &GetSymbolsWithLocations() const {
return SymbolsWithLocations;
}
std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) override;
void print(raw_ostream &OS) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() const { print(dbgs()); }
#endif
};
} // end namespace logicalview
} // end namespace llvm
#endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H