summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Core/ArchSpec.h14
-rw-r--r--lldb/include/lldb/Core/Disassembler.h31
-rw-r--r--lldb/include/lldb/Core/Opcode.h3
-rw-r--r--lldb/include/lldb/Symbol/SymbolContext.h2
-rw-r--r--lldb/source/API/SBInstruction.cpp4
-rw-r--r--lldb/source/API/SBInstructionList.cpp3
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp26
-rw-r--r--lldb/source/Commands/CommandObjectDisassemble.cpp74
-rw-r--r--lldb/source/Commands/CommandObjectDisassemble.h1
-rw-r--r--lldb/source/Core/ArchSpec.cpp91
-rw-r--r--lldb/source/Core/Disassembler.cpp200
-rw-r--r--lldb/source/Core/Module.cpp6
-rw-r--r--lldb/source/Core/Opcode.cpp2
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp3
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp42
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h8
-rw-r--r--lldb/source/Symbol/SymbolContext.cpp43
-rw-r--r--lldb/source/Target/Target.cpp10
-rw-r--r--lldb/source/Target/ThreadPlanTracer.cpp4
-rw-r--r--lldb/test/settings/TestSettings.py3
20 files changed, 330 insertions, 240 deletions
diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h
index 618048217e7..d0009800303 100644
--- a/lldb/include/lldb/Core/ArchSpec.h
+++ b/lldb/include/lldb/Core/ArchSpec.h
@@ -46,7 +46,8 @@ public:
eCore_arm_armv7f,
eCore_arm_armv7k,
eCore_arm_armv7s,
- eCore_arm_xscale,
+ eCore_arm_xscale,
+ eCore_thumb_generic,
eCore_ppc_generic,
eCore_ppc_ppc601,
@@ -258,7 +259,16 @@ public:
/// and the default/assumed byte order may be incorrect.
//------------------------------------------------------------------
void
- SetByteOrder (lldb::ByteOrder byteorder);
+ SetByteOrder (lldb::ByteOrder byte_order)
+ {
+ m_byte_order = byte_order;
+ }
+
+ uint32_t
+ GetMinimumOpcodeByteSize() const;
+
+ uint32_t
+ GetMaximumOpcodeByteSize() const;
Core
GetCore () const
diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h
index 836c6953739..40167f9d9d8 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -27,7 +27,7 @@ namespace lldb_private {
class Instruction
{
public:
- Instruction (const Address &address);
+ Instruction (const Address &address, AddressClass addr_class);
virtual
~Instruction();
@@ -38,14 +38,21 @@ public:
return m_address;
}
+ AddressClass
+ GetAddressClass ();
+
void
SetAddress (const Address &addr)
{
+ // Invalidate the address class to lazily discover
+ // it if we need to.
+ m_address_class = eAddressClassInvalid;
m_address = addr;
}
virtual void
Dump (Stream *s,
+ uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const ExecutionContext *exe_ctx,
@@ -55,9 +62,9 @@ public:
DoesBranch () const = 0;
virtual size_t
- Extract (const Disassembler &disassembler,
- const DataExtractor& data,
- uint32_t data_offset) = 0;
+ Decode (const Disassembler &disassembler,
+ const DataExtractor& data,
+ uint32_t data_offset) = 0;
const Opcode &
GetOpcode () const
@@ -67,6 +74,13 @@ public:
protected:
Address m_address; // The section offset address of this instruction
+ // We include an address class in the Instruction class to
+ // allow the instruction specify the eAddressClassCodeAlternateISA
+ // (currently used for thumb), and also to specify data (eAddressClassData).
+ // The usual value will be eAddressClassCode, but often when
+ // disassembling memory, you might run into data. This can
+ // help us to disassemble appropriately.
+ AddressClass m_address_class;
Opcode m_opcode; // The opcode for this instruction
};
@@ -79,6 +93,9 @@ public:
size_t
GetSize() const;
+
+ uint32_t
+ GetMaxOpcocdeByteSize () const;
lldb::InstructionSP
GetInstructionAtIndex (uint32_t idx) const;
@@ -194,14 +211,12 @@ public:
size_t
ParseInstructions (const ExecutionContext *exe_ctx,
- const AddressRange &range,
- DataExtractor& data);
+ const AddressRange &range);
size_t
ParseInstructions (const ExecutionContext *exe_ctx,
const Address &range,
- uint32_t num_instructions,
- DataExtractor& data);
+ uint32_t num_instructions);
virtual size_t
DecodeInstructions (const Address &base_addr,
diff --git a/lldb/include/lldb/Core/Opcode.h b/lldb/include/lldb/Core/Opcode.h
index 77f58c2b7f1..cfa283636cc 100644
--- a/lldb/include/lldb/Core/Opcode.h
+++ b/lldb/include/lldb/Core/Opcode.h
@@ -11,8 +11,6 @@
#define lldb_Opcode_h
// C Includes
-#include <string.h>
-
// C++ Includes
// Other libraries and framework includes
// Project includes
@@ -163,6 +161,7 @@ namespace lldb_private {
if (bytes && length > 0)
{
m_type = eTypeBytes;
+ m_data.inst.length = length;
assert (length < sizeof (m_data.inst.bytes));
memcpy (m_data.inst.bytes, bytes, length);
}
diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h
index 9f096f6c8fb..512493bb23e 100644
--- a/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/lldb/include/lldb/Symbol/SymbolContext.h
@@ -347,7 +347,7 @@ public:
Append (const SymbolContext& sc);
bool
- AppendIfUnique (const SymbolContext& sc);
+ AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function);
//------------------------------------------------------------------
/// Clear the object's state.
diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp
index 48b2e7399ff..75683f600e8 100644
--- a/lldb/source/API/SBInstruction.cpp
+++ b/lldb/source/API/SBInstruction.cpp
@@ -89,7 +89,7 @@ SBInstruction::GetDescription (lldb::SBStream &s)
{
// Use the "ref()" instead of the "get()" accessor in case the SBStream
// didn't have a stream already created, one will get created...
- m_opaque_sp->Dump (&s.ref(), true, false, NULL, false);
+ m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, false);
return true;
}
return false;
@@ -104,6 +104,6 @@ SBInstruction::Print (FILE *out)
if (m_opaque_sp)
{
StreamFile out_stream (out, false);
- m_opaque_sp->Dump (&out_stream, true, false, NULL, false);
+ m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false);
}
}
diff --git a/lldb/source/API/SBInstructionList.cpp b/lldb/source/API/SBInstructionList.cpp
index 37c7f874e19..312922fd825 100644
--- a/lldb/source/API/SBInstructionList.cpp
+++ b/lldb/source/API/SBInstructionList.cpp
@@ -93,12 +93,13 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
// 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();
for (size_t i=0; i<num_instructions; ++i)
{
Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst == NULL)
break;
- inst->Dump (&sref, true, false, NULL, false);
+ inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, false);
sref.EOL();
}
return true;
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index c7bbf85c0b0..6bf408b2460 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -155,7 +155,7 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
break;
case 'f':
- m_filename = option_arg;
+ m_filename.assign (option_arg);
break;
case 'l':
@@ -163,32 +163,32 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
break;
case 'b':
- m_func_name = option_arg;
+ m_func_name.assign (option_arg);
m_func_name_type_mask |= eFunctionNameTypeBase;
break;
case 'n':
- m_func_name = option_arg;
+ m_func_name.assign (option_arg);
m_func_name_type_mask |= eFunctionNameTypeAuto;
break;
case 'F':
- m_func_name = option_arg;
+ m_func_name.assign (option_arg);
m_func_name_type_mask |= eFunctionNameTypeFull;
break;
case 'S':
- m_func_name = option_arg;
+ m_func_name.assign (option_arg);
m_func_name_type_mask |= eFunctionNameTypeSelector;
break;
case 'M':
- m_func_name = option_arg;
+ m_func_name.assign (option_arg);
m_func_name_type_mask |= eFunctionNameTypeMethod;
break;
case 'r':
- m_func_regexp = option_arg;
+ m_func_regexp.assign (option_arg);
break;
case 's':
@@ -211,10 +211,10 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
}
break;
case 'T':
- m_thread_name = option_arg;
+ m_thread_name.assign (option_arg);
break;
case 'q':
- m_queue_name = option_arg;
+ m_queue_name.assign (option_arg);
break;
case 'x':
{
@@ -1087,7 +1087,7 @@ CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, co
switch (short_option)
{
case 'f':
- m_filename = option_arg;
+ m_filename.assign (option_arg);
break;
case 'l':
@@ -1406,7 +1406,7 @@ CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, c
{
case 'c':
if (option_arg != NULL)
- m_condition = option_arg;
+ m_condition.assign (option_arg);
else
m_condition.clear();
m_condition_passed = true;
@@ -1445,14 +1445,14 @@ CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, c
break;
case 'T':
if (option_arg != NULL)
- m_thread_name = option_arg;
+ m_thread_name.assign (option_arg);
else
m_thread_name.clear();
m_name_passed = true;
break;
case 'q':
if (option_arg != NULL)
- m_queue_name = option_arg;
+ m_queue_name.assign (option_arg);
else
m_queue_name.clear();
m_queue_passed = true;
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp
index c3b52cfeab8..74c27e39090 100644
--- a/lldb/source/Commands/CommandObjectDisassemble.cpp
+++ b/lldb/source/Commands/CommandObjectDisassemble.cpp
@@ -40,7 +40,8 @@ CommandObjectDisassemble::CommandOptions::CommandOptions () :
m_start_addr(),
m_end_addr (),
m_at_pc (false),
- m_plugin_name ()
+ m_plugin_name (),
+ m_arch()
{
ResetOptionValues();
}
@@ -64,7 +65,7 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
show_mixed = true;
break;
- case 'x':
+ case 'C':
num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("Invalid num context lines string: \"%s\".\n", option_arg);
@@ -118,6 +119,10 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
// There's no need to set any flag.
break;
+ case 'a':
+ m_arch.SetTriple (option_arg);
+ break;
+
default:
error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
break;
@@ -140,6 +145,7 @@ CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
m_end_addr = LLDB_INVALID_ADDRESS;
raw = false;
m_plugin_name.clear();
+ m_arch.Clear();
}
const OptionDefinition*
@@ -151,28 +157,23 @@ CommandObjectDisassemble::CommandOptions::GetDefinitions ()
OptionDefinition
CommandObjectDisassemble::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "bytes", 'b', no_argument, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL, false, "context", 'x', required_argument, NULL, 0, eArgTypeNumLines,"Number of context lines of source to show."},
-{ LLDB_OPT_SET_ALL, false, "mixed", 'm', no_argument, NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
-{ LLDB_OPT_SET_ALL, false, "raw", 'r', no_argument, NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
-{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
-
-{ LLDB_OPT_SET_1, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."},
-{ LLDB_OPT_SET_1, false, "end-address", 'e', required_argument, NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."},
-
-{ LLDB_OPT_SET_2, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."},
-{ LLDB_OPT_SET_2, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-
-{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
-{ LLDB_OPT_SET_3, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-
-{ LLDB_OPT_SET_4, true, "current-frame", 'f', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
-{ LLDB_OPT_SET_4, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-
-{ LLDB_OPT_SET_5, true, "current-pc", 'p', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the current pc."},
-{ LLDB_OPT_SET_5, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-
-{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL , false , "bytes", 'b', no_argument , NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
+{ LLDB_OPT_SET_ALL , false , "context", 'C', required_argument , NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
+{ LLDB_OPT_SET_ALL , false , "mixed", 'm', no_argument , NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
+{ LLDB_OPT_SET_ALL , false , "raw", 'r', no_argument , NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
+{ LLDB_OPT_SET_ALL , false , "plugin", 'P', required_argument , NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
+{ LLDB_OPT_SET_ALL , false , "arch", 'a', required_argument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
+{ LLDB_OPT_SET_1 |
+ LLDB_OPT_SET_2 , true , "start-address" , 's', required_argument , NULL, 0, eArgTypeStartAddress,"Address at which to start disassembling."},
+{ LLDB_OPT_SET_1 , false , "end-address" , 'e', required_argument , NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."},
+{ LLDB_OPT_SET_2 |
+ LLDB_OPT_SET_3 |
+ LLDB_OPT_SET_4 |
+ LLDB_OPT_SET_5 , false , "count", 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
+{ LLDB_OPT_SET_3 , true , "name", 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_4 , true , "frame", 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
+{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the current pc."},
+{ 0 , false , NULL, 0, 0 , NULL, 0, eArgTypeNone, NULL }
};
@@ -207,27 +208,28 @@ CommandObjectDisassemble::Execute
result.SetStatus (eReturnStatusFailed);
return false;
}
+ if (!m_options.m_arch.IsValid())
+ m_options.m_arch = target->GetArchitecture();
- ArchSpec arch(target->GetArchitecture());
- if (!arch.IsValid())
+ if (!m_options.m_arch.IsValid())
{
- result.AppendError ("target needs valid architecure in order to be able to disassemble");
+ result.AppendError ("use the --arch option or set the target architecure to disassemble");
result.SetStatus (eReturnStatusFailed);
return false;
}
const char *plugin_name = m_options.GetPluginName ();
- Disassembler *disassembler = Disassembler::FindPlugin(arch, plugin_name);
+ Disassembler *disassembler = Disassembler::FindPlugin(m_options.m_arch, plugin_name);
if (disassembler == NULL)
{
if (plugin_name)
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture named '%s'.\n",
- arch.GetArchitectureName(),
- plugin_name);
+ result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
+ plugin_name,
+ m_options.m_arch.GetArchitectureName());
else
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n",
- arch.GetArchitectureName());
+ result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
+ m_options.m_arch.GetArchitectureName());
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -255,7 +257,7 @@ CommandObjectDisassemble::Execute
ConstString name(m_options.m_func_name.c_str());
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- arch,
+ m_options.m_arch,
plugin_name,
exe_ctx,
name,
@@ -337,7 +339,7 @@ CommandObjectDisassemble::Execute
}
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- arch,
+ m_options.m_arch,
plugin_name,
exe_ctx,
start_addr,
@@ -387,7 +389,7 @@ CommandObjectDisassemble::Execute
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- arch,
+ m_options.m_arch,
plugin_name,
exe_ctx,
range,
diff --git a/lldb/source/Commands/CommandObjectDisassemble.h b/lldb/source/Commands/CommandObjectDisassemble.h
index 91812af3187..42ede79787d 100644
--- a/lldb/source/Commands/CommandObjectDisassemble.h
+++ b/lldb/source/Commands/CommandObjectDisassemble.h
@@ -63,6 +63,7 @@ public:
lldb::addr_t m_end_addr;
bool m_at_pc;
std::string m_plugin_name;
+ ArchSpec m_arch;
static OptionDefinition g_option_table[];
};
diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp
index 17134938d09..210d32aa421 100644
--- a/lldb/source/Core/ArchSpec.cpp
+++ b/lldb/source/Core/ArchSpec.cpp
@@ -30,6 +30,8 @@ namespace lldb_private {
{
ByteOrder default_byte_order;
uint32_t addr_byte_size;
+ uint32_t min_opcode_byte_size;
+ uint32_t max_opcode_byte_size;
llvm::Triple::ArchType machine;
ArchSpec::Core core;
const char *name;
@@ -40,45 +42,47 @@ namespace lldb_private {
// This core information can be looked using the ArchSpec::Core as the index
static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] =
{
- { eByteOrderLittle, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" },
-
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" },
- { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" },
+ // TODO: verify alpha has 32 bit fixed instructions
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" },
+
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" },
+ { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumb_generic , "thumb" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
- { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
- { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" },
- { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
+ { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" },
+ { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
- { eByteOrderLittle, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
- { eByteOrderLittle, 8, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
+ { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
+ { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
- { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" },
- { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" },
- { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" },
+ { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" },
+ { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" },
+ { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" },
- { eByteOrderLittle, 8, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" }
+ { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" }
};
struct ArchDefinitionEntry
@@ -118,6 +122,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] =
{ ArchSpec::eCore_arm_armv7f , llvm::MachO::CPUTypeARM , 10 },
{ ArchSpec::eCore_arm_armv7k , llvm::MachO::CPUTypeARM , 12 },
{ ArchSpec::eCore_arm_armv7s , llvm::MachO::CPUTypeARM , 11 },
+ { ArchSpec::eCore_thumb_generic , llvm::MachO::CPUTypeARM , 0 },
{ ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , CPU_ANY },
{ ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , 0 },
{ ArchSpec::eCore_ppc_ppc601 , llvm::MachO::CPUTypePowerPC , 1 },
@@ -496,10 +501,22 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su
return IsValid();
}
-void
-ArchSpec::SetByteOrder (lldb::ByteOrder byte_order)
+uint32_t
+ArchSpec::GetMinimumOpcodeByteSize() const
+{
+ const CoreDefinition *core_def = FindCoreDefinition (m_core);
+ if (core_def)
+ return core_def->min_opcode_byte_size;
+ return 0;
+}
+
+uint32_t
+ArchSpec::GetMaximumOpcodeByteSize() const
{
- m_byte_order = byte_order;
+ const CoreDefinition *core_def = FindCoreDefinition (m_core);
+ if (core_def)
+ return core_def->max_opcode_byte_size;
+ return 0;
}
//===----------------------------------------------------------------------===//
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 9f3897752fe..e37f4818c9c 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -69,6 +69,33 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
}
+static void
+ResolveAddress (const ExecutionContext &exe_ctx,
+ const Address &addr,
+ Address &resolved_addr)
+{
+ if (!addr.IsSectionOffset())
+ {
+ // If we weren't passed in a section offset address range,
+ // try and resolve it to something
+ if (exe_ctx.target)
+ {
+ if (exe_ctx.target->GetSectionLoadList().IsEmpty())
+ {
+ exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
+ }
+ else
+ {
+ exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
+ }
+ // We weren't able to resolve the address, just treat it as a
+ // raw address
+ if (resolved_addr.IsValid())
+ return;
+ }
+ }
+ resolved_addr = addr;
+}
size_t
Disassembler::Disassemble
@@ -192,8 +219,7 @@ Disassembler::DisassembleRange
if (disasm_sp)
{
- DataExtractor data;
- size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, data);
+ size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
if (bytes_disassembled == 0)
disasm_sp.reset();
}
@@ -223,27 +249,11 @@ Disassembler::Disassemble
if (disasm_ap.get())
{
- AddressRange range(disasm_range);
+ AddressRange range;
+ ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
+ range.SetByteSize (disasm_range.GetByteSize());
- // If we weren't passed in a section offset address range,
- // try and resolve it to something
- if (range.GetBaseAddress().IsSectionOffset() == false)
- {
- if (exe_ctx.target)
- {
- if (exe_ctx.target->GetSectionLoadList().IsEmpty())
- {
- exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
- }
- else
- {
- exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
- }
- }
- }
-
- DataExtractor data;
- size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range, data);
+ size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
if (bytes_disassembled == 0)
return false;
@@ -280,29 +290,12 @@ Disassembler::Disassemble
if (num_instructions > 0)
{
std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
- Address addr = start_address;
-
if (disasm_ap.get())
{
- // If we weren't passed in a section offset address range,
- // try and resolve it to something
- if (addr.IsSectionOffset() == false)
- {
- if (exe_ctx.target)
- {
- if (exe_ctx.target->GetSectionLoadList().IsEmpty())
- {
- exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr);
- }
- else
- {
- exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr);
- }
- }
- }
+ Address addr;
+ ResolveAddress (exe_ctx, start_address, addr);
- DataExtractor data;
- size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data);
+ size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
if (bytes_disassembled == 0)
return false;
return PrintInstructions (disasm_ap.get(),
@@ -341,11 +334,12 @@ Disassembler::PrintInstructions
if (num_instructions > 0 && num_instructions < num_instructions_found)
num_instructions_found = num_instructions;
+ const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
uint32_t offset = 0;
SymbolContext sc;
SymbolContext prev_sc;
AddressRange sc_range;
- Address addr = start_addr;
+ Address addr (start_addr);
if (num_mixed_context_lines)
strm.IndentMore ();
@@ -425,7 +419,7 @@ Disassembler::PrintInstructions
if (num_mixed_context_lines)
strm.IndentMore ();
strm.Indent();
- inst->Dump(&strm, true, show_bytes, &exe_ctx, raw);
+ inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
strm.EOL();
addr.Slide(inst->GetOpcode().GetByteSize());
@@ -492,8 +486,9 @@ Disassembler::Disassemble
strm);
}
-Instruction::Instruction(const Address &address) :
+Instruction::Instruction(const Address &address, AddressClass addr_class) :
m_address (address),
+ m_address_class (addr_class),
m_opcode()
{
}
@@ -502,6 +497,13 @@ Instruction::~Instruction()
{
}
+AddressClass
+Instruction::GetAddressClass ()
+{
+ if (m_address_class == eAddressClassInvalid)
+ m_address_class = m_address.GetAddressClass();
+ return m_address_class;
+}
InstructionList::InstructionList() :
m_instructions()
@@ -518,6 +520,23 @@ InstructionList::GetSize() const
return m_instructions.size();
}
+uint32_t
+InstructionList::GetMaxOpcocdeByteSize () const
+{
+ uint32_t max_inst_size = 0;
+ collection::const_iterator pos, end;
+ for (pos = m_instructions.begin(), end = m_instructions.end();
+ pos != end;
+ ++pos)
+ {
+ uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
+ if (max_inst_size < inst_size)
+ max_inst_size = inst_size;
+ }
+ return max_inst_size;
+}
+
+
InstructionSP
InstructionList::GetInstructionAtIndex (uint32_t idx) const
@@ -546,8 +565,7 @@ size_t
Disassembler::ParseInstructions
(
const ExecutionContext *exe_ctx,
- const AddressRange &range,
- DataExtractor& data
+ const AddressRange &range
)
{
Target *target = exe_ctx->target;
@@ -559,17 +577,20 @@ Disassembler::ParseInstructions
DataBufferSP data_sp(heap_buffer);
Error error;
- bool prefer_file_cache = true;
- const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
+ const bool prefer_file_cache = true;
+ const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
+ prefer_file_cache,
+ heap_buffer->GetBytes(),
+ heap_buffer->GetByteSize(),
+ error);
if (bytes_read > 0)
{
if (bytes_read != heap_buffer->GetByteSize())
heap_buffer->SetByteSize (bytes_read);
-
- data.SetData(data_sp);
- data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ DataExtractor data (data_sp,
+ m_arch.GetByteOrder(),
+ m_arch.GetAddressByteSize());
return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
}
@@ -581,64 +602,45 @@ Disassembler::ParseInstructions
(
const ExecutionContext *exe_ctx,
const Address &start,
- uint32_t num_instructions,
- DataExtractor& data
+ uint32_t num_instructions
)
{
- Address addr = start;
-
- if (num_instructions == 0)
+ m_instruction_list.Clear();
+
+ if (num_instructions == 0 || !start.IsValid())
return 0;
Target *target = exe_ctx->target;
- // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it.
- const addr_t byte_size = num_instructions * 2;
- addr_t data_offset = 0;
- addr_t next_instruction_offset = 0;
- size_t buffer_size = byte_size;
+ // Calculate the max buffer size we will need in order to disassemble
+ const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
- uint32_t num_instructions_found = 0;
-
- if (target == NULL || byte_size == 0 || !start.IsValid())
+ if (target == NULL || byte_size == 0)
return 0;
DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
- DataBufferSP data_sp(heap_buffer);
-
- data.SetData(data_sp);
- data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ DataBufferSP data_sp (heap_buffer);
Error error;
bool prefer_file_cache = true;
-
- m_instruction_list.Clear();
-
- while (num_instructions_found < num_instructions)
- {
- if (buffer_size < data_offset + byte_size)
- {
- buffer_size = data_offset + byte_size;
- heap_buffer->SetByteSize (buffer_size);
- data.SetData(data_sp); // Resizing might have changed the backing store location, so we have to reset
- // the DataBufferSP in the extractor so it changes to pointing at the right thing.
- }
- const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error);
- size_t num_bytes_read = 0;
- if (bytes_read == 0)
- break;
-
- num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true);
- if (num_bytes_read == 0)
- break;
- num_instructions_found = m_instruction_list.GetSize();
-
- // Prepare for the next round.
- data_offset += bytes_read;
- addr.Slide (bytes_read);
- next_instruction_offset += num_bytes_read;
- }
-
+ const size_t bytes_read = target->ReadMemory (start,
+ prefer_file_cache,
+ heap_buffer->GetBytes(),
+ byte_size,
+ error);
+
+ if (bytes_read == 0)
+ return 0;
+ DataExtractor data (data_sp,
+ m_arch.GetByteOrder(),
+ m_arch.GetAddressByteSize());
+
+ const bool append_instructions = true;
+ DecodeInstructions (start,
+ data,
+ 0,
+ num_instructions,
+ append_instructions);
+
return m_instruction_list.GetSize();
}
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index a504829d75c..735dde4a5da 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -351,11 +351,12 @@ Module::FindFunctions (const ConstString &name,
const uint32_t num_matches = symbol_indexes.size();
if (num_matches)
{
+ const bool merge_symbol_into_function = true;
SymbolContext sc(this);
for (uint32_t i=0; i<num_matches; i++)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- sc_list.AppendIfUnique (sc);
+ sc_list.AppendIfUnique (sc, merge_symbol_into_function);
}
}
}
@@ -392,11 +393,12 @@ Module::FindFunctions (const RegularExpression& regex,
const uint32_t num_matches = symbol_indexes.size();
if (num_matches)
{
+ const bool merge_symbol_into_function = true;
SymbolContext sc(this);
for (uint32_t i=0; i<num_matches; i++)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- sc_list.AppendIfUnique (sc);
+ sc_list.AppendIfUnique (sc, merge_symbol_into_function);
}
}
}
diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp
index d33c80c76de..b765bf7dd1d 100644
--- a/lldb/source/Core/Opcode.cpp
+++ b/lldb/source/Core/Opcode.cpp
@@ -48,7 +48,7 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width)
for (uint32_t i=0; i<m_data.inst.length; ++i)
{
if (i > 0)
- s->PutChar (' ');
+ bytes_written += s->PutChar (' ');
bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
}
}
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index 12a4472957e..59849351e19 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -742,13 +742,14 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX, false);
InstructionList &instruction_list = disassembler->GetInstructionList();
-
+ const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize();
instruction_index < num_instructions;
++instruction_index)
{
Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
instruction->Dump (&stream,
+ max_opcode_byte_size,
true,
true,
&exe_ctx,
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
index 9c55042640f..59e6d9a4bb4 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
@@ -74,8 +74,10 @@ static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg)
return -1;
}
-DisassemblerLLVM::InstructionLLVM::InstructionLLVM (const Address &addr, EDDisassemblerRef disassembler) :
- Instruction (addr),
+DisassemblerLLVM::InstructionLLVM::InstructionLLVM (const Address &addr,
+ AddressClass addr_class,
+ EDDisassemblerRef disassembler) :
+ Instruction (addr, addr_class),
m_disassembler (disassembler)
{
}
@@ -99,6 +101,7 @@ void
DisassemblerLLVM::InstructionLLVM::Dump
(
Stream *s,
+ uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
@@ -131,13 +134,19 @@ DisassemblerLLVM::InstructionLLVM::Dump
// x86_64 and i386 are the only ones that use bytes right now so
// pad out the byte dump to be able to always show 15 bytes (3 chars each)
// plus a space
- m_opcode.Dump (s, 15 * 3 + 1);
+ if (max_opcode_byte_size > 0)
+ m_opcode.Dump (s, max_opcode_byte_size * 3 + 1);
+ else
+ m_opcode.Dump (s, 15 * 3 + 1);
}
else
{
// Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
// plus two for padding...
- m_opcode.Dump (s, 12);
+ if (max_opcode_byte_size > 0)
+ m_opcode.Dump (s, max_opcode_byte_size * 3 + 1);
+ else
+ m_opcode.Dump (s, 12);
}
}
@@ -329,9 +338,9 @@ DisassemblerLLVM::InstructionLLVM::DoesBranch() const
}
size_t
-DisassemblerLLVM::InstructionLLVM::Extract (const Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- uint32_t data_offset)
+DisassemblerLLVM::InstructionLLVM::Decode (const Disassembler &disassembler,
+ const lldb_private::DataExtractor &data,
+ uint32_t data_offset)
{
if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
{
@@ -382,6 +391,7 @@ SyntaxForArchSpec (const ArchSpec &arch)
case llvm::Triple::x86_64:
return kEDAssemblySyntaxX86ATT;
case llvm::Triple::arm:
+ case llvm::Triple::thumb:
return kEDAssemblySyntaxARMUAL;
default:
break;
@@ -411,17 +421,16 @@ DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) :
if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch)))
m_disassembler = NULL;
llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch();
+ // Don't have the lldb::Triple::thumb architecture here. If someone specifies
+ // "thumb" as the architecture, we want a thumb only disassembler. But if any
+ // architecture starting with "arm" if specified, we want to auto detect the
+ // arm/thumb code automatically using the AddressClass from section offset
+ // addresses.
if (llvm_arch == llvm::Triple::arm)
{
if (EDGetDisassembler(&m_disassembler_thumb, "thumb-apple-darwin", kEDAssemblySyntaxARMUAL))
m_disassembler_thumb = NULL;
}
- else if (llvm_arch == llvm::Triple::thumb)
- {
- m_disassembler_thumb = m_disassembler;
- if (EDGetDisassembler(&m_disassembler, "arm-apple-darwin-unknown", kEDAssemblySyntaxARMUAL))
- m_disassembler = NULL;
- }
}
}
@@ -456,15 +465,18 @@ DisassemblerLLVM::DecodeInstructions
// If we have a thumb disassembler, then we have an ARM architecture
// so we need to check what the instruction address class is to make
// sure we shouldn't be disassembling as thumb...
+ AddressClass inst_address_class = eAddressClassInvalid;
if (m_disassembler_thumb)
{
- if (inst_addr.GetAddressClass () == eAddressClassCodeAlternateISA)
+ inst_address_class = inst_addr.GetAddressClass ();
+ if (inst_address_class == eAddressClassCodeAlternateISA)
use_thumb = true;
}
InstructionSP inst_sp (new InstructionLLVM (inst_addr,
+ inst_address_class,
use_thumb ? m_disassembler_thumb : m_disassembler));
- size_t inst_byte_size = inst_sp->Extract (*this, data, data_offset);
+ size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset);
if (inst_byte_size == 0)
break;
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
index 9e01bf3f2c6..8408d70dc87 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
@@ -23,6 +23,7 @@ public:
{
public:
InstructionLLVM (const lldb_private::Address &addr,
+ lldb_private::AddressClass addr_class,
EDDisassemblerRef disassembler);
virtual
@@ -30,6 +31,7 @@ public:
virtual void
Dump (lldb_private::Stream *s,
+ uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
@@ -39,9 +41,9 @@ public:
DoesBranch () const;
virtual size_t
- Extract (const Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- uint32_t data_offset);
+ Decode (const Disassembler &disassembler,
+ const lldb_private::DataExtractor &data,
+ uint32_t data_offset);
protected:
EDDisassemblerRef m_disassembler;
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index f595e531a72..a5a36bb9d4e 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -334,11 +334,11 @@ bool
lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
{
return lhs.function != rhs.function
- && lhs.symbol != rhs.symbol
- && lhs.module_sp.get() != rhs.module_sp.get()
- && lhs.comp_unit != rhs.comp_unit
- && lhs.target_sp.get() != rhs.target_sp.get()
- && LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
+ || lhs.symbol != rhs.symbol
+ || lhs.module_sp.get() != rhs.module_sp.get()
+ || lhs.comp_unit != rhs.comp_unit
+ || lhs.target_sp.get() != rhs.target_sp.get()
+ || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
}
bool
@@ -749,14 +749,43 @@ SymbolContextList::Append(const SymbolContext& sc)
}
bool
-SymbolContextList::AppendIfUnique (const SymbolContext& sc)
+SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
{
- collection::const_iterator pos, end = m_symbol_contexts.end();
+ collection::iterator pos, end = m_symbol_contexts.end();
for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
{
if (*pos == sc)
return false;
}
+ if (merge_symbol_into_function
+ && sc.symbol != NULL
+ && sc.comp_unit == NULL
+ && sc.function == NULL
+ && sc.block == NULL
+ && sc.line_entry.IsValid() == false)
+ {
+ const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr();
+ if (symbol_range)
+ {
+ for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
+ {
+ if (pos->function)
+ {
+ if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress())
+ {
+ // Do we already have a function with this symbol?
+ if (pos->symbol == sc.symbol)
+ return false;
+ if (pos->symbol == NULL)
+ {
+ pos->symbol = sc.symbol;
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
m_symbol_contexts.push_back(sc);
return true;
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 3dc11049f6c..0b734c53446 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -587,18 +587,16 @@ Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size
bool process_is_valid = m_process_sp && m_process_sp->IsAlive();
size_t bytes_read = 0;
- Address resolved_addr(addr);
- if (!resolved_addr.IsSectionOffset())
+ Address resolved_addr;
+ if (!addr.IsSectionOffset())
{
if (process_is_valid)
- {
m_section_load_list.ResolveLoadAddress (addr.GetOffset(), resolved_addr);
- }
else
- {
m_images.ResolveFileAddress(addr.GetOffset(), resolved_addr);
- }
}
+ if (!resolved_addr.IsValid())
+ resolved_addr = addr;
if (prefer_file_cache)
{
diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp
index 578a160251e..fe95b9a5a9a 100644
--- a/lldb/source/Target/ThreadPlanTracer.cpp
+++ b/lldb/source/Target/ThreadPlanTracer.cpp
@@ -209,11 +209,13 @@ ThreadPlanAssemblyTracer::Log ()
m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1, false);
InstructionList &instruction_list = m_disassembler->GetInstructionList();
-
+ const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
+
if (instruction_list.GetSize())
{
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
instruction->Dump (&desc,
+ max_opcode_byte_size,
false,
false,
NULL,
diff --git a/lldb/test/settings/TestSettings.py b/lldb/test/settings/TestSettings.py
index 129a209dac0..8e70df1f705 100644
--- a/lldb/test/settings/TestSettings.py
+++ b/lldb/test/settings/TestSettings.py
@@ -240,9 +240,6 @@ class SettingsCommandTestCase(TestBase):
"auto-confirm (boolean) = ",
"target.default-arch (string):",
"target.expr-prefix (string) = ",
- "target.execution-level (enum) = ",
- "target.execution-mode (enum) = ",
- "target.execution-os-type (enum) = ",
"target.process.run-args (array):",
"target.process.env-vars (dictionary):",
"target.process.inherit-env (boolean) = ",
OpenPOWER on IntegriCloud