This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: [Ada] extract known tasks array parameters from symbol table


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]