From a9f14fa5499a9f8d089c188f72c154de731551a0 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 17 Nov 2020 11:25:02 -0700 Subject: [PATCH] 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 * ada-tasks.c (struct ada_tasks_pspace_data) : New field. (ada_get_tcb_types_info): Look for __gnat_gdb_cpu_first_id. (read_atcb): Use cpu_id_offset. --- gdb/ChangeLog | 7 +++++++ gdb/ada-tasks.c | 22 ++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 79e84bc4180..4533a6a7b8b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-12-11 Tom Tromey + + * ada-tasks.c (struct ada_tasks_pspace_data) : 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 * ada-lang.c (ada_fold_name): Fix off-by-one error. diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index c66d08f92fa..15149067609 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 -- 2.30.2