]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/python/py-value.c
gdb: building inferior strings from within GDB
[thirdparty/binutils-gdb.git] / gdb / python / py-value.c
index 92a15304c34dc53a4bff647910d9575d1b90392c..933af92a664bb73a9c792036696b293d08f660e3 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to values.
 
-   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+   Copyright (C) 2008-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,6 +18,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "top.h"               /* For quit_force ().  */
 #include "charset.h"
 #include "value.h"
 #include "language.h"
@@ -53,9 +54,6 @@
 #define builtin_type_pybool \
   language_bool_type (current_language, gdbpy_enter::get_gdbarch ())
 
-#define builtin_type_pychar \
-  language_string_char_type (current_language, gdbpy_enter::get_gdbarch ())
-
 struct value_object {
   PyObject_HEAD
   struct value_object *next;
@@ -81,7 +79,7 @@ static void
 valpy_clear_value (value_object *self)
 {
   /* Indicate we are no longer interested in the value object.  */
-  value_decref (self->value);
+  self->value->decref ();
   self->value = nullptr;
 
   Py_CLEAR (self->address);
@@ -228,7 +226,7 @@ gdbpy_preserve_values (const struct extension_language_defn *extlang,
   value_object *iter;
 
   for (iter = values_in_python; iter; iter = iter->next)
-    preserve_one_value (iter->value, objfile, copied_types);
+    iter->value->preserve (objfile, copied_types);
 }
 
 /* Given a value of a pointer type, apply the C unary * operator to it.  */
@@ -272,7 +270,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
       scoped_value_mark free_values;
 
       self_val = ((value_object *) self)->value;
-      switch (check_typedef (value_type (self_val))->code ())
+      switch (check_typedef (self_val->type ())->code ())
        {
        case TYPE_CODE_PTR:
          res_val = value_ind (self_val);
@@ -371,6 +369,10 @@ valpy_get_address (PyObject *self, void *closure)
          res_val = value_addr (val_obj->value);
          val_obj->address = value_to_value_object (res_val);
        }
+      catch (const gdb_exception_forced_quit &except)
+       {
+         quit_force (NULL, 0);
+       }
       catch (const gdb_exception &except)
        {
          val_obj->address = Py_None;
@@ -391,7 +393,7 @@ valpy_get_type (PyObject *self, void *closure)
 
   if (!obj->type)
     {
-      obj->type = type_to_type_object (value_type (obj->value));
+      obj->type = type_to_type_object (obj->value->type ());
       if (!obj->type)
        return NULL;
     }
@@ -418,7 +420,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       struct value *val = obj->value;
       scoped_value_mark free_values;
 
-      type = value_type (val);
+      type = val->type ();
       type = check_typedef (type);
 
       if (type->is_pointer_or_reference ()
@@ -506,7 +508,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
       struct type *type, *realtype;
       CORE_ADDR addr;
 
-      type = value_type (value);
+      type = value->type ();
       realtype = check_typedef (type);
 
       switch (realtype->code ())
@@ -538,7 +540,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
                                                low_bound,
                                                low_bound + length - 1);
              }
-           addr = value_address (value);
+           addr = value->address ();
            break;
          }
        case TYPE_CODE_PTR:
@@ -548,7 +550,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
          break;
        default:
          /* Should flag an error here.  PR 20769.  */
-         addr = value_address (value);
+         addr = value->address ();
          break;
        }
 
@@ -647,6 +649,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
       "actual_objects",                /* See set print object on|off.  */
       "static_members",                /* See set print static-members on|off.  */
       /* C non-bool options.  */
+      "max_characters",        /* See set print characters N.  */
       "max_elements",          /* See set print elements N.  */
       "max_depth",             /* See set print max-depth N.  */
       "repeat_threshold",      /* See set print repeats.  */
@@ -675,7 +678,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
 
   struct value_print_options opts;
   gdbpy_get_print_options (&opts);
