diff options
author | Sean Callanan <scallanan@apple.com> | 2011-12-14 23:49:37 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2011-12-14 23:49:37 +0000 |
commit | 50952e9571ee97d10888a7f2cfe0106a921e5b57 (patch) | |
tree | b835defe94f1da8c6055a1eeadf29dbeb1d64f9c | |
parent | 75d7d5e988539819d596f345d99c26a7aa3bd09b (diff) | |
download | bcm5719-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.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBTarget.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Core/Disassembler.h | 7 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBTarget.i | 5 | ||||
-rw-r--r-- | lldb/scripts/Python/python-typemaps.swig | 48 | ||||
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 27 | ||||
-rw-r--r-- | lldb/source/Core/Disassembler.cpp | 31 | ||||
-rw-r--r-- | lldb/test/api/disassemble-raw-data/TestDisassembleRawData.py | 40 |
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() |