From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by sourceware.org (Postfix) with ESMTPS id 6AFE3385842A for ; Fri, 27 Jan 2023 16:54:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6AFE3385842A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: by mail-wm1-x32e.google.com with SMTP id e19-20020a05600c439300b003db1cac0c1fso5814660wmn.5 for ; Fri, 27 Jan 2023 08:54:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FRf+HapD7MgHuzwwGF/remR7RSN5CRWoe0E+I4hKqrY=; b=kBnR3EiVUUG7/t3bGPskPpjv2V2AUpUbiW7y6Qoa2xYpFZd4fC971YJXslPthwxV01 y2l2aBcnoEndABhCUv4eWOGoeaKRERGe5z5qQLORvS2qB1z/5/5waVkisyOWG1SnGlFv 9/EZlCVuHeMYm7mOuBVgKW5aZhX6PU1r9IrcZrWC48cbcfhhdHmWaUgSgeUYiDg2r0IK Z4UPZW2gcvNvZX9TVoxRWpCr4h1YJnYsDaaaXmNFTe/c3fNf2b24rq64EdFzGS8MsnPs giFrF4Onug1WQwidS64cA5GQx28tucLxMPu1U4ZO6VAFtiTGp29iH5538ADF0XNVWDq5 Kwkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FRf+HapD7MgHuzwwGF/remR7RSN5CRWoe0E+I4hKqrY=; b=MJlZAC2j7DGUMNPaBaXQ9BsQrH6n2Hsu3b8GFRsI/boIwflqVhd6GQdTKtsR1O7apS var40FktwRDQORQenj4GfBGXlp0jfYYV+gSRnI6X/tXArPbJhMGphASUcuR0U17Lzi9M lw5zcrfjygEFzpu3F4Lmwbrs2juvEzF5+wKhWWm5mwwyknylMkrKCa9UOkpI1ormgz7n hSCNC1VNjsO6drpega9dq5lzGoGeZLUUDPCA9kwpAXEp7JLT9jttcm52+eQVqpk0By8V brWSnVNMzdgH7tsnm1hMJMRnJHwStWA7Zt5nyHrlH1gs1yHhukJiFlgnFcCK28bVXWgL nFfw== X-Gm-Message-State: AFqh2kr/lpczbbuBwXnnrWDmuAzcrIIu2WirTyWn5R9Exvk4SZzfM7UV Ks+DHQDT+5ZOIslKJHr9fwHEeae9s7bfUiT+ X-Google-Smtp-Source: AMrXdXuoBYKQz9BG6ZA3yEOSp4ieYGysIqKHI4XcKgVy2mCUlO5xyso7O0vXccRJqfBHbCRbFtkBSg== X-Received: by 2002:a05:600c:c0a:b0:3db:2858:db84 with SMTP id fm10-20020a05600c0c0a00b003db2858db84mr30917357wmb.34.1674838485893; Fri, 27 Jan 2023 08:54:45 -0800 (PST) Received: from localhost.localdomain ([2a01:e0a:253:fe0:b0cf:cb2e:f4d5:6223]) by smtp.gmail.com with ESMTPSA id g9-20020a05600c308900b003db0dbbea53sm4590502wmn.30.2023.01.27.08.54.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 08:54:45 -0800 (PST) From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= To: gdb-patches@sourceware.org Cc: simark@simark.ca, =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Subject: [PATCH v2 3/3] gdb: Fix Ada tasking for baremetal targets using Ravenscar threads Date: Fri, 27 Jan 2023 17:53:37 +0100 Message-Id: <20230127165337.1832937-4-legouguec@adacore.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230127165337.1832937-1-legouguec@adacore.com> References: <87tu0ugxt7.fsf@adacore.com> <20230127165337.1832937-1-legouguec@adacore.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: For some boards, the Ada tasking runtime defines a __gnat_gdb_cpu_first_id symbol to let GDB map the ATCB's "Base_CPU" indices (ranging from 1 to System.Multiprocessors.CPU) onto the CPU numbers that we read from the remote stub and record in our ptids. In other words, this symbol lets GDB translate "Ada CPUs" into "target CPUs". For example, for the Microchip PolarFire board, the runtime defines this offset as: package System.BB.Board_Parameters is -- [...] GDB_First_CPU_Id : constant Interfaces.Unsigned_32 := 1; pragma Export (C, GDB_First_CPU_Id, "__gnat_gdb_cpu_first_id"); This is because on this board, CPU#1 is the "monitor" CPU; CPUs #2-5 are the "application" CPUs that run user code. So while the ATCB shows Base_CPUs equal to 1, QEMU reports that our code is running on CPU #2. We convert the ATCB's Base_CPUs into "target" CPUs before recording them in struct ada_task_info.base_cpu; this is what we need in most of ravenscar-thread.c, except in one specific spot: when reading the active thread from __gnat_running_thread_table, which is defined as: package System.BB.Threads.Queues is -- [...] Running_Thread_Table : array (System.Multiprocessors.CPU) of Thread_Id On baremetal targets, System.Multiprocessors.CPU is defined as: package System.Multiprocessors is -- [...] type CPU_Range is range 0 .. System.BB.Parameters.Max_Number_Of_CPUs; subtype CPU is CPU_Range range 1 .. CPU_Range'Last; Not_A_Specific_CPU : constant CPU_Range := 0; Thus __gnat_running_thread_table has Max_Number_Of_CPUs elements; for the Microchip PolarFire board, the runtime define this as: package System.BB.Parameters is -- [...] Max_Number_Of_CPUs : constant := 1; So the table has just one element, but ravenscar-thread.c attempts to index it using the "target" CPU ID, i.e. 2. This remained undetected because as luck would have it, with the specific compiler we were using, *(__gnat_running_thread_table+8) happened to contain exactly the same content as *__gnat_running_thread_table. After bumping the compiler, the layout of the tasking runtime changed, and so did the content of *(__gnat_running_thread_table+8). This commit introduces a new function to let GDB convert a "target" CPU back to an "Ada" CPU. Tested on x86_64-linux and riscv64-elf with AdaCore's internal testsuite, which has more extensive coverage of Ada tasking and "Ravenscar thread" features. --- gdb/ada-lang.h | 6 +++++- gdb/ada-tasks.c | 11 +++++++++++ gdb/ada-tasks.h | 6 ++++++ gdb/ravenscar-thread.c | 16 +++++++++++++--- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index e0d44756218..e634a8d1d40 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -145,7 +145,11 @@ struct ada_task_info /* The CPU on which the task is running. This is dependent on the runtime actually providing that info, which is not always the case. Normally, we should be able to count on it on - bare-metal targets. */ + bare-metal targets. + + NB: This CPU number has been normalized to match the IDs reported by the + target, as recorded in the LWP field of PTIDs. It may not map directly to + the Base_CPU recorded in the ATCB; see ada_get_runtime_cpu_index. */ int base_cpu; }; diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index a1afd25f9a5..7d98a16228d 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -301,6 +301,17 @@ get_ada_tasks_pspace_data (struct program_space *pspace) return data; } +/* See ada-tasks.h. */ + +int +ada_get_runtime_cpu_index (struct ada_tasks_pspace_data *pspace_data, + int target_cpu) +{ + gdb_assert (pspace_data->initialized_p); + + return target_cpu - pspace_data->cpu_id_offset; +} + /* Return the ada-tasks module's data for the given inferior (INF). If none is found, add a zero'ed one now. diff --git a/gdb/ada-tasks.h b/gdb/ada-tasks.h index aa85c853a47..325f99ca0f3 100644 --- a/gdb/ada-tasks.h +++ b/gdb/ada-tasks.h @@ -82,4 +82,10 @@ struct ada_tasks_pspace_data; struct ada_tasks_pspace_data * get_ada_tasks_pspace_data (struct program_space *pspace); +/* Translate a "target" CPU index into a "runtime" index suitable for addressing + arrays dimensioned with System.Multiprocessors.CPU. */ + +extern int ada_get_runtime_cpu_index (struct ada_tasks_pspace_data *pspace_data, + int target_cpu); + #endif /* ADA_TASKS_H */ diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c index 57ac9634233..8289b9999bc 100644 --- a/gdb/ravenscar-thread.c +++ b/gdb/ravenscar-thread.c @@ -31,6 +31,7 @@ #include "top.h" #include "regcache.h" #include "objfiles.h" +#include "progspace.h" #include /* This module provides support for "Ravenscar" tasks (Ada) when @@ -194,7 +195,11 @@ struct ravenscar_thread_target final : public target_ops /* This maps a TID to the CPU on which it was running. This is needed because sometimes the runtime will report an active task that hasn't yet been put on the list of tasks that is read by - ada-tasks.c. */ + ada-tasks.c. + + NB: These CPU numbers correspond to those reported by the target, + which may differ from the numbers recorded in the ATCB. See + ada_get_runtime_cpu_index. */ std::unordered_map m_cpu_map; }; @@ -376,8 +381,13 @@ ravenscar_thread_target::runtime_initialized () Return 0 if the ID could not be determined. */ static CORE_ADDR -get_running_thread_id (int cpu) +get_running_thread_id (int target_cpu) { + struct ada_tasks_pspace_data *pspace_data + = get_ada_tasks_pspace_data (current_program_space); + + int runtime_cpu = ada_get_runtime_cpu_index (pspace_data, target_cpu); + struct bound_minimal_symbol object_msym = get_running_thread_msymbol (); int object_size; int buf_size; @@ -391,7 +401,7 @@ get_running_thread_id (int cpu) object_size = builtin_type_void_data_ptr->length (); object_addr = (object_msym.value_address () - + (cpu - 1) * object_size); + + (runtime_cpu - 1) * object_size); buf_size = object_size; buf = (gdb_byte *) alloca (buf_size); read_memory (object_addr, buf, buf_size); -- 2.25.1