Add a "debugger tuning" concept that allows us to fine-tune how we

emit debug info, according to the preferences of the different
debuggers used on various targets.
Darwin and FreeBSD default to tuning for LLDB; PS4 defaults to tuning for
the SCE (Sony Computer Entertainment) debugger.  All others default to GDB.

Differential Revision: http://reviews.llvm.org/D8506


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242338 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Paul Robinson 2015-07-15 22:04:54 +00:00
parent 063eb4e389
commit 641735d426
4 changed files with 116 additions and 11 deletions

View File

@ -76,6 +76,17 @@ static cl::opt<bool> GenerateARangeSection("generate-arange-section",
cl::desc("Generate dwarf aranges"),
cl::init(false));
static cl::opt<DebuggerKind>
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,32 +208,44 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
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());
// Turn on accelerator tables for Darwin by default, pubnames by
// default for non-Darwin/PS4, and handle split dwarf.
// 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 LLDB by default.
if (DwarfAccelTables == Default)
HasDwarfAccelTables = IsDarwin;
HasDwarfAccelTables = tuneForLLDB();
else
HasDwarfAccelTables = DwarfAccelTables == Enable;
// Handle split DWARF. Off by default for now.
if (SplitDwarf == Default)
HasSplitDwarf = false;
else
HasSplitDwarf = SplitDwarf == Enable;
// Pubnames/pubtypes on by default for GDB.
if (DwarfPubSections == Default)
HasDwarfPubSections = !IsDarwin && !IsPS4;
HasDwarfPubSections = tuneForGDB();
else
HasDwarfPubSections = DwarfPubSections == Enable;
@ -230,9 +253,12 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
: MMI->getModule()->getDwarfVersion();
// Darwin and PS4 use the standard TLS opcode (defined in DWARF 3).
// Everybody else uses GNU's.
UseGNUTLSOpcode = !(IsDarwin || IsPS4) || DwarfVersion < 3;
// Work around a GDB bug. GDB doesn't support the standard opcode;
// SCE doesn't support GNU's; LLDB prefers the standard opcode, which
// is defined as of DWARF 3.
// See GDB bug 11616 - DW_OP_form_tls_address is unimplemented
// https://sourceware.org/bugzilla/show_bug.cgi?id=11616
UseGNUTLSOpcode = tuneForGDB() || DwarfVersion < 3;
Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);

View File

@ -203,6 +203,30 @@ struct SymbolCU {
DwarfCompileUnit *CU;
};
/// Identify a debugger for "tuning" the debug info.
///
/// 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.
///
/// The "tuning" 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.
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).
};
/// Collects and handles dwarf debug information.
class DwarfDebug : public AsmPrinterHandler {
/// Target of Dwarf emission.
@ -338,7 +362,6 @@ class DwarfDebug : public AsmPrinterHandler {
/// True iff there are multiple CUs in this module.
bool SingleCU;
bool IsDarwin;
bool IsPS4;
AddressPool AddrPool;
@ -349,6 +372,9 @@ class DwarfDebug : public AsmPrinterHandler {
DenseMap<const Function *, DISubprogram *> FunctionDIs;
// Identify a debugger for "tuning" the debug info.
DebuggerKind DebuggerTuning;
MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);
const SmallVectorImpl<std::unique_ptr<DwarfUnit>> &getUnits() {
@ -565,6 +591,15 @@ public:
/// standard DW_OP_form_tls_address opcode
bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; }
/// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.
///
/// Returns whether we are "tuning" for a given debugger.
/// @{
bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; }
bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; }
bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; }
/// @}
// Experimental DWARF5 features.
/// Returns whether or not to emit tables that dwarf consumers can

View File

@ -0,0 +1,44 @@
; Verify target-based defaults for "debugger tuning," and the ability to
; override defaults.
; We use existence of the debug_pubnames section to distinguish the GDB case,
; and the apple_names section to distinguish the LLDB case. SCE has neither.
; Verify defaults for various targets.
; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj < %s | llvm-readobj -sections - | FileCheck --check-prefix=SCE %s
; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %s | llvm-readobj -sections - | FileCheck --check-prefix=LLDB %s
; RUN: llc -mtriple=x86_64-pc-freebsd -filetype=obj < %s | llvm-readobj -sections - | FileCheck --check-prefix=LLDB %s
; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj < %s | llvm-readobj -sections - | FileCheck --check-prefix=GDB %s
; We can override defaults.
; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -debugger-tune=gdb < %s | llvm-readobj -sections - | FileCheck --check-prefix=GDB %s
; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -debugger-tune=lldb < %s | llvm-readobj -sections - | FileCheck --check-prefix=LLDB %s
; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=sce < %s | llvm-readobj -sections - | FileCheck --check-prefix=SCE %s
; GDB-NOT: apple_names
; GDB: debug_pubnames
; GDB-NOT: apple_names
; LLDB-NOT: debug_pubnames
; LLDB: apple_names
; LLDB-NOT: debug_pubnames
; SCE-NOT: debug_pubnames
; SCE-NOT: apple_names
@globalvar = global i32 0, align 4
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!6, !7}
!llvm.ident = !{!8}
!0 = !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.7.0 (trunk 238808)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2)
!1 = !DIFile(filename: "debugger-tune.cpp", directory: "/home/probinson/projects/scratch")
!2 = !{}
!3 = !{!4}
!4 = !DIGlobalVariable(name: "globalvar", scope: !0, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, variable: i32* @globalvar)
!5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!6 = !{i32 2, !"Dwarf Version", i32 4}
!7 = !{i32 2, !"Debug Info Version", i32 3}
!8 = !{!"clang version 3.7.0 (trunk 238808)"}

View File

@ -14,7 +14,7 @@
; RUN: | FileCheck --check-prefix=DARWIN --check-prefix=STDOP %s
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd \
; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=GNUOP %s
; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s
; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use
; that here instead of raw assembly printing