This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFA: [Ada] extract known tasks array parameters from symbol table
Hi Joel,
here is the new version, taking into account your comments: I have mostly reshaped ada_set_current_inferior_known_tasks_addr, tell me if the new form is ok (and then I will test it more thoroughly).
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): Remove.
(ada_set_current_inferior_known_tasks_addr): Try symtab first.
Merge former get_known_tasks_addr code.
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..5815cf9 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,23 +841,6 @@ 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. */
-
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
-{
- struct minimal_symbol *msym;
-
- msym = lookup_minimal_symbol (name, NULL, NULL);
- if (msym == NULL)
- return 0;
-
- return SYMBOL_VALUE_ADDRESS (msym);
-}
-
/* Assuming DATA is the ada-tasks' data for the current inferior,
set the known_tasks_kind and known_tasks_addr fields. Do nothing
if those fields are already set and still up to date. */
@@ -865,27 +848,95 @@ 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;
+ const char *name;
+ struct minimal_symbol *msym;
+ struct symbol *sym;
+ /* Return now if already set. */
if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
return;
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
- if (known_tasks_addr != 0)
+ /* First with the symtab, which knows the exact array type and size. */
+
+ /* Try array. */
+
+ sym = lookup_symbol_in_language (KNOWN_TASKS_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;
+
+ 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;
+ }
+ }
+
+ /* Try list. */
+
+ sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+
+ 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;
+ }
+ }
+
+ /* Fallback using the minsymtab. The runtime may have been stripped (as in
+ some distributions), but it is likely that the executable still contains
+ debug information on the task type (due to implicit with of Ada.Tasking).
+ */
+
+ /* Try array. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_ARRAY;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
return;
}
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
- if (known_tasks_addr != 0)
+ /* Try list. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_LIST;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = 1;
return;
}
+ /* Can't find tasks. */
+
data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
data->known_tasks_addr = 0;
}
@@ -917,9 +968,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