#include "DwarfDebug.h"
#include "ByteStreamer.h"
#include "DIEHash.h"
#include "DwarfCompileUnit.h"
#include "DwarfExpression.h"
#include "DwarfUnit.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cstddef>
#include <iterator>
#include <optional>
#include <string>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumCSParams, "Number of dbg call site params created");
static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier(
"use-dwarf-ranges-base-address-specifier", cl::Hidden,
cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));
static cl::opt<bool> GenerateARangeSection("generate-arange-section",
cl::Hidden,
cl::desc("Generate dwarf aranges"),
cl::init(false));
static cl::opt<bool>
GenerateDwarfTypeUnits("generate-type-units", cl::Hidden,
cl::desc("Generate DWARF4 type units."),
cl::init(false));
static cl::opt<bool> SplitDwarfCrossCuReferences(
"split-dwarf-cross-cu-references", cl::Hidden,
cl::desc("Enable cross-cu references in DWO files"), cl::init(false));
enum DefaultOnOff { … };
static cl::opt<DefaultOnOff> UnknownLocations(
"use-unknown-locations", cl::Hidden,
cl::desc("Make an absence of debug location information explicit."),
cl::values(clEnumVal(Default, "At top of block or after label"),
clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")),
cl::init(Default));
static cl::opt<AccelTableKind> AccelTables(
"accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."),
cl::values(clEnumValN(AccelTableKind::Default, "Default",
"Default for platform"),
clEnumValN(AccelTableKind::None, "Disable", "Disabled."),
clEnumValN(AccelTableKind::Apple, "Apple", "Apple"),
clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")),
cl::init(AccelTableKind::Default));
static cl::opt<DefaultOnOff>
DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden,
cl::desc("Use inlined strings rather than string section."),
cl::values(clEnumVal(Default, "Default for platform"),
clEnumVal(Enable, "Enabled"),
clEnumVal(Disable, "Disabled")),
cl::init(Default));
static cl::opt<bool>
NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden,
cl::desc("Disable emission .debug_ranges section."),
cl::init(false));
static cl::opt<DefaultOnOff> DwarfSectionsAsReferences(
"dwarf-sections-as-references", cl::Hidden,
cl::desc("Use sections+offset as references rather than labels."),
cl::values(clEnumVal(Default, "Default for platform"),
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
cl::init(Default));
static cl::opt<bool>
UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden,
cl::desc("Emit the GNU .debug_macro format with DWARF <5"),
cl::init(false));
static cl::opt<DefaultOnOff> DwarfOpConvert(
"dwarf-op-convert", cl::Hidden,
cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"),
cl::values(clEnumVal(Default, "Default for platform"),
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
cl::init(Default));
enum LinkageNameOption { … };
static cl::opt<LinkageNameOption>
DwarfLinkageNames("dwarf-linkage-names", cl::Hidden,
cl::desc("Which DWARF linkage-name attributes to emit."),
cl::values(clEnumValN(DefaultLinkageNames, "Default",
"Default for platform"),
clEnumValN(AllLinkageNames, "All", "All"),
clEnumValN(AbstractLinkageNames, "Abstract",
"Abstract subprograms")),
cl::init(DefaultLinkageNames));
static cl::opt<DwarfDebug::MinimizeAddrInV5> MinimizeAddrInV5Option(
"minimize-addr-in-v5", cl::Hidden,
cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
"address pool entry sharing to reduce relocations/object size"),
cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default",
"Default address minimization strategy"),
clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges",
"Use rnglists for contiguous ranges if that allows "
"using a pre-existing base address"),
clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions,
"Expressions",
"Use exprloc addrx+offset expressions for any "
"address with a prior base address"),
clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form",
"Use addrx+offset extension form for any address "
"with a prior base address"),
clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled",
"Stuff")),
cl::init(DwarfDebug::MinimizeAddrInV5::Default));
static constexpr unsigned ULEB128PadSize = …;
void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) { … }
void DebugLocDwarfExpression::emitSigned(int64_t Value) { … }
void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) { … }
void DebugLocDwarfExpression::emitData1(uint8_t Value) { … }
void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) { … }
bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
llvm::Register MachineReg) { … }
void DebugLocDwarfExpression::enableTemporaryBuffer() { … }
void DebugLocDwarfExpression::disableTemporaryBuffer() { … }
unsigned DebugLocDwarfExpression::getTemporaryBufferSize() { … }
void DebugLocDwarfExpression::commitTemporaryBuffer() { … }
const DIType *DbgVariable::getType() const { … }
static DbgValueLoc getDebugLocValue(const MachineInstr *MI) { … }
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr) { … }
bool llvm::operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS) { … }
bool llvm::operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS) { … }
Loc::Single::Single(DbgValueLoc ValueLoc)
: … { … }
Loc::Single::Single(const MachineInstr *DbgValue)
: … { … }
const std::set<FrameIndexExpr> &Loc::MMI::getFrameIndexExprs() const { … }
void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) { … }
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
bool GenerateTypeUnits,
DebuggerKind Tuning,
const Triple &TT) { … }
DwarfDebug::DwarfDebug(AsmPrinter *A)
: … { … }
DwarfDebug::~DwarfDebug() = default;
static bool isObjCClass(StringRef Name) { … }
static bool hasObjCCategory(StringRef Name) { … }
static void getObjCClassCategory(StringRef In, StringRef &Class,
StringRef &Category) { … }
static StringRef getObjCMethodName(StringRef In) { … }
void DwarfDebug::addSubprogramNames(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind,
const DISubprogram *SP, DIE &Die) { … }
bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { … }
template <typename Func> static void forBothCUs(DwarfCompileUnit &CU, Func F) { … }
bool DwarfDebug::shareAcrossDWOCUs() const { … }
void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
LexicalScope *Scope) { … }
struct FwdRegParamInfo { … };
FwdRegWorklist;
ClobberedRegSet;
static const DIExpression *combineDIExpressions(const DIExpression *Original,
const DIExpression *Addition) { … }
template <typename ValT>
static void finishCallSiteParams(ValT Val, const DIExpression *Expr,
ArrayRef<FwdRegParamInfo> DescribedParams,
ParamSet &Params) { … }
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg,
const DIExpression *Expr,
ArrayRef<FwdRegParamInfo> ParamsToAdd) { … }
static void interpretValues(const MachineInstr *CurMI,
FwdRegWorklist &ForwardedRegWorklist,
ParamSet &Params,
ClobberedRegSet &ClobberedRegUnits) { … }
static bool interpretNextInstr(const MachineInstr *CurMI,
FwdRegWorklist &ForwardedRegWorklist,
ParamSet &Params,
ClobberedRegSet &ClobberedRegUnits) { … }
static void collectCallSiteParameters(const MachineInstr *CallMI,
ParamSet &Params) { … }
void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
DwarfCompileUnit &CU, DIE &ScopeDIE,
const MachineFunction &MF) { … }
void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const { … }
void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
DwarfCompileUnit &NewCU) { … }
DwarfCompileUnit &
DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { … }
static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { … }
void DwarfDebug::beginModule(Module *M) { … }
void DwarfDebug::finishEntityDefinitions() { … }
void DwarfDebug::finishSubprogramDefinitions() { … }
void DwarfDebug::finalizeModuleInfo() { … }
void DwarfDebug::endModule() { … }
void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
const DINode *Node, const MDNode *ScopeNode) { … }
static const DILocalScope *getRetainedNodeScope(const MDNode *N) { … }
void DwarfDebug::collectVariableInfoFromMFTable(
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) { … }
static bool validThroughout(LexicalScopes &LScopes,
const MachineInstr *DbgValue,
const MachineInstr *RangeEnd,
const InstructionOrdering &Ordering) { … }
bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const DbgValueHistoryMap::Entries &Entries) { … }
DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
LexicalScope &Scope,
const DINode *Node,
const DILocation *Location,
const MCSymbol *Sym) { … }
void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
const DISubprogram *SP,
DenseSet<InlinedEntity> &Processed) { … }
void DwarfDebug::beginInstruction(const MachineInstr *MI) { … }
static std::pair<const MachineInstr *, bool>
findPrologueEndLoc(const MachineFunction *MF) { … }
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
const MDNode *S, unsigned Flags, unsigned CUID,
uint16_t DwarfVersion,
ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) { … }
const MachineInstr *
DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) { … }
void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { … }
unsigned
DwarfDebug::getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU) { … }
void DwarfDebug::terminateLineTable(const DwarfCompileUnit *CU) { … }
void DwarfDebug::skippedNonDebugFunction() { … }
void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { … }
void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
unsigned Flags) { … }
void DwarfDebug::emitDebugInfo() { … }
void DwarfDebug::emitAbbreviations() { … }
void DwarfDebug::emitStringOffsetsTableHeader() { … }
template <typename AccelTableT>
void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section,
StringRef TableName) { … }
void DwarfDebug::emitAccelDebugNames() { … }
void DwarfDebug::emitAccelNames() { … }
void DwarfDebug::emitAccelObjC() { … }
void DwarfDebug::emitAccelNamespaces() { … }
void DwarfDebug::emitAccelTypes() { … }
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
const DIE *Die) { … }
void DwarfDebug::emitDebugPubSections() { … }
void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) { … }
void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
DwarfCompileUnit *TheU,
const StringMap<const DIE *> &Globals) { … }
void DwarfDebug::emitDebugStr() { … }
void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocStream::Entry &Entry,
const DwarfCompileUnit *CU) { … }
void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
const DbgValueLoc &Value,
DwarfExpression &DwarfExpr) { … }
void DebugLocEntry::finalize(const AsmPrinter &AP,
DebugLocStream::ListBuilder &List,
const DIBasicType *BT,
DwarfCompileUnit &TheCU) { … }
void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
const DwarfCompileUnit *CU) { … }
static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm,
const DwarfFile &Holder) { … }
static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
const DwarfDebug &DD) { … }
template <typename Ranges, typename PayloadEmitter>
static void emitRangeList(
DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R,
const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair,
unsigned StartxLength, unsigned EndOfList,
StringRef (*StringifyEnum)(unsigned),
bool ShouldUseBaseAddress,
PayloadEmitter EmitPayload) { … }
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List) { … }
void DwarfDebug::emitDebugLocImpl(MCSection *Sec) { … }
void DwarfDebug::emitDebugLoc() { … }
void DwarfDebug::emitDebugLocDWO() { … }
struct ArangeSpan { … };
void DwarfDebug::emitDebugARanges() { … }
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm,
const RangeSpanList &List) { … }
void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section) { … }
void DwarfDebug::emitDebugRanges() { … }
void DwarfDebug::emitDebugRangesDWO() { … }
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
const DwarfCompileUnit &CU, uint16_t DwarfVersion) { … }
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) { … }
void DwarfDebug::emitMacro(DIMacro &M) { … }
void DwarfDebug::emitMacroFileImpl(
DIMacroFile &MF, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
StringRef (*MacroFormToString)(unsigned Form)) { … }
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) { … }
void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) { … }
void DwarfDebug::emitDebugMacinfo() { … }
void DwarfDebug::emitDebugMacinfoDWO() { … }
void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
std::unique_ptr<DwarfCompileUnit> NewU) { … }
DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) { … }
void DwarfDebug::emitDebugInfoDWO() { … }
void DwarfDebug::emitDebugAbbrevDWO() { … }
void DwarfDebug::emitDebugLineDWO() { … }
void DwarfDebug::emitStringOffsetsTableHeaderDWO() { … }
void DwarfDebug::emitDebugStrDWO() { … }
void DwarfDebug::emitDebugAddr() { … }
MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) { … }
uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) { … }
void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
StringRef Identifier, DIE &RefDie,
const DICompositeType *CTy) { … }
template <typename DataT>
void DwarfDebug::addAccelNameImpl(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind,
AccelTable<DataT> &AppleAccel, StringRef Name, const DIE &Die) { … }
void DwarfDebug::addAccelName(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name,
const DIE &Die) { … }
void DwarfDebug::addAccelObjC(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name,
const DIE &Die) { … }
void DwarfDebug::addAccelNamespace(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name,
const DIE &Die) { … }
void DwarfDebug::addAccelType(
const DwarfUnit &Unit,
const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name,
const DIE &Die, char Flags) { … }
uint16_t DwarfDebug::getDwarfVersion() const { … }
dwarf::Form DwarfDebug::getDwarfSectionOffsetForm() const { … }
const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) { … }
void DwarfDebug::insertSectionLabel(const MCSymbol *S) { … }
std::optional<MD5::MD5Result>
DwarfDebug::getMD5AsBytes(const DIFile *File) const { … }
bool DwarfDebug::alwaysUseRanges(const DwarfCompileUnit &CU) const { … }
void DwarfDebug::beginCodeAlignment(const MachineBasicBlock &MBB) { … }