Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tristan Gingold <gingold@adacore.com>
To: "gdb-patches@sourceware.org ml" <gdb-patches@sourceware.org>
Cc: Joel Brobecker <brobecker@adacore.com>
Subject: RFA: [Ada] extract known tasks array parameters from symbol table
Date: Mon, 13 Feb 2012 15:14:00 -0000	[thread overview]
Message-ID: <7A06C670-A574-4AE4-A89C-2532671E5F64@adacore.com> (raw)

Hi,

while trying to use 'info tasks' on VMS, I hit an issue with the known_tasks array business, because the elements are only 32 bit pointers on VMS.  I took the occasion to make the code more generic and getting rid of the fixed parameters.  So this patch now tries to extract array size and element type from the symbol table first, and fall back to the minsymtab in case of error.

Maybe we should get rid of the fallback, as without debug symbol for Ada.Tasking, the whole ada-tasks.c code is pretty useless.

Manually tested on ia64-hp-openvms.

Tristan.

gdb/
2012-02-13  Tristan Gingold  <gingold@adacore.com>

	* ada-tasks.c (struct ada_tasks_inferior_data): Add
	known_tasks_element and known_tasks_length fields.
	(read_known_tasks_array): Change argument type.  Use pointer type
	and number of elements from DATA.  Adjust.
	(read_known_tasks_list): Likewise.
	(get_known_tasks_addr): Change profile.  Try symtab first, and
	extract type and size from it.
	(ada_set_current_inferior_known_tasks_addr): Adjust for above
	change.

diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..45b597f 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -215,6 +215,12 @@ struct ada_tasks_inferior_data
      above.  */
   CORE_ADDR known_tasks_addr;
 
+  /* Type of elements of the known task.  Usually a pointer.  */
+  struct type *known_tasks_element;
+
+  /* Number of elements in the known tasks array.  */
+  unsigned int known_tasks_length;
+
   /* When nonzero, this flag indicates that the task_list field
      below is up to date.  When set to zero, the list has either
      not been initialized, or has potentially become stale.  */
@@ -774,24 +780,21 @@ add_ada_task (CORE_ADDR task_id, struct inferior *inf)
    it in the current inferior's TASK_LIST.  Return non-zero upon success.  */
 
 static int
