From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id T8xoLuuUa2kYxwcAWB0awg (envelope-from ) for ; Sat, 17 Jan 2026 08:55:55 -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=U4Ig8lsI; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id AF3FA1E0DD; Sat, 17 Jan 2026 08:55:55 -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 BADA31E070 for ; Sat, 17 Jan 2026 08:55:54 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 41A774BA23C7 for ; Sat, 17 Jan 2026 13:55:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 41A774BA23C7 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=U4Ig8lsI 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 335C24BA2E1E for ; Sat, 17 Jan 2026 13:55:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 335C24BA2E1E 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 335C24BA2E1E 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=1768658120; cv=none; b=vfOWuVoMFryYViiMLV8dw3sxJpcJZwXWrXPAEAQpFzj1kJHPMPOxLvZjinjU8SvqO4UYK3geKGBd6tWSFU9X+1PmzEFdFBdDIV6USc7/1N1QHS3u4kZdtHs0O0UZbdM1Qy4gnU0gaQF8nikll4ExPcA4pk+adbu/vado95Pa2Fg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1768658120; c=relaxed/simple; bh=78BwvhUwNNsZfFnwxOZvJ6iG3sM59P4H+xZYtqz+22Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=fSeayEU7OBDtMsiR+T3V8t5brzZei8jda+ftMy+TiufxWfHldzq5QH/lKFJJG8SCd3gqi/kQn0uFXmckqUVo4aw6AFENeYYMIl5DiMtZwgST3HjqVphT6bpbiqw34zDbxFdehuoMnpW98L33O68/WAmMg/MLvSJ3mioVpvidpfY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 335C24BA2E1E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1768658119; bh=vxe0g4RlD9CZQ7x7pNDOVV45umP0PEaJVlumNyZdNKc=; h=From:To:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=U4Ig8lsIA6KjGW10Ejmkbr23PpwMtDl02WG36lViCoeQk5I3vUWbZaXkZiHb8ClyEJLrYkBl1dJsaVxYl8nJPxazht0+QL5EGqH7lm6iinCqIO4fffPQI/eXHtbSxRKohraRIuZ+PfQG8VSD8T0sG0S7cVXgKjQKt/qMggKrd0W4zYuX9DKPCAAEOabO2B6dx5ilgTks5KqJg/mU3/i2VoaN6l1MN/dexXCJaSdI0YqIUmdavD24wvFcaTurfsWOx9W/OLNY9Ffszt3f01kkV0SxB8Xz21ECiOYc94EubmdQ/ghalRAAG00jj19sauRRb3cRtAeCQZZttSHl9LRAFA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1768658119; bh=n8/Uo5zTbjRYvkwgtbXFx7ZEawynO234d0smHPlJfNi=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=aoxNysKqnc/uugcYF592GnkGA2f/d3DtCVscRuJJc+HBeVMn2gOQS5WinYzM7qIi6YszkaL3S8EE/Ip9WPY6iGiATd3L7kITAymN05/4CHEKsmAv1wvopPx4BDSTAoS/LtYASsC8GWhWxOBnTXPX47jPNA6E4IyhCaFdWfteRnW8dcAEYauxL/644cAZzMca5G87i6BJF8coc/G0Vuoqj6Iz2WASee3trAyQ4SHwl4pzBsjeKSzDvBm5JRoqGszwoJiOehDZ7rDjMR2hyTWNMgk7S9Lh6ZDHS7IRoQnuPQyZVaS+NfpfpUuam9NwY5Qkd9ATw0soPfxg7dq5uPB1yw== X-YMail-OSG: DG2fmQoVM1l52NKpFIbpTGNM9GVfcFiH5g27MjLY49qirPPBA.lQh3CPHmTPNf1 bUvON7tdqZUlcw27o6vhA9c.uNNJUiN8pX2iOFWmBtn_RMiD1AGB7ZEm56dChfe_ZMqORnXRK4TT OU_6E7Jd.6qcjViH72XkwmpGRBgykeaCkIA5fMxg7khSx35d07tfkdm3TWdmPvWk1OnG8hwlOsvL etYoCkulf0ePWeBFYIVdbmTESTC8Yq2bAoQGsb4bLe64sIi8t0zpbXVkNLPoPUksvvp1xkfyb8hy QvM98UUllpKn4MeerhHrMdu927KgfoY.j18Wd_eE2bw8LfYpyYM1EapDv9F84Cr9sRg1xeTWINy3 ryErUceozCD6TKGASbQvjLnoF_tfn0FyJFir32Graad828aIQdit9Y0DeUdCHCxdZx9d7fWq5kmV hoKGWC2dU6pERfj_08RF26yS.zPnCJk4kSyC6PjUPFxXE0CcPeaqJsJAkshz_eQTdWzVBHBjHJ7I 5AdwrVbICdevs8Towl75XoQFLWA0tTx7HrVnd5m9SXnMKzCAp2EVthuS8YlExfbn_sdng0NihhBR sSoDYSsMLYFCUDv7wjCIKLWQPTCh73GG0iqyF7VyjCZuGI1_1QyZjWAvKRJ4YxVTEozYN9qWR2Ov GeOqB9g1hF9oe4vwzOB39rd4bTDwYBKo5TQ3acFSbqVWobzOCCUdAifdtS8.zpAaV83Q0KwzMdYg 3GvWE029m29faDybwE4xugwj04NOQJ7jfcyCBOqpPaR4uTp7H.C_QHDz5EKXQlcmHU7tB26evE_w IxVo5tJeSxUhceNtBjE0rYHit8fnKBFPQ2_yBRzfRfcwoW8LwANjEVWguqh3U4cOv0cox0hOWBdT Cs5qQlgExokun1Fz7fqgeEAkdARUXG1ZXPuvr6Xjv18kEsjkuqM4C6ayHbMYKEB70RwSd8L9hpVl XUoxywgpCTfpQ9AT65WKK1f2w55G5OTrZ3t3KuObGsC3yUKsBwA9O3fUuJQ.EeRKPp3PVD_zk7Y_ Xzu306BsES7mgXaeGASSFSfGssysHWC5e10S.sp_C6z5dZ07sYzDFsUuSOWEZZxZEzQPDWS2jvz1 FXEEmX2lcyHtBR0vBdoQIg4Z0tJxfw9aopG00gkLtdqsRKFawncyxg47Y4vLWGP4pSYjUuuSxHa_ HR5Bnz6YpKADJNz98ptXlh9un0DbgTWeXf1h3KGyYsXJjTNk1Q4cNP3LoX_XxM1CaPktyP1BpVT1 LkWKZY.LWVJOrJESuEu7obaYEkiz0b_BEdXPRC.XamxjBeV_sWhmrrl68GgCtsRnkgcPsdAN9pkt 7Slmndv7wzQXDz6qPbG6UM2qKxnpmy.KWCvjlZpFgR6L3qsFF2qgLsaO3p1sdWfE2R4LwPnA6Nu4 o00FT4_oIjfSocyhY9GG.XtzfkfJfHGvngesvk4ZdhI3pJtx78p2_1R6gcEKe5FZwvw0Sn4b5N36 i5fFTXoHbrUsjEypA7p9YuV14LWTQvgQojXKtTYo0n7XaVuPFebzupvSA3ZJ0fGXsl.FgsxcRlvL d3ucfhi1P6X5Nqeah3AWdHpfXVcMgeRJGBTPXuGH2U2gMmnovMO0FsFiPxG5cSoSubEEdAhYx9hU gxF6JQ3drwWod1vpYfWoleIuNWU19UkOJlGjS27ouHBGfGmRStJ4itFBMWxvSe6otUu85wly8pFV 79B9r3atroMvfL3Gpy3ZSa0sL5qsDP55vqSNRBFx1Zse.Q.ZnQ7D.neuaMKXZeZ_CprGav6HYKlC j2LydYkt27aNL5zBZ3eLYRJoh7STONAwUchL1c3LyF8dxrZ2kfyX.nk4cQJX503IWqjbQQSIhTal iRSprUB.rdKirmG8PF7XaafXWcEGpf3Uc3INgMQWVVK2DGNfDyIO3NC9oU9aMB36KrGKHTWxbeOU lQkPCJOGr1DpYzZgCvzjD_XsULqbRxX9jneR8iUScpuTKgBWCyX8aPoRkbGqKILIm8nuHWLQ4QNG nEZOskQHZXhYTE.4NkYr9p17PfSyvUSa_tjQCVKQnqizzqSTvIxr6lawVoOAxvUikPW7fRvRArAh vI2NpcqtkB1hzvFGczlAaxzCWHs_yVFh9AHHDjkOAMbU75TMwdfBwLtKTo.KoJetxJwymGd7c._Q M7_gF_DkcfAH7EyGjkSI6.Jp9LqLmPIn889oeUsAgV9FZW4ypQMON4XLbDFpL8a.GhGmci9Wnn9J e8apEYiNvqFhVA4SUGg3PGnmf0c4JLCJhP4GtJiFeFw-- X-Sonic-MF: X-Sonic-ID: 38b610df-d9de-4440-891e-36a6213e9dca Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ir2.yahoo.com with HTTP; Sat, 17 Jan 2026 13:55:19 +0000 Received: by hermes--production-ir2-6fcf857f6f-68cr8 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 1ab9324439058ba9e338fb11da35c341; Sat, 17 Jan 2026 13:55:15 +0000 (UTC) From: Hannes Domani To: gdb-patches@sourceware.org Subject: [PATCH v2 06/11] Move x86 register code into x86-windows-nat.c Date: Sat, 17 Jan 2026 14:54:29 +0100 Message-ID: <20260117135448.2666604-6-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 --- gdb/windows-nat.c | 144 ++---------------------------------------- gdb/windows-nat.h | 29 +++++++-- gdb/x86-windows-nat.c | 137 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 163 insertions(+), 147 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index e1da956b125..926b85d479b 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -57,9 +57,6 @@ #include "xml-support.h" #include "inttypes.h" -#include "i386-tdep.h" -#include "i387-tdep.h" - #include "windows-tdep.h" #include "windows-nat.h" #include "complaints.h" @@ -389,79 +386,6 @@ windows_nat_target::delete_thread (ptid_t ptid, DWORD exit_code, windows_process->thread_list.erase (iter); } -/* Fetches register number R from the given windows_thread_info, - and supplies its value to the given regcache. - - This function assumes that R is non-negative. A failed assertion - is raised if that is not true. - - This function assumes that TH->RELOAD_CONTEXT is not set, meaning - that the windows_thread_info has an up-to-date context. A failed - assertion is raised if that assumption is violated. */ - -static void -windows_fetch_one_register (struct regcache *regcache, - windows_thread_info *th, int r) -{ - gdb_assert (r >= 0); - gdb_assert (!th->reload_context); - - char *context_ptr = windows_process->with_context (th, [] (auto *context) - { - return (char *) context; - }); - - char *context_offset = context_ptr + windows_process->mappings[r]; - struct gdbarch *gdbarch = regcache->arch (); - i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - - gdb_assert (!gdbarch_read_pc_p (gdbarch)); - gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0); - gdb_assert (!gdbarch_write_pc_p (gdbarch)); - - /* GDB treats some registers as 32-bit, where they are in fact only - 16 bits long. These cases must be handled specially to avoid - reading extraneous bits from the context. */ - if (r == I387_FISEG_REGNUM (tdep) || windows_process->segment_register_p (r)) - { - gdb_byte bytes[4] = {}; - memcpy (bytes, context_offset, 2); - regcache->raw_supply (r, bytes); - } - else if (r == I387_FOP_REGNUM (tdep)) - { - long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); - regcache->raw_supply (r, &l); - } - else - { - if (th->stopped_at_software_breakpoint - && !th->pc_adjusted - && r == gdbarch_pc_regnum (gdbarch)) - { - int size = register_size (gdbarch, r); - if (size == 4) - { - uint32_t value; - memcpy (&value, context_offset, size); - value -= gdbarch_decr_pc_after_break (gdbarch); - memcpy (context_offset, &value, size); - } - else - { - gdb_assert (size == 8); - uint64_t value; - memcpy (&value, context_offset, size); - value -= gdbarch_decr_pc_after_break (gdbarch); - memcpy (context_offset, &value, size); - } - /* Make sure we only rewrite the PC a single time. */ - th->pc_adjusted = true; - } - regcache->raw_supply (r, context_offset); - } -} - void windows_nat_target::fetch_registers (struct regcache *regcache, int r) { @@ -482,51 +406,9 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r) if (r < 0) for (r = 0; r < gdbarch_num_regs (regcache->arch()); r++) - windows_fetch_one_register (regcache, th, r); - else - windows_fetch_one_register (regcache, th, r); -} - -/* Collect the register number R from the given regcache, and store - its value into the corresponding area of the given thread's context. - - This function assumes that R is non-negative. A failed assertion - assertion is raised if that is not true. */ - -static void -windows_store_one_register (const struct regcache *regcache, - windows_thread_info *th, int r) -{ - gdb_assert (r >= 0); - - char *context_ptr = windows_process->with_context (th, [] (auto *context) - { - return (char *) context; - }); - - struct gdbarch *gdbarch = regcache->arch (); - i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - - /* GDB treats some registers as 32-bit, where they are in fact only - 16 bits long. These cases must be handled specially to avoid - overwriting other registers in the context. */ - if (r == I387_FISEG_REGNUM (tdep) || windows_process->segment_register_p (r)) - { - gdb_byte bytes[4]; - regcache->raw_collect (r, bytes); - memcpy (context_ptr + windows_process->mappings[r], bytes, 2); - } - else if (r == I387_FOP_REGNUM (tdep)) - { - gdb_byte bytes[4]; - regcache->raw_collect (r, bytes); - /* The value of FOP occupies the top two bytes in the context, - so write the two low-order bytes from the cache into the - appropriate spot. */ - memcpy (context_ptr + windows_process->mappings[r] + 2, bytes, 2); - } + fetch_one_register (regcache, th, r); else - regcache->raw_collect (r, context_ptr + windows_process->mappings[r]); + fetch_one_register (regcache, th, r); } /* Store a new register value into the context of the thread tied to @@ -545,9 +427,9 @@ windows_nat_target::store_registers (struct regcache *regcache, int r) if (r < 0) for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++) - windows_store_one_register (regcache, th, r); + store_one_register (regcache, th, r); else - windows_store_one_register (regcache, th, r); + store_one_register (regcache, th, r); } bool @@ -1472,7 +1354,7 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching) { struct inferior *inf; - initialize_windows_arch (); + initialize_windows_arch (attaching); windows_process->last_sig = GDB_SIGNAL_0; windows_process->open_process_used = 0; @@ -1490,22 +1372,6 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching) clear_proceed_status (0); init_wait_for_inferior (); -#ifdef __x86_64__ - windows_process->ignore_first_breakpoint - = !attaching && windows_process->wow64_process; - - if (!windows_process->wow64_process) - { - windows_process->mappings = amd64_mappings; - windows_process->segment_register_p = amd64_windows_segment_register_p; - } - else -#endif - { - windows_process->mappings = i386_mappings; - windows_process->segment_register_p = i386_windows_segment_register_p; - } - inferior_appeared (inf, pid); inf->attach_flag = attaching; diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h index 6553052f420..df872907535 100644 --- a/gdb/windows-nat.h +++ b/gdb/windows-nat.h @@ -83,10 +83,6 @@ struct windows_per_inferior : public windows_nat::windows_process_info const int *mappings = nullptr; - /* The function to use in order to determine whether a register is - a segment register or not. */ - segment_register_p_ftype *segment_register_p = nullptr; - std::vector solibs; #ifdef __CYGWIN__ @@ -184,8 +180,9 @@ struct windows_nat_target : public inf_child_target protected: /* Initialize arch-specific data for a new inferior (debug registers, - register mappings). */ - virtual void initialize_windows_arch () = 0; + register mappings). If ATTACHING is true, we're attaching to an + already-running process. */ + virtual void initialize_windows_arch (bool attaching) = 0; /* Cleanup arch-specific data after inferior exit. */ virtual void cleanup_windows_arch () = 0; @@ -198,6 +195,26 @@ struct windows_nat_target : public inf_child_target /* Set the stepping bit in the thread context. */ virtual void thread_context_step (windows_thread_info *th) = 0; + /* Fetches register number R from the given windows_thread_info, + and supplies its value to the given regcache. + + This function assumes that R is non-negative. A failed assertion + is raised if that is not true. + + This function assumes that TH->RELOAD_CONTEXT is not set, meaning + that the windows_thread_info has an up-to-date context. A failed + assertion is raised if that assumption is violated. */ + virtual void fetch_one_register (struct regcache *regcache, + windows_thread_info *th, int r) = 0; + + /* Collect the register number R from the given regcache, and store + its value into the corresponding area of the given thread's context. + + This function assumes that R is non-negative. A failed assertion + assertion is raised if that is not true. */ + virtual void store_one_register (const struct regcache *regcache, + windows_thread_info *th, int r) = 0; + private: windows_thread_info *add_thread (ptid_t ptid, HANDLE h, void *tlb, diff --git a/gdb/x86-windows-nat.c b/gdb/x86-windows-nat.c index 88844e0675a..96dd61b39fb 100644 --- a/gdb/x86-windows-nat.c +++ b/gdb/x86-windows-nat.c @@ -23,6 +23,9 @@ #include "x86-nat.h" +#include "i386-tdep.h" +#include "i387-tdep.h" + using namespace windows_nat; /* If we're not using the old Cygwin header file set, define the @@ -53,17 +56,26 @@ check (BOOL ok, const char *file, int line) struct x86_windows_per_inferior : public windows_per_inferior { uintptr_t dr[8] {}; + + /* The function to use in order to determine whether a register is + a segment register or not. */ + segment_register_p_ftype *segment_register_p = nullptr; }; struct x86_windows_nat_target final : public x86_nat_target { - void initialize_windows_arch () 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; }; /* The current process. */ @@ -72,9 +84,25 @@ static x86_windows_per_inferior x86_windows_process; /* See windows-nat.h. */ void -x86_windows_nat_target::initialize_windows_arch () +x86_windows_nat_target::initialize_windows_arch (bool attaching) { memset (x86_windows_process.dr, 0, sizeof (x86_windows_process.dr)); + +#ifdef __x86_64__ + x86_windows_process.ignore_first_breakpoint + = !attaching && x86_windows_process.wow64_process; + + if (!x86_windows_process.wow64_process) + { + x86_windows_process.mappings = amd64_mappings; + x86_windows_process.segment_register_p = amd64_windows_segment_register_p; + } + else +#endif + { + x86_windows_process.mappings = i386_mappings; + x86_windows_process.segment_register_p = i386_windows_segment_register_p; + } } /* See windows-nat.h. */ @@ -158,6 +186,111 @@ x86_windows_nat_target::thread_context_step (windows_thread_info *th) }); } +/* See windows-nat.h. */ + +void +x86_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 = x86_windows_process.with_context (th, [] (auto *context) + { + return (char *) context; + }); + + char *context_offset = context_ptr + x86_windows_process.mappings[r]; + struct gdbarch *gdbarch = regcache->arch (); + i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + gdb_assert (!gdbarch_read_pc_p (gdbarch)); + gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0); + gdb_assert (!gdbarch_write_pc_p (gdbarch)); + + /* GDB treats some registers as 32-bit, where they are in fact only + 16 bits long. These cases must be handled specially to avoid + reading extraneous bits from the context. */ + if (r == I387_FISEG_REGNUM (tdep) + || x86_windows_process.segment_register_p (r)) + { + gdb_byte bytes[4] = {}; + memcpy (bytes, context_offset, 2); + regcache->raw_supply (r, bytes); + } + else if (r == I387_FOP_REGNUM (tdep)) + { + long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + regcache->raw_supply (r, &l); + } + else + { + if (th->stopped_at_software_breakpoint + && !th->pc_adjusted + && r == gdbarch_pc_regnum (gdbarch)) + { + int size = register_size (gdbarch, r); + if (size == 4) + { + uint32_t value; + memcpy (&value, context_offset, size); + value -= gdbarch_decr_pc_after_break (gdbarch); + memcpy (context_offset, &value, size); + } + else + { + gdb_assert (size == 8); + uint64_t value; + memcpy (&value, context_offset, size); + value -= gdbarch_decr_pc_after_break (gdbarch); + memcpy (context_offset, &value, size); + } + /* 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 +x86_windows_nat_target::store_one_register (const struct regcache *regcache, + windows_thread_info *th, int r) +{ + gdb_assert (r >= 0); + + char *context_ptr = x86_windows_process.with_context (th, [] (auto *context) + { + return (char *) context; + }); + + struct gdbarch *gdbarch = regcache->arch (); + i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* GDB treats some registers as 32-bit, where they are in fact only + 16 bits long. These cases must be handled specially to avoid + overwriting other registers in the context. */ + if (r == I387_FISEG_REGNUM (tdep) + || x86_windows_process.segment_register_p (r)) + { + gdb_byte bytes[4]; + regcache->raw_collect (r, bytes); + memcpy (context_ptr + x86_windows_process.mappings[r], bytes, 2); + } + else if (r == I387_FOP_REGNUM (tdep)) + { + gdb_byte bytes[4]; + regcache->raw_collect (r, bytes); + /* The value of FOP occupies the top two bytes in the context, + so write the two low-order bytes from the cache into the + appropriate spot. */ + memcpy (context_ptr + x86_windows_process.mappings[r] + 2, bytes, 2); + } + else + regcache->raw_collect (r, context_ptr + x86_windows_process.mappings[r]); +} + /* Hardware watchpoint support, adapted from go32-nat.c code. */ /* Pass the address ADDR to the inferior in the I'th debug register. -- 2.52.0