diff options
author | Tom Tromey <tromey@adacore.com> | 2020-11-17 11:25:02 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-12-11 08:01:47 -0700 |
commit | a9f14fa5499a9f8d089c188f72c154de731551a0 (patch) | |
tree | e22499752cf8c5f8376fe699092911e550c34d27 /gdb | |
parent | b143e2d506bee1020752597f979d5af174edc36d (diff) | |
download | gdb-a9f14fa5499a9f8d089c188f72c154de731551a0.zip gdb-a9f14fa5499a9f8d089c188f72c154de731551a0.tar.gz gdb-a9f14fa5499a9f8d089c188f72c154de731551a0.tar.bz2 |
Handle CPU offset for Ravenscar
The Ravenscar support assumes that the thread ID is the same as the
CPU ID that appears in the Ada task structure. However, on some
systems, gdbserver will report thread IDs that are off by some
constant. This can happen, e.g., with qemu in a scenario where there
is an additional (unreported) CPU in the emulation.
The Ada Ravenscar runtimes have been modified to store this offset in
a global variable. This patch changes gdb to read this variable, when
it exists, and apply the offset to the base CPU ID. This fixes some
crashes that otherwise occur.
2020-12-11 Tom Tromey <tromey@adacore.com>
* ada-tasks.c (struct ada_tasks_pspace_data) <cpu_id_offset>: New
field.
(ada_get_tcb_types_info): Look for __gnat_gdb_cpu_first_id.
(read_atcb): Use cpu_id_offset.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/ada-tasks.c | 22 |
2 files changed, 27 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 79e84bc..4533a6a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-12-11 Tom Tromey <tromey@adacore.com> + + * ada-tasks.c (struct ada_tasks_pspace_data) <cpu_id_offset>: New + field. + (ada_get_tcb_types_info): Look for __gnat_gdb_cpu_first_id. + (read_atcb): Use cpu_id_offset. + 2020-12-10 Kevin Buettner <kevinb@redhat.com> * ada-lang.c (ada_fold_name): Fix off-by-one error. diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index c66d08f..1514906 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -159,6 +159,10 @@ struct ada_tasks_pspace_data /* The index of various fields in the ATCB record and sub-records. */ struct atcb_fieldnos atcb_fieldno {}; + + /* On some systems, gdbserver applies an offset to the CPU that is + reported. */ + unsigned int cpu_id_offset = 0; }; /* Key to our per-program-space data. */ @@ -564,6 +568,18 @@ ada_get_tcb_types_info (void) if (fieldnos.ll_lwp < 0) fieldnos.ll_lwp = ada_get_field_index (ll_type, "thread_id", 1); + /* Check for the CPU offset. */ + bound_minimal_symbol first_id_sym + = lookup_bound_minimal_symbol ("__gnat_gdb_cpu_first_id"); + unsigned int first_id = 0; + if (first_id_sym.minsym != nullptr) + { + CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (first_id_sym); + /* This symbol always has type uint32_t. */ + struct type *u32type = builtin_type (target_gdbarch ())->builtin_uint32; + first_id = value_as_long (value_at (u32type, addr)); + } + /* Set all the out parameters all at once, now that we are certain that there are no potential error() anymore. */ pspace_data = get_ada_tasks_pspace_data (current_program_space); @@ -573,6 +589,7 @@ ada_get_tcb_types_info (void) pspace_data->atcb_ll_type = ll_type; pspace_data->atcb_call_type = call_type; pspace_data->atcb_fieldno = fieldnos; + pspace_data->cpu_id_offset = first_id; return NULL; } @@ -769,8 +786,9 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info) } task_info->base_cpu - = value_as_long (value_field (common_value, - pspace_data->atcb_fieldno.base_cpu)); + = (pspace_data->cpu_id_offset + + value_as_long (value_field (common_value, + pspace_data->atcb_fieldno.base_cpu))); /* And finally, compute the task ptid. Note that there is not point in computing it if the task is no longer alive, in which case |