From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id kRr3DVeVa2kYxwcAWB0awg (envelope-from ) for ; Sat, 17 Jan 2026 08:57:43 -0500 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=yahoo.de header.i=@yahoo.de header.a=rsa-sha256 header.s=s2048 header.b=BoxBCH1q; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 3645D1E0DD; Sat, 17 Jan 2026 08:57:43 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 03CC11E093 for ; Sat, 17 Jan 2026 08:57:41 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 546B14BA23F6 for ; Sat, 17 Jan 2026 13:57:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 546B14BA23F6 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=yahoo.de header.i=@yahoo.de header.a=rsa-sha256 header.s=s2048 header.b=BoxBCH1q Received: from sonic306-20.consmr.mail.ir2.yahoo.com (sonic306-20.consmr.mail.ir2.yahoo.com [77.238.176.206]) by sourceware.org (Postfix) with ESMTPS id 2C77B4BA23D6 for ; Sat, 17 Jan 2026 13:55:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2C77B4BA23D6 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=yahoo.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yahoo.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2C77B4BA23D6 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=77.238.176.206 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1768658130; cv=none; b=jYmqOdA3Dmo/k4cWnNuuHQrfoIkXWDjff6SgdZPqgwL1mt5zHnj6Jz7bdPUc5tA7H0JlcBE/EXaxM+avwFKJpScUqQYiLpak5KfTLbJRIfyypcjFQMKlqijKAk1Irq+aCC6f51TS3VCThPrfOoZxtH/ZNlY+fRIFitg/NH8II18= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1768658130; c=relaxed/simple; bh=XvwvXkeA9RK2qJ63r/H8xxq42o94B9LibEQgJI81gVg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=fAr9+7sD7cEH7cgAHvhj/MU/d0AgJFqiEjFwyKL11BB4iMNDd5umnToJqgq7J2iVWEhGJGzL9tFjFQ9RUZ6wPJlglMg02x3Lli2W/Js0hRNCuCpPoFWAqSq04v6hCOg+yEGISrgjn3nJYXm7vSIU+MQw+0SNPs7Zhxl1Gdb54TE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C77B4BA23D6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1768658129; bh=V76cbmsWMwgfz+yhn4i8Il1Lu7TGNXPe9m1obAplwLM=; h=From:To:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=BoxBCH1q1vyyUNurQiIS0MIeBwRVtvTr46svT7eqagQl1c6Pivps9Gn6BkHveASD6T5q2q2zPXHjmg33HJFbcaABfa0uk7zEdaJt3W+ypRLw06RQi+SWSTvstKIp0rqQd+BYTWWJAzRC7N/xaoteo9bav2mn14egEC5g9+NJC7YtE1t89PO2ta2OzsvWjQJH5GfhfT75HrPmVOaBz06p4Zz6/Xgn8ZjQa6wAXhQU4f8jI2F28v6Q4R4Jj644DKl1ccJN+lo/q/9+pXyHt3c/hL8q2SzFGLTlPXG0PdZmUit5XiuZyDDDl8N6imea3r1jPVqVv6Kh3sc2vZaLQsotYQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1768658129; bh=wLvVZ6oVfuw8UZ/GnsbTbVa4xIVwthsSLDpAfbpfNXo=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=AVPnJJk6wxSdVGYeEhJTtCkfLJSdkY1uYQSlMrmSv1/jXiaPINZIE8Zzf1osIEX9hVKjSt0I8PwQe25aPvxwdTUehuZOEu489gwMn3eRyJWoCkQKmKWN6kGole7vw7QfrnkcYstWrJNfKvttbqFcgtac3UxxMCyEsiP38y7Pcriy1s7rcuQxOLy4sOuyzjkXzoM31jwaTa3v/LM03dpE44DDq3ESN8kJoGsth8VkY20B7sikMFrwR78nwsQte0Dwn0OVekHApofZX/LH87fkRie0VyPRFfgWy3NVXqqTuNJjDv1/Y/AvCpfmEF+ZDHIwXqMfWTsHsQo1dxCV9O4u5Q== X-YMail-OSG: iHju5NQVM1mzDxXiA1etns.tnCHIgUhrtJw5r9riMxLOzYgrL90Atg19vLoy.qU 97V.i1ZXM1kCpJf76V8ENrN.70n5WSlED6RTkmvCarvJP8bhiSIlD1xYCIS5T2Mcqy3L9MT34ATP H7sI51XNcZY2TiEqmqaGhfB_dyv.yBsCtuoUGLZ_kWUVb8Dz9s5RUs4DI9n896PF1NsT9OCYjk8l vXsblx5Q2e10Lf1aZPwyBTzFyj7NyRWFk1AxnOv7XTM3oG6BEgpSjRt6CbY3g4tyx6WPnSA2pLvF jX8oVhnourKUE.p1fA_uP5haz5CIG03vpb.PSJu3O5_4aAZpnvus0c2tu2rBT8.46lT8C4GN48WU Fu1dX92pob3IHI37oSe9AmFk_Pnw9iHOM1E0l1YCEhexaRPYBL1Pabhf5kBQrXEvD.T.MmUoJwd4 4CukOXF.GfyoBz8qnKAWjQTuKBEif3AqSew91BhAIQIXwLFzNaJMRfEibPsxHPCyVHDQv9hvf_cS ECjYGWgbde0YXXTQ1WImqCTi18VBr22ejLyfu2KTq7Eb1Dtw6ALGLNwOxVlPfHF6boqE5IuMYcwQ 2TvSftW1QNTgZvXvWXGX.U9YdiVTLiXFeT83io8BKm5cY.hMeag7RJhE0_XFvRSixOIqJJrM4hjV 64a6KlAmXjAgTokJ2YEl24djBlKT8UFyFPPdBz8TGWOAfUXdXNTkRUZlj37yAK5I.GWKbW6H8IRk yBwi52av.uowF0iFkvNORIoUovjmjba5P5dFCwcBSr37c3rMJP.15XklgBu6zmeTPCQ.sSDVu7E5 GCQouxNpTldQjNTnjo1hj9vRAXgUdayYwGJ3cCwfbG3aFLIjz9kxnQn2ykMTDt0vyV1l7qY2STL3 1CiOsB52YAdJnUfmclMtvi4zigDZgpjkS3nj7knTMm35IMa4QKuhiPf84YR6G8yMeLumBl81fLbW A24VgeRk_iLd9PPxojlY57mzzx802UmLrA5XaSU9pAri.oxhwWQxIAIPiAqY_bIxPGqORQvdPUKI vlMUDF7H3P7O.kMN_U1GnGQua.9Wp8D5AZkxWve.PbuG2WB2dlrBu3iy6PfqediWg920LvKvB6Qi 6Q_BGgeHXc38z86q.WO4ATYNKdsinRDjNzhzxWUMycNkkfCAHuMH4RGFECJnqpUrPw..T59kqv8F KwHtMqtQYgW_H2paOQmwH1Nfhv8x6G098RweZ7.e35P.ax80tua0E895_qyrTTXDfeHJeJ73tSTc ZUH.jwEcdEw6kpmKVK.dPQmTU0P1.cZ8__uT1aOVq6JTGbHikLmltx9bnvUF_ILt3WMBYycDliv7 GnlNHwosN73Al2AbCegxVSFESdFpuDugFjPg5nSit1SzdLUXEcFxzS.VnPRTvmcfhiRinCvUi5gW AeThri3SLvl7dFhc80JWIDArlj4bLQEu6ZNwtAMhTzDwlhqQuAEcOQpUpoqYP20X0pCg1KdJlLeu by_xDNgGQqLe6XnAtELDY3.IEpgfxwcunOOpZfHeGL.zXL03FJSiVbPeuCrDhGlhVGOBH4iiuG8b Uvw4sIrR8nGwsZozMy7ED1jSf9uo4Nbm9Nxe7Ku9EENOgdfo9Nt5.XVFPuKT2DQyN12Hfg.ZMBCE BXj5Vo7WS397TNYIlCCZRPTZ7T4byBvtpDklvd34eqqDMUOdi_XYLDpkqrsMuVMej98r7pibAWA8 m2ewE2kBiBhmKBZ4s1sg5c1FHg84ILI1SPJDwmS3teYxOn3cZamWFDKRoUEe7_XyH3IWcX6_vhXi LzdlqFW8WiWVdKNm.6vUrzfDNPUYdV9hLghD1qcGtOc7ufJKAhw8R1XSocY.FLGPR.OX5cTp1J23 5.H9zZM7PdvzyK9T4WftUY0Jv4eELzfJJ9MCeeZrgwbOYmVqaD9fFkewBU_pkHeSNFcI0BEMw7JT OIB8EwT8M6cphbnKNms6qOak3F.AJo_w83qZMPnd8sEJkyWgi5ggOrtCqDGV5TNA.Ci.2aU6nWns P0K.vN0X_IUxTS83zM5N4tV8gfM_nr6E_mskSkz9Su7JpuGHpb.YVeCtxFflPfXMxzIlrUZLie_2 GLNZDjMc0DIXe9lFQwTVQtGCgJrSKk3xRqd8FvYB8h4KFWllUCk7Np03.vdWvLeCPV8E7iod25qj wIQ2jskxqAAMrbz7ObYP7dC91KVzIyiE3lWn9.zDqUyMjH03UqoLmy1tRFFlDJpIvjFWSFm3bEPe R8_OE1q3y_eHBXxenmFAuZXjPqiyueBVjTCHfkE5c7w-- X-Sonic-MF: X-Sonic-ID: 62f0b789-d2f5-40d3-931b-18be42cc027f Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ir2.yahoo.com with HTTP; Sat, 17 Jan 2026 13:55:29 +0000 Received: by hermes--production-ir2-6fcf857f6f-68cr8 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 1ab9324439058ba9e338fb11da35c341; Sat, 17 Jan 2026 13:55:25 +0000 (UTC) From: Hannes Domani To: gdb-patches@sourceware.org Subject: [PATCH v2 11/11] Add aarch64-windows support Date: Sat, 17 Jan 2026 14:54:34 +0100 Message-ID: <20260117135448.2666604-11-ssbssa@yahoo.de> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260117134052.2660009-1-ssbssa@yahoo.de> References: <20260117134052.2660009-1-ssbssa@yahoo.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This makes most debugging work, except unwinding doesn't always work from inside dlls where no debug info is available, because SEH unwinding is not implemented. The number of available hardware breakpoints is taken from ID_AA64DFR0_EL1 (registry key "CP 4028"). As for hardware watchpoints, even though ARM64_MAX_WATCHPOINTS is 2, testing showed that only 1 ever works, so it's fixed to that value. --- Changes in v2: - added new source files to ALLDEPFILES - created NEWS entry - removed set_gdbarch_auto_wide_charset and set_gdbarch_long_bit calls since these are now done in windows-tdep.c - added comments to aarch64_windows_breakpoint and set_gdbarch_decr_pc_after_break - removed unused 32bit code in aarch64_windows_nat_target::fetch_one_register() - changed stopped_data_address() to stopped_data_addresses() in aarch64_windows_nat_target, and updated stopped_by_watchpoint() - initialize windows_process inside INIT_GDB_FILE(aarch64_windows_nat) --- gdb/Makefile.in | 3 + gdb/NEWS | 2 + gdb/aarch64-windows-nat.c | 346 +++++++++++++++++++++++++++++++++++++ gdb/aarch64-windows-tdep.c | 70 ++++++++ gdb/coff-pe-read.c | 6 +- gdb/configure.host | 3 + gdb/configure.nat | 4 + gdb/configure.tgt | 5 + gdb/nat/windows-nat.c | 5 + gdb/nat/windows-nat.h | 2 + 10 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 gdb/aarch64-windows-nat.c create mode 100644 gdb/aarch64-windows-tdep.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index b564048f9fa..fc76925344f 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -735,6 +735,7 @@ ALL_64_TARGET_OBS = \ aarch64-newlib-tdep.o \ aarch64-ravenscar-thread.o \ aarch64-tdep.o \ + aarch64-windows-tdep.o \ alpha-bsd-tdep.o \ alpha-linux-tdep.o \ alpha-netbsd-tdep.o \ @@ -1784,6 +1785,8 @@ ALLDEPFILES = \ aarch64-newlib-tdep.c \ aarch64-ravenscar-thread.c \ aarch64-tdep.c \ + aarch64-windows-nat.c \ + aarch64-windows-tdep.c \ aix-thread.c \ alpha-bsd-nat.c \ alpha-bsd-tdep.c \ diff --git a/gdb/NEWS b/gdb/NEWS index 74fc353d7e9..7ea41940566 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -61,6 +61,8 @@ GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux* +AArch64 MinGW aarch64-*-mingw* + * New commands set local-environment diff --git a/gdb/aarch64-windows-nat.c b/gdb/aarch64-windows-nat.c new file mode 100644 index 00000000000..838a9483634 --- /dev/null +++ b/gdb/aarch64-windows-nat.c @@ -0,0 +1,346 @@ +/* Native-dependent code for Windows AArch64. + + Copyright (C) 2025-2026 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "windows-nat.h" +#include "regcache.h" +#include "gdbarch.h" +#include "inferior.h" + +#include "aarch64-nat.h" + +using namespace windows_nat; + +#define CHECK(x) check (x, __FILE__,__LINE__) + +static void +check (BOOL ok, const char *file, int line) +{ + if (!ok) + { + unsigned err = (unsigned) GetLastError (); + gdb_printf ("error return %s:%d was %u: %s\n", file, line, + err, strwinerror (err)); + } +} + +struct aarch64_windows_per_inferior : public windows_per_inferior +{ + aarch64_debug_reg_state dr_state; +}; + +struct aarch64_windows_nat_target final : + public aarch64_nat_target +{ + std::vector stopped_data_addresses () override; + bool stopped_by_watchpoint () override; + + void initialize_windows_arch (bool attaching) override; + void cleanup_windows_arch () override; + + void fill_thread_context (windows_thread_info *th) override; + + void thread_context_continue (windows_thread_info *th, int killed) override; + void thread_context_step (windows_thread_info *th) override; + + void fetch_one_register (struct regcache *regcache, + windows_thread_info *th, int r) override; + void store_one_register (const struct regcache *regcache, + windows_thread_info *th, int r) override; + + bool is_sw_breakpoint (EXCEPTION_RECORD *er) override; +}; + +/* The current process. */ +static aarch64_windows_per_inferior aarch64_windows_process; + +#define context_offset(x) (offsetof (CONTEXT, x)) +const int aarch64_mappings[] = +{ + context_offset (X0), + context_offset (X1), + context_offset (X2), + context_offset (X3), + context_offset (X4), + context_offset (X5), + context_offset (X6), + context_offset (X7), + context_offset (X8), + context_offset (X9), + context_offset (X10), + context_offset (X11), + context_offset (X12), + context_offset (X13), + context_offset (X14), + context_offset (X15), + context_offset (X16), + context_offset (X17), + context_offset (X18), + context_offset (X19), + context_offset (X20), + context_offset (X21), + context_offset (X22), + context_offset (X23), + context_offset (X24), + context_offset (X25), + context_offset (X26), + context_offset (X27), + context_offset (X28), + context_offset (Fp), + context_offset (Lr), + context_offset (Sp), + context_offset (Pc), + context_offset (Cpsr), + context_offset (V[0]), + context_offset (V[1]), + context_offset (V[2]), + context_offset (V[3]), + context_offset (V[4]), + context_offset (V[5]), + context_offset (V[6]), + context_offset (V[7]), + context_offset (V[8]), + context_offset (V[9]), + context_offset (V[10]), + context_offset (V[11]), + context_offset (V[12]), + context_offset (V[13]), + context_offset (V[14]), + context_offset (V[15]), + context_offset (V[16]), + context_offset (V[17]), + context_offset (V[18]), + context_offset (V[19]), + context_offset (V[20]), + context_offset (V[21]), + context_offset (V[22]), + context_offset (V[23]), + context_offset (V[24]), + context_offset (V[25]), + context_offset (V[26]), + context_offset (V[27]), + context_offset (V[28]), + context_offset (V[29]), + context_offset (V[30]), + context_offset (V[31]), + context_offset (Fpsr), + context_offset (Fpcr), +}; +#undef context_offset + +/* Implement the "stopped_data_addresses" target_ops method. */ + +std::vector +aarch64_windows_nat_target::stopped_data_addresses () +{ + if (aarch64_windows_process.siginfo_er.ExceptionCode != EXCEPTION_BREAKPOINT + || aarch64_windows_process.siginfo_er.NumberParameters != 2) + return {}; + + const CORE_ADDR addr_trap + = (CORE_ADDR) aarch64_windows_process.siginfo_er.ExceptionInformation[1]; + + struct aarch64_debug_reg_state *state + = aarch64_get_debug_reg_state (inferior_ptid.pid ()); + return aarch64_stopped_data_addresses (state, addr_trap); +} + +/* Implement the "stopped_by_watchpoint" target_ops method. */ + +bool +aarch64_windows_nat_target::stopped_by_watchpoint () +{ + return !stopped_data_addresses ().empty (); +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::initialize_windows_arch (bool attaching) +{ + memset (&aarch64_windows_process.dr_state, 0, + sizeof (aarch64_windows_process.dr_state)); + + aarch64_windows_process.mappings = aarch64_mappings; +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::cleanup_windows_arch () +{ + aarch64_remove_debug_reg_state (inferior_ptid.pid ()); +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::fill_thread_context (windows_thread_info *th) +{ + CONTEXT *context = &th->context; + + context->ContextFlags = WindowsContext::all; + CHECK (get_thread_context (th->h, context)); +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::thread_context_continue (windows_thread_info *th, + int killed) +{ + CONTEXT *context = &th->context; + + if (th->debug_registers_changed) + { + context->ContextFlags |= WindowsContext::debug; + for (int i = 0; i < aarch64_num_bp_regs; i++) + { + context->Bvr[i] = aarch64_windows_process.dr_state.dr_addr_bp[i]; + context->Bcr[i] = aarch64_windows_process.dr_state.dr_ctrl_bp[i]; + } + for (int i = 0; i < aarch64_num_wp_regs; i++) + { + context->Wvr[i] = aarch64_windows_process.dr_state.dr_addr_wp[i]; + context->Wcr[i] = aarch64_windows_process.dr_state.dr_ctrl_wp[i]; + } + th->debug_registers_changed = false; + } + + if (context->ContextFlags) + { + DWORD ec = 0; + + if (GetExitCodeThread (th->h, &ec) + && ec == STILL_ACTIVE) + { + BOOL status = set_thread_context (th->h, context); + + if (!killed) + CHECK (status); + } + context->ContextFlags = 0; + } +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::thread_context_step (windows_thread_info *th) +{ + th->context.Cpsr |= 0x200000; +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::fetch_one_register (struct regcache *regcache, + windows_thread_info *th, int r) +{ + gdb_assert (r >= 0); + gdb_assert (!th->reload_context); + + char *context_ptr = (char *) &th->context; + char *context_offset = context_ptr + aarch64_windows_process.mappings[r]; + struct gdbarch *gdbarch = regcache->arch (); + + gdb_assert (!gdbarch_read_pc_p (gdbarch)); + gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0); + gdb_assert (!gdbarch_write_pc_p (gdbarch)); + + if (th->stopped_at_software_breakpoint + && !th->pc_adjusted + && r == gdbarch_pc_regnum (gdbarch)) + { + uint64_t value; + memcpy (&value, context_offset, 8); + value -= gdbarch_decr_pc_after_break (gdbarch); + memcpy (context_offset, &value, 8); + /* Make sure we only rewrite the PC a single time. */ + th->pc_adjusted = true; + } + regcache->raw_supply (r, context_offset); +} + +/* See windows-nat.h. */ + +void +aarch64_windows_nat_target::store_one_register (const struct regcache *regcache, + windows_thread_info *th, int r) +{ + gdb_assert (r >= 0); + + char *context_ptr = (char *) &th->context; + + regcache->raw_collect (r, context_ptr + aarch64_windows_process.mappings[r]); +} + +/* See windows-nat.h. */ + +bool +aarch64_windows_nat_target::is_sw_breakpoint (EXCEPTION_RECORD *er) +{ + /* On aarch64, hardware breakpoints also get EXCEPTION_BREAKPOINT, + but they can be recognized with ExceptionInformation. */ + return (er->ExceptionCode == EXCEPTION_BREAKPOINT + && er->NumberParameters == 1 + && er->ExceptionInformation[0] == 0); +} + +/* Notify all threads that the debug registers changed. */ + +void +aarch64_notify_debug_reg_change (ptid_t ptid, + int is_watchpoint, unsigned int idx) +{ + struct aarch64_debug_reg_state *state + = aarch64_get_debug_reg_state (inferior_ptid.pid ()); + aarch64_windows_process.dr_state = *state; + + for (auto &th : aarch64_windows_process.thread_list) + th->debug_registers_changed = true; +} + +INIT_GDB_FILE (aarch64_windows_nat) +{ + aarch64_initialize_hw_point (); + + /* Get ID_AA64DFR0_EL1 value (CP 4028) from registry. */ + aarch64_num_bp_regs = 0; + uint64_t cp4028; + DWORD cp4028_size = sizeof(cp4028); + if (RegGetValueA (HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + "CP 4028", RRF_RT_REG_QWORD, NULL, &cp4028, &cp4028_size) + == ERROR_SUCCESS) + { + /* Bits 12-15 are the number of breakpoints, minus 1. */ + aarch64_num_bp_regs = ((cp4028 & 0xf000) >> 12) + 1; + if (aarch64_num_bp_regs > ARM64_MAX_BREAKPOINTS) + aarch64_num_bp_regs = ARM64_MAX_BREAKPOINTS; + } + + /* ARM64_MAX_WATCHPOINTS is 2, but only 1 works. */ + aarch64_num_wp_regs = 1; + + /* The target is not a global specifically to avoid a C++ "static + initializer fiasco" situation. */ + add_inf_child_target (new aarch64_windows_nat_target); + + windows_process = &aarch64_windows_process; +} diff --git a/gdb/aarch64-windows-tdep.c b/gdb/aarch64-windows-tdep.c new file mode 100644 index 00000000000..e7312d296ae --- /dev/null +++ b/gdb/aarch64-windows-tdep.c @@ -0,0 +1,70 @@ +/* Target-dependent code for Windows AArch64. + + Copyright (C) 2025-2026 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "gdbarch.h" +#include "aarch64-tdep.h" +#include "arch-utils.h" +#include "regset.h" +#include "windows-tdep.h" + +/* Windows uses the various BRK instruction variants for special operations, + and BRK #0xf000 triggers a breakpoint exception in the debugger. */ +constexpr gdb_byte aarch64_windows_breakpoint[] = {0x00, 0x00, 0x3e, 0xd4}; + +typedef BP_MANIPULATION (aarch64_windows_breakpoint) aarch64_w_breakpoint; + +/* gdbarch initialization for Windows on AArch64. */ + +static void +aarch64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + set_gdbarch_ps_regnum (gdbarch, AARCH64_CPSR_REGNUM); + + set_gdbarch_breakpoint_kind_from_pc (gdbarch, + aarch64_w_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, + aarch64_w_breakpoint::bp_from_kind); + + /* Usually the arm BRK instruction triggers with the PC still at the + instruction, but Windows increments the PC before notifying the + debugger. */ + set_gdbarch_decr_pc_after_break (gdbarch, 4); + + windows_init_abi (info, gdbarch); +} + +static gdb_osabi +aarch64_windows_osabi_sniffer (bfd *abfd) +{ + const char *target_name = bfd_get_target (abfd); + + if (!streq (target_name, "pei-aarch64-little")) + return GDB_OSABI_UNKNOWN; + + return GDB_OSABI_WINDOWS; +} + +INIT_GDB_FILE (aarch64_windows_tdep) +{ + gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_WINDOWS, + aarch64_windows_init_abi); + + gdbarch_register_osabi_sniffer (bfd_arch_aarch64, bfd_target_coff_flavour, + aarch64_windows_osabi_sniffer); +} diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c index f78f825fa12..5073a4b0c4b 100644 --- a/gdb/coff-pe-read.c +++ b/gdb/coff-pe-read.c @@ -339,7 +339,8 @@ read_pe_exported_syms (minimal_symbol_reader &reader, is_pe64 = (strcmp (target, "pe-x86-64") == 0 || strcmp (target, "pei-x86-64") == 0 || strcmp (target, "pe-aarch64") == 0 - || strcmp (target, "pei-aarch64") == 0); + || strcmp (target, "pei-aarch64") == 0 + || strcmp (target, "pei-aarch64-little") == 0); is_pe32 = (strcmp (target, "pe-i386") == 0 || strcmp (target, "pei-i386") == 0 || strcmp (target, "pe-arm-wince-little") == 0 @@ -638,7 +639,8 @@ pe_text_section_offset (struct bfd *abfd) is_pe64 = (strcmp (target, "pe-x86-64") == 0 || strcmp (target, "pei-x86-64") == 0 || strcmp (target, "pe-aarch64") == 0 - || strcmp (target, "pei-aarch64") == 0); + || strcmp (target, "pei-aarch64") == 0 + || strcmp (target, "pei-aarch64-little") == 0); is_pe32 = (strcmp (target, "pe-i386") == 0 || strcmp (target, "pei-i386") == 0 || strcmp (target, "pe-arm-wince-little") == 0 diff --git a/gdb/configure.host b/gdb/configure.host index fdd651987e3..e83b944c0b8 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -81,6 +81,9 @@ case "${host}" in aarch64*-*-linux*) gdb_host=linux ;; aarch64*-*-freebsd*) gdb_host=fbsd ;; +aarch64*-*-mingw*) gdb_host=mingw64a + gdb_host_obs=mingw-hdep.o + ;; alpha*-*-linux*) gdb_host=alpha-linux ;; alpha*-*-netbsdaout* | alpha*-*-knetbsdaout*-gnu) diff --git a/gdb/configure.nat b/gdb/configure.nat index 3ac0319328f..38dd4179511 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -77,6 +77,10 @@ case ${gdb_host} in cygwin*) NATDEPFILES='x86-nat.o nat/x86-dregs.o windows-nat.o nat/windows-nat.o' ;; + mingw64a) + NATDEPFILES='aarch64-nat.o aarch64-windows-nat.o windows-nat.o \ + nat/windows-nat.o nat/aarch64-hw-point.o' + ;; mingw*) NATDEPFILES='x86-nat.o nat/x86-dregs.o windows-nat.o nat/windows-nat.o' ;; diff --git a/gdb/configure.tgt b/gdb/configure.tgt index c0031e3f7a6..ba418653e86 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -155,6 +155,11 @@ aarch64*-*-linux*) symfile-mem.o linux-record.o" ;; +aarch64-*-mingw*) + # Target: MingW/aarch64 + gdb_target_obs="aarch64-windows-tdep.o windows-tdep.o" + ;; + alpha*-*-linux*) # Target: Little-endian Alpha running Linux gdb_target_obs="alpha-linux-tdep.o \ diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c index 2d0c7ddc2ca..a74bab75238 100644 --- a/gdb/nat/windows-nat.c +++ b/gdb/nat/windows-nat.c @@ -530,6 +530,7 @@ windows_process_info::add_dll (LPVOID load_addr) if (!ret) return; +#if defined __i386__ || defined __x86_64__ char system_dir[MAX_PATH]; char syswow_dir[MAX_PATH]; size_t system_dir_len = 0; @@ -560,6 +561,7 @@ windows_process_info::add_dll (LPVOID load_addr) } } +#endif for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++) { MODULEINFO mi; @@ -583,6 +585,8 @@ windows_process_info::add_dll (LPVOID load_addr) #else name = dll_name; #endif + +#if defined __i386__ || defined __x86_64__ /* Convert the DLL path of 32bit processes returned by GetModuleFileNameEx from the 64bit system directory to the 32bit syswow64 directory if necessary. */ @@ -595,6 +599,7 @@ windows_process_info::add_dll (LPVOID load_addr) syswow_dll_path += name + system_dir_len; name = syswow_dll_path.c_str(); } +#endif /* Record the DLL if either LOAD_ADDR is NULL or the address at which the DLL was loaded is equal to LOAD_ADDR. */ diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index c9cae999a70..5411c73ff97 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -474,7 +474,9 @@ struct WindowsContext static constexpr DWORD full = CONTEXT_FULL; static constexpr DWORD all = (CONTEXT_FULL | CONTEXT_FLOATING_POINT +#ifdef CONTEXT_SEGMENTS | CONTEXT_SEGMENTS +#endif | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS); }; -- 2.52.0