From: Andrew Burgess Date: Thu, 23 Feb 2023 18:18:45 +0000 (+0000) Subject: gdb/gdbarch: split postdefault setup from invalid check in gdbarch.py X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74b1406e90bfa156aa324f9ecde424a5488cac51;p=binutils-gdb.git gdb/gdbarch: split postdefault setup from invalid check in gdbarch.py 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. Approved-By: Simon Marchi --- diff --git a/gdb/gdbarch.py b/gdb/gdbarch.py index 93b1e8bf84e..5437c827f34 100755 --- a/gdb/gdbarch.py +++ b/gdb/gdbarch.py @@ -203,35 +203,47 @@ with open("gdbarch.c", "w") as f: file=f, ) for c in filter(not_info, components): + # An opportunity to write in the 'postdefault' value. We + # change field's value to the postdefault if its current value + # is not different to the initial value of the field. + if c.postdefault is not None: + init_value = c.predefault or "0" + print(f" if (gdbarch->{c.name} == {init_value})", 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 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: - 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) + 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: - 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: - print(f" if (gdbarch->{c.name} == 0)", file=f) - print(f""" log.puts ("\\n\\t{c.name}");""", file=f) + if c.postdefault is not None: + # 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: + init_value = c.predefault or "0" + print(f" if (gdbarch->{c.name} == {init_value})", file=f) + print(f""" log.puts ("\\n\\t{c.name}");""", file=f) 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 d3dfcfc806f..1f217123216 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 field's 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 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 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: #