diff options
-rw-r--r-- | lldb/include/lldb/API/SBData.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBProcess.h | 18 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBProcess.i | 19 | ||||
-rw-r--r-- | lldb/scripts/Python/python-typemaps.swig | 153 | ||||
-rw-r--r-- | lldb/source/API/SBProcess.cpp | 125 | ||||
-rw-r--r-- | lldb/test/python_api/sbdata/TestSBData.py | 42 |
6 files changed, 358 insertions, 0 deletions
diff --git a/lldb/include/lldb/API/SBData.h b/lldb/include/lldb/API/SBData.h index cd611ac2601..1bbfd71b4d4 100644 --- a/lldb/include/lldb/API/SBData.h +++ b/lldb/include/lldb/API/SBData.h @@ -126,6 +126,7 @@ protected: private: friend class SBInstruction; + friend class SBProcess; friend class SBSection; friend class SBValue; diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 2a9e396be61..b81de7d721f 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -185,7 +185,25 @@ public: lldb::SBError UnloadImage (uint32_t image_token); + + lldb::SBData + GetDataFromCString(const char* data); + + lldb::SBData + GetDataFromUnsignedInt64Array(uint64_t* array, size_t array_len); + + lldb::SBData + GetDataFromUnsignedInt32Array(uint32_t* array, size_t array_len); + lldb::SBData + GetDataFromSignedInt64Array(int64_t* array, size_t array_len); + + lldb::SBData + GetDataFromSignedInt32Array(int32_t* array, size_t array_len); + + lldb::SBData + GetDataFromDoubleArray(double* array, size_t array_len); + protected: friend class SBAddress; friend class SBBreakpoint; diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i index da8a28f209a..ee324d21b11 100644 --- a/lldb/scripts/Python/interface/SBProcess.i +++ b/lldb/scripts/Python/interface/SBProcess.i @@ -280,6 +280,25 @@ public: lldb::SBError UnloadImage (uint32_t image_token); + + lldb::SBData + GetDataFromCString(const char* data); + + lldb::SBData + GetDataFromUnsignedInt64Array(uint64_t* array, size_t array_len); + + lldb::SBData + GetDataFromUnsignedInt32Array(uint32_t* array, size_t array_len); + + lldb::SBData + GetDataFromSignedInt64Array(int64_t* array, size_t array_len); + + lldb::SBData + GetDataFromSignedInt32Array(int32_t* array, size_t array_len); + + lldb::SBData + GetDataFromDoubleArray(double* array, size_t array_len); + }; } // namespace lldb diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig index 86ce7af6980..539e55a01a7 100644 --- a/lldb/scripts/Python/python-typemaps.swig +++ b/lldb/scripts/Python/python-typemaps.swig @@ -135,3 +135,156 @@ $result = PyString_FromStringAndSize(static_cast<const char*>($1),result); free($1); } + +// these typemaps allow Python users to pass list objects +// and have them turn into C++ arrays (this is useful, for instance +// when creating SBData objects from lists of numbers) +%typemap(in) (uint64_t* array, size_t array_len) { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $2 = size; + $1 = (uint64_t*) malloc(size * sizeof(uint64_t)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyInt_Check(o)) { + $1[i] = PyInt_AsLong(o); + } + else { + PyErr_SetString(PyExc_TypeError,"list must contain numbers"); + free($1); + return NULL; + } + } + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (uint64_t* array, size_t array_len) { + free($1); +} + +%typemap(in) (uint32_t* array, size_t array_len) { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $2 = size; + $1 = (uint32_t*) malloc(size * sizeof(uint32_t)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyInt_Check(o)) { + $1[i] = PyInt_AsLong(o); + } + else { + PyErr_SetString(PyExc_TypeError,"list must contain numbers"); + free($1); + return NULL; + } + } + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (uint32_t* array, size_t array_len) { + free($1); +} + +%typemap(in) (int64_t* array, size_t array_len) { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $2 = size; + $1 = (int64_t*) malloc(size * sizeof(int64_t)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyInt_Check(o)) { + $1[i] = PyInt_AsLong(o); + } + else { + PyErr_SetString(PyExc_TypeError,"list must contain numbers"); + free($1); + return NULL; + } + } + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (int64_t* array, size_t array_len) { + free($1); +} + +%typemap(in) (int32_t* array, size_t array_len) { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $2 = size; + $1 = (int32_t*) malloc(size * sizeof(int32_t)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyInt_Check(o)) { + $1[i] = PyInt_AsLong(o); + } + else { + PyErr_SetString(PyExc_TypeError,"list must contain numbers"); + free($1); + return NULL; + } + } + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (int32_t* array, size_t array_len) { + free($1); +} + +%typemap(in) (double* array, size_t array_len) { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $2 = size; + $1 = (double*) malloc(size * sizeof(double)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyFloat_Check(o)) { + $1[i] = PyFloat_AsDouble(o); + } + else { + PyErr_SetString(PyExc_TypeError,"list must contain floating-point numbers"); + free($1); + return NULL; + } + } + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) (double* array, size_t array_len) { + free($1); +} diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 89932a37208..2930f286876 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -919,4 +919,129 @@ SBProcess::UnloadImage (uint32_t image_token) return sb_error; } +lldb::SBData +SBProcess::GetDataFromCString(const char* data) +{ + if (!IsValid()) + return SBData(); + + if (!data || !data[0]) + return SBData(); + + uint32_t data_len = strlen(data); + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBProcess::GetDataFromUnsignedInt64Array(uint64_t* array, size_t array_len) +{ + if (!IsValid()) + return SBData(); + + if (!array || array_len == 0) + return SBData(); + + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + size_t data_len = array_len * sizeof(uint64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBProcess::GetDataFromUnsignedInt32Array(uint32_t* array, size_t array_len) +{ + if (!IsValid()) + return SBData(); + + if (!array || array_len == 0) + return SBData(); + + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + size_t data_len = array_len * sizeof(uint32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBProcess::GetDataFromSignedInt64Array(int64_t* array, size_t array_len) +{ + if (!IsValid()) + return SBData(); + + if (!array || array_len == 0) + return SBData(); + + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + size_t data_len = array_len * sizeof(int64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBProcess::GetDataFromSignedInt32Array(int32_t* array, size_t array_len) +{ + if (!IsValid()) + return SBData(); + + if (!array || array_len == 0) + return SBData(); + + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + size_t data_len = array_len * sizeof(int32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBProcess::GetDataFromDoubleArray(double* array, size_t array_len) +{ + if (!IsValid()) + return SBData(); + + if (!array || array_len == 0) + return SBData(); + + lldb::ByteOrder byte_order = GetByteOrder(); + uint8_t addr_size = GetAddressByteSize(); + size_t data_len = array_len * sizeof(double); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, byte_order, addr_size)); + + SBData ret(data_sp); + + return ret; +} diff --git a/lldb/test/python_api/sbdata/TestSBData.py b/lldb/test/python_api/sbdata/TestSBData.py index c1c2e6f9f8a..36dbfd3a4dd 100644 --- a/lldb/test/python_api/sbdata/TestSBData.py +++ b/lldb/test/python_api/sbdata/TestSBData.py @@ -212,6 +212,48 @@ class SBDataAPICase(TestBase): self.assertTrue(data.GetUnsignedInt8(error, offset) == 68, 'made-up data == 68') offset += 1 + # check the new API calls introduced per LLVM bugzilla enhancement request + # 11619 (Allow creating SBData values from arrays or primitives in Python) + + data2 = process.GetDataFromCString('hello!') + self.assertTrue(data2.GetUnsignedInt8(error,0) == 104, 'h == 104') + self.assertTrue(data2.GetUnsignedInt8(error,1) == 101, 'e == 101') + self.assertTrue(data2.GetUnsignedInt8(error,2) == 108, 'l == 108') + self.assertTrue(data2.GetUnsignedInt8(error,3) == 108, 'l == 108') + self.assertTrue(data2.GetUnsignedInt8(error,4) == 111, 'o == 111') + self.assertTrue(data2.GetUnsignedInt8(error,5) == 33, '! == 33') + self.assertTrue(data2.GetUnsignedInt8(error,6) == 0, 'binary 0 terminator') + + data2 = process.GetDataFromUnsignedInt64Array([1,2,3,4,5]) + self.assertTrue(data2.GetUnsignedInt64(error,0) == 1, 'data2[0] = 1') + self.assertTrue(data2.GetUnsignedInt64(error,8) == 2, 'data2[1] = 2') + self.assertTrue(data2.GetUnsignedInt64(error,16) == 3, 'data2[2] = 3') + self.assertTrue(data2.GetUnsignedInt64(error,24) == 4, 'data2[3] = 4') + self.assertTrue(data2.GetUnsignedInt64(error,32) == 5, 'data2[4] = 5') + + data2 = process.GetDataFromSignedInt32Array([2, -2]) + self.assertTrue(data2.GetSignedInt32(error,0) == 2, 'signed32 data2[0] = 2') + self.assertTrue(data2.GetSignedInt32(error,4) == -2, 'signed32 data2[1] = -2') + + data2.Append(process.GetDataFromSignedInt64Array([2, -2])) + self.assertTrue(data2.GetSignedInt32(error,0) == 2, 'signed32 data2[0] = 2') + self.assertTrue(data2.GetSignedInt32(error,4) == -2, 'signed32 data2[1] = -2') + self.assertTrue(data2.GetSignedInt64(error,8) == 2, 'signed64 data2[0] = 2') + self.assertTrue(data2.GetSignedInt64(error,16) == -2, 'signed64 data2[1] = -2') + + data2 = process.GetDataFromUnsignedInt32Array([1,2,3,4,5]) + self.assertTrue(data2.GetUnsignedInt32(error,0) == 1, '32-bit data2[0] = 1') + self.assertTrue(data2.GetUnsignedInt32(error,4) == 2, '32-bit data2[1] = 2') + self.assertTrue(data2.GetUnsignedInt32(error,8) == 3, '32-bit data2[2] = 3') + self.assertTrue(data2.GetUnsignedInt32(error,12) == 4, '32-bit data2[3] = 4') + self.assertTrue(data2.GetUnsignedInt32(error,16) == 5, '32-bit data2[4] = 5') + + data2 = process.GetDataFromDoubleArray([3.14,6.28,2.71]) + self.assertTrue( fabs(data2.GetDouble(error,0) - 3.14) < 0.5, 'double data2[0] = 3.14') + self.assertTrue( fabs(data2.GetDouble(error,8) - 6.28) < 0.5, 'double data2[1] = 6.28') + self.assertTrue( fabs(data2.GetDouble(error,16) - 2.71) < 0.5, 'double data2[2] = 2.71') + + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() |