Skip to content

Commit

Permalink
Merge branch 'refs/heads/upstream-HEAD' into repo-HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
Delphix Engineering committed Sep 7, 2024
2 parents 22b3907 + d0ce699 commit 9a538db
Show file tree
Hide file tree
Showing 25 changed files with 1,574 additions and 228 deletions.
58 changes: 47 additions & 11 deletions _drgn.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1690,18 +1690,48 @@ def NULL(prog: Program, type: Union[str, Type]) -> Object:

def cast(type: Union[str, Type], obj: Object) -> Object:
"""
Get the value of the given object casted to another type.
Get the value of an object explicitly casted to another type.
Objects with a scalar type (integer, boolean, enumerated, floating-point,
or pointer) can be casted to a different scalar type. Other objects can
only be casted to the same type. This always results in a value object. See
also :func:`drgn.reinterpret()`.
This uses the programming language's rules for explicit conversions, like
the cast operator.
>>> cast("unsigned int", Object(prog, "float", 2.0))
(unsigned int)2
>>> cast("void *", Object(prog, "int", 0))
(void *)0x0
See also :func:`implicit_convert()` for implicit conversions (which usually
do stricter type checking) and :func:`reinterpret()` for reinterpreting the
raw memory of an object.
:param type: Type to cast to.
:param obj: Object to cast.
:return: Casted object. This is always a value object.
:raises TypeError: if casting *obj* to *type* is not allowed
"""
...

def implicit_convert(type: Union[str, Type], obj: Object) -> Object:
"""
Get the value of an object implicitly converted to another type.
This uses the programming language's rules for implicit conversions, like
when assigning to a variable or passing arguments to a function call.
>>> implicit_convert("unsigned int", Object(prog, "float", 2.0))
(unsigned int)2
>>> implicit_convert("void *", Object(prog, "int", 0))
Traceback (most recent call last):
...
TypeError: cannot convert 'int' to incompatible type 'void *'
See also :func:`cast()` for explicit conversions and :func:`reinterpret()`
for reinterpreting the raw memory of an object.
:param type: Type to convert to.
:param obj: Object to convert.
:return: Converted object. This is always a value object.
:raises TypeError: if converting *obj* to *type* is not allowed
"""
...