-read_known_tasks_array (CORE_ADDR known_tasks_addr)
+read_known_tasks_array (struct ada_tasks_inferior_data *data)
 {
-  const int target_ptr_byte =
-    gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
-  const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
+  const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
+  const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
   gdb_byte *known_tasks = alloca (known_tasks_size);
   int i;
 
   /* Build a new list by reading the ATCBs from the Known_Tasks array
      in the Ada runtime.  */
-  read_memory (known_tasks_addr, known_tasks, known_tasks_size);
-  for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
+  read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
+  for (i = 0; i < data->known_tasks_length; i++)
     {
-      struct type *data_ptr_type =
-        builtin_type (target_gdbarch)->builtin_data_ptr;
       CORE_ADDR task_id =
         extract_typed_address (known_tasks + i * target_ptr_byte,
-			       data_ptr_type);
+			       data->known_tasks_element);
 
       if (task_id != 0)
         add_ada_task (task_id, current_inferior ());
@@ -804,13 +807,10 @@ read_known_tasks_array (CORE_ADDR known_tasks_addr)
    the current inferior's TASK_LIST.  Return non-zero upon success.  */
 
 static int
-read_known_tasks_list (CORE_ADDR known_tasks_addr)
+read_known_tasks_list (struct ada_tasks_inferior_data *data)
 {
-  const int target_ptr_byte =
-    gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
+  const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
   gdb_byte *known_tasks = alloca (target_ptr_byte);
-  struct type *data_ptr_type =
-    builtin_type (target_gdbarch)->builtin_data_ptr;
   CORE_ADDR task_id;
   const struct ada_tasks_pspace_data *pspace_data
     = get_ada_tasks_pspace_data (current_program_space);
@@ -820,8 +820,8 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
     return 0;
 
   /* Build a new list by reading the ATCBs.  Read head of the list.  */
-  read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
-  task_id = extract_typed_address (known_tasks, data_ptr_type);
+  read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
+  task_id = extract_typed_address (known_tasks, data->known_tasks_element);
   while (task_id != 0)
     {
       struct value *tcb_value;
@@ -841,21 +841,85 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
   return 1;
 }
 
-/* Return the address of the variable NAME that contains all the known
-   tasks maintained in the Ada Runtime.  Return NULL if the variable
-   could not be found, meaning that the inferior program probably does
-   not use tasking.  */
+/* Try method KIND to extract known tasks info for DATA.
+   Return non-zero in case of success, and set the known tasks field of DATA.
+*/
 
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
+static int
+get_known_tasks_addr (struct ada_tasks_inferior_data *data,
+		      enum ada_known_tasks_kind kind)
 {
+  const char *name;
   struct minimal_symbol *msym;
+  struct symbol *sym;
+
+  switch (kind)
+    {
+    case ADA_TASKS_ARRAY:
+      name = KNOWN_TASKS_NAME;
+      break;
+    case ADA_TASKS_LIST:
+      name = KNOWN_TASKS_LIST;
+      break;
+    default:
+      /* Should never happen, but be safe.  */
+      return 0;
+    }
+
+  /* First try psymtab/symtab.  */
+  sym = lookup_symbol_in_language (name, NULL, VAR_DOMAIN, language_c, NULL);
 
+  if (sym != NULL)
+    {
+      /* Validate.  */
+      struct type *type = check_typedef (SYMBOL_TYPE (sym));
+      struct type *eltype;
+      struct type *idxtype;
+
+      switch (kind)
+	{
+	case ADA_TASKS_ARRAY:
+	  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+	      && (eltype = check_typedef (TYPE_TARGET_TYPE (type)))
+	      && TYPE_CODE (eltype) == TYPE_CODE_PTR
+	      && (idxtype = check_typedef (TYPE_INDEX_TYPE (type)))
+	      && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
+	      && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
+	    {
+	      data->known_tasks_kind = ADA_TASKS_ARRAY;
+	      data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+	      data->known_tasks_element = eltype;
+	      data->known_tasks_length =
+		TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
+	      return 1;
+	    }
+	  break;
+	case ADA_TASKS_LIST:
+	  if (TYPE_CODE (type) == TYPE_CODE_PTR)
+	    {
+	      data->known_tasks_kind = ADA_TASKS_LIST;
+	      data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+	      data->known_tasks_element = type;
+	      data->known_tasks_length = 1;
+	      return 1;
+	    }
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  /* Fallback using minsymtab.  */
   msym = lookup_minimal_symbol (name, NULL, NULL);
   if (msym == NULL)
     return 0;
 
-  return SYMBOL_VALUE_ADDRESS (msym);
+  data->known_tasks_kind = kind;
+  data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+  data->known_tasks_element = builtin_type (target_gdbarch)->builtin_data_ptr;
+  data->known_tasks_length =
+    (kind == ADA_TASKS_ARRAY) ? MAX_NUMBER_OF_KNOWN_TASKS : 1;
+  return 1;
 }
 
 /* Assuming DATA is the ada-tasks' data for the current inferior,
@@ -865,26 +929,14 @@ get_known_tasks_addr (const char *name)
 static void
 ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
 {
-  CORE_ADDR known_tasks_addr;
-
   if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
     return;
 
-  known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
-  if (known_tasks_addr != 0)
-    {
-      data->known_tasks_kind = ADA_TASKS_ARRAY;
-      data->known_tasks_addr = known_tasks_addr;
-      return;
-    }
+  if (get_known_tasks_addr (data, ADA_TASKS_ARRAY))
+    return;
 
-  known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
-  if (known_tasks_addr != 0)
-    {
-      data->known_tasks_kind = ADA_TASKS_LIST;
-      data->known_tasks_addr = known_tasks_addr;
-      return;
-    }
+  if (get_known_tasks_addr (data, ADA_TASKS_LIST))
+    return;
 
   data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
   data->known_tasks_addr = 0;
@@ -917,9 +969,9 @@ read_known_tasks (void)
       case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior.  */
         return 0;
       case ADA_TASKS_ARRAY:
-        return read_known_tasks_array (data->known_tasks_addr);
+        return read_known_tasks_array (data);
       case ADA_TASKS_LIST:
-        return read_known_tasks_list (data->known_tasks_addr);
+        return read_known_tasks_list (data);
     }
 
   /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks


             reply	other threads:[~2012-02-13 15:14 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-13 15:14 Tristan Gingold [this message]
2012-02-13 16:16 ` Joel Brobecker
2012-02-14  8:19   ` Tristan Gingold
2012-02-14 15:47     ` Joel Brobecker
2012-02-16 14:40   ` Tristan Gingold
2012-02-16 17:19     ` Joel Brobecker
2012-02-17 16:34       ` Tristan Gingold
2012-02-17 16:37         ` Joel Brobecker
2012-02-17 19:23           ` Tristan Gingold
2012-02-20 17:11           ` Tristan Gingold
2012-02-21 18:16             ` Joel Brobecker
2012-02-23 16:34               ` Tristan Gingold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7A06C670-A574-4AE4-A89C-2532671E5F64@adacore.com \
    --to=gingold@adacore.com \
    --cc=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox