aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2020-11-17 11:25:02 -0700
committerTom Tromey <tromey@adacore.com>2020-12-11 08:01:47 -0700
commita9f14fa5499a9f8d089c188f72c154de731551a0 (patch)
treee22499752cf8c5f8376fe699092911e550c34d27 /gdb
parentb143e2d506bee1020752597f979d5af174edc36d (diff)
downloadgdb-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/ChangeLog7
-rw-r--r--gdb/ada-tasks.c22
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