[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / lldb / bindings / python / python-typemaps.swig
blobbf3de66b91bf1a1d4dedb42fd3aa93c18c807f3c
1 /* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
3 %inline %{
5 #include "../bindings/python/python-typemaps.h"
7 %}
9 %typemap(in) char ** {
10   /* Check if is a list  */
11   if (PythonList::Check($input)) {
12     PythonList list(PyRefType::Borrowed, $input);
13     int size = list.GetSize();
14     int i = 0;
15     $1 = (char **)malloc((size + 1) * sizeof(char *));
16     for (i = 0; i < size; i++) {
17       PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
18       if (!py_str.IsAllocated()) {
19         PyErr_SetString(PyExc_TypeError, "list must contain strings");
20         free($1);
21         return nullptr;
22       }
24       $1[i] = const_cast<char *>(py_str.GetString().data());
25     }
26     $1[i] = 0;
27   } else if ($input == Py_None) {
28     $1 = NULL;
29   } else {
30     PyErr_SetString(PyExc_TypeError, "not a list");
31     return NULL;
32   }
35 %typemap(typecheck) char ** {
36   /* Check if is a list  */
37   $1 = 1;
38   if (PythonList::Check($input)) {
39     PythonList list(PyRefType::Borrowed, $input);
40     int size = list.GetSize();
41     int i = 0;
42     for (i = 0; i < size; i++) {
43       PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
44       if (!s.IsAllocated()) {
45         $1 = 0;
46       }
47     }
48   } else {
49     $1 = (($input == Py_None) ? 1 : 0);
50   }
53 %typemap(freearg) char** {
54   free((char *) $1);
57 %typemap(out) char** {
58   int len;
59   int i;
60   len = 0;
61   while ($1[len])
62     len++;
63   PythonList list(len);
64   for (i = 0; i < len; i++)
65     list.SetItemAtIndex(i, PythonString($1[i]));
66   $result = list.release();
69 %typemap(in) lldb::tid_t {
70   PythonObject obj = Retain<PythonObject>($input);
71   lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj));
72   if (PyErr_Occurred())
73     return nullptr;
74   $1 = value;
77 %typemap(in) lldb::StateType {
78   PythonObject obj = Retain<PythonObject>($input);
79   unsigned long long state_type_value =
80       unwrapOrSetPythonException(As<unsigned long long>(obj));
81   if (PyErr_Occurred())
82     return nullptr;
83   if (state_type_value > lldb::StateType::kLastStateType) {
84     PyErr_SetString(PyExc_ValueError, "Not a valid StateType value");
85     return nullptr;
86   }
87   $1 = static_cast<lldb::StateType>(state_type_value);
90 /* Typemap definitions to allow SWIG to properly handle char buffer. */
92 // typemap for a char buffer
93 %typemap(in) (char *dst, size_t dst_len) {
94   if (!PyInt_Check($input)) {
95     PyErr_SetString(PyExc_ValueError, "Expecting an integer");
96     return NULL;
97   }
98   $2 = PyInt_AsLong($input);
99   if ($2 <= 0) {
100     PyErr_SetString(PyExc_ValueError, "Positive integer expected");
101     return NULL;
102   }
103   $1 = (char *)malloc($2);
105 // SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
106 // as char data instead of byte data.
107 %typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
109 // Return the char buffer.  Discarding any previous return result
110 %typemap(argout) (char *dst, size_t dst_len) {
111   Py_XDECREF($result); /* Blow away any previous result */
112   if (result == 0) {
113     PythonString string("");
114     $result = string.release();
115     Py_INCREF($result);
116   } else {
117     llvm::StringRef ref(static_cast<const char *>($1), result);
118     PythonString string(ref);
119     $result = string.release();
120   }
121   free($1);
123 // SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
124 // as char data instead of byte data.
125 %typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
128 // typemap for handling an snprintf-like API like SBThread::GetStopDescription.
129 %typemap(in) (char *dst_or_null, size_t dst_len) {
130   if (!PyInt_Check($input)) {
131     PyErr_SetString(PyExc_ValueError, "Expecting an integer");
132     return NULL;
133   }
134   $2 = PyInt_AsLong($input);
135   if ($2 <= 0) {
136     PyErr_SetString(PyExc_ValueError, "Positive integer expected");
137     return NULL;
138   }
139   $1 = (char *)malloc($2);
141 %typemap(argout) (char *dst_or_null, size_t dst_len) {
142   Py_XDECREF($result); /* Blow away any previous result */
143   llvm::StringRef ref($1);
144   PythonString string(ref);
145   $result = string.release();
146   free($1);
150 // typemap for an outgoing buffer
151 // See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
152 // Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
153 %typemap(in) (const char *cstr, uint32_t cstr_len),
154              (const char *src, size_t src_len) {
155   if (PythonString::Check($input)) {
156     PythonString str(PyRefType::Borrowed, $input);
157     $1 = (char *)str.GetString().data();
158     $2 = str.GetSize();
159   } else if (PythonByteArray::Check($input)) {
160     PythonByteArray bytearray(PyRefType::Borrowed, $input);
161     $1 = (char *)bytearray.GetBytes().data();
162     $2 = bytearray.GetSize();
163   } else if (PythonBytes::Check($input)) {
164     PythonBytes bytes(PyRefType::Borrowed, $input);
165     $1 = (char *)bytes.GetBytes().data();
166     $2 = bytes.GetSize();
167   } else {
168     PyErr_SetString(PyExc_ValueError, "Expecting a string");
169     return NULL;
170   }
172 // For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
173 %typemap(in) (const void *buf, size_t size),
174              (const void *data, size_t data_len) {
175   if (PythonString::Check($input)) {
176     PythonString str(PyRefType::Borrowed, $input);
177     $1 = (void *)str.GetString().data();
178     $2 = str.GetSize();
179   } else if (PythonByteArray::Check($input)) {
180     PythonByteArray bytearray(PyRefType::Borrowed, $input);
181     $1 = (void *)bytearray.GetBytes().data();
182     $2 = bytearray.GetSize();
183   } else if (PythonBytes::Check($input)) {
184     PythonBytes bytes(PyRefType::Borrowed, $input);
185     $1 = (void *)bytes.GetBytes().data();
186     $2 = bytes.GetSize();
187   } else {
188     PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
189     return NULL;
190   }
193 // typemap for an incoming buffer
194 // See also SBProcess::ReadMemory.
195 %typemap(in) (void *buf, size_t size) {
196   if (PyInt_Check($input)) {
197     $2 = PyInt_AsLong($input);
198   } else if (PyLong_Check($input)) {
199     $2 = PyLong_AsLong($input);
200   } else {
201     PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
202     return NULL;
203   }
204   if ($2 <= 0) {
205     PyErr_SetString(PyExc_ValueError, "Positive integer expected");
206     return NULL;
207   }
208   $1 = (void *)malloc($2);
211 // Return the buffer.  Discarding any previous return result
212 // See also SBProcess::ReadMemory.
213 %typemap(argout) (void *buf, size_t size) {
214   Py_XDECREF($result); /* Blow away any previous result */
215   if (result == 0) {
216     $result = Py_None;
217     Py_INCREF($result);
218   } else {
219     PythonBytes bytes(static_cast<const uint8_t *>($1), result);
220     $result = bytes.release();
221   }
222   free($1);
226 namespace {
227 template <class T>
228 T PyLongAsT(PyObject *obj) {
229   static_assert(true, "unsupported type");
232 template <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) {
233   return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj));
236 template <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) {
237   return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj));
240 template <> int64_t PyLongAsT<int64_t>(PyObject *obj) {
241   return static_cast<int64_t>(PyLong_AsLongLong(obj));
244 template <> int32_t PyLongAsT<int32_t>(PyObject *obj) {
245   return static_cast<int32_t>(PyLong_AsLong(obj));
248 template <class T> bool SetNumberFromPyObject(T &number, PyObject *obj) {
249   if (PyInt_Check(obj))
250     number = static_cast<T>(PyInt_AsLong(obj));
251   else if (PyLong_Check(obj))
252     number = PyLongAsT<T>(obj);
253   else
254     return false;
256   return true;
259 template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
260   if (PyFloat_Check(obj)) {
261     number = PyFloat_AsDouble(obj);
262     return true;
263   }
265   return false;
268 } // namespace
271 // these typemaps allow Python users to pass list objects
272 // and have them turn into C++ arrays (this is useful, for instance
273 // when creating SBData objects from lists of numbers)
274 %typemap(in) (uint64_t* array, size_t array_len),
275              (uint32_t* array, size_t array_len),
276              (int64_t* array, size_t array_len),
277              (int32_t* array, size_t array_len),
278              (double* array, size_t array_len) {
279   /* Check if is a list  */
280   if (PyList_Check($input)) {
281     int size = PyList_Size($input);
282     int i = 0;
283     $2 = size;
284     $1 = ($1_type)malloc(size * sizeof($*1_type));
285     for (i = 0; i < size; i++) {
286       PyObject *o = PyList_GetItem($input, i);
287       if (!SetNumberFromPyObject($1[i], o)) {
288         PyErr_SetString(PyExc_TypeError, "list must contain numbers");
289         free($1);
290         return NULL;
291       }
293       if (PyErr_Occurred()) {
294         free($1);
295         return NULL;
296       }
297     }
298   } else if ($input == Py_None) {
299     $1 = NULL;
300     $2 = 0;
301   } else {
302     PyErr_SetString(PyExc_TypeError, "not a list");
303     return NULL;
304   }
307 %typemap(freearg) (uint64_t* array, size_t array_len),
308                   (uint32_t* array, size_t array_len),
309                   (int64_t* array, size_t array_len),
310                   (int32_t* array, size_t array_len),
311                   (double* array, size_t array_len) {
312   free($1);
315 // these typemaps wrap SBModule::GetVersion() from requiring a memory buffer
316 // to the more Pythonic style where a list is returned and no previous allocation
317 // is necessary - this will break if more than 50 versions are ever returned
318 %typemap(typecheck) (uint32_t *versions, uint32_t num_versions) {
319   $1 = ($input == Py_None ? 1 : 0);
322 %typemap(in, numinputs=0) (uint32_t *versions) {
323   $1 = (uint32_t *)malloc(sizeof(uint32_t) * 50);
326 %typemap(in, numinputs=0) (uint32_t num_versions) {
327   $1 = 50;
330 %typemap(argout) (uint32_t *versions, uint32_t num_versions) {
331   uint32_t count = result;
332   if (count >= $2)
333     count = $2;
334   PyObject *list = PyList_New(count);
335   for (uint32_t j = 0; j < count; j++) {
336     PyObject *item = PyInt_FromLong($1[j]);
337     int ok = PyList_SetItem(list, j, item);
338     if (ok != 0) {
339       $result = Py_None;
340       break;
341     }
342   }
343   $result = list;
346 %typemap(freearg) (uint32_t *versions) {
347   free($1);
351 // For Log::LogOutputCallback
352 %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
353   if (!($input == Py_None ||
354         PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
355     PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
356     return NULL;
357   }
359   // FIXME (filcab): We can't currently check if our callback is already
360   // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
361   // baton) nor can we just remove all traces of a callback, if we want to
362   // revert to a file logging mechanism.
364   // Don't lose the callback reference
365   Py_INCREF($input);
366   $1 = LLDBSwigPythonCallPythonLogOutputCallback;
367   $2 = $input;
370 %typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
371   $1 = $input == Py_None;
372   $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
376 %typemap(in) lldb::FileSP {
377   PythonFile py_file(PyRefType::Borrowed, $input);
378   if (!py_file) {
379     PyErr_SetString(PyExc_TypeError, "not a file");
380     return nullptr;
381   }
382   auto sp = unwrapOrSetPythonException(py_file.ConvertToFile());
383   if (!sp)
384     return nullptr;
385   $1 = sp;
388 %typemap(in) lldb::FileSP FORCE_IO_METHODS {
389   PythonFile py_file(PyRefType::Borrowed, $input);
390   if (!py_file) {
391     PyErr_SetString(PyExc_TypeError, "not a file");
392     return nullptr;
393   }
394   auto sp = unwrapOrSetPythonException(
395       py_file.ConvertToFileForcingUseOfScriptingIOMethods());
396   if (!sp)
397     return nullptr;
398   $1 = sp;
401 %typemap(in) lldb::FileSP BORROWED {
402   PythonFile py_file(PyRefType::Borrowed, $input);
403   if (!py_file) {
404     PyErr_SetString(PyExc_TypeError, "not a file");
405     return nullptr;
406   }
407   auto sp =
408       unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));
409   if (!sp)
410     return nullptr;
411   $1 = sp;
414 %typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS {
415   PythonFile py_file(PyRefType::Borrowed, $input);
416   if (!py_file) {
417     PyErr_SetString(PyExc_TypeError, "not a file");
418     return nullptr;
419   }
420   auto sp = unwrapOrSetPythonException(
421       py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));
422   if (!sp)
423     return nullptr;
424   $1 = sp;
427 %typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
428   if (PythonFile::Check($input)) {
429     $1 = 1;
430   } else {
431     PyErr_Clear();
432     $1 = 0;
433   }
436 %typemap(out) lldb::FileSP {
437   $result = nullptr;
438   lldb::FileSP &sp = $1;
439   if (sp) {
440     PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp));
441     if (!pyfile.IsValid())
442       return nullptr;
443     $result = pyfile.release();
444   }
445   if (!$result) {
446     $result = Py_None;
447     Py_INCREF(Py_None);
448   }
451 %typemap(in) (const char* string, int len) {
452   if ($input == Py_None) {
453     $1 = NULL;
454     $2 = 0;
455   } else if (PythonString::Check($input)) {
456     PythonString py_str(PyRefType::Borrowed, $input);
457     llvm::StringRef str = py_str.GetString();
458     $1 = const_cast<char *>(str.data());
459     $2 = str.size();
460     // In Python 2, if $input is a PyUnicode object then this
461     // will trigger a Unicode -> String conversion, in which
462     // case the `PythonString` will now own the PyString.  Thus
463     // if it goes out of scope, the data will be deleted.  The
464     // only way to avoid this is to leak the Python object in
465     // that case.  Note that if there was no conversion, then
466     // releasing the string will not leak anything, since we
467     // created this as a borrowed reference.
468     py_str.release();
469   } else {
470     PyErr_SetString(PyExc_TypeError, "not a string-like object");
471     return NULL;
472   }
475 // These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
476 // and fixed so they will not crash if PyObject_GetBuffer fails.
477 // https://github.com/swig/swig/issues/1640
479 // I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper,
480 // doing it right away is not legal according to the python buffer protocol.
482 %define %pybuffer_mutable_binary(TYPEMAP, SIZE)
483 %typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
484   int res;
485   Py_ssize_t size = 0;
486   void *buf = 0;
487   res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE);
488   if (res < 0) {
489     PyErr_Clear();
490     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
491   }
492   size = view.buffer.len;
493   buf = view.buffer.buf;
494   $1 = ($1_ltype)buf;
495   $2 = ($2_ltype)(size / sizeof($*1_type));
497 %enddef
499 %define %pybuffer_binary(TYPEMAP, SIZE)
500 %typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
501   int res;
502   Py_ssize_t size = 0;
503   const void *buf = 0;
504   res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO);
505   if (res < 0) {
506     PyErr_Clear();
507     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
508   }
509   size = view.buffer.len;
510   buf = view.buffer.buf;
511   $1 = ($1_ltype)buf;
512   $2 = ($2_ltype)(size / sizeof($*1_type));
514 %enddef
516 %pybuffer_binary(const uint8_t *buf, size_t num_bytes);
517 %pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);