summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2011-12-14 23:49:37 +0000
committerSean Callanan <scallanan@apple.com>2011-12-14 23:49:37 +0000
commit50952e9571ee97d10888a7f2cfe0106a921e5b57 (patch)
treeb835defe94f1da8c6055a1eeadf29dbeb1d64f9c
parent75d7d5e988539819d596f345d99c26a7aa3bd09b (diff)
downloadbcm5719-llvm-50952e9571ee97d10888a7f2cfe0106a921e5b57.tar.gz
bcm5719-llvm-50952e9571ee97d10888a7f2cfe0106a921e5b57.zip
I have added a function to SBTarget that allows
clients to disassemble a series of raw bytes as demonstrated by a new testcase. In the future, this API will also allow clients to provide a callback that adds comments for addresses in the disassembly. I also modified the SWIG harness to ensure that Python ByteArrays work as well as strings as sources of raw data. llvm-svn: 146611
-rw-r--r--lldb/include/lldb/API/SBInstructionList.h1
-rw-r--r--lldb/include/lldb/API/SBTarget.h6
-rw-r--r--lldb/include/lldb/Core/Disassembler.h7
-rw-r--r--lldb/scripts/Python/interface/SBTarget.i5
-rw-r--r--lldb/scripts/Python/python-typemaps.swig48
-rw-r--r--lldb/source/API/SBTarget.cpp27
-rw-r--r--lldb/source/Core/Disassembler.cpp31
-rw-r--r--lldb/test/api/disassemble-raw-data/TestDisassembleRawData.py40
8 files changed, 149 insertions, 16 deletions
diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h
index 7fecd52d8b6..0d336d4005a 100644
--- a/lldb/include/lldb/API/SBInstructionList.h
+++ b/lldb/include/lldb/API/SBInstructionList.h
@@ -58,6 +58,7 @@ public:
protected:
friend class SBFunction;
friend class SBSymbol;
+ friend class SBTarget;
void
SetDisassembler (const lldb::DisassemblerSP &opaque_sp);
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 7ac46c8a64f..7aad7950e3e 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -494,6 +494,12 @@ public:
SBSourceManager
GetSourceManager();
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size);
#ifndef SWIG
bool
diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h
index 126a411374c..719e069d1b7 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -261,6 +261,13 @@ public:
const char *plugin_name,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range);
+
+ static lldb::DisassemblerSP
+ DisassembleBytes (const ArchSpec &arch,
+ const char *plugin_name,
+ const Address &start,
+ const void *bytes,
+ size_t length);
static bool
Disassemble (Debugger &debugger,
diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i
index 04dcfbf9d21..676a6c0bab4 100644
--- a/lldb/scripts/Python/interface/SBTarget.i
+++ b/lldb/scripts/Python/interface/SBTarget.i
@@ -470,7 +470,10 @@ public:
lldb::SBBroadcaster
GetBroadcaster () const;
-
+
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+
bool
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
};
diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig
index 55f2819ce0c..86ce7af6980 100644
--- a/lldb/scripts/Python/python-typemaps.swig
+++ b/lldb/scripts/Python/python-typemaps.swig
@@ -69,30 +69,48 @@
// typemap for an outgoing buffer
// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
%typemap(in) (const char *cstr, uint32_t cstr_len) {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_ValueError, "Expecting a string");
- return NULL;
+ if (PyString_Check($input)) {
+ $1 = (char *) PyString_AsString($input);
+ $2 = PyString_Size($input);
+ }
+ else if(PyByteArray_Check($input)) {
+ $1 = (char *) PyByteArray_AsString($input);
+ $2 = PyByteArray_Size($input);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a string");
+ return NULL;
}
- $1 = (char *) PyString_AsString($input);
- $2 = PyString_Size($input);
}
// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
%typemap(in) (const char *src, size_t src_len) {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_ValueError, "Expecting a string");
- return NULL;
+ if (PyString_Check($input)) {
+ $1 = (char *) PyString_AsString($input);
+ $2 = PyString_Size($input);
+ }
+ else if(PyByteArray_Check($input)) {
+ $1 = (char *) PyByteArray_AsString($input);
+ $2 = PyByteArray_Size($input);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a string");
+ return NULL;
}
- $1 = (char *) PyString_AsString($input);
- $2 = PyString_Size($input);
}
// And SBProcess::WriteMemory.
%typemap(in) (const void *buf, size_t size) {
- if (!PyString_Check($input)) {
- PyErr_SetString(PyExc_ValueError, "Expecting a string");
- return NULL;
+ if (PyString_Check($input)) {
+ $1 = (void *) PyString_AsString($input);
+ $2 = PyString_Size($input);
+ }
+ else if(PyByteArray_Check($input)) {
+ $1 = (void *) PyByteArray_AsString($input);
+ $2 = PyByteArray_Size($input);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a string");
+ return NULL;
}
- $1 = (void *) PyString_AsString($input);
- $2 = PyString_Size($input);
}
// typemap for an incoming buffer
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 179cb9372de..b922d2ae4f2 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1285,6 +1285,33 @@ SBTarget::GetSourceManager()
return source_manager;
}
+lldb::SBInstructionList
+SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size)
+{
+ SBInstructionList sb_instructions;
+
+ if (m_opaque_sp)
+ {
+ Address addr;
+
+ if (base_addr.get())
+ addr = *base_addr.get();
+
+ sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (m_opaque_sp->GetArchitecture(),
+ NULL,
+ addr,
+ buf,
+ size));
+ }
+
+ return sb_instructions;
+}
+
+lldb::SBInstructionList
+SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size)
+{
+ return GetInstructions (ResolveLoadAddress(base_addr), buf, size);
+}
SBError
SBTarget::SetSectionLoadAddress (lldb::SBSection section,
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 1628f3a215d..fe044a6dc4c 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -230,6 +230,37 @@ Disassembler::DisassembleRange
return disasm_sp;
}
+lldb::DisassemblerSP
+Disassembler::DisassembleBytes
+(
+ const ArchSpec &arch,
+ const char *plugin_name,
+ const Address &start,
+ const void *bytes,
+ size_t length
+)
+{
+ lldb::DisassemblerSP disasm_sp;
+
+ if (bytes)
+ {
+ disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
+
+ if (disasm_sp)
+ {
+ DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
+
+ (void)disasm_sp->DecodeInstructions (start,
+ data,
+ 0,
+ UINT32_MAX,
+ false);
+ }
+ }
+
+ return disasm_sp;
+}
+
bool
Disassembler::Disassemble
diff --git a/lldb/test/api/disassemble-raw-data/TestDisassembleRawData.py b/lldb/test/api/disassemble-raw-data/TestDisassembleRawData.py
new file mode 100644
index 00000000000..d9d35d03c80
--- /dev/null
+++ b/lldb/test/api/disassemble-raw-data/TestDisassembleRawData.py
@@ -0,0 +1,40 @@
+"""
+Use lldb Python API to disassemble raw machine code bytes
+"""
+
+import os, time
+import re
+import unittest2
+import lldb, lldbutil
+from lldbtest import *
+
+class DisassembleRawDataTestCase(TestBase):
+
+ mydir = os.path.join("api", "disassemble-raw-data")
+
+ @python_api_test
+ def test_disassemble_raw_data(self):
+ """Test disassembling raw bytes with the API."""
+ self.disassemble_raw_data()
+
+ def disassemble_raw_data(self):
+ """Test disassembling raw bytes with the API."""
+ # Create a target from the debugger.
+
+ target = self.dbg.CreateTargetWithFileAndTargetTriple ("", "x86_64-apple-darwin")
+ self.assertTrue(target, VALID_TARGET)
+
+ raw_bytes = bytearray([0x48, 0x89, 0xe5])
+
+ insts = target.GetInstructions(lldb.SBAddress(), raw_bytes)
+
+ inst = insts.GetInstructionAtIndex(0)
+
+ self.assertTrue (inst.GetMnemonic(target) == "movq")
+ self.assertTrue (inst.GetOperands(target) == '%' + "rsp, " + '%' + "rbp")
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
OpenPOWER on IntegriCloud