177 changes: 162 additions & 15 deletions lldb/source/Core/Debugger.cpp

Large diffs are not rendered by default.

55 changes: 21 additions & 34 deletions lldb/source/Core/Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,17 +410,18 @@ Disassembler::PrintInstructions
SymbolContext prev_sc;
AddressRange sc_range;
const Address *pc_addr_ptr = NULL;
ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
StackFrame *frame = exe_ctx.GetFramePtr();

TargetSP target_sp (exe_ctx.GetTargetSP());
SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();

if (frame)
{
pc_addr_ptr = &frame->GetFrameCodeAddress();
}
const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
for (size_t i=0; i<num_instructions_found; ++i)
for (size_t i = 0; i < num_instructions_found; ++i)
{
Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst)
Expand All @@ -447,7 +448,7 @@ Disassembler::PrintInstructions
if (offset != 0)
strm.EOL();

sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false);
strm.EOL();

if (sc.comp_unit && sc.line_entry.IsValid())
Expand All @@ -462,36 +463,20 @@ Disassembler::PrintInstructions
}
}
}
else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
{
if (prev_sc.function || prev_sc.symbol)
strm.EOL();

bool show_fullpaths = false;
bool show_module = true;
bool show_inlined_frames = true;
sc.DumpStopContext (&strm,
exe_scope,
addr,
show_fullpaths,
show_module,
show_inlined_frames);

strm << ":\n";
}
}
else
{
sc.Clear(true);
}
}

if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
const bool show_bytes = (options & eOptionShowBytes) != 0;
const char *disassembly_format = "${addr-file-or-load}: ";
if (exe_ctx.HasTargetScope())
{
strm.PutCString(inst_is_at_pc ? "-> " : " ");
disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
}
const bool show_bytes = (options & eOptionShowBytes) != 0;
inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, disassembly_format);
strm.EOL();
}
else
Expand Down Expand Up @@ -578,7 +563,10 @@ Instruction::Dump (lldb_private::Stream *s,
uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const ExecutionContext* exe_ctx)
const ExecutionContext* exe_ctx,
const SymbolContext *sym_ctx,
const SymbolContext *prev_sym_ctx,
const char *disassembly_addr_format_spec)
{
size_t opcode_column_width = 7;
const size_t operand_column_width = 25;
Expand All @@ -589,13 +577,7 @@ Instruction::Dump (lldb_private::Stream *s,

if (show_address)
{
m_address.Dump(&ss,
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
Address::DumpStyleLoadAddress,
Address::DumpStyleModuleWithFileAddress,
0);

ss.PutCString(": ");
Debugger::FormatDisassemblerAddress (disassembly_addr_format_spec, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
}

if (show_bytes)
Expand All @@ -621,7 +603,7 @@ Instruction::Dump (lldb_private::Stream *s,
}
}

const size_t opcode_pos = ss.GetSize();
const size_t opcode_pos = ss.GetSizeOfLastLine();

// The default opcode size of 7 characters is plenty for most architectures
// but some like arm can pull out the occasional vqrshrun.s16. We won't get
Expand Down Expand Up @@ -1003,13 +985,18 @@ InstructionList::Dump (Stream *s,
{
const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
collection::const_iterator pos, begin, end;
const char *disassemble_format = "${addr-file-or-load}: ";
if (exe_ctx)
{
disassemble_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
}
for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
pos != end;
++pos)
{
if (pos != begin)
s->EOL();
(*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
(*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassemble_format);
}
}

Expand Down
62 changes: 62 additions & 0 deletions lldb/source/Core/Mangled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4986,10 +4986,12 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
#include "lldb/Target/CPPLanguageRuntime.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>


using namespace lldb_private;

static inline bool
Expand All @@ -5000,6 +5002,58 @@ cstring_is_mangled (const char *s)
return false;
}

static const ConstString &
get_demangled_name_without_arguments (const Mangled *obj)
{
// This pair is <mangled name, demangled name without function arguments>
static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;

// Need to have the mangled & demangled names we're currently examining as statics
// so we can return a const ref to them at the end of the func if we don't have
// anything better.
static ConstString g_last_mangled;
static ConstString g_last_demangled;

ConstString mangled = obj->GetMangledName ();
ConstString demangled = obj->GetDemangledName ();

if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
{
return g_most_recent_mangled_to_name_sans_args.second;
}

g_last_demangled = demangled;
g_last_mangled = mangled;

const char *mangled_name_cstr = mangled.GetCString();
const char *demangled_name_cstr = demangled.GetCString();

if (demangled && mangled_name_cstr && mangled_name_cstr[0])
{
if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
(mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
mangled_name_cstr[2] != 'G' && // avoid guard variables
mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
{
CPPLanguageRuntime::MethodName cxx_method (demangled);
if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty())
{
std::string shortname = cxx_method.GetContext().str();
shortname += "::";
shortname += cxx_method.GetBasename().str();
ConstString result(shortname.c_str());
g_most_recent_mangled_to_name_sans_args.first = mangled;
g_most_recent_mangled_to_name_sans_args.second = result;
return g_most_recent_mangled_to_name_sans_args.second;
}
}
}

if (demangled)
return g_last_demangled;
return g_last_mangled;
}

#pragma mark Mangled
//----------------------------------------------------------------------
// Default constructor
Expand Down Expand Up @@ -5215,6 +5269,14 @@ Mangled::NameMatches (const RegularExpression& regex) const
const ConstString&
Mangled::GetName (Mangled::NamePreference preference) const
{
if (preference == ePreferDemangledWithoutArguments)
{
// Call the accessor to make sure we get a demangled name in case
// it hasn't been demangled yet...
GetDemangledName();

return get_demangled_name_without_arguments (this);
}
if (preference == ePreferDemangled)
{
// Call the accessor to make sure we get a demangled name in case
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Core/StreamString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ StreamString::GetSize () const
return m_packet.size();
}

size_t
StreamString::GetSizeOfLastLine () const
{
const size_t length = m_packet.size();
size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
if (last_line_begin_pos == std::string::npos)
{
return length;
}
else
{
++last_line_begin_pos;
return length - last_line_begin_pos;
}
}

std::string &
StreamString::GetString()
{
Expand Down
11 changes: 10 additions & 1 deletion lldb/source/Expression/IRExecutionUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "llvm/Support/SourceMgr.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
Expand Down Expand Up @@ -199,6 +200,11 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,

InstructionList &instruction_list = disassembler_sp->GetInstructionList();
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
const char *disassemble_format = "${addr-file-or-load}: ";
if (exe_ctx.HasTargetScope())
{
disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
}

for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
instruction_index < num_instructions;
Expand All @@ -209,7 +215,10 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
max_opcode_byte_size,
true,
true,
&exe_ctx);
&exe_ctx,
NULL,
NULL,
disassemble_format);
stream.PutChar('\n');
}
// FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
Expand Down
10 changes: 9 additions & 1 deletion lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,11 +832,19 @@ const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,

value_so_addr.Dump (&ss,
target,
Address::DumpStyleResolvedDescriptionNoModule,
Address::DumpStyleResolvedDescriptionNoFunctionArguments,
Address::DumpStyleSectionNameOffset);

if (!ss.GetString().empty())
{
// If Address::Dump returned a multi-line description, most commonly seen when we
// have multiple levels of inlined functions at an address, only show the first line.
std::string &str(ss.GetString());
size_t first_eol_char = str.find_first_of ("\r\n");
if (first_eol_char != std::string::npos)
{
str.erase (first_eol_char);
}
m_inst->AppendComment(ss.GetString());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
if (log && log->GetVerbose ())
{
StreamString strm;
inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL);
const char *disassemble_format = "${frame.pc}: ";
inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, disassemble_format);
log->PutCString (strm.GetData());
}