Expand All @@ -1710,15 +1740,24 @@ def reinterpret(type: Union[str, Type], obj: Object) -> Object:
Get the representation of an object reinterpreted as another type.
This reinterprets the raw memory of the object, so an object can be
reinterpreted as any other type. Reinterpreting a reference results in a
reference, and reinterpreting a value results in a value. See also
:func:`drgn.cast()`.
reinterpreted as any other type.
>>> reinterpret("unsigned int", Object(prog, "float", 2.0))
(unsigned int)1073741824
.. note::
You usually want :func:`cast()` or :func:`implicit_convert()` instead,
which convert the *value* of an object instead of its in-memory
representation.
:param type: Type to reinterpret as.
:param obj: Object to reinterpret.
:return: Reinterpreted object. If *obj* is a reference object, then this is
a reference object. If *obj* is a value object, then this is a value
object.
:raises OutOfBoundsError: if *obj* is a value object and *type* is larger
than *obj*
"""
...

Expand Down Expand Up @@ -2401,9 +2440,6 @@ class TypeKind(enum.Enum):
FLOAT = ...
"""Floating-point type."""

COMPLEX = ...
"""Complex type."""

STRUCT = ...
"""Structure type."""

Expand Down
1 change: 1 addition & 0 deletions docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Objects
.. drgndoc:: Object
.. drgndoc:: NULL
.. drgndoc:: cast
.. drgndoc:: implicit_convert
.. drgndoc:: reinterpret
.. drgndoc:: container_of

Expand Down
2 changes: 2 additions & 0 deletions drgn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
filename_matches,
get_default_prog,
host_platform,
implicit_convert,
offsetof,
program_from_core_dump,
program_from_kernel,
Expand Down Expand Up @@ -140,6 +141,7 @@
"filename_matches",
"get_default_prog",
"host_platform",
"implicit_convert",
"offsetof",
"program_from_core_dump",
"program_from_kernel",
Expand Down
1 change: 0 additions & 1 deletion libdrgn/build-aux/gen_c_keywords_inc_strswitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
C_KEYWORDS = (
"_Atomic",
"_Bool",
"_Complex",
"char",
"class",
"const",
Expand Down
3 changes: 1 addition & 2 deletions libdrgn/c_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ enum {
C_TOKEN_BOOL,
C_TOKEN_FLOAT,
C_TOKEN_DOUBLE,
C_TOKEN_COMPLEX,
MAX_SPECIFIER_TOKEN = C_TOKEN_COMPLEX,
MAX_SPECIFIER_TOKEN = C_TOKEN_DOUBLE,
MIN_QUALIFIER_TOKEN,
C_TOKEN_CONST = MIN_QUALIFIER_TOKEN,
C_TOKEN_RESTRICT,
Expand Down
1 change: 1 addition & 0 deletions libdrgn/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ AC_SYS_LARGEFILE
AC_REQUIRE_AUX_FILE([tap-driver.sh])

MY_C_AUTO
MY_C_SWITCH_ENUM
MY_CHECK_VA_ARGS_COMMA_DELETION

AC_ARG_ENABLE([openmp],
Expand Down
41 changes: 29 additions & 12 deletions libdrgn/drgn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2083,36 +2083,53 @@ struct drgn_error *drgn_format_object(const struct drgn_object *obj,
*/

/**
* Set a @ref drgn_object to the value of an object casted to a another type.
* Set a @ref drgn_object to the value of an object explicitly casted to a
* another type.
*
* Objects with a scalar type can be casted to a different scalar type. Other
* objects can only be casted to the same type. @p res is always set to a value
* object.
* This uses the programming language's rules for explicit conversions, like the
* cast operator.
*
* @sa drgn_object_reinterpret()
* @sa drgn_object_implicit_convert(), drgn_object_reinterpret()
*
* @param[out] res Object to set.
* @param[out] res Object to set. Always set to a value object.
* @param[in] qualified_type New type.
* @param[in] obj Object to read.
* @param[in] obj Object to cast.
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *drgn_object_cast(struct drgn_object *res,
struct drgn_qualified_type qualified_type,
const struct drgn_object *obj);

/**
* Set a @ref drgn_object to the value of an object implicitly converted to a
* another type.
*
* This uses the programming language's rules for implicit conversions, like
* when assigning to a variable or passing arguments to a function call.
*
* @sa drgn_object_cast(), drgn_object_reinterpret()
*
* @param[out] res Object to set. Always set to a value object.
* @param[in] qualified_type New type.
* @param[in] obj Object to convert.
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *
drgn_object_implicit_convert(struct drgn_object *res,
struct drgn_qualified_type qualified_type,
const struct drgn_object *obj);

/**
* Set a @ref drgn_object to the representation of an object reinterpreted as
* another type.
*
* This reinterprets the raw memory of the object, so an object can be
* reinterpreted as any other type.
*
* If @c obj is a value, then @c res is set to a value; if @c obj is a
* reference, then @c res is set to a reference.
*
* @sa drgn_object_cast()
* @sa drgn_object_cast(), drgn_object_implicit_convert()
*
* @param[out] res Object to set.
* @param[out] res Object to set. If @p obj is a value, set to a value. If @p
* obj is a reference, set to a reference.
* @param[in] qualified_type New type.
* @param[in] obj Object to reinterpret.
* @return @c NULL on success, non-@c NULL on error.
Expand Down
13 changes: 13 additions & 0 deletions libdrgn/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ drgn_qualified_type_error(const char *format,
struct drgn_qualified_type qualified_type)
__attribute__((__returns_nonnull__));

/**
* Create a @ref drgn_error with two qualified type names.
*
* @param[in] format Format string for the type error. Must contain two `%s`,
* which will be replaced with the two type names, and no other conversion
* specifications.
*/
struct drgn_error *
drgn_2_qualified_types_error(const char *format,
struct drgn_qualified_type qualified_type1,
struct drgn_qualified_type qualified_type2)
__attribute__((__returns_nonnull__));

/**
* Create a @ref drgn_error for an incomplete type.
*
Expand Down
1 change: 1 addition & 0 deletions libdrgn/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ struct drgn_language {
*/
drgn_float_literal_fn *float_literal;
drgn_cast_op *op_cast;
drgn_cast_op *op_implicit_convert;
drgn_bool_op *op_bool;
drgn_cmp_op *op_cmp;
drgn_binary_op *op_add;
Expand Down
Loading

0 comments on commit 9a538db

Please sign in to comment.