Files
llvm/lldb/source/API/SBInstructionList.cpp
Jason Molenda aff1b357b0 Add a new disassembly-format specification so that the disassembler
output style can be customized.  Change the built-in default to be
more similar to gdb's disassembly formatting.

The disassembly-format for a gdb-like output is

${addr-file-or-load} <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>: 

The disassembly-format for the lldb style output is

{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: 

The two backticks in the lldb style formatter triggers the sub-expression evaluation in
CommandInterpreter::PreprocessCommand() so you can't use that one as-is ... changing to
use ' characters instead of ` would work around that.

<rdar://problem/9885398> 

llvm-svn: 219544
2014-10-10 23:07:36 +00:00

147 lines
3.5 KiB
C++

//===-- SBInstructionList.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/API/SBInstructionList.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/SymbolContext.h"
using namespace lldb;
using namespace lldb_private;
SBInstructionList::SBInstructionList () :
m_opaque_sp()
{
}
SBInstructionList::SBInstructionList(const SBInstructionList &rhs) :
m_opaque_sp (rhs.m_opaque_sp)
{
}
const SBInstructionList &
SBInstructionList::operator = (const SBInstructionList &rhs)
{
if (this != &rhs)
m_opaque_sp = rhs.m_opaque_sp;
return *this;
}
SBInstructionList::~SBInstructionList ()
{
}
bool
SBInstructionList::IsValid () const
{
return m_opaque_sp.get() != NULL;
}
size_t
SBInstructionList::GetSize ()
{
if (m_opaque_sp)
return m_opaque_sp->GetInstructionList().GetSize();
return 0;
}
SBInstruction
SBInstructionList::GetInstructionAtIndex (uint32_t idx)
{
SBInstruction inst;
if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
inst.SetOpaque (m_opaque_sp->GetInstructionList().GetInstructionAtIndex (idx));
return inst;
}
void
SBInstructionList::Clear ()
{
m_opaque_sp.reset();
}
void
SBInstructionList::AppendInstruction (SBInstruction insn)
{
}
void
SBInstructionList::SetDisassembler (const lldb::DisassemblerSP &opaque_sp)
{
m_opaque_sp = opaque_sp;
}
void
SBInstructionList::Print (FILE *out)
{
if (out == NULL)
return;
}
bool
SBInstructionList::GetDescription (lldb::SBStream &description)
{
if (m_opaque_sp)
{
size_t num_instructions = GetSize ();
if (num_instructions)
{
// Call the ref() to make sure a stream is created if one deesn't
// exist already inside description...
Stream &sref = description.ref();
const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
const char *disassemble_format = "${addr-file-or-load}: ";
SymbolContext sc;
SymbolContext prev_sc;
for (size_t i=0; i<num_instructions; ++i)
{
Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst == NULL)
break;
const Address &addr = inst->GetAddress();
prev_sc = sc;
ModuleSP module_sp (addr.GetModule());
if (module_sp)
{
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
}
inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, disassemble_format);
sref.EOL();
}
return true;
}
}
return false;
}
bool
SBInstructionList::DumpEmulationForAllInstructions (const char *triple)
{
if (m_opaque_sp)
{
size_t len = GetSize();
for (size_t i = 0; i < len; ++i)
{
if (!GetInstructionAtIndex((uint32_t) i).DumpEmulation (triple))
return false;
}
}
return true;
}