From patchwork Sat Nov 2 02:56:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 840281 Delivered-To: patch@linaro.org Received: by 2002:adf:a38c:0:b0:37d:45d0:187 with SMTP id l12csp1158778wrb; Fri, 1 Nov 2024 20:00:17 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUwk8lBPi/Id0UFmmqGDiqoUcwUxm0FOWUod5rx1Qw9vKDRkTGt+xGiMHCpGqmRtEP8e7/6Rw==@linaro.org X-Google-Smtp-Source: AGHT+IFgi8jM9pHolXVZUZuQHHaEChGBCYEfjgf263fePo0KhVqerODGdjD5eaZRFpTOCNeLELt1 X-Received: by 2002:a05:620a:4504:b0:7af:c818:bdd with SMTP id af79cd13be357-7b193f5c275mr3721756485a.53.1730516417185; Fri, 01 Nov 2024 20:00:17 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1730516417; cv=pass; d=google.com; s=arc-20240605; b=dAKsuJmKSH7Pz65xeuz7T+jZRFTyCShNP9qq8uPqweoaxi5ZlbxHetoCdm9FGEYlMC tdfCaaUWyFcV39aYRqaZvjvwn9utinhj2sfTnImV3r5FvfkUpVPtB940suPH51f6PZyn 06SfFc/IwLwHdQ8Rp0/QebhGCzRpZRYAMzEmcTXLxWinSFXOAXa2deKpQ+xeQQ5IxuEP pSoqFWYJR26vHBmTHDJiPhFenxa49gh3e/3Kq/HmJ+Lp7AKEcCjsJ8AKQGX6xwXTBD+Q jg3G2bItM2NZ6RZBKOezReM82H57za0r49V41mXHj9zm7aIx6Wg1M58O+OIIbqrUOrs1 Gv9g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=TjpzGrnsL13WQqOD4TM0r4eNciZz8ObLqi+8sGv2Dyw=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=L5CxroFgSGCYeKtpf9JxkCfNLqEXuW4or4YOOCfAdswr/yaxGOd6apSwDryUIX2XjN Uu2qPJ1nUs5HiWZvxFW7oZNHpBu7Elkwc8VIN93oB1AyF1clmqubFiYPqXt8N3HzHAGR FnJrNk4wEoSqxyxDffZZ+cgRL5I0/Q08K4Jox7QeUza8kmfJKvCHKOemoeIzrSZyNfkr voT4PTwmrRMkSzO7RukQcHmlPpDbPs60ayEa/1ZWwEQEfIwkmsHP7ebtlsB6GbjigMN/ Lu7I0BdL41UW7sFimRYE7q8I3dZHo0/RMgR+nCxQ6wvfgQuIxZayOemrtQVubSLOew0K bl7A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Co/6hSVz"; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id af79cd13be357-7b2f3a811f8si587697985a.320.2024.11.01.20.00.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2024 20:00:17 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Co/6hSVz"; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5F9993857C5D for ; Sat, 2 Nov 2024 03:00:15 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id 394703857C68 for ; Sat, 2 Nov 2024 02:57:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 394703857C68 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 394703857C68 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::532 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730516238; cv=none; b=r/sevi9juIIoKEzrnZaRRJ43N5uiqkZQckh2dJWN+XIK72MHF7vVCacKVZY9gHOdF63zvsnUGGKLDCqb784v8e1mmv2sN5Z/0IG+bS9ps74XfZSe3XKleJCOKdjeSBhr+x42jNsaD4ABQWo0wHPLx2/WTkMoiRZhAjLWC6AiYK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730516238; c=relaxed/simple; bh=QRyiiwAfnrp3RXmn9bNNjY/up8oxDSwToSUC3yoyYvM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DTWXRoqAUIL0BFNdJ5qsX6sNsra2tFKUkzMVQvuqapk9PWfo+oANyepFxGwH0nor4zINbjdhRo2gKdnf+SY1L4jnDJKvk9pYynmlsQZXj8f26pLUf5U6GwEJTnYqdoh28ZaD59JBOLgogTRlKo6kgEtAe8U6v6G1szQR+YJtgtU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pg1-x532.google.com with SMTP id 41be03b00d2f7-7eab7622b61so2021567a12.1 for ; Fri, 01 Nov 2024 19:57:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1730516231; x=1731121031; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=TjpzGrnsL13WQqOD4TM0r4eNciZz8ObLqi+8sGv2Dyw=; b=Co/6hSVz2mY5IhrGDhhSpRwbnRLAH9E0XPzJxvhlAFuYMrwvKeimPKgGowNCvoGghu 0faQqbeg/M2ytjrGhOxC1it+y+JIwrXezwKVM226iYIDhQ1j6WZK+XhvZMs6YMw231Ki cxeUNA3YK7KBYu1B7gTGKkp4WncNT2nBvNL5uEJVlnC8zoZ+5PzNZjdy11Tg+Z56rqJC 0PLcswTtljI4cafgJeqYyBn1Qd89Aa8KAbfOYzJHmZhKUYIgm85vEQCXla1jDQNf+KD9 oKzvpF5ohgf2P0GOhUNxdjngla/IwqSIrkxBy1MBeLxdY1GfoOPNjz5vEMsPLJFetDjV ZYKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730516231; x=1731121031; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TjpzGrnsL13WQqOD4TM0r4eNciZz8ObLqi+8sGv2Dyw=; b=qRP8PX01Yu6rhkplrvQR/9HU9ovTROAK3/dRjSaaMoGwcoNhk5Hk90oMNMoY8eVEL7 VhbDbJhsy6sSskICjKlbgNLqmvy4OKxiE1SHAoZyuaLc5sWkf2qEGgzIAmf97aebRmNS us9TWt/PULQEaYlc+WTzAzH4tE3wzaWYThRcqiZV0hHAjWolUfxyXKtcMVebAVzEyit/ /JjACBP2EeQLK18bpv/r8qnpVIfq6nn5XYaNmGIw1GE4t+KUkOqXqsqnTm4bPY3qTcqG VRcPy+TkDVR3bAhTObOFNe3HoT1m7UpXIjlfEsLxTwqUN0qfJF41C7FCXtVPw3G1901k z9Kg== X-Gm-Message-State: AOJu0YwjNo9tTOd4n4N01QgBsQKw/58kXQQ/3JYoXzaZEWAoCJrxa7pY o353W6Wq68u/Igmt5Ziy36Jk3xMitDF+7E1dBn7Qb+Tmb+H6z86S1+NmVMOXAPjSblSJujYfoIU W X-Received: by 2002:a05:6a21:1796:b0:1d8:a1dc:b43 with SMTP id adf61e73a8af0-1d9a8402d85mr35656025637.24.1730516230658; Fri, 01 Nov 2024 19:57:10 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:f214:b4dc:314a:c1ee]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-720bc31874bsm3353844b3a.213.2024.11.01.19.57.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2024 19:57:10 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Subject: [RFC PATCH v4 10/15] GDB: Add concept of variable-size registers to the regcache Date: Fri, 1 Nov 2024 23:56:30 -0300 Message-ID: <20241102025635.586759-11-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241102025635.586759-1-thiago.bauermann@linaro.org> References: <20241102025635.586759-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org The contents of variable-size registers are placed in a separate buffer, because their size will only be known a while after the buffer is created but some fixed-size registers (particularly the program counter) need to be stored or fetched before then. This is also why the state related to variable-size registers is lazily initialised at the moment it's first needed (by calling the initialize_variable_size_registers () method). Simon suggested placing the variable-size registers at the end of the existing contents buffer to avoid having to use a separate one. I will experiment with that idea and see if it simplifies the code. The regcache now also stores the resolved type and size of the variable-size registers. Some places needed to be changed from calling the register_size () function to calling the register_size () method instead, because they may call them for variable-size registers. The frame-unwinding code doesn't have a regcache readily available, so the register_size () function is changed to optionally accept a frame_info_ptr which it uses to create a readonly_detached_regcache. When debugging a remote target, if the regcache has variable-size registers the maximum packet size may change with new values of expedited registers. Therefore, update the maximum packet size when expedited registers are supplied, or load-early registers are fetched. Finally, there are FIXMEs related to the const_casts needed to remove the const from the "this" pointer when calling reg_buffer::initialize_variable_size_registers (). I'm still thinking about what to do with them. I tried the simple solution of changing the calling methods to be non-const, but the change escalates quickly. --- gdb/aarch64-tdep.c | 9 +- gdb/eval.c | 13 ++- gdb/findvar.c | 5 +- gdb/frame.c | 45 +++++--- gdb/record-full.c | 3 +- gdb/regcache.c | 269 +++++++++++++++++++++++++++++++++++++-------- gdb/regcache.h | 39 ++++++- gdb/remote.c | 62 +++++++++-- gdb/value.c | 16 ++- gdbsupport/tdesc.h | 4 +- 10 files changed, 377 insertions(+), 88 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 8a2a9b1e23c1..04442f22ea3f 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1728,7 +1728,7 @@ pass_in_v (struct gdbarch *gdbarch, { int regnum = AARCH64_V0_REGNUM + info->nsrn; /* Enough space for a full vector register. */ - gdb::byte_vector reg (register_size (gdbarch, regnum), 0); + gdb::byte_vector reg (regcache->register_size (regnum), 0); gdb_assert (len <= reg.size ()); info->argnum++; @@ -2543,7 +2543,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, { int regno = AARCH64_V0_REGNUM + i; /* Enough space for a full vector register. */ - gdb::byte_vector buf (register_size (gdbarch, regno)); + gdb::byte_vector buf (regs->register_size (regno)); gdb_assert (len <= buf.size ()); aarch64_debug_printf @@ -2657,7 +2657,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, { int regno = AARCH64_V0_REGNUM + i; /* Enough space for a full vector register. */ - gdb::byte_vector tmpbuf (register_size (gdbarch, regno)); + gdb::byte_vector tmpbuf (regs->register_size (regno)); gdb_assert (len <= tmpbuf.size ()); aarch64_debug_printf @@ -3308,7 +3308,8 @@ aarch64_pseudo_write_1 (gdbarch *gdbarch, const frame_info_ptr &next_frame, various 'scalar' pseudo registers to behavior like architectural writes, register width bytes are written the remainder are set to zero. */ - gdb::byte_vector raw_buf (register_size (gdbarch, raw_regnum), 0); + int raw_reg_size = register_size (gdbarch, raw_regnum, &next_frame); + gdb::byte_vector raw_buf (raw_reg_size, 0); static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); gdb::array_view raw_view (raw_buf); diff --git a/gdb/eval.c b/gdb/eval.c index 457a4362289d..9f20ec557db3 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1151,13 +1151,14 @@ eval_op_register (struct type *expect_type, struct expression *exp, if (regno == -1) error (_("Register $%s not available."), name); - /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return - a value with the appropriate register type. Unfortunately, - we don't have easy access to the type of user registers. - So for these registers, we fetch the register value regardless - of the evaluation mode. */ + /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return a value with + the appropriate register type. Unfortunately, we don't have easy + access to the type of user registers and variable-size registers. So + for these registers, we fetch the register value regardless of the + evaluation mode. */ if (noside == EVAL_AVOID_SIDE_EFFECTS - && regno < gdbarch_num_cooked_regs (exp->gdbarch)) + && regno < gdbarch_num_cooked_regs (exp->gdbarch) + && !register_is_variable_size (exp->gdbarch, regno)) val = value::zero (register_type (exp->gdbarch, regno), not_lval); else val = value_of_register diff --git a/gdb/findvar.c b/gdb/findvar.c index d65bf2fc278c..1ecfd3558383 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -562,11 +562,12 @@ read_frame_register_value (value *value) LONGEST reg_offset = value->offset (); int regnum = value->regnum (); int len = type_length_units (check_typedef (value->type ())); + int reg_size = register_size (gdbarch, regnum, &next_frame); /* Skip registers wholly inside of REG_OFFSET. */ - while (reg_offset >= register_size (gdbarch, regnum)) + while (reg_offset >= reg_size) { - reg_offset -= register_size (gdbarch, regnum); + reg_offset -= reg_size; regnum++; } diff --git a/gdb/frame.c b/gdb/frame.c index 663ff7fa773b..0f480ce75b09 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1322,12 +1322,24 @@ frame_unwind_register_value (const frame_info_ptr &next_frame, int regnum) gdb_printf (&debug_file, " lazy"); else if (value->entirely_available ()) { - int i; + int i, reg_size; gdb::array_view buf = value->contents (); gdb_printf (&debug_file, " bytes="); gdb_printf (&debug_file, "["); - for (i = 0; i < register_size (gdbarch, regnum); i++) + + if (register_is_variable_size (gdbarch, regnum)) + /* To get the size of a variable-size register, we need to + call frame_save_as_regcache () so that we can call + regcache::register_size (). Unfortunatlly the former + ends up calling this function so we enter into an + infinite recursion. So just assume that the value has + the correct size. */ + reg_size = buf.size (); + else + reg_size = register_size (gdbarch, regnum); + + for (i = 0; i < reg_size; i++) gdb_printf (&debug_file, "%02x", buf[i]); gdb_printf (&debug_file, "]"); } @@ -1446,7 +1458,7 @@ put_frame_register (const frame_info_ptr &next_frame, int regnum, int unavail; enum lval_type lval; CORE_ADDR addr; - int size = register_size (gdbarch, regnum); + int size = register_size (gdbarch, regnum, &next_frame); gdb_assert (buf.size () == size); @@ -1462,8 +1474,9 @@ put_frame_register (const frame_info_ptr &next_frame, int regnum, break; } case lval_register: - /* Not sure if that's always true... but we have a problem if not. */ - gdb_assert (size == register_size (gdbarch, realnum)); + if (regnum != realnum) + /* Not sure if that's always true... but we have a problem if not. */ + gdb_assert (size == register_size (gdbarch, realnum)); if (realnum < gdbarch_num_regs (gdbarch) || !gdbarch_pseudo_register_write_p (gdbarch)) @@ -1509,9 +1522,9 @@ get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, gdbarch *gdbarch = frame_unwind_arch (next_frame); /* Skip registers wholly inside of OFFSET. */ - while (offset >= register_size (gdbarch, regnum)) + while (offset >= register_size (gdbarch, regnum, &next_frame)) { - offset -= register_size (gdbarch, regnum); + offset -= register_size (gdbarch, regnum, &next_frame); regnum++; } @@ -1521,7 +1534,7 @@ get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, int numregs = gdbarch_num_cooked_regs (gdbarch); for (int i = regnum; i < numregs; i++) { - int thissize = register_size (gdbarch, i); + int thissize = register_size (gdbarch, i, &next_frame); if (thissize == 0) break; /* This register is not available on this architecture. */ @@ -1535,10 +1548,10 @@ get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, /* Copy the data. */ while (!buffer.empty ()) { - int curr_len = std::min (register_size (gdbarch, regnum) - offset, - buffer.size ()); + int reg_size = register_size (gdbarch, regnum, &next_frame); + int curr_len = std::min (reg_size - offset, buffer.size ()); - if (curr_len == register_size (gdbarch, regnum)) + if (curr_len == reg_size) { enum lval_type lval; CORE_ADDR addr; @@ -1586,19 +1599,19 @@ put_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, gdbarch *gdbarch = frame_unwind_arch (next_frame); /* Skip registers wholly inside of OFFSET. */ - while (offset >= register_size (gdbarch, regnum)) + while (offset >= register_size (gdbarch, regnum, &next_frame)) { - offset -= register_size (gdbarch, regnum); + offset -= register_size (gdbarch, regnum, &next_frame); regnum++; } /* Copy the data. */ while (!buffer.empty ()) { - int curr_len = std::min (register_size (gdbarch, regnum) - offset, - buffer.size ()); + int reg_size = register_size (gdbarch, regnum, &next_frame); + int curr_len = std::min (reg_size - offset, buffer.size ()); - if (curr_len == register_size (gdbarch, regnum)) + if (curr_len == reg_size) put_frame_register (next_frame, regnum, buffer.slice (0, curr_len)); else { diff --git a/gdb/record-full.c b/gdb/record-full.c index 8e4915abd083..0ce370ae32bf 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -399,12 +399,11 @@ static inline struct record_full_entry * record_full_reg_alloc (struct regcache *regcache, int regnum) { struct record_full_entry *rec; - struct gdbarch *gdbarch = regcache->arch (); rec = XCNEW (struct record_full_entry); rec->type = record_full_reg; rec->u.reg.num = regnum; - rec->u.reg.len = register_size (gdbarch, regnum); + rec->u.reg.len = regcache->register_size (regnum); if (rec->u.reg.len > sizeof (rec->u.reg.u.buf)) rec->u.reg.u.ptr = (gdb_byte *) xmalloc (rec->u.reg.len); diff --git a/gdb/regcache.c b/gdb/regcache.c index 61289d46f4b1..dfcfffb02aa0 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -51,7 +51,7 @@ struct regcache_descr redundant information - if the PC is constructed from two registers then those registers and not the PC lives in the raw cache. */ - long sizeof_raw_registers = 0; + long sizeof_fixed_size_raw_registers = 0; /* The cooked register space. Each cooked register in the range [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw @@ -60,7 +60,7 @@ struct regcache_descr both raw registers and memory by the architecture methods gdbarch_pseudo_register_read and gdbarch_pseudo_register_write. */ int nr_cooked_registers = 0; - long sizeof_cooked_registers = 0; + long sizeof_fixed_size_cooked_registers = 0; /* Offset and size (in 8 bit bytes), of each register in the register cache. All registers (including those in the range @@ -69,9 +69,16 @@ struct regcache_descr long *register_offset = nullptr; long *sizeof_register = nullptr; - /* Registers that need to be loaded early in the register cache. */ + /* Registers that need to be loaded early in the register cache, because + variable-size registers depend on them to calculate their size. */ std::set load_early_regs; + /* Vector indicating whether a given register is variable-size. */ + bool *register_is_variable_size = nullptr; + + /* Does the regcache contains any variable-size register? */ + bool has_variable_size_registers = false; + /* Cached table containing the type of each register. */ struct type **register_type = nullptr; }; @@ -119,26 +126,52 @@ init_regcache_descr (struct gdbarch *gdbarch) = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); descr->register_offset = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long); + descr->register_is_variable_size + = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, bool); + for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { - descr->sizeof_register[i] = descr->register_type[i]->length (); - descr->register_offset[i] = offset; - offset += descr->sizeof_register[i]; + descr->register_is_variable_size[i] + = is_dynamic_type (descr->register_type[i]); + if (descr->register_is_variable_size[i]) + { + descr->sizeof_register[i] = -1; + descr->register_offset[i] = -1; + descr->has_variable_size_registers = true; + } + else + { + descr->sizeof_register[i] = descr->register_type[i]->length (); + descr->register_offset[i] = offset; + offset += descr->sizeof_register[i]; + } if (tdesc_register_is_early_load (gdbarch, i)) descr->load_early_regs.insert (i); } + /* Set the real size of the raw register cache buffer. */ - descr->sizeof_raw_registers = offset; + descr->sizeof_fixed_size_raw_registers = offset; for (; i < descr->nr_cooked_registers; i++) { - descr->sizeof_register[i] = descr->register_type[i]->length (); - descr->register_offset[i] = offset; - offset += descr->sizeof_register[i]; + descr->register_is_variable_size[i] + = is_dynamic_type (descr->register_type[i]); + if (descr->register_is_variable_size[i]) + { + descr->sizeof_register[i] = -1; + descr->register_offset[i] = -1; + descr->has_variable_size_registers = true; + } + else + { + descr->sizeof_register[i] = descr->register_type[i]->length (); + descr->register_offset[i] = offset; + offset += descr->sizeof_register[i]; + } } /* Set the real size of the readonly register cache buffer. */ - descr->sizeof_cooked_registers = offset; + descr->sizeof_fixed_size_cooked_registers = offset; } return descr; @@ -160,27 +193,60 @@ regcache_descr (struct gdbarch *gdbarch) /* Utility functions returning useful register attributes stored in the regcache descr. */ +/* See gdb/regcache.h. */ + struct type * register_type (struct gdbarch *gdbarch, int regnum) { struct regcache_descr *descr = regcache_descr (gdbarch); gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers); - return descr->register_type[regnum]; + + struct type *type = descr->register_type[regnum]; + + if (descr->register_is_variable_size[regnum]) + { + frame_info_ptr current_frame = get_current_frame (); + type = resolve_dynamic_type (type, {}, 0, ¤t_frame); + } + + return type; } -/* Utility functions returning useful register attributes stored in - the regcache descr. */ +/* See gdb/regcache.h. */ int -register_size (struct gdbarch *gdbarch, int regnum) +register_size (struct gdbarch *gdbarch, int regnum, + const frame_info_ptr *next_frame) { struct regcache_descr *descr = regcache_descr (gdbarch); - int size; - gdb_assert (regnum >= 0 && regnum < gdbarch_num_cooked_regs (gdbarch)); - size = descr->sizeof_register[regnum]; - return size; + gdb_assert (regnum >= 0); + gdb_assert (regnum < descr->nr_cooked_registers); + + if (descr->register_is_variable_size[regnum]) + { + gdb_assert (next_frame != nullptr); + + std::unique_ptr regcache = + frame_save_as_regcache (get_prev_frame (*next_frame)); + return regcache->register_size (regnum); + } + + return descr->sizeof_register[regnum]; +} + +/* See gdb/regcache.h. */ + +bool +register_is_variable_size (struct gdbarch *gdbarch, int regnum) +{ + struct regcache_descr *descr = regcache_descr (gdbarch); + + gdb_assert (regnum >= 0); + gdb_assert (regnum < descr->nr_cooked_registers); + + return descr->register_is_variable_size[regnum]; } /* See gdbsupport/common-regcache.h. */ @@ -188,7 +254,47 @@ register_size (struct gdbarch *gdbarch, int regnum) int reg_buffer::register_size (int regnum) const { - return ::register_size (this->arch (), regnum); + gdb_assert (regnum >= 0); + gdb_assert (regnum < m_descr->nr_cooked_registers); + + int size; + + if (m_descr->register_is_variable_size[regnum]) + { + if (!m_variable_size_registers) + const_cast (this) + ->initialize_variable_size_registers (); // FIXME: Remove cast. + + size = m_variable_size_register_sizeof[regnum]; + } + else + size = m_descr->sizeof_register[regnum]; + + return size; +} + +/* See gdb/regcache.h. */ + +struct type * +reg_buffer::register_type (int regnum) const +{ + gdb_assert (regnum >= 0); + gdb_assert (regnum < m_descr->nr_cooked_registers); + + struct type *type; + + if (m_descr->register_is_variable_size[regnum]) + { + if (!m_variable_size_registers) + const_cast (this) + ->initialize_variable_size_registers (); // FIXME: Remove cast. + + type = m_variable_size_register_type[regnum]; + } + else + type = m_descr->register_type[regnum]; + + return type; } reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo) @@ -202,13 +308,13 @@ reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo) REG_VALID. */ if (has_pseudo) { - m_registers.reset (new gdb_byte[m_descr->sizeof_cooked_registers]); + m_fixed_size_registers.reset (new gdb_byte[m_descr->sizeof_fixed_size_cooked_registers]); m_register_status.reset (new register_status[m_descr->nr_cooked_registers] ()); } else { - m_registers.reset (new gdb_byte[m_descr->sizeof_raw_registers]); + m_fixed_size_registers.reset (new gdb_byte[m_descr->sizeof_fixed_size_raw_registers]); m_register_status.reset (new register_status[gdbarch_num_regs (gdbarch)] ()); } @@ -237,9 +343,6 @@ reg_buffer::arch () const return m_descr->gdbarch; } -/* Utility functions returning useful register attributes stored in - the regcache descr. */ - /* See regcache.h. */ bool @@ -281,6 +384,55 @@ reg_buffer::load_early_registers () return m_descr->load_early_regs; } +/* See regcache.h. */ + +void +reg_buffer::initialize_variable_size_registers () +{ + unsigned long total_size = 0; + + /* We need load early registers to resolve types of variable-size + registers. */ + if (!this->fetch_load_early_registers ()) + error (_("Missing register contents for variable-size registers.")); + + m_variable_size_register_type.resize (m_descr->nr_cooked_registers); + m_variable_size_register_sizeof.resize (m_descr->nr_cooked_registers); + m_variable_size_register_offset.resize (m_descr->nr_cooked_registers); + + for (unsigned int i = 0; i < m_descr->nr_cooked_registers; i++) + { + if (!m_descr->register_is_variable_size[i]) + { + m_variable_size_register_type[i] = nullptr; + m_variable_size_register_sizeof[i] = -1; + m_variable_size_register_offset[i] = -1; + continue; + } + + m_variable_size_register_type[i] + = resolve_dynamic_type (m_descr->register_type[i], {}, + /* Unused address. */ 0, nullptr, this); + + ULONGEST size = m_variable_size_register_type[i]->length (); + gdb_assert (size != 0); + m_variable_size_register_sizeof[i] = size; + m_variable_size_register_offset[i] = total_size; + m_register_status[i] = REG_UNKNOWN; + total_size += size; + } + + m_variable_size_registers.reset (new gdb_byte[total_size]); +} + +/* See regcache.h. */ + +bool +reg_buffer::has_variable_size_registers () +{ + return m_descr->has_variable_size_registers; +} + /* Helper for reg_buffer::register_buffer. */ template @@ -288,8 +440,19 @@ gdb::array_view reg_buffer::register_buffer (int regnum) const { assert_regnum (regnum); - ElemType *start = &m_registers[m_descr->register_offset[regnum]]; - int size = m_descr->sizeof_register[regnum]; + ElemType *start; + + if (m_descr->register_is_variable_size[regnum]) + { + if (!m_variable_size_registers) + const_cast(this)->initialize_variable_size_registers (); // FIXME: Remove cast. + + start = &m_variable_size_registers[m_variable_size_register_offset[regnum]]; + } + else + start = &m_fixed_size_registers[m_descr->register_offset[regnum]]; + + int size = register_size (regnum); return gdb::array_view (start, size); } @@ -317,9 +480,14 @@ reg_buffer::save (register_read_ftype cooked_read) /* It should have pseudo registers. */ gdb_assert (m_has_pseudo); /* Clear the dest. */ - memset (m_registers.get (), 0, m_descr->sizeof_cooked_registers); + memset (m_fixed_size_registers.get (), 0, m_descr->sizeof_fixed_size_cooked_registers); memset (m_register_status.get (), REG_UNKNOWN, m_descr->nr_cooked_registers); + /* For data related to variable-size registers, we only need to reset + their buffer at this point. Other data will be resized/re-set by + initialize_variable_size_registers (). */ + m_variable_size_registers.reset (); + /* Save load early registers first. */ for (int regnum : m_descr->load_early_regs) { @@ -379,6 +547,12 @@ regcache::restore (readonly_detached_regcache *src) continue; cooked_write (regnum, src->register_buffer (regnum)); + + if (m_variable_size_registers) + /* For data related to variable-size registers, we only need to reset + their buffer at this point. Other data will be resized/re-set by + initialize_variable_size_registers (). */ + m_variable_size_registers.reset (); } /* Copy over any registers, being careful to only restore those that @@ -709,7 +883,7 @@ register_status readable_regcache::raw_read (int regnum, gdb::array_view dst) { assert_regnum (regnum); - gdb_assert (dst.size () == m_descr->sizeof_register[regnum]); + gdb_assert (dst.size () == register_size (regnum)); raw_update (regnum); @@ -725,7 +899,7 @@ register_status readable_regcache::raw_read (int regnum, gdb_byte *dst) { assert_regnum (regnum); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); return raw_read (regnum, gdb::make_array_view (dst, size)); } @@ -741,7 +915,7 @@ enum register_status readable_regcache::raw_read (int regnum, T *val) { assert_regnum (regnum); - size_t size = m_descr->sizeof_register[regnum]; + size_t size = register_size (regnum); gdb_byte *buf = (gdb_byte *) alloca (size); auto view = gdb::make_array_view (buf, size); register_status status = raw_read (regnum, view); @@ -776,7 +950,7 @@ regcache::raw_write (int regnum, T val) { assert_regnum (regnum); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); gdb_byte *buf = (gdb_byte *) alloca (size); auto view = gdb::make_array_view (buf, size); store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val); @@ -815,7 +989,7 @@ readable_regcache::cooked_read (int regnum, gdb::array_view dst) if (regnum < num_raw_registers ()) return raw_read (regnum, dst); - gdb_assert (dst.size () == m_descr->sizeof_register[regnum]); + gdb_assert (dst.size () == register_size (regnum)); if (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN) { @@ -857,7 +1031,7 @@ readable_regcache::cooked_read (int regnum, gdb_byte *dst) gdb_assert (regnum >= 0); gdb_assert (regnum < m_descr->nr_cooked_registers); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); return cooked_read (regnum, gdb::make_array_view (dst, size)); } @@ -871,8 +1045,12 @@ readable_regcache::cooked_read_value (int regnum) || (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN) || !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch)) { + /* Provide the register type if its size is fixed to avoid infinite + recursion in the case of variable-size registers. */ + struct type *type = (m_descr->register_is_variable_size[regnum] ? + nullptr : m_descr->register_type[regnum]); value *result = value::allocate_register - (get_next_frame_sentinel_okay (get_current_frame ()), regnum); + (get_next_frame_sentinel_okay (get_current_frame ()), regnum, type); /* It is more efficient in general to do this delegation in this direction than in the other one, even though the value-based @@ -902,7 +1080,7 @@ enum register_status readable_regcache::cooked_read (int regnum, T *val) { gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); - size_t size = m_descr->sizeof_register[regnum]; + size_t size = register_size (regnum); gdb_byte *buf = (gdb_byte *) alloca (size); auto view = gdb::make_array_view (buf, size); register_status status = cooked_read (regnum, view); @@ -936,7 +1114,7 @@ regcache::cooked_write (int regnum, T val) gdb_assert (regnum >= 0); gdb_assert (regnum < m_descr->nr_cooked_registers); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); gdb_byte *buf = (gdb_byte *) alloca (size); auto view = gdb::make_array_view (buf, size); store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val); @@ -955,7 +1133,7 @@ void regcache::raw_write (int regnum, gdb::array_view src) { assert_regnum (regnum); - gdb_assert (src.size () == m_descr->sizeof_register[regnum]); + gdb_assert (src.size () == register_size (regnum)); /* On the sparc, writing %g0 is a no-op, so we don't even want to change the registers array if something writes to this register. */ @@ -992,7 +1170,7 @@ regcache::raw_write (int regnum, const gdb_byte *src) { assert_regnum (regnum); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); raw_write (regnum, gdb::make_array_view (src, size)); } @@ -1023,7 +1201,7 @@ regcache::cooked_write (int regnum, const gdb_byte *src) gdb_assert (regnum >= 0); gdb_assert (regnum < m_descr->nr_cooked_registers); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); return cooked_write (regnum, gdb::make_array_view (src, size)); } @@ -1235,6 +1413,11 @@ reg_buffer::raw_supply (int regnum, gdb::array_view src) { copy (src, dst); m_register_status[regnum] = REG_VALID; + + if (this->is_load_early_register (regnum) + && memcmp (src.data (), dst.data (), dst.size ())) + /* Invalidate variable-size registers. */ + this->initialize_variable_size_registers (); } else { @@ -1253,7 +1436,7 @@ reg_buffer::raw_supply (int regnum, const void *src) { assert_regnum (regnum); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); raw_supply (regnum, gdb::make_array_view ((const gdb_byte *) src, size)); } @@ -1297,7 +1480,7 @@ reg_buffer::raw_collect (int regnum, void *dst) const { assert_regnum (regnum); - int size = m_descr->sizeof_register[regnum]; + int size = register_size (regnum); return raw_collect (regnum, gdb::make_array_view ((gdb_byte *) dst, size)); } @@ -1372,7 +1555,7 @@ regcache::transfer_regset (const struct regset *regset, int regbase, regno += regbase; if (slot_size == 0 && regno != REGCACHE_MAP_SKIP) - slot_size = m_descr->sizeof_register[regno]; + slot_size = register_size (regnum); if (regno == REGCACHE_MAP_SKIP || (regnum != -1 diff --git a/gdb/regcache.h b/gdb/regcache.h index 5c28fec4af11..6b6687b9f349 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -165,10 +165,15 @@ extern bool regcache_map_supplies (const struct regcache_map_entry *map, extern struct type *register_type (struct gdbarch *gdbarch, int regnum); -/* Return the size of register REGNUM. All registers should have only - one size. */ +/* Return the size of register REGNUM. FRAME is needed in case regnum is a + variable-size register. */ -extern int register_size (struct gdbarch *gdbarch, int regnum); +extern int register_size (struct gdbarch *gdbarch, int regnum, + const frame_info_ptr *next_frame = nullptr); + +/* Return whether REGNUM is a variable-size register. */ + +extern bool register_is_variable_size (struct gdbarch *gdbarch, int regnum); using register_read_ftype = gdb::function_view)>; @@ -266,6 +271,12 @@ class reg_buffer : public reg_buffer_common /* Return set of regnums which need to be loaded before other registers. */ const std::set &load_early_registers (); + /* Whether any register in this regcache has a dynamic type. */ + bool has_variable_size_registers (); + + /* Return type of register REGNUM. */ + struct type *register_type (int regnum) const; + /* See gdbsupport/common-regcache.h. */ int register_size (int regnum) const override; @@ -279,6 +290,10 @@ class reg_buffer : public reg_buffer_common Return false if they aren't. */ virtual bool fetch_load_early_registers (); + /* Initialize (or reset) information about variable-size registers in this + reg_buffer. */ + void initialize_variable_size_registers (); + /* Return a view on register REGNUM's buffer cache. */ template gdb::array_view register_buffer (int regnum) const; @@ -293,11 +308,25 @@ class reg_buffer : public reg_buffer_common struct regcache_descr *m_descr; bool m_has_pseudo; - /* The register buffers. */ - std::unique_ptr m_registers; + + /* The fixed-size register buffers. */ + std::unique_ptr m_fixed_size_registers; + + /* The variable-size register buffers (if any). */ + std::unique_ptr m_variable_size_registers; + /* Register cache status. */ std::unique_ptr m_register_status; + /* The resolved types for variable-size registers (if any). */ + std::vector m_variable_size_register_type; + + /* The size of resolved types for variable-size registers (if any). */ + std::vector m_variable_size_register_sizeof; + + /* The offset of resolved types for variable-size registers (if any). */ + std::vector m_variable_size_register_offset; + friend class regcache; friend class detached_regcache; }; diff --git a/gdb/remote.c b/gdb/remote.c index 0217c05bce52..0930977d4304 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -471,6 +471,8 @@ struct packet_reg at present. */ }; +struct remote_state; + struct remote_arch_state { explicit remote_arch_state (struct gdbarch *gdbarch); @@ -493,6 +495,10 @@ struct remote_arch_state /* This is the maximum size (in chars) of a non read/write packet. It is also used as a cap on the size of read/write packets. */ long remote_packet_size; + + /* Make sure the maximum packet size reflects current size of variable-size + registers. */ + void update_packet_size (const struct regcache *regcache, remote_state *rs); }; /* Description of the remote protocol state for the currently @@ -1897,7 +1903,8 @@ show_remote_exec_file (struct ui_file *file, int from_tty, } static int -map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) +map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs, + const struct regcache *regcache = nullptr) { int regnum, num_remote_regs, offset; struct packet_reg **remote_regs; @@ -1905,8 +1912,15 @@ map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++) { struct packet_reg *r = ®s[regnum]; + bool skip_register; - if (register_size (gdbarch, regnum) == 0) + if (regcache == nullptr) + skip_register = (register_is_variable_size (gdbarch, regnum) + || register_size (gdbarch, regnum) == 0); + else + skip_register = regcache->register_size (regnum) == 0; + + if (skip_register) /* Do not try to fetch zero-sized (placeholder) registers. */ r->pnum = -1; else @@ -1934,7 +1948,10 @@ map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs) { remote_regs[regnum]->in_g_packet = 1; remote_regs[regnum]->offset = offset; - offset += register_size (gdbarch, remote_regs[regnum]->regnum); + if (regcache == nullptr) + offset += register_size (gdbarch, remote_regs[regnum]->regnum); + else + offset += regcache->register_size (remote_regs[regnum]->regnum); } return offset; @@ -1995,6 +2012,29 @@ remote_arch_state::remote_arch_state (struct gdbarch *gdbarch) this->remote_packet_size = (this->sizeof_g_packet * 2 + 32); } +/* See remote_arch_state class declaration. */ + +void +remote_arch_state::update_packet_size (const struct regcache *regcache, + remote_state *rs) +{ + /* Record the maximum possible size of the g packet - it may turn out + to be smaller. */ + this->sizeof_g_packet + = map_regcache_remote_table (regcache->arch (), this->regs.get (), + regcache); + + this->remote_packet_size = 400 - 1; + + if (this->sizeof_g_packet > (this->remote_packet_size - 32) / 2) + this->remote_packet_size = this->sizeof_g_packet * 2 + 32; + + /* Make sure that the packet buffer is plenty big enough for + this architecture. */ + if (rs->buf.size () < this->remote_packet_size) + rs->buf.resize (2 * this->remote_packet_size); +} + /* Get a pointer to the current remote target. If not connected to a remote target, return NULL. */ @@ -8553,6 +8593,10 @@ remote_target::supply_expedited_regs (struct regcache *regcache, regcache->raw_supply (reg.num, reg.data); rs->last_seen_expedited_registers.insert (reg.num); } + + if (regcache->has_variable_size_registers ()) + get_remote_state ()->get_remote_arch_state (regcache->arch ()) + ->update_packet_size (regcache, &m_remote_state); } /* Called when it is decided that STOP_REPLY holds the info of the @@ -8979,6 +9023,9 @@ remote_target::fetch_early_registers (struct regcache *regcache) if (res == 0) error (_("Could not load early register %d using p packet."), regnum); } + + get_remote_state ()->get_remote_arch_state (regcache->arch ()) + ->update_packet_size (regcache, &m_remote_state); } /* Fetch the registers included in the target's 'g' packet. */ @@ -9054,7 +9101,7 @@ remote_target::process_g_packet (struct regcache *regcache) for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { long offset = rsa->regs[i].offset; - long reg_size = register_size (gdbarch, i); + long reg_size = regcache->register_size (i); if (rsa->regs[i].pnum == -1) continue; @@ -9102,7 +9149,7 @@ remote_target::process_g_packet (struct regcache *regcache) for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { struct packet_reg *r = &rsa->regs[i]; - long reg_size = register_size (gdbarch, i); + long reg_size = regcache->register_size (i); if (r->in_g_packet) { @@ -9240,7 +9287,8 @@ remote_target::store_register_using_P (const struct regcache *regcache, struct remote_state *rs = get_remote_state (); /* Try storing a single register. */ char *buf = rs->buf.data (); - gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum)); + int reg_size = regcache->register_size (reg->regnum); + gdb_byte *regp = (gdb_byte *) alloca (reg_size); char *p; if (m_features.packet_support (PACKET_P) == PACKET_DISABLE) @@ -9252,7 +9300,7 @@ remote_target::store_register_using_P (const struct regcache *regcache, xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0)); p = buf + strlen (buf); regcache->raw_collect (reg->regnum, regp); - bin2hex (regp, p, register_size (gdbarch, reg->regnum)); + bin2hex (regp, p, reg_size); putpkt (rs->buf); getpkt (&rs->buf); diff --git a/gdb/value.c b/gdb/value.c index d9b3c6ece04c..2b88279bd845 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -4071,12 +4071,24 @@ value::fetch_lazy_register () if (new_val->entirely_available ()) { - int i; + int i, reg_size; gdb::array_view buf = new_val->contents (); gdb_printf (&debug_file, " bytes="); gdb_printf (&debug_file, "["); - for (i = 0; i < register_size (gdbarch, regnum); i++) + + if (register_is_variable_size (gdbarch, regnum)) + /* To get the size of a variable-size register, we need to + call frame_save_as_regcache () so that we can call + regcache::register_size (). Unfortunatlly the former + ends up calling this function so we enter into an + infinite recursion. So just assume that the value has + the correct size. */ + reg_size = buf.size (); + else + reg_size = register_size (gdbarch, regnum); + + for (i = 0; i < reg_size; i++) gdb_printf (&debug_file, "%02x", buf[i]); gdb_printf (&debug_file, "]"); } diff --git a/gdbsupport/tdesc.h b/gdbsupport/tdesc.h index 5f20e6ab8627..74c5ff4deaf1 100644 --- a/gdbsupport/tdesc.h +++ b/gdbsupport/tdesc.h @@ -115,7 +115,9 @@ struct tdesc_reg : tdesc_element /* The target-described type corresponding to TYPE, if found. */ struct tdesc_type *tdesc_type; - /* Whether this register needs to be loaded early in GDB's regcache. + /* Whether this register needs to be loaded early in GDB's regcache, + because it is used to evaluate the DWARF expression giving the size of + another register. In addition, if true gdbserver will send it as an expedited register in stop replies. */