Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -203,6 +203,14 @@ DwarfCompileUnit *CU; }; +/// \brief Identify a debugger for "tuning" the debug info. +enum class DebuggerKind { + Default, // No specific tuning requested. + GDB, // Tune debug info for gdb. + LLDB, // Tune debug info for lldb. + SCE // Tune debug info for SCE targets (e.g. PS4). +}; + /// \brief Collects and handles dwarf debug information. class DwarfDebug : public AsmPrinterHandler { // Target of Dwarf emission. @@ -335,7 +343,6 @@ // True iff there are multiple CUs in this module. bool SingleCU; bool IsDarwin; - bool IsPS4; AddressPool AddrPool; @@ -346,6 +353,9 @@ DenseMap FunctionDIs; + // Identify a debugger for "tuning" the debug info. + DebuggerKind DebuggerTuning; + MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); const SmallVectorImpl> &getUnits() { @@ -559,6 +569,29 @@ /// standard DW_OP_form_tls_address opcode bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; } + // The "debugger tuning" concept allows us to present a more intuitive + // interface that unpacks into different sets of defaults for the various + // individual feature-flag settings, that suit the preferences of the + // various debuggers. However, it's worth remembering that debuggers are + // not the only consumers of debug info, and some variations in DWARF might + // better be treated as target/platform issues. Fundamentally, + // o if the feature is useful (or not) to a particular debugger, regardless + // of the target, that's a tuning decision; + // o if the feature is useful (or not) on a particular platform, regardless + // of the debugger, that's a target decision. + // It's not impossible to see both factors in some specific case. + // + /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. + /// + /// The "tuning" predicates should be used to set defaults for individual + /// feature flags in DwarfDebug; if a given feature has a more specific + /// command-line option, that option should take precedence over the tuning. + /// @{ + bool tuneDebugForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } + bool tuneDebugForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } + bool tuneDebugForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } + /// @} + // Experimental DWARF5 features. /// \brief Returns whether or not to emit tables that dwarf consumers can Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -76,6 +76,17 @@ cl::desc("Generate dwarf aranges"), cl::init(false)); +static cl::opt +DebuggerTuningOpt("debugger-tune", + cl::desc("Tune debug info for a particular debugger"), + cl::init(DebuggerKind::Default), + cl::values( + clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), + clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), + clEnumValN(DebuggerKind::SCE, "sce", + "SCE targets (e.g. PS4)"), + clEnumValEnd)); + namespace { enum DefaultOnOff { Default, Enable, Disable }; } @@ -197,20 +208,31 @@ UsedNonDefaultText(false), SkeletonHolder(A, "skel_string", DIEValueAllocator), IsDarwin(Triple(A->getTargetTriple()).isOSDarwin()), - IsPS4(Triple(A->getTargetTriple()).isPS4()), AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), - AccelTypes(TypeAtoms) { + AccelTypes(TypeAtoms), DebuggerTuning(DebuggerKind::Default) { CurFn = nullptr; CurMI = nullptr; + Triple TT(Asm->getTargetTriple()); + + // Make sure we know our "debugger tuning." The command-line option takes + // precedence; fall back to triple-based defaults. + if (DebuggerTuningOpt != DebuggerKind::Default) + DebuggerTuning = DebuggerTuningOpt; + else if (IsDarwin || TT.isOSFreeBSD()) + DebuggerTuning = DebuggerKind::LLDB; + else if (TT.isPS4CPU()) + DebuggerTuning = DebuggerKind::SCE; + else + DebuggerTuning = DebuggerKind::GDB; // Turn on accelerator tables for Darwin by default, pubnames by - // default for non-Darwin/PS4, and handle split dwarf. + // default for GDB, and handle split dwarf. if (DwarfAccelTables == Default) HasDwarfAccelTables = IsDarwin; else @@ -222,7 +244,7 @@ HasSplitDwarf = SplitDwarf == Enable; if (DwarfPubSections == Default) - HasDwarfPubSections = !IsDarwin && !IsPS4; + HasDwarfPubSections = tuneDebugForGDB(); else HasDwarfPubSections = DwarfPubSections == Enable; @@ -232,7 +254,7 @@ // Darwin and PS4 use the standard TLS opcode (defined in DWARF 3). // Everybody else uses GNU's. - UseGNUTLSOpcode = !(IsDarwin || IsPS4) || DwarfVersion < 3; + UseGNUTLSOpcode = !(IsDarwin || TT.isPS4CPU()) || DwarfVersion < 3; Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);