From 08581263dcff5c5fa6fa2e8d674a809554a35d1d Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Mon, 12 Mar 2018 21:17:04 +0000 Subject: [PATCH] Re-add change for https://reviews.llvm.org/D42582 with added directories. llvm-svn: 327331 --- lldb/include/lldb/Core/Architecture.h | 34 +++++++++++ lldb/lit/Breakpoint/Inputs/ppc64-localentry.s | 55 +++++++++++++++++ lldb/lit/Breakpoint/ppc64-localentry.test | 12 ++++ lldb/lit/lit.cfg | 2 + lldb/lldb.xcodeproj/project.pbxproj | 22 +++++++ lldb/source/API/SystemInitializerFull.cpp | 2 + lldb/source/Breakpoint/BreakpointResolverName.cpp | 8 +++ lldb/source/Plugins/Architecture/CMakeLists.txt | 1 + .../Architecture/PPC64/ArchitecturePPC64.cpp | 69 ++++++++++++++++++++++ .../Plugins/Architecture/PPC64/ArchitecturePPC64.h | 44 ++++++++++++++ .../Plugins/Architecture/PPC64/CMakeLists.txt | 11 ++++ lldb/source/Target/ThreadPlanStepInRange.cpp | 13 ++++ lldb/tools/lldb-test/SystemInitializerTest.cpp | 2 + lldb/tools/lldb-test/lldb-test.cpp | 9 ++- 14 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 lldb/lit/Breakpoint/Inputs/ppc64-localentry.s create mode 100644 lldb/lit/Breakpoint/ppc64-localentry.test create mode 100644 lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp create mode 100644 lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h create mode 100644 lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt diff --git a/lldb/include/lldb/Core/Architecture.h b/lldb/include/lldb/Core/Architecture.h index af774ec..8f163fd 100644 --- a/lldb/include/lldb/Core/Architecture.h +++ b/lldb/include/lldb/Core/Architecture.h @@ -33,6 +33,40 @@ public: //------------------------------------------------------------------ virtual void OverrideStopInfo(Thread &thread) = 0; + //------------------------------------------------------------------ + /// This method is used to get the number of bytes that should be + /// skipped, from function start address, to reach the first + /// instruction after the prologue. If overrode, it must return + /// non-zero only if the current address matches one of the known + /// function entry points. + /// + /// This method is called only if the standard platform-independent + /// code fails to get the number of bytes to skip, giving the plugin + /// a chance to try to find the missing info. + /// + /// This is specifically used for PPC64, where functions may have + /// more than one entry point, global and local, so both should + /// be compared with current address, in order to find out the + /// number of bytes that should be skipped, in case we are stopped + /// at either function entry point. + //------------------------------------------------------------------ + virtual size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const { + return 0; + } + + //------------------------------------------------------------------ + /// Adjust function breakpoint address, if needed. In some cases, + /// the function start address is not the right place to set the + /// breakpoint, specially in functions with multiple entry points. + /// + /// This is specifically used for PPC64, for functions that have + /// both a global and a local entry point. In this case, the + /// breakpoint is adjusted to the first function address reached + /// by both entry points. + //------------------------------------------------------------------ + virtual void AdjustBreakpointAddress(const Symbol &func, + Address &addr) const {} + private: Architecture(const Architecture &) = delete; void operator=(const Architecture &) = delete; diff --git a/lldb/lit/Breakpoint/Inputs/ppc64-localentry.s b/lldb/lit/Breakpoint/Inputs/ppc64-localentry.s new file mode 100644 index 0000000..5fe0a97 --- /dev/null +++ b/lldb/lit/Breakpoint/Inputs/ppc64-localentry.s @@ -0,0 +1,55 @@ + .text + .abiversion 2 + + .globl lfunc + .p2align 4 + .type lfunc,@function +lfunc: # @lfunc +.Lfunc_begin0: +.Lfunc_gep0: + addis 2, 12, .TOC.-.Lfunc_gep0@ha + addi 2, 2, .TOC.-.Lfunc_gep0@l +.Lfunc_lep0: + .localentry lfunc, .Lfunc_lep0-.Lfunc_gep0 +# BB#0: + mr 4, 3 + addis 3, 2, .LC0@toc@ha + ld 3, .LC0@toc@l(3) + stw 4, -12(1) + lwz 4, 0(3) + lwz 5, -12(1) + mullw 4, 4, 5 + extsw 3, 4 + blr + .long 0 + .quad 0 +.Lfunc_end0: + .size lfunc, .Lfunc_end0-.Lfunc_begin0 + + .globl simple + .p2align 4 + .type simple,@function +simple: # @simple +.Lfunc_begin1: +# %bb.0: # %entry + mr 4, 3 + stw 4, -12(1) + lwz 4, -12(1) + mulli 4, 4, 10 + extsw 3, 4 + blr + .long 0 + .quad 0 +.Lfunc_end1: + .size simple, .Lfunc_end1-.Lfunc_begin1 + + .section .toc,"aw",@progbits +.LC0: + .tc g_foo[TC],g_foo + .type g_foo,@object # @g_foo + .data + .globl g_foo + .p2align 2 +g_foo: + .long 2 # 0x2 + .size g_foo, 4 diff --git a/lldb/lit/Breakpoint/ppc64-localentry.test b/lldb/lit/Breakpoint/ppc64-localentry.test new file mode 100644 index 0000000..16cce70 --- /dev/null +++ b/lldb/lit/Breakpoint/ppc64-localentry.test @@ -0,0 +1,12 @@ +# REQUIRES: powerpc +# +# RUN: llvm-mc -triple=powerpc64le -filetype=obj %p/Inputs/ppc64-localentry.s -o %t +# RUN: lldb-test breakpoints %t %s | FileCheck %s + +breakpoint set -n lfunc +# CHECK-LABEL: breakpoint set -n lfunc +# CHECK: Address: {{.*}}`lfunc + 8 + +breakpoint set -n simple +# CHECK-LABEL: breakpoint set -n simple +# CHECK: Address: {{.*}}`simple diff --git a/lldb/lit/lit.cfg b/lldb/lit/lit.cfg index 35972af..7b44292 100644 --- a/lldb/lit/lit.cfg +++ b/lldb/lit/lit.cfg @@ -156,6 +156,8 @@ if re.search(r'ARM', llvm_config_output_list[2]): config.available_features.add('arm') if re.search(r'Mips', llvm_config_output_list[2]): config.available_features.add('mips') +if re.search(r'PowerPC', llvm_config_output_list[2]): + config.available_features.add('powerpc') if re.search(r'X86', llvm_config_output_list[2]): config.available_features.add('x86') llvm_config_cmd.wait() diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index ca7adfa..168b800 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -712,6 +712,7 @@ 49F811F31E931B2100F4E163 /* CPlusPlusNameParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F811EF1E931B1500F4E163 /* CPlusPlusNameParser.cpp */; }; 4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; }; 4C05332B1F62121E00DED368 /* SBBreakpointOptionCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */; }; + 4C14CEFB2057258D00DEEF94 /* ArchitecturePPC64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C14CEF82057258D00DEEF94 /* ArchitecturePPC64.cpp */; }; 4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; }; 4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; }; 4C4EB7811E6A4DCC002035C0 /* DumpDataExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */; }; @@ -2541,6 +2542,8 @@ 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSpec.h; path = include/lldb/Target/ThreadSpec.h; sourceTree = ""; }; 4C09CB73116BD98B00C7A725 /* CommandCompletions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandCompletions.h; path = include/lldb/Interpreter/CommandCompletions.h; sourceTree = ""; }; 4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandCompletions.cpp; path = source/Commands/CommandCompletions.cpp; sourceTree = ""; }; + 4C14CEF72057258D00DEEF94 /* ArchitecturePPC64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchitecturePPC64.h; sourceTree = ""; }; + 4C14CEF82057258D00DEEF94 /* ArchitecturePPC64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArchitecturePPC64.cpp; sourceTree = ""; }; 4C2479BE1BA39843009C9A7B /* ExpressionParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ExpressionParser.h; path = include/lldb/Expression/ExpressionParser.h; sourceTree = ""; }; 4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ExpressionTypeSystemHelper.h; path = include/lldb/Expression/ExpressionTypeSystemHelper.h; sourceTree = ""; }; 4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedCluster.h; path = include/lldb/Utility/SharedCluster.h; sourceTree = ""; }; @@ -5963,6 +5966,23 @@ name = Clang; sourceTree = ""; }; + 4C14CEF52057258D00DEEF94 /* PPC64 */ = { + isa = PBXGroup; + children = ( + 4C14CEF72057258D00DEEF94 /* ArchitecturePPC64.h */, + 4C14CEF82057258D00DEEF94 /* ArchitecturePPC64.cpp */, + 4C14CEF92057258D00DEEF94 /* New Group */, + ); + path = PPC64; + sourceTree = ""; + }; + 4C14CEF92057258D00DEEF94 /* New Group */ = { + isa = PBXGroup; + children = ( + ); + path = "New Group"; + sourceTree = ""; + }; 4CC7C64B1D5298AB0076FF94 /* OCaml */ = { isa = PBXGroup; children = ( @@ -6600,6 +6620,7 @@ AF2E029F1FA2CE8A00A86C34 /* Architecture */ = { isa = PBXGroup; children = ( + 4C14CEF52057258D00DEEF94 /* PPC64 */, AF2E02A01FA2CE9900A86C34 /* Arm */, ); path = Architecture; @@ -7611,6 +7632,7 @@ 943BDEFE1AA7B2F800789CE8 /* LLDBAssert.cpp in Sources */, 26474CB418D0CB180073DEBA /* RegisterContextLinux_x86_64.cpp in Sources */, 2689006613353E0E00698AC0 /* DWARFExpression.cpp in Sources */, + 4C14CEFB2057258D00DEEF94 /* ArchitecturePPC64.cpp in Sources */, 2689006713353E0E00698AC0 /* ASTDumper.cpp in Sources */, AFC234091AF85CE100CDE8B6 /* CommandObjectLanguage.cpp in Sources */, 2689006813353E0E00698AC0 /* ASTResultSynthesizer.cpp in Sources */, diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index a27b649..8f6f05c 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -43,6 +43,7 @@ #include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h" #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" #include "Plugins/Architecture/Arm/ArchitectureArm.h" +#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h" #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" @@ -308,6 +309,7 @@ void SystemInitializerFull::Initialize() { ABISysV_s390x::Initialize(); ArchitectureArm::Initialize(); + ArchitecturePPC64::Initialize(); DisassemblerLLVMC::Initialize(); diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 468de35..dd51bff 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -16,11 +16,13 @@ #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Architecture.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -365,6 +367,12 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, sc.symbol->GetPrologueByteSize(); if (prologue_byte_size) break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); + else { + Architecture *arch = + m_breakpoint->GetTarget().GetArchitecturePlugin(); + if (arch) + arch->AdjustBreakpointAddress(*sc.symbol, break_addr); + } } } diff --git a/lldb/source/Plugins/Architecture/CMakeLists.txt b/lldb/source/Plugins/Architecture/CMakeLists.txt index 5abaa8e..01365a6 100644 --- a/lldb/source/Plugins/Architecture/CMakeLists.txt +++ b/lldb/source/Plugins/Architecture/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(Arm) +add_subdirectory(PPC64) diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp new file mode 100644 index 0000000..619de09 --- /dev/null +++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp @@ -0,0 +1,69 @@ +//===-- ArchitecturePPC64.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ArchSpec.h" + +#include "llvm/BinaryFormat/ELF.h" + +using namespace lldb_private; +using namespace lldb; + +ConstString ArchitecturePPC64::GetPluginNameStatic() { + return ConstString("ppc64"); +} + +void ArchitecturePPC64::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "PPC64-specific algorithms", + &ArchitecturePPC64::Create); +} + +void ArchitecturePPC64::Terminate() { + PluginManager::UnregisterPlugin(&ArchitecturePPC64::Create); +} + +std::unique_ptr ArchitecturePPC64::Create(const ArchSpec &arch) { + if ((arch.GetMachine() != llvm::Triple::ppc64 && + arch.GetMachine() != llvm::Triple::ppc64le) || + arch.GetTriple().getObjectFormat() != llvm::Triple::ObjectFormatType::ELF) + return nullptr; + return std::unique_ptr(new ArchitecturePPC64()); +} + +ConstString ArchitecturePPC64::GetPluginName() { return GetPluginNameStatic(); } +uint32_t ArchitecturePPC64::GetPluginVersion() { return 1; } + +static int32_t GetLocalEntryOffset(const Symbol &sym) { + unsigned char other = sym.GetFlags() >> 8 & 0xFF; + return llvm::ELF::decodePPC64LocalEntryOffset(other); +} + +size_t ArchitecturePPC64::GetBytesToSkip(Symbol &func, + const Address &curr_addr) const { + if (curr_addr.GetFileAddress() == + func.GetFileAddress() + GetLocalEntryOffset(func)) + return func.GetPrologueByteSize(); + return 0; +} + +void ArchitecturePPC64::AdjustBreakpointAddress(const Symbol &func, + Address &addr) const { + int32_t loffs = GetLocalEntryOffset(func); + if (!loffs) + return; + + addr.SetOffset(addr.GetOffset() + loffs); +} diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h new file mode 100644 index 0000000..6c87471 --- /dev/null +++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h @@ -0,0 +1,44 @@ +//===-- ArchitecturePPC64.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGIN_ARCHITECTURE_PPC64_H +#define LLDB_PLUGIN_ARCHITECTURE_PPC64_H + +#include "lldb/Core/Architecture.h" + +namespace lldb_private { + +class ArchitecturePPC64 : public Architecture { +public: + static ConstString GetPluginNameStatic(); + static void Initialize(); + static void Terminate(); + + ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; + + void OverrideStopInfo(Thread &thread) override {} + + //------------------------------------------------------------------ + /// This method compares current address with current function's + /// local entry point, returning the bytes to skip if they match. + //------------------------------------------------------------------ + size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const override; + + void AdjustBreakpointAddress(const Symbol &func, + Address &addr) const override; + +private: + static std::unique_ptr Create(const ArchSpec &arch); + ArchitecturePPC64() = default; +}; + +} // namespace lldb_private + +#endif // LLDB_PLUGIN_ARCHITECTURE_PPC64_H diff --git a/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt b/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt new file mode 100644 index 0000000..2cba112 --- /dev/null +++ b/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_library(lldbPluginArchitecturePPC64 PLUGIN + ArchitecturePPC64.cpp + + LINK_LIBS + lldbPluginProcessUtility + lldbCore + lldbTarget + lldbUtility + LINK_COMPONENTS + Support + ) diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index 6c5a995..015c784 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -12,11 +12,13 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanStepInRange.h" +#include "lldb/Core/Architecture.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" @@ -277,6 +279,17 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { bytes_to_skip = sc.symbol->GetPrologueByteSize(); } + if (bytes_to_skip == 0 && sc.symbol) { + TargetSP target = m_thread.CalculateTarget(); + Architecture *arch = target->GetArchitecturePlugin(); + if (arch) { + Address curr_sec_addr; + target->GetSectionLoadList().ResolveLoadAddress(curr_addr, + curr_sec_addr); + bytes_to_skip = arch->GetBytesToSkip(*sc.symbol, curr_sec_addr); + } + } + if (bytes_to_skip != 0) { func_start_address.Slide(bytes_to_skip); log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP); diff --git a/lldb/tools/lldb-test/SystemInitializerTest.cpp b/lldb/tools/lldb-test/SystemInitializerTest.cpp index a58be5c..fef28e4 100644 --- a/lldb/tools/lldb-test/SystemInitializerTest.cpp +++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp @@ -33,6 +33,7 @@ #include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h" #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" #include "Plugins/Architecture/Arm/ArchitectureArm.h" +#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h" #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" @@ -162,6 +163,7 @@ void SystemInitializerTest::Initialize() { ABISysV_s390x::Initialize(); ArchitectureArm::Initialize(); + ArchitecturePPC64::Initialize(); DisassemblerLLVMC::Initialize(); diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index 29d72f9..3d17ed8 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -98,9 +98,12 @@ void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) { AutoIndent Indent(P, 2); P.formatLine("Enabled: {0}", Loc->IsEnabled()); P.formatLine("Resolved: {0}", Loc->IsResolved()); - P.formatLine("Address: {0}+{1:x}", - Loc->GetAddress().GetSection()->GetName(), - Loc->GetAddress().GetOffset()); + SymbolContext sc; + Loc->GetAddress().CalculateSymbolContext(&sc); + lldb_private::StreamString S; + sc.DumpStopContext(&S, BP->GetTarget().GetProcessSP().get(), + Loc->GetAddress(), false, true, false, true, true); + P.formatLine("Address: {0}", S.GetString()); } } P.NewLine(); -- 2.7.4