-  opts.deref_ref = 0;
+  opts.deref_ref = false;
 
   /* We need objects for booleans as the "p" flag for bools is new in
      Python 3.3.  */
@@ -695,7 +698,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
   char *format = NULL;
   if (!gdb_PyArg_ParseTupleAndKeywords (args,
                                        kw,
-                                       "|O!O!O!O!O!O!O!O!O!O!O!O!O!IIIs",
+                                       "|O!O!O!O!O!O!O!O!O!O!O!O!O!IIIIs",
                                        keywords,
                                        &PyBool_Type, &raw_obj,
                                        &PyBool_Type, &pretty_arrays_obj,
@@ -710,6 +713,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
                                        &PyBool_Type, &deref_refs_obj,
                                        &PyBool_Type, &actual_objects_obj,
                                        &PyBool_Type, &static_members_obj,
+                                       &opts.print_max_chars,
                                        &opts.print_max,
                                        &opts.max_depth,
                                        &opts.repeat_count_threshold,
@@ -883,7 +887,7 @@ value_has_field (struct value *v, PyObject *field)
 
   try
     {
-      val_type = value_type (v);
+      val_type = v->type ();
       val_type = check_typedef (val_type);
       if (val_type->is_pointer_or_reference ())
        val_type = check_typedef (val_type->target_type ());
@@ -1035,7 +1039,7 @@ valpy_getitem (PyObject *self, PyObject *key)
        {
          struct type *val_type;
 
-         val_type = check_typedef (value_type (tmp));
+         val_type = check_typedef (tmp->type ());
          if (val_type->code () == TYPE_CODE_PTR)
            res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
          else if (val_type->code () == TYPE_CODE_REF)
@@ -1061,7 +1065,7 @@ valpy_getitem (PyObject *self, PyObject *key)
              struct type *type;
 
              tmp = coerce_ref (tmp);
-             type = check_typedef (value_type (tmp));
+             type = check_typedef (tmp->type ());
              if (type->code () != TYPE_CODE_ARRAY
                  && type->code () != TYPE_CODE_PTR)
                  error (_("Cannot subscript requested type."));
@@ -1104,7 +1108,7 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 
   try
     {
-      ftype = check_typedef (value_type (function));
+      ftype = check_typedef (function->type ());
     }
   catch (const gdb_exception &except)
     {
@@ -1169,7 +1173,7 @@ valpy_str (PyObject *self)
   struct value_print_options opts;
 
   gdbpy_get_print_options (&opts);
-  opts.deref_ref = 0;
+  opts.deref_ref = false;
 
   string_file stb;
 
@@ -1195,7 +1199,7 @@ valpy_get_is_optimized_out (PyObject *self, void *closure)
 
   try
     {
-      opt = value_optimized_out (value);
+      opt = value->optimized_out ();
     }
   catch (const gdb_exception &except)
     {
@@ -1217,7 +1221,7 @@ valpy_get_is_lazy (PyObject *self, void *closure)
 
   try
     {
-      opt = value_lazy (value);
+      opt = value->lazy ();
     }
   catch (const gdb_exception &except)
     {
@@ -1238,8 +1242,8 @@ valpy_fetch_lazy (PyObject *self, PyObject *args)
 
   try
     {
-      if (value_lazy (value))
-       value_fetch_lazy (value);
+      if (value->lazy ())
+       value->fetch_lazy ();
     }
   catch (const gdb_exception &except)
     {
@@ -1309,8 +1313,8 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
     {
     case VALPY_ADD:
       {
-       struct type *ltype = value_type (arg1);
-       struct type *rtype = value_type (arg2);
+       struct type *ltype = arg1->type ();
+       struct type *rtype = arg2->type ();
 
        ltype = check_typedef (ltype);
        ltype = STRIP_REFERENCE (ltype);
@@ -1333,8 +1337,8 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
       break;
     case VALPY_SUB:
       {
-       struct type *ltype = value_type (arg1);
-       struct type *rtype = value_type (arg2);
+       struct type *ltype = arg1->type ();
+       struct type *rtype = arg2->type ();
 
        ltype = check_typedef (ltype);
        ltype = STRIP_REFERENCE (ltype);
@@ -1504,7 +1508,7 @@ valpy_absolute (PyObject *self)
     {
       scoped_value_mark free_values;
 
-      if (value_less (value, value_zero (value_type (value), not_lval)))
+      if (value_less (value, value::zero (value->type (), not_lval)))
        isabs = 0;
     }
   catch (const gdb_exception &except)
@@ -1529,13 +1533,13 @@ valpy_nonzero (PyObject *self)
 
   try
     {
-      type = check_typedef (value_type (self_value->value));
+      type = check_typedef (self_value->value->type ());
 
       if (is_integral_type (type) || type->code () == TYPE_CODE_PTR)
        nonzero = !!value_as_long (self_value->value);
       else if (is_floating_value (self_value->value))
        nonzero = !target_float_is_zero
-         (value_contents (self_value->value).data (), type);
+         (self_value->value->contents ().data (), type);
       else
        /* All other values are True.  */
        nonzero = 1;
@@ -1557,18 +1561,20 @@ valpy_nonzero (PyObject *self)
 static PyObject *
 valpy_invert (PyObject *self)
 {
-  struct value *val = NULL;
+  PyObject *result = nullptr;
 
   try
     {
-      val = value_complement (((value_object *) self)->value);
+      scoped_value_mark free_values;
+      struct value *val = value_complement (((value_object *) self)->value);
+      result = value_to_value_object (val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (val);
+  return result;
 }
 
 /* Implements left shift for value objects.  */
@@ -1710,7 +1716,7 @@ static PyObject *
 valpy_long (PyObject *self)
 {
   struct value *value = ((value_object *) self)->value;
-  struct type *type = value_type (value);
+  struct type *type = value->type ();
   LONGEST l = 0;
 
   try
@@ -1745,7 +1751,7 @@ static PyObject *
 valpy_float (PyObject *self)
 {
   struct value *value = ((value_object *) self)->value;
-  struct type *type = value_type (value);
+  struct type *type = value->type ();
   double d = 0;
 
   try
@@ -1753,7 +1759,7 @@ valpy_float (PyObject *self)
       type = check_typedef (type);
 
       if (type->code () == TYPE_CODE_FLT && is_floating_value (value))
-       d = target_float_to_host_double (value_contents (value).data (), type);
+       d = target_float_to_host_double (value->contents ().data (), type);
       else if (type->code () == TYPE_CODE_INT)
        {
          /* Note that valpy_long accepts TYPE_CODE_PTR and some
@@ -1772,39 +1778,17 @@ valpy_float (PyObject *self)
   return PyFloat_FromDouble (d);
 }
 
-/* Returns an object for a value which is released from the all_values chain,
-   so its lifetime is not bound to the execution of a command.  */
-PyObject *
-value_to_value_object (struct value *val)
-{
-  value_object *val_obj;
-
-  val_obj = PyObject_New (value_object, &value_object_type);
-  if (val_obj != NULL)
-    {
-      val_obj->value = release_value (val).release ();
-      val_obj->next = nullptr;
-      val_obj->prev = nullptr;
-      val_obj->address = NULL;
-      val_obj->type = NULL;
-      val_obj->dynamic_type = NULL;
-      note_value (val_obj);
-    }
-
-  return (PyObject *) val_obj;
-}
-
-/* Returns an object for a value, but without releasing it from the
+/* Returns an object for a value, without releasing it from the
    all_values chain.  */
 PyObject *
-value_to_value_object_no_release (struct value *val)
+value_to_value_object (struct value *val)
 {
   value_object *val_obj;
 
   val_obj = PyObject_New (value_object, &value_object_type);
   if (val_obj != NULL)
     {
-      value_incref (val);
+      val->incref ();
       val_obj->value = val;
       val_obj->next = nullptr;
       val_obj->prev = nullptr;
@@ -1894,17 +1878,18 @@ convert_value_from_python (PyObject *obj)
          gdb::unique_xmalloc_ptr<char> s
            = python_string_to_target_string (obj);
          if (s != NULL)
-           value = value_cstring (s.get (), strlen (s.get ()),
-                                  builtin_type_pychar);
+           value
+             = current_language->value_string (gdbpy_enter::get_gdbarch (),
+                                               s.get (), strlen (s.get ()));
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
-       value = value_copy (((value_object *) obj)->value);
+       value = ((value_object *) obj)->value->copy ();
       else if (gdbpy_is_lazy_string (obj))
        {
          PyObject *result;
 
          result = PyObject_CallMethodObjArgs (obj, gdbpy_value_cst,  NULL);
-         value = value_copy (((value_object *) result)->value);
+         value = ((value_object *) result)->value->copy ();
        }
       else
        PyErr_Format (PyExc_TypeError,
@@ -1924,21 +1909,23 @@ PyObject *
 gdbpy_history (PyObject *self, PyObject *args)
 {
   int i;
-  struct value *res_val = NULL;          /* Initialize to appease gcc warning.  */
 
   if (!PyArg_ParseTuple (args, "i", &i))
     return NULL;
 
+  PyObject *result = nullptr;
   try
     {
-      res_val = access_value_history (i);
+      scoped_value_mark free_values;
+      struct value *res_val = access_value_history (i);
+      result = value_to_value_object (res_val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Add a gdb.Value into GDB's history, and return (as an integer) the
@@ -1957,7 +1944,7 @@ gdbpy_add_history (PyObject *self, PyObject *args)
 
   try
     {
-      int idx = record_latest_value (value);
+      int idx = value->record_latest ();
       return gdb_py_object_from_longest (idx).release ();
     }
   catch (const gdb_exception &except)
@@ -1986,15 +1973,23 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
   if (!PyArg_ParseTuple (args, "s", &varname))
     return NULL;
 
+  PyObject *result = nullptr;
+  bool found = false;
   try
     {
       struct internalvar *var = lookup_only_internalvar (varname);
 
       if (var != NULL)
        {
+         scoped_value_mark free_values;
          res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
-         if (value_type (res_val)->code () == TYPE_CODE_VOID)
+         if (res_val->type ()->code () == TYPE_CODE_VOID)
            res_val = NULL;
+         else
+           {
+             found = true;
+             result = value_to_value_object (res_val);
+           }
        }
     }
   catch (const gdb_exception &except)
@@ -2002,10 +1997,10 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (res_val == NULL)
+  if (result == nullptr && !found)
     Py_RETURN_NONE;
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Set the value of a convenience variable.  */
@@ -2059,7 +2054,7 @@ gdbpy_is_value_object (PyObject *obj)
   return PyObject_TypeCheck (obj, &value_object_type);
 }
 
-int
+static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
 gdbpy_initialize_values (void)
 {
   if (PyType_Ready (&value_object_type) < 0)
@@ -2069,6 +2064,8 @@ gdbpy_initialize_values (void)
                                 (PyObject *) &value_object_type);
 }
 
+GDBPY_INITIALIZE_FILE (gdbpy_initialize_values);
+
 \f
 
 static gdb_PyGetSetDef value_object_getset[] = {
@@ -2107,7 +2104,7 @@ reinterpret_cast operator."
   { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
   { "const_value", valpy_const_value, METH_NOARGS,
-    "Return a 'const' qualied version of the same value." },
+    "Return a 'const' qualified version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
     METH_VARARGS | METH_KEYWORDS,
     "lazy_string ([encoding]  [, length]) -> lazy_string\n\