[RFC,v2,17/21] gdb/python: add add_symbol () method to gdb.Block

Message ID 20241121124714.419946-18-jan.vrany@labware.com
State New
Headers
Series Add Python "JIT" API |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm warning Skipped upon request
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 warning Skipped upon request

Commit Message

Jan Vraný Nov. 21, 2024, 12:47 p.m. UTC
  This commit adds new method add_symbol () to gdb.Block objects.
A typical use of it is to add previously instantiated gdb.Symbol object
to block when interfacing with JIT compiler.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
 gdb/doc/python.texi                   |  5 +++
 gdb/python/py-block.c                 | 52 +++++++++++++++++++++++----
 gdb/testsuite/gdb.python/py-block.exp | 20 +++++++++++
 3 files changed, 71 insertions(+), 6 deletions(-)
  

Comments

Eli Zaretskii Nov. 21, 2024, 1:36 p.m. UTC | #1
> From: Jan Vrany <jan.vrany@labware.com>
> CC: Jan Vrany <jan.vrany@labware.com>,
> 	Eli Zaretskii <eliz@gnu.org>
> Date: Thu, 21 Nov 2024 12:47:10 +0000
> 
> This commit adds new method add_symbol () to gdb.Block objects.
> A typical use of it is to add previously instantiated gdb.Symbol object
> to block when interfacing with JIT compiler.
> 
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
> ---
>  gdb/doc/python.texi                   |  5 +++
>  gdb/python/py-block.c                 | 52 +++++++++++++++++++++++----
>  gdb/testsuite/gdb.python/py-block.exp | 20 +++++++++++
>  3 files changed, 71 insertions(+), 6 deletions(-)

OK for the documentation part, thanks.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
  

Patch

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 55ca91920cb..43109dc6554 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -6043,6 +6043,11 @@  The new block's @var{start}--@var{end} range must be within superblock's
 range and must not overlap with any block already contained in superblock.
 @end defun
 
+@defun Block.add_symbol (symbol)
+Add @var{symbol} to this block.  Both the block and the @var{symbol} must
+belong to the same compunit (@pxref{Compunits In Python}).
+@end defun
+
 @defun Block.is_valid ()
 Returns @code{True} if the @code{gdb.Block} object is valid,
 @code{False} if not.  A block object can become invalid if the block it
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 626ed10deb6..f3b635f64b8 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -261,6 +261,43 @@  blpy_is_static (PyObject *self, void *closure)
   Py_RETURN_FALSE;
 }
 
+/* Implementation of gdb.Block.add_symbol (self, symbol).
+   Adds SYMBOL to this block.  */
+
+static PyObject *
+blpy_add_symbol (PyObject *self, PyObject *symbol_obj)
+{
+  const struct block *block;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  struct symbol *symbol = symbol_object_to_symbol (symbol_obj);
+  if (symbol == nullptr)
+    {
+      return PyErr_Format (PyExc_TypeError,
+			   _("The symbol argument is not valid gdb.Symbol"));
+    }
+
+  if (symbol->symtab ()->compunit() != block->global_block ()->compunit ())
+    {
+      return PyErr_Format (PyExc_TypeError,
+			   _("The symbol argument belongs to different "
+			     "compunit than block"));
+    }
+
+  multidictionary *dict = block->multidict ();
+  if (dict == nullptr)
+    {
+      auto_obstack *obstack =
+	&(block->global_block ()->compunit ()->objfile ()->objfile_obstack);
+      dict = mdict_create_linear (obstack, nullptr);
+      const_cast<struct block *>(block)->set_multidict (dict);
+    }
+
+  mdict_add_symbol (dict, symbol);
+  Py_RETURN_NONE;
+}
+
 /* Given a string, returns the gdb.Symbol representing that symbol in this
    block.  If such a symbol does not exist, returns NULL with a Python
    exception.  */
@@ -358,7 +395,7 @@  blpy_init (PyObject *zelf, PyObject *args, PyObject *kw)
       return -1;
     }
 
-  static const char *keywords[] = { "superblock", "start", "end", NULL };
+  static const char *keywords[] = { "superblock", "start", "end", nullptr };
   PyObject *superblock_obj;
   uint64_t start;
   uint64_t end;
@@ -398,9 +435,9 @@  blpy_init (PyObject *zelf, PyObject *args, PyObject *kw)
 
   /* Check that start-end range does not overlap with any
      "sibling" blocks' range.  */
-  auto cu = superblock->global_block ()->compunit ();
+  compunit_symtab *cu = superblock->global_block ()->compunit ();
 
-  for (auto each : cu->blockvector ()->blocks ())
+  for (const struct block *each : cu->blockvector ()->blocks ())
     {
       if (each->superblock () == superblock)
 	{
@@ -415,11 +452,11 @@  blpy_init (PyObject *zelf, PyObject *args, PyObject *kw)
 	}
     }
 
-  auto obstack = &(cu->objfile ()->objfile_obstack);
-  auto blk = new (obstack) block ();
+  auto_obstack *obstack = &(cu->objfile ()->objfile_obstack);
+  struct block *blk = new (obstack) block ();
 
   blk->set_superblock (superblock);
-  blk->set_multidict (mdict_create_linear (obstack, NULL));
+  blk->set_multidict (mdict_create_linear (obstack, nullptr));
   blk->set_start ((CORE_ADDR) start);
   blk->set_end ((CORE_ADDR) end);
 
@@ -651,6 +688,9 @@  static PyMethodDef block_object_methods[] = {
   { "is_valid", blpy_is_valid, METH_NOARGS,
     "is_valid () -> Boolean.\n\
 Return true if this block is valid, false if not." },
+  { "add_symbol", blpy_add_symbol, METH_O,
+    "add_symbol (symbol) -> None.\n\
+Add given symbol to the block." },
   {NULL}  /* Sentinel */
 };
 
diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp
index 3c5d291edb0..6bc98e9563f 100644
--- a/gdb/testsuite/gdb.python/py-block.exp
+++ b/gdb/testsuite/gdb.python/py-block.exp
@@ -138,6 +138,26 @@  gdb_test "python print ( gdb.Block(cu.static_block(), 160, 170))" \
 	 "<gdb.Block <anonymous> \{.*\}>" \
 	 "Create sibling block"
 
+# Test adding symbols to a block.
+gdb_py_test_silent_cmd "python symtab = gdb.Symtab(\"some_file.txt\", cu)" \
+		       "Create new symtab" 1
+gdb_py_test_silent_cmd "python typ = gdb.selected_inferior().architecture().integer_type(0).function()" \
+		       "Create type of new symbol" 1
+gdb_py_test_silent_cmd "python sym = gdb.Symbol(\"static_block\", symtab, typ, gdb.SYMBOL_FUNCTION_DOMAIN, gdb.SYMBOL_LOC_BLOCK, cu.static_block() )" \
+		       "Create new symbol" 1
+gdb_test "python print ( sym in list(cu.global_block()) )" \
+	 "False" \
+	 "Symbol is not in global block"
+gdb_py_test_silent_cmd "python cu.global_block().add_symbol(sym)" \
+		       "Add new symbol to block" 1
+gdb_test "python print ( sym in list(cu.global_block()) )" \
+		       "True" \
+		       "Symbol is in global block"
+gdb_test "python print ( cu.global_block().add_symbol(cu))" \
+	 "TypeError.*:.*" \
+	 "Add non-symbol to block"
+
+
 # Test Block is_valid.  This must always be the last test in this
 # testcase as it unloads the object file.
 delete_breakpoints