public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH 1/2] gdb: updates to gdbarch.py algorithm
Date: Tue, 28 Feb 2023 16:51:12 +0000	[thread overview]
Message-ID: <fe3aafc30dc898d865c651b6f5acaa1eab3174f3.1677602918.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1677602918.git.aburgess@redhat.com>

Restructure how gdbarch.py generates the verify_gdbarch function.
Previously the postdefault handling was bundled together with the
validation.  This means that a field can't have both a postdefault,
and set its invalid attribute to a string.

This doesn't seem reasonable to me, I see no reason why a field can't
have both a postdefault (used when the tdep doesn't set the field),
and an invalid expression, which can be used to validate the value
that a tdep might set.

In this commit I restructure the verify_gdbarch generation code to
allow the above, there is no change in the actual generated code in
this commit, that will come in later commit.

I did end up having to remove the "invalid" attribute (where the
attribute was set to True) from a number of fields in this commit.
This invalid attribute was never having an effect as these components
all have a postdefault.  Consider; the "postdefault" is applied if the
field still has its initial value, while an "invalid" attribute set to
True means error if the field still has its default value.  But the
field never will have its default value, it will always have its
postdefault value.
---
 gdb/gdbarch.py            | 31 ++++++++++++++++---------
 gdb/gdbarch_components.py | 49 ++++++++++++++-------------------------
 2 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/gdb/gdbarch.py b/gdb/gdbarch.py
index 93b1e8bf84e..7fea41c9572 100755
--- a/gdb/gdbarch.py
+++ b/gdb/gdbarch.py
@@ -203,35 +203,44 @@ with open("gdbarch.c", "w") as f:
         file=f,
     )
     for c in filter(not_info, components):
-        if c.invalid is False:
-            print(f"  /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
-        elif c.predicate:
-            print(f"  /* Skip verify of {c.name}, has predicate.  */", file=f)
-        elif isinstance(c.invalid, str) and c.postdefault is not None:
-            print(f"  if ({c.invalid})", file=f)
-            print(f"    gdbarch->{c.name} = {c.postdefault};", file=f)
-        elif c.predefault is not None and c.postdefault is not None:
+        # An opportunity to write in the 'postdefault' value.
+        if c.postdefault is not None and c.predefault is not None:
             print(f"  if (gdbarch->{c.name} == {c.predefault})", file=f)
             print(f"    gdbarch->{c.name} = {c.postdefault};", file=f)
         elif c.postdefault is not None:
             print(f"  if (gdbarch->{c.name} == 0)", file=f)
             print(f"    gdbarch->{c.name} = {c.postdefault};", file=f)
+
+        # Now validate the value.
+        if c.invalid is False:
+            print(f"  /* Skip verify of {c.name}, invalid_p == 0 */", file=f)
+        elif c.predicate:
+            print(f"  /* Skip verify of {c.name}, has predicate.  */", file=f)
+        elif c.invalid is None:
+            # No validation has been requested for this component.
+            pass
         elif isinstance(c.invalid, str):
             print(f"  if ({c.invalid})", file=f)
             print(f"""    log.puts ("\\n\\t{c.name}");""", file=f)
-        elif c.predefault is not None:
+        elif c.invalid is True and c.predefault is not None:
             print(f"  if (gdbarch->{c.name} == {c.predefault})", file=f)
             print(f"""    log.puts ("\\n\\t{c.name}");""", file=f)
-        elif c.invalid is True:
+        elif c.invalid is True and c.postdefault is None:
             print(f"  if (gdbarch->{c.name} == 0)", file=f)
             print(f"""    log.puts ("\\n\\t{c.name}");""", file=f)
+        elif c.invalid is True:
+            # This component has its 'invalid' field set to True, but
+            # also has a postdefault.  This makes no sense, the
+            # postdefault will have been applied above, so this field
+            # will not have a zero value.
+            raise Exception(f"component {c.name} has postdefault and invalid set to True")
         else:
             # We should not allow ourselves to simply do nothing here
             # because no other case applies.  If we end up here then
             # either the input data needs adjusting so one of the
             # above cases matches, or we need additional cases adding
             # here.
-            raise Exception("unhandled case when generating gdbarch validation")
+            raise Exception(f"unhandled case when generating gdbarch validation: {c.name}")
     print("  if (!log.empty ())", file=f)
     print(
         """    internal_error (_("verify_gdbarch: the following are invalid ...%s"),""",
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index caa65c334ec..1d420a513f9 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -63,34 +63,28 @@
 # * "predefault", "postdefault", and "invalid" - These are used for
 # the initialization and verification steps:
 #
-# A gdbarch is zero-initialized.  Then, if a field has a pre-default,
-# the field is set to that value.  After initialization is complete
-# (that is, after the tdep code has a chance to change the settings),
-# the post-initialization step is done.
+# A gdbarch is zero-initialized.  Then, if a field has a "predefault",
+# the field is set to that value.  This becomes the fields initial
+# value.
 #
-# There is a generic algorithm to generate a "validation function" for
-# all fields.  If the field has an "invalid" attribute with a string
-# value, then this string is the expression (note that a string-valued
-# "invalid" and "predicate" are mutually exclusive; and the case where
-# invalid is True means to ignore this field and instead use the
-# default checking that is about to be described).  Otherwise, if
-# there is a "predefault", then the field is valid if it differs from
-# the predefault.  Otherwise, the check is done against 0 (really NULL
-# for function pointers, but same idea).
-#
-# In post-initialization / validation, there are several cases.
+# After initialization is complete (that is, after the tdep code has a
+# chance to change the settings), the post-initialization step is
+# done.
 #
-# * If "invalid" is False, or if the field specifies "predicate",
-# validation is skipped.  Otherwise, a validation step is emitted.
+# If the field still has its initial value (see above), and the field
+# has a "postdefault", then the post field is set to this value.
 #
-# * Otherwise, the validity is checked using the usual validation
-# function (see above).  If the field is considered valid, nothing is
-# done.
+# After the possible "postdefault" assignment, validation is
+# performed for fields that don't have a "predicate".
 #
-# * Otherwise, the field's value is invalid.  If there is a
-# "postdefault", then the field is assigned that value.
+# If the field has an "invalid" attribute with a string value, then
+# this string is the expression that should evaluate to true when the
+# field is invalid.
 #
-# * Otherwise, the gdbarch will fail validation and gdb will crash.
+# Otherwise, if "invalid" is True, then the generic validation
+# function is used: the field is considered invalid it it still
+# contains its default value.  This validation is what is used within
+# the _p predicate function if the field has "predicate" set to True.
 #
 # Function and Method share:
 #
@@ -206,7 +200,6 @@ Value(
     type="const struct floatformat **",
     name="bfloat16_format",
     postdefault="floatformats_bfloat16",
-    invalid=True,
     printer="pformat (gdbarch, gdbarch->bfloat16_format)",
 )
 
@@ -221,7 +214,6 @@ Value(
     type="const struct floatformat **",
     name="half_format",
     postdefault="floatformats_ieee_half",
-    invalid=True,
     printer="pformat (gdbarch, gdbarch->half_format)",
 )
 
@@ -236,7 +228,6 @@ Value(
     type="const struct floatformat **",
     name="float_format",
     postdefault="floatformats_ieee_single",
-    invalid=True,
     printer="pformat (gdbarch, gdbarch->float_format)",
 )
 
@@ -251,7 +242,6 @@ Value(
     type="const struct floatformat **",
     name="double_format",
     postdefault="floatformats_ieee_double",
-    invalid=True,
     printer="pformat (gdbarch, gdbarch->double_format)",
 )
 
@@ -266,7 +256,6 @@ Value(
     type="const struct floatformat **",
     name="long_double_format",
     postdefault="floatformats_ieee_double",
-    invalid=True,
     printer="pformat (gdbarch, gdbarch->long_double_format)",
 )
 
@@ -289,7 +278,6 @@ One if `wchar_t' is signed, zero if unsigned.
     name="wchar_signed",
     predefault="-1",
     postdefault="1",
-    invalid=True,
 )
 
 Method(
@@ -332,7 +320,6 @@ addr_bit is the size of a target address as represented in gdb
     name="addr_bit",
     predefault="0",
     postdefault="gdbarch_ptr_bit (gdbarch)",
-    invalid=True,
 )
 
 Value(
@@ -355,7 +342,6 @@ and if Dwarf versions < 4 need to be supported.
     name="dwarf2_addr_size",
     predefault="0",
     postdefault="gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT",
-    invalid=True,
 )
 
 Value(
@@ -366,7 +352,6 @@ One if `char' acts like `signed char', zero if `unsigned char'.
     name="char_signed",
     predefault="-1",
     postdefault="1",
-    invalid=True,
 )
 
 Function(
-- 
2.25.4


  reply	other threads:[~2023-02-28 16:51 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-28 16:51 [PATCH 0/2] Add new gdbarch::displaced_step_max_buffer_length field Andrew Burgess
2023-02-28 16:51 ` Andrew Burgess [this message]
2023-03-01  3:09   ` [PATCH 1/2] gdb: updates to gdbarch.py algorithm Simon Marchi
2023-03-02 10:13     ` Andrew Burgess
2023-03-02 16:49       ` Simon Marchi
2023-03-01 15:58   ` Tom Tromey
2023-02-28 16:51 ` [PATCH 2/2] gdb: add gdbarch::displaced_step_max_buffer_length Andrew Burgess
2023-03-02 18:28   ` Simon Marchi
2023-03-06 15:31 ` [PATCHv2 0/5] Add new gdbarch::displaced_step_buffer_length field Andrew Burgess
2023-03-06 15:31   ` [PATCHv2 1/5] gdb/gdbarch: remove unused 'invalid=True' from gdbarch_components.py Andrew Burgess
2023-03-06 15:31   ` [PATCHv2 2/5] gdb/gdbarch: remove yet more " Andrew Burgess
2023-03-06 15:31   ` [PATCHv2 3/5] gdb/gdbarch: split postdefault setup from invalid check in gdbarch.py Andrew Burgess
2023-03-06 18:26     ` Simon Marchi
2023-03-06 15:31   ` [PATCHv2 4/5] gdb/gdbarch: remove the 'invalid=None' state from gdbarch_components.py Andrew Burgess
2023-03-06 20:13     ` Simon Marchi
2023-03-07 15:17     ` Tom Tromey
2023-03-07 15:20       ` Simon Marchi
2023-03-06 15:31   ` [PATCHv2 5/5] gdb: add gdbarch::displaced_step_buffer_length Andrew Burgess
2023-03-06 21:15     ` Simon Marchi
2023-03-10 18:43   ` [PATCHv3 0/9] Add new gdbarch::displaced_step_buffer_length field Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 1/9] gdb/gdbarch: remove unused 'invalid=True' from gdbarch_components.py Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 2/9] gdb/gdbarch: remove yet more " Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 3/9] gdb/gdbarch: split postdefault setup from invalid check in gdbarch.py Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 4/9] gdb/gdbarch: remove the 'invalid=None' state from gdbarch_components.py Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 5/9] gdbarch: use predefault for more value components within gdbarch Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 6/9] gdbarch: improve generation of validation in gdbarch getters Andrew Burgess
2023-03-11  2:57       ` Simon Marchi
2023-03-10 18:43     ` [PATCHv3 7/9] gdbarch: remove some unneeded predefault="0" from gdbarch_components.py Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 8/9] gdbarch: make invalid=True the default for all Components Andrew Burgess
2023-03-10 18:43     ` [PATCHv3 9/9] gdb: add gdbarch::displaced_step_buffer_length Andrew Burgess
2023-03-11  2:57     ` [PATCHv3 0/9] Add new gdbarch::displaced_step_buffer_length field Simon Marchi
2023-03-13 22:01       ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fe3aafc30dc898d865c651b6f5acaa1eab3174f3.1677602918.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).