mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
libdrgn: python: add PyLong_From* and PyLong_As* wrappers for stdint.h types
It feels icky to write code that, for example, passes a uint64_t to PyLong_FromUnsignedLongLong(). In practice it's fine, but it's much nicer to have conversion functions specifically for the stdint.h types. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
7180304c88
commit
73fea86792
@ -39,6 +39,33 @@
|
||||
|
||||
#define DRGNPY_PUBLIC __attribute__((__visibility__("default")))
|
||||
|
||||
// PyLong_From* and PyLong_As* for stdint.h types. These use _Generic for
|
||||
// slightly more type safety (e.g., so you can't pass an int64_t to
|
||||
// PyLong_FromUint64()).
|
||||
#if ULONG_MAX == UINT64_MAX
|
||||
#define PyLong_FromUint64(v) _Generic((v), uint64_t: PyLong_FromUnsignedLong)(v)
|
||||
#define PyLong_AsUint64(obj) ((uint64_t)PyLong_AsUnsignedLong(obj))
|
||||
#define PyLong_AsUint64Mask(obj) ((uint64_t)PyLong_AsUnsignedLongMask(obj))
|
||||
#elif ULLONG_MAX == UINT64_MAX
|
||||
#define PyLong_FromUint64(v) _Generic((v), uint64_t: PyLong_FromUnsignedLongLong)(v)
|
||||
#define PyLong_AsUint64(obj) ((uint64_t)PyLong_AsUnsignedLongLong(obj))
|
||||
#define PyLong_AsUint64Mask(obj) ((uint64_t)PyLong_AsUnsignedLongLongMask(obj))
|
||||
#endif
|
||||
|
||||
#if LONG_MIN == INT64_MIN && LONG_MAX == INT64_MAX
|
||||
#define PyLong_FromInt64(v) _Generic((v), int64_t: PyLong_FromLong)(v)
|
||||
#define PyLong_AsInt64(obj) ((int64_t)PyLong_AsLong(obj))
|
||||
#elif LLONG_MIN == INT64_MIN && LLONG_MAX == INT64_MAX
|
||||
#define PyLong_FromInt64(v) _Generic((v), int64_t: PyLong_FromLongLong)(v)
|
||||
#define PyLong_AsInt64(obj) ((int64_t)PyLong_AsLongLong(obj))
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX >= UINT32_MAX
|
||||
#define PyLong_FromUint32(v) _Generic((v), uint32_t: PyLong_FromUnsignedLong)(v)
|
||||
#define PyLong_FromUint16(v) _Generic((v), uint16_t: PyLong_FromUnsignedLong)(v)
|
||||
#define PyLong_FromUint8(v) _Generic((v), uint8_t: PyLong_FromUnsignedLong)(v)
|
||||
#endif
|
||||
|
||||
#define Py_RETURN_BOOL(cond) do { \
|
||||
if (cond) \
|
||||
Py_RETURN_TRUE; \
|
||||
|
@ -16,7 +16,7 @@ PyObject *drgnpy_linux_helper_direct_mapping_offset(PyObject *self, PyObject *ar
|
||||
err = linux_helper_direct_mapping_offset(&((Program *)arg)->prog, &ret);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return PyLong_FromUnsignedLongLong(ret);
|
||||
return PyLong_FromUint64(ret);
|
||||
}
|
||||
|
||||
PyObject *drgnpy_linux_helper_read_vm(PyObject *self, PyObject *args,
|
||||
@ -114,7 +114,7 @@ PyObject *drgnpy_linux_helper_task_cpu(PyObject *self, PyObject *args,
|
||||
err = linux_helper_task_cpu(&task->obj, &cpu);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return PyLong_FromUnsignedLongLong(cpu);
|
||||
return PyLong_FromUint64(cpu);
|
||||
}
|
||||
|
||||
DrgnObject *drgnpy_linux_helper_radix_tree_lookup(PyObject *self,
|
||||
@ -311,7 +311,7 @@ PyObject *drgnpy_linux_helper_kaslr_offset(PyObject *self, PyObject *args,
|
||||
|
||||
if (!(prog->prog.flags & DRGN_PROGRAM_IS_LINUX_KERNEL))
|
||||
return PyErr_Format(PyExc_ValueError, "not Linux kernel");
|
||||
return PyLong_FromUnsignedLongLong(prog->prog.vmcoreinfo.kaslr_offset);
|
||||
return PyLong_FromUint64(prog->prog.vmcoreinfo.kaslr_offset);
|
||||
}
|
||||
|
||||
PyObject *drgnpy_linux_helper_pgtable_l5_enabled(PyObject *self, PyObject *args,
|
||||
|
@ -70,7 +70,6 @@ static PyObject *sizeof_(PyObject *self, PyObject *arg)
|
||||
{
|
||||
struct drgn_error *err;
|
||||
uint64_t size;
|
||||
|
||||
if (PyObject_TypeCheck(arg, &DrgnType_type)) {
|
||||
err = drgn_type_sizeof(((DrgnType *)arg)->type, &size);
|
||||
} else if (PyObject_TypeCheck(arg, &DrgnObject_type)) {
|
||||
@ -82,7 +81,7 @@ static PyObject *sizeof_(PyObject *self, PyObject *arg)
|
||||
}
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return PyLong_FromUnsignedLongLong(size);
|
||||
return PyLong_FromUint64(size);
|
||||
}
|
||||
|
||||
static PyObject *offsetof_(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
@ -99,7 +98,7 @@ static PyObject *offsetof_(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
err = drgn_type_offsetof(type->type, member, &offset);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return PyLong_FromUnsignedLongLong(offset);
|
||||
return PyLong_FromUint64(offset);
|
||||
}
|
||||
|
||||
static PyMethodDef drgn_methods[] = {
|
||||
|
@ -18,19 +18,16 @@ static int DrgnObject_literal(struct drgn_object *res, PyObject *literal)
|
||||
if (PyBool_Check(literal)) {
|
||||
err = drgn_object_bool_literal(res, literal == Py_True);
|
||||
} else if (PyLong_Check(literal)) {
|
||||
unsigned long long uvalue;
|
||||
bool is_negative;
|
||||
|
||||
is_negative = Py_SIZE(literal) < 0;
|
||||
bool is_negative = Py_SIZE(literal) < 0;
|
||||
if (is_negative) {
|
||||
literal = PyNumber_Negative(literal);
|
||||
if (!literal)
|
||||
return -1;
|
||||
}
|
||||
uvalue = PyLong_AsUnsignedLongLong(literal);
|
||||
uint64_t uvalue = PyLong_AsUint64(literal);
|
||||
if (is_negative)
|
||||
Py_DECREF(literal);
|
||||
if (uvalue == (unsigned long long)-1 && PyErr_Occurred())
|
||||
if (uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
err = drgn_object_integer_literal(res, uvalue);
|
||||
if (!err && is_negative)
|
||||
@ -214,9 +211,9 @@ static int serialize_py_object(struct drgn_program *prog, char *buf,
|
||||
int64_t svalue;
|
||||
uint64_t uvalue;
|
||||
} tmp;
|
||||
tmp.uvalue = PyLong_AsUnsignedLongLongMask(long_obj);
|
||||
tmp.uvalue = PyLong_AsUint64Mask(long_obj);
|
||||
Py_DECREF(long_obj);
|
||||
if (tmp.uvalue == (unsigned long long)-1 && PyErr_Occurred())
|
||||
if (tmp.uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
if (type->encoding == DRGN_OBJECT_ENCODING_SIGNED) {
|
||||
tmp.svalue = truncate_signed(tmp.svalue,
|
||||
@ -438,10 +435,9 @@ static DrgnObject *DrgnObject_new(PyTypeObject *subtype, PyObject *args,
|
||||
long_obj = PyNumber_Long(value_obj);
|
||||
if (!long_obj)
|
||||
goto err;
|
||||
tmp.uvalue = PyLong_AsUnsignedLongLongMask(long_obj);
|
||||
tmp.uvalue = PyLong_AsUint64Mask(long_obj);
|
||||
Py_DECREF(long_obj);
|
||||
if (tmp.uvalue == (unsigned long long)-1 &&
|
||||
PyErr_Occurred())
|
||||
if (tmp.uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
goto err;
|
||||
if (encoding == DRGN_OBJECT_ENCODING_SIGNED) {
|
||||
err = drgn_object_set_signed(&obj->obj,
|
||||
@ -641,22 +637,20 @@ static PyObject *DrgnObject_value_impl(struct drgn_object *obj)
|
||||
switch (obj->encoding) {
|
||||
case DRGN_OBJECT_ENCODING_SIGNED: {
|
||||
int64_t svalue;
|
||||
|
||||
err = drgn_object_read_signed(obj, &svalue);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
return PyLong_FromLongLong(svalue);
|
||||
return PyLong_FromInt64(svalue);
|
||||
}
|
||||
case DRGN_OBJECT_ENCODING_UNSIGNED: {
|
||||
uint64_t uvalue;
|
||||
|
||||
err = drgn_object_read_unsigned(obj, &uvalue);
|
||||
if (err)
|
||||
return set_drgn_error(err);
|
||||
if (drgn_type_kind(underlying_type) == DRGN_TYPE_BOOL)
|
||||
Py_RETURN_BOOL(uvalue);
|
||||
else
|
||||
return PyLong_FromUnsignedLongLong(uvalue);
|
||||
return PyLong_FromUint64(uvalue);
|
||||
}
|
||||
case DRGN_OBJECT_ENCODING_FLOAT: {
|
||||
double fvalue;
|
||||
@ -1017,7 +1011,7 @@ static PyObject *DrgnObject_get_absent(DrgnObject *self, void *arg)
|
||||
static PyObject *DrgnObject_get_address(DrgnObject *self, void *arg)
|
||||
{
|
||||
if (self->obj.kind == DRGN_OBJECT_REFERENCE)
|
||||
return PyLong_FromUnsignedLongLong(self->obj.address);
|
||||
return PyLong_FromUint64(self->obj.address);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -1026,7 +1020,7 @@ static PyObject *DrgnObject_get_bit_offset(DrgnObject *self, void *arg)
|
||||
{
|
||||
SWITCH_ENUM(self->obj.kind,
|
||||
case DRGN_OBJECT_REFERENCE:
|
||||
return PyLong_FromLong(self->obj.bit_offset);
|
||||
return PyLong_FromUint8(self->obj.bit_offset);
|
||||
case DRGN_OBJECT_VALUE:
|
||||
case DRGN_OBJECT_ABSENT:
|
||||
Py_RETURN_NONE;
|
||||
@ -1036,7 +1030,7 @@ static PyObject *DrgnObject_get_bit_offset(DrgnObject *self, void *arg)
|
||||
static PyObject *DrgnObject_get_bit_field_size(DrgnObject *self, void *arg)
|
||||
{
|
||||
if (self->obj.is_bit_field)
|
||||
return PyLong_FromUnsignedLongLong(self->obj.bit_size);
|
||||
return PyLong_FromUint64(self->obj.bit_size);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -1166,10 +1160,10 @@ static PyObject *DrgnObject_int(DrgnObject *self)
|
||||
|
||||
switch (self->obj.encoding) {
|
||||
case DRGN_OBJECT_ENCODING_SIGNED:
|
||||
ret = PyLong_FromLongLong(value->svalue);
|
||||
ret = PyLong_FromInt64(value->svalue);
|
||||
break;
|
||||
case DRGN_OBJECT_ENCODING_UNSIGNED:
|
||||
ret = PyLong_FromUnsignedLongLong(value->uvalue);
|
||||
ret = PyLong_FromUint64(value->uvalue);
|
||||
break;
|
||||
case DRGN_OBJECT_ENCODING_FLOAT:
|
||||
ret = PyLong_FromDouble(value->fvalue);
|
||||
@ -1235,10 +1229,10 @@ static PyObject *DrgnObject_index(DrgnObject *self)
|
||||
|
||||
switch (self->obj.encoding) {
|
||||
case DRGN_OBJECT_ENCODING_SIGNED:
|
||||
ret = PyLong_FromLongLong(value->svalue);
|
||||
ret = PyLong_FromInt64(value->svalue);
|
||||
break;
|
||||
case DRGN_OBJECT_ENCODING_UNSIGNED:
|
||||
ret = PyLong_FromUnsignedLongLong(value->uvalue);
|
||||
ret = PyLong_FromUint64(value->uvalue);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -1328,10 +1322,10 @@ static PyObject *DrgnObject_##func(DrgnObject *self) \
|
||||
\
|
||||
switch (self->obj.encoding) { \
|
||||
case DRGN_OBJECT_ENCODING_SIGNED: \
|
||||
ret = PyLong_FromLongLong(value->svalue); \
|
||||
ret = PyLong_FromInt64(value->svalue); \
|
||||
break; \
|
||||
case DRGN_OBJECT_ENCODING_UNSIGNED: \
|
||||
ret = PyLong_FromUnsignedLongLong(value->uvalue); \
|
||||
ret = PyLong_FromUint64(value->uvalue); \
|
||||
break; \
|
||||
case DRGN_OBJECT_ENCODING_FLOAT: \
|
||||
ret = PyLong_FromDouble(func(value->fvalue)); \
|
||||
@ -1834,7 +1828,7 @@ static DrgnObject *ObjectIterator_next(ObjectIterator *self)
|
||||
|
||||
static PyObject *ObjectIterator_length_hint(ObjectIterator *self)
|
||||
{
|
||||
return PyLong_FromUnsignedLongLong(self->length);
|
||||
return PyLong_FromUint64(self->length);
|
||||
}
|
||||
|
||||
static PyMethodDef ObjectIterator_methods[] = {
|
||||
|
@ -248,7 +248,7 @@ static PyObject *StackFrame_register(StackFrame *self, PyObject *arg)
|
||||
"register value is not known");
|
||||
return NULL;
|
||||
}
|
||||
return PyLong_FromUnsignedLongLong(value);
|
||||
return PyLong_FromUint64(value);
|
||||
}
|
||||
|
||||
static PyObject *StackFrame_registers(StackFrame *self)
|
||||
@ -266,7 +266,7 @@ static PyObject *StackFrame_registers(StackFrame *self)
|
||||
if (!drgn_stack_frame_register(self->trace->trace, self->i, reg,
|
||||
&value))
|
||||
continue;
|
||||
PyObject *value_obj = PyLong_FromUnsignedLongLong(value);
|
||||
PyObject *value_obj = PyLong_FromUint64(value);
|
||||
if (!value_obj) {
|
||||
Py_DECREF(dict);
|
||||
return NULL;
|
||||
@ -312,7 +312,7 @@ static PyObject *StackFrame_get_pc(StackFrame *self, void *arg)
|
||||
{
|
||||
uint64_t pc;
|
||||
if (drgn_stack_frame_pc(self->trace->trace, self->i, &pc)) {
|
||||
return PyLong_FromUnsignedLongLong(pc);
|
||||
return PyLong_FromUint64(pc);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_LookupError,
|
||||
"program counter is not known");
|
||||
@ -324,7 +324,7 @@ static PyObject *StackFrame_get_sp(StackFrame *self, void *arg)
|
||||
{
|
||||
uint64_t sp;
|
||||
if (drgn_stack_frame_sp(self->trace->trace, self->i, &sp)) {
|
||||
return PyLong_FromUnsignedLongLong(sp);
|
||||
return PyLong_FromUint64(sp);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_LookupError,
|
||||
"stack pointer is not known");
|
||||
|
@ -41,12 +41,12 @@ static PyObject *Symbol_get_name(Symbol *self, void *arg)
|
||||
|
||||
static PyObject *Symbol_get_address(Symbol *self, void *arg)
|
||||
{
|
||||
return PyLong_FromUnsignedLongLong(drgn_symbol_address(self->sym));
|
||||
return PyLong_FromUint64(drgn_symbol_address(self->sym));
|
||||
}
|
||||
|
||||
static PyObject *Symbol_get_size(Symbol *self, void *arg)
|
||||
{
|
||||
return PyLong_FromUnsignedLongLong(drgn_symbol_size(self->sym));
|
||||
return PyLong_FromUint64(drgn_symbol_size(self->sym));
|
||||
}
|
||||
|
||||
static PyObject *Symbol_get_binding(Symbol *self, void *arg)
|
||||
|
@ -38,7 +38,7 @@ static void Thread_dealloc(Thread *self)
|
||||
|
||||
static PyObject *Thread_get_tid(Thread *self)
|
||||
{
|
||||
return PyLong_FromUnsignedLong(self->thread.tid);
|
||||
return PyLong_FromUint32(self->thread.tid);
|
||||
}
|
||||
|
||||
static DrgnObject *Thread_get_object(Thread *self)
|
||||
|
@ -117,7 +117,7 @@ static PyObject *DrgnType_get_size(DrgnType *self)
|
||||
}
|
||||
if (!drgn_type_is_complete(self->type))
|
||||
Py_RETURN_NONE;
|
||||
return PyLong_FromUnsignedLongLong(drgn_type_size(self->type));
|
||||
return PyLong_FromUint64(drgn_type_size(self->type));
|
||||
}
|
||||
|
||||
static PyObject *DrgnType_get_length(DrgnType *self)
|
||||
@ -128,7 +128,7 @@ static PyObject *DrgnType_get_length(DrgnType *self)
|
||||
drgn_type_kind_str(self->type));
|
||||
}
|
||||
if (drgn_type_is_complete(self->type))
|
||||
return PyLong_FromUnsignedLongLong(drgn_type_length(self->type));
|
||||
return PyLong_FromUint64(drgn_type_length(self->type));
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -196,7 +196,7 @@ static TypeMember *TypeMember_wrap(PyObject *parent,
|
||||
Py_INCREF(Py_None);
|
||||
py_member->name = Py_None;
|
||||
}
|
||||
py_member->bit_offset = PyLong_FromUnsignedLongLong(bit_offset);
|
||||
py_member->bit_offset = PyLong_FromUint64(bit_offset);
|
||||
if (!py_member->bit_offset)
|
||||
goto err;
|
||||
return py_member;
|
||||
@ -1081,17 +1081,15 @@ static void TypeMember_dealloc(TypeMember *self)
|
||||
|
||||
static PyObject *TypeMember_get_offset(TypeMember *self, void *arg)
|
||||
{
|
||||
unsigned long long bit_offset;
|
||||
|
||||
bit_offset = PyLong_AsUnsignedLongLong(self->bit_offset);
|
||||
if (bit_offset == (unsigned long long)-1 && PyErr_Occurred())
|
||||
uint64_t bit_offset = PyLong_AsUint64(self->bit_offset);
|
||||
if (bit_offset == (uint64_t)-1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
if (bit_offset % 8) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"member is not byte-aligned");
|
||||
return NULL;
|
||||
}
|
||||
return PyLong_FromUnsignedLongLong(bit_offset / 8);
|
||||
return PyLong_FromUint64(bit_offset / 8);
|
||||
}
|
||||
|
||||
static PyObject *TypeMember_get_bit_field_size(TypeMember *self, void *arg)
|
||||
@ -1100,7 +1098,7 @@ static PyObject *TypeMember_get_bit_field_size(TypeMember *self, void *arg)
|
||||
if (!object)
|
||||
return NULL;
|
||||
if (object->obj.is_bit_field)
|
||||
return PyLong_FromUnsignedLongLong(object->obj.bit_size);
|
||||
return PyLong_FromUint64(object->obj.bit_size);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -1633,9 +1631,8 @@ static int unpack_member(struct drgn_compound_type_builder *builder,
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long long bit_offset =
|
||||
PyLong_AsUnsignedLongLong(member->bit_offset);
|
||||
if (bit_offset == (unsigned long long)-1 && PyErr_Occurred())
|
||||
uint64_t bit_offset = PyLong_AsUint64(member->bit_offset);
|
||||
if (bit_offset == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
|
||||
union drgn_lazy_object object;
|
||||
@ -1878,14 +1875,13 @@ static int unpack_enumerator(struct drgn_enum_type_builder *builder,
|
||||
|
||||
struct drgn_error *err;
|
||||
if (is_signed) {
|
||||
long long svalue = PyLong_AsLongLong(enumerator->value);
|
||||
int64_t svalue = PyLong_AsInt64(enumerator->value);
|
||||
if (svalue == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
err = drgn_enum_type_builder_add_signed(builder, name, svalue);
|
||||
} else {
|
||||
unsigned long long uvalue =
|
||||
PyLong_AsUnsignedLongLong(enumerator->value);
|
||||
if (uvalue == (unsigned long long)-1 && PyErr_Occurred())
|
||||
uint64_t uvalue = PyLong_AsUint64(enumerator->value);
|
||||
if (uvalue == (uint64_t)-1 && PyErr_Occurred())
|
||||
return -1;
|
||||
err = drgn_enum_type_builder_add_unsigned(builder, name,
|
||||
uvalue);
|
||||
|
Loading…
Reference in New Issue
Block a user