Expand Down
12 changes: 9 additions & 3 deletions lldb/source/Symbol/SymbolContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ SymbolContext::DumpStopContext
const Address &addr,
bool show_fullpaths,
bool show_module,
bool show_inlined_frames
bool show_inlined_frames,
bool show_function_arguments
) const
{
bool dumped_something = false;
Expand All @@ -146,7 +147,12 @@ SymbolContext::DumpStopContext
{
SymbolContext inline_parent_sc;
Address inline_parent_addr;
if (function->GetMangled().GetName())
if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments))
{
dumped_something = true;
function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments).Dump(s);
}
else if (function->GetMangled().GetName())
{
dumped_something = true;
function->GetMangled().GetName().Dump(s);
Expand Down Expand Up @@ -188,7 +194,7 @@ SymbolContext::DumpStopContext
{
s->EOL();
s->Indent();
return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames);
return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments);
}
}
else
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Symbol/Variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,15 @@ Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module)
sc.block = nullptr;
sc.line_entry.Clear();
bool show_inlined_frames = false;
const bool show_function_arguments = true;

dumped_declaration_info = sc.DumpStopContext (s,
nullptr,
Address(),
show_fullpaths,
show_module,
show_inlined_frames);
show_inlined_frames,
show_function_arguments);

if (sc.function)
s->PutChar(':');
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1380,12 +1380,14 @@ StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
GetSymbolContext(eSymbolContextEverything);
const bool show_module = true;
const bool show_inline = true;
const bool show_function_arguments = true;
m_sc.DumpStopContext (strm,
exe_ctx.GetBestExecutionContextScope(),
GetFrameCodeAddress(),
show_fullpaths,
show_module,
show_inline);
show_inline,
show_function_arguments);
}

void
Expand Down
6 changes: 5 additions & 1 deletion lldb/source/Target/ThreadPlanTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,15 @@ ThreadPlanAssemblyTracer::Log ()
const bool show_bytes = true;
const bool show_address = true;
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
const char *disassemble_format = "${addr-file-or-load}: ";
instruction->Dump (stream,
max_opcode_byte_size,
show_address,
show_bytes,
NULL);
NULL,
NULL,
NULL,
disassemble_format);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions lldb/test/functionalities/abbreviation/TestAbbreviations.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ def running_abbreviations (self):
# ARCH, if not specified, defaults to x86_64.
if self.getArchitecture() in ["", 'x86_64', 'i386']:
self.expect("dis -f",
startstr = "a.out`sum(int, int)",
substrs = [' mov',
substrs = ['<sum(int, int)>:',
' mov',
' addl ',
'ret'])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,11 @@ def inferior_asserting_disassemble(self):
# of the function and in the next function. We also can't back the PC up
# because we don't know how much to back it up by on targets with opcodes
# that have differing sizes
self.expect("disassemble -a %s" % frame.GetPC(),
substrs = ['->'])
pc_backup_offset = 1
if frame.GetFrameID() == 0:
pc_backup_offset = 0
self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
substrs = ['<%s>:' % frame.GetFunctionName()])

def check_expr_in_main(self, thread):
depth = thread.GetNumFrames()
Expand Down