brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.6 KiB · d784950 Raw
1059 lines · python
1""" Check that register fields found in target XML are properly processed.2 3These tests make XML out of string substitution. This can lead to some strange4failures. Check that the final XML is valid and each child is indented more than5the parent tag.6"""7 8from textwrap import dedent9import lldb10from lldbsuite.test.lldbtest import *11from lldbsuite.test.decorators import *12from lldbsuite.test.gdbclientutils import *13from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase14 15 16class MultiDocResponder(MockGDBServerResponder):17    # docs is a dictionary of filename -> file content.18    def __init__(self, docs):19        super().__init__()20        self.docs = docs21 22    def qXferRead(self, obj, annex, offset, length):23        try:24            return self.docs[annex], False25        except KeyError:26            return (None,)27 28    def readRegister(self, regnum):29        return "E01"30 31    def readRegisters(self):32        return "".join(33            [34                # Data for all registers requested by the tests below.35                # 0x7 and 0xE are used because their lsb and msb are opposites, which36                # is needed for a byte order test.37                "77777777EEEEEEEE",  # 64 bit x0/r038                "7777EEEE",  # 32 bit cpsr/fpc39                "0000000000000000",  # 64 bit pc/pswa40            ]41        )42 43 44class TestXMLRegisterFlags(GDBRemoteTestBase):45    def setup_multidoc_test(self, docs):46        self.server.responder = MultiDocResponder(docs)47        target = self.dbg.CreateTarget("")48 49        if self.TraceOn():50            self.runCmd("log enable gdb-remote packets process")51            self.addTearDownHook(52                lambda: self.runCmd("log disable gdb-remote packets process")53            )54 55        process = self.connect(target)56        lldbutil.expect_state_changes(57            self, self.dbg.GetListener(), process, [lldb.eStateStopped]58        )59 60    def setup_register_test(self, registers):61        self.setup_multidoc_test(62            # This *must* begin with the opening tag, leading whitespace is not allowed.63            {64                "target.xml": dedent(65                    """\66            <?xml version="1.0"?>67              <target version="1.0">68                <architecture>aarch64</architecture>69                <feature name="org.gnu.gdb.aarch64.core">70                  {}71                </feature>72            </target>"""73                ).format(registers)74            }75        )76 77    def setup_flags_test(self, flags):78        # pc is required here though we don't look at it in the tests.79        # x0 is only used by some tests but always including it keeps the data ordering80        # the same throughout.81        self.setup_register_test(82            """\83          <flags id="cpsr_flags" size="4">84            {}85          </flags>86          <reg name="pc" bitsize="64"/>87          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>88          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>""".format(89                flags90            )91        )92 93    @skipIfXmlSupportMissing94    @skipIfRemote95    def test_no_flags(self):96        self.setup_flags_test("")97        self.expect("register read cpsr", substrs=["= 0xeeee7777"])98 99    @skipIfXmlSupportMissing100    @skipIfRemote101    def test_single_field_pad_msb(self):102        self.setup_flags_test("""<field name="SP" start="0" end="0"/>""")103        # Pads from 31 to 1.104        self.expect("register read cpsr", substrs=["(SP = 1)"])105 106    @skipIfXmlSupportMissing107    @skipIfRemote108    def test_single_field_pad_lsb(self):109        self.setup_flags_test("""<field name="SP" start="31" end="31"/>""")110        self.expect("register read cpsr", substrs=["(SP = 1)"])111 112    @skipIfXmlSupportMissing113    @skipIfRemote114    def test_multiple_fields_sorted(self):115        self.setup_flags_test(116            """<field name="SP" start="0" end="0"/>117                                 <field name="EL" start="1" end="2"/>"""118        )119 120        # Fields should be sorted with MSB on the left.121        self.expect("register read cpsr", substrs=["(EL = 3, SP = 1)"])122 123    @skipIfXmlSupportMissing124    @skipIfRemote125    def test_ignore_invalid_start_end(self):126        self.setup_flags_test(127            # Is valid so is used.128            '<field name="EL" start="2" end="3"/>'129            # Start/end cannot be negative, ignored.130            '<field name="SP" start="-1" end="2"/>'131            '<field name="SP2" start="1" end="-5"/>'132            # Start is not <= end, ignored.133            '<field name="ABC" start="12" end="10"/>'134            # Start cannot be >= (size of register in bits)135            '<field name="?" start="32" end="29"/>'136            # End cannot be >= (size of register in bits)137            '<field name="DEF" start="30" end="35"/>'138        )139 140        self.expect("register read cpsr", substrs=["(EL = 1)"])141 142    @skipIfXmlSupportMissing143    @skipIfRemote144    def test_field_overlap(self):145        self.setup_flags_test(146            '<field name="?" start="10" end="12"/>'147            # A overlaps B148            '<field name="A" start="0" end="3"/>'149            '<field name="B" start="0" end="0"/>'150        )151 152        # Ignore the whole flags set, it is unlikely to be valid.153        self.expect("register read cpsr", substrs=["("], matching=False)154 155    @skipIfXmlSupportMissing156    @skipIfRemote157    def test_field_required_attributes(self):158        # Fields must have a name, start and end. Any without are ignored.159        self.setup_flags_test(160            # Missing name161            '<field start="0" end="0"/>'162            # Missing start163            '<field name="A" end="0"/>'164            # Missing end165            '<field name="B" start="0"/>'166            # Valid167            '<field name="C" start="0" end="0"/>'168        )169 170        self.expect("register read cpsr", substrs=["(C = 1)"])171 172    @skipIfXmlSupportMissing173    @skipIfRemote174    def test_little_endian_target_order(self):175        # We are using little endian AArch64 here.176        self.setup_register_test(177            """\178           <flags id="cpsr_flags" size="4">179             <field name="lsb" start="0" end="0"/>180             <field name="msb" start="31" end="31"/>181           </flags>182           <flags id="x0_flags" size="8">183             <field name="lsb" start="0" end="0"/>184             <field name="msb" start="63" end="63"/>185           </flags>186           <reg name="pc" bitsize="64"/>187           <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>188           <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""189        )190 191        # If lldb used the wrong byte ordering for the value for printing fields,192        # these field values would flip. Since the top and bottom bits of 0x7 and 0xE193        # are different.194        self.expect(195            "register read cpsr x0",196            substrs=[197                "    cpsr = 0xeeee7777\n"198                "         = (msb = 1, lsb = 1)\n"199                "      x0 = 0xeeeeeeee77777777\n"200                "         = (msb = 1, lsb = 1)"201            ],202        )203 204    @skipIfXmlSupportMissing205    @skipIfRemote206    # Unlike AArch64, we do need the backend present for this test to work.207    @skipIfLLVMTargetMissing("SystemZ")208    def test_big_endian_target_order(self):209        # s390x/SystemZ is big endian.210        self.setup_multidoc_test(211            {212                "target.xml": dedent(213                    """\214              <?xml version="1.0"?>215              <target version="1.0">216                <architecture>s390x</architecture>217                <feature name="org.gnu.gdb.s390x.core">218                  <flags id="r0_flags" size="8">219                    <field name="lsb" start="0" end="0"/>220                    <field name="msb" start="63" end="63"/>221                  </flags>222                  <flags id="fpc_flags" size="4">223                    <field name="lsb" start="0" end="0"/>224                    <field name="msb" start="31" end="31"/>225                  </flags>226                  <reg name="r0" bitsize="64" type="r0_flags"/>227                  <reg name="fpc" bitsize="32" type="fpc_flags"/>228                  <reg name="pswa" bitsize="64"/>229                </feature>230              </target>"""231                )232            }233        )234 235        # If we did not swap correctly, these fields would show as 1s when run on236        # a little endian host.237        self.expect(238            "register read r0 fpc",239            substrs=[240                "      r0 = 0x77777777eeeeeeee\n"241                "         = (msb = 0, lsb = 0)\n"242                "     fpc = 0x7777eeee\n"243                "         = (msb = 0, lsb = 0)\n"244            ],245        )246 247    @skipIfXmlSupportMissing248    @skipIfRemote249    def test_many_flag_sets(self):250        self.setup_register_test(251            """\252          <flags id="cpsr_flags" size="4">253            <field name="correct" start="0" end="0"/>254          </flags>255          <flags id="cpsr_flags_alt" size="4">256            <field name="incorrect" start="0" end="0"/>257          </flags>258          <flags id="x0_flags" size="8">259            <field name="foo" start="0" end="0"/>260          </flags>261          <reg name="pc" bitsize="64"/>262          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>263          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""264        )265 266        self.expect(267            "register read cpsr x0",268            substrs=[269                "    cpsr = 0xeeee7777\n"270                "         = (correct = 1)\n"271                "      x0 = 0xeeeeeeee77777777\n"272                "         = (foo = 1)"273            ],274        )275 276    @skipIfXmlSupportMissing277    @skipIfRemote278    def test_repeated_flag_set(self):279        # The second definition of "cpsr_flags" should be ignored.280        # This is because we assign the types to registers as we go. If we allowed281        # the later flag set, it would destroy the first definition, making the282        # pointer to the flags invalid.283        self.setup_register_test(284            """\285          <flags id="cpsr_flags" size="4">286            <field name="correct" start="0" end="0"/>287          </flags>288          <flags id="cpsr_flags" size="4">289            <field name="incorrect" start="0" end="0"/>290          </flags>291          <reg name="pc" bitsize="64"/>292          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""293        )294 295        self.expect("register read cpsr", substrs=["(correct = 1)"])296 297    @skipIfXmlSupportMissing298    @skipIfRemote299    def test_missing_flags(self):300        self.setup_register_test(301            """\302          <reg name="pc" bitsize="64"/>303          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""304        )305 306        # Register prints with default formatting only if we can't find the307        # flags type.308        self.expect("register read cpsr", substrs=["cpsr = 0xeeee7777"])309        self.expect("register read cpsr", substrs=["("], matching=False)310 311    @skipIfXmlSupportMissing312    @skipIfRemote313    def test_flags_invalid_size(self):314        # We're not using the size for anything yet so just check that we handle315        # it not being a positive integer.316        self.setup_register_test(317            """\318          <flags id="cpsr_flags" size="???">319            <field name="A" start="0" end="0"/>320          </flags>321          <flags id="cpsr_flags" size="-1">322            <field name="B" start="0" end="0"/>323          </flags>324          <flags id="cpsr_flags" size="4">325            <field name="C" start="0" end="0"/>326          </flags>327          <reg name="pc" bitsize="64"/>328          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""329        )330 331        # Only the final set has a valid size, use that.332        self.expect("register read cpsr", substrs=["(C = 1)"])333 334    @skipIfXmlSupportMissing335    @skipIfRemote336    def test_flags_unknown_attribute(self):337        # Unknown attributes on flags or field are ignored.338        self.setup_register_test(339            """\340          <flags id="cpsr_flags" size="4" stuff="abcd">341            <field name="A" start="0" abcd="???" end="0"/>342          </flags>343          <reg name="pc" bitsize="64"/>344          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""345        )346 347        self.expect("register read cpsr", substrs=["(A = 1)"])348 349    @skipIfXmlSupportMissing350    @skipIfRemote351    def test_flags_required_attributes(self):352        # flags must have an id and size so the flags with "C" is the only valid one353        # here.354        self.setup_register_test(355            """\356          <flags size="4">357            <field name="A" start="0" end="0"/>358          </flags>359          <flags id="cpsr_flags">360            <field name="B" start="0" end="0"/>361          </flags>362          <flags id="cpsr_flags" size="4">363            <field name="C" start="0" end="0"/>364          </flags>365          <reg name="pc" bitsize="64"/>366          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""367        )368 369        self.expect("register read cpsr", substrs=["(C = 1)"])370 371    @skipIfXmlSupportMissing372    @skipIfRemote373    def test_flags_register_size_mismatch(self):374        # If the size of the flag set found does not match the size of the375        # register, we discard the flags.376        self.setup_register_test(377            """\378          <flags id="cpsr_flags" size="8">379            <field name="C" start="0" end="0"/>380          </flags>381          <reg name="pc" bitsize="64"/>382          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""383        )384 385        self.expect("register read cpsr", substrs=["(C = 1)"], matching=False)386 387    @skipIfXmlSupportMissing388    @skipIfRemote389    def test_flags_set_even_if_format_set(self):390        # lldb also sends "format". If that is set, we should still read the391        # flags type.392        self.setup_register_test(393            """\394          <flags id="cpsr_flags" size="4">395            <field name="B" start="0" end="0"/>396          </flags>397          <reg name="pc" bitsize="64"/>398          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"399            format="example"/>"""400        )401 402        self.expect("register read cpsr", substrs=["(B = 1)"])403 404    @skipIfXmlSupportMissing405    @skipIfRemote406    def test_flags_set_even_if_encoding_set(self):407        # lldb also sends "encoding". If that is set, we should still read the408        # flags type.409        self.setup_register_test(410            """\411          <flags id="cpsr_flags" size="4">412            <field name="B" start="0" end="0"/>413          </flags>414          <reg name="pc" bitsize="64"/>415          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"416            encoding="example"/>"""417        )418 419        self.expect("register read cpsr", substrs=["(B = 1)"])420 421    @skipIfXmlSupportMissing422    @skipIfRemote423    def test_flags_set_even_if_encoding_and_format_set(self):424        # As above but both encoding and format are set.425        self.setup_register_test(426            """\427          <flags id="cpsr_flags" size="4">428            <field name="B" start="0" end="0"/>429          </flags>430          <reg name="pc" bitsize="64"/>431          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"432            encoding="example" format="example"/>"""433        )434 435        self.expect("register read cpsr", substrs=["(B = 1)"])436 437    @skipIfXmlSupportMissing438    @skipIfRemote439    def test_flags_multiple_lines(self):440        # Since we use C types they follow lldb's usual decisions as to whether441        # to print them on one line or many. Long field names will usually mean442        # many lines.443        self.setup_flags_test(444            '<field name="this_is_a_long_field_0" start="0" end="0"/>'445            '<field name="this_is_a_long_field_1" start="1" end="1"/>'446            '<field name="this_is_a_long_field_2" start="2" end="2"/>'447            '<field name="this_is_a_long_field_3" start="3" end="3"/>'448        )449 450        self.expect(451            "register read cpsr",452            substrs=[453                "    cpsr = 0xeeee7777\n"454                "         = {\n"455                "             this_is_a_long_field_3 = 0\n"456                "             this_is_a_long_field_2 = 1\n"457                "             this_is_a_long_field_1 = 1\n"458                "             this_is_a_long_field_0 = 1\n"459                "           }"460            ],461        )462 463    @skipIfXmlSupportMissing464    @skipIfRemote465    def test_flags_child_limit(self):466        # Flags print like C types so they should follow the child limit setting.467        self.runCmd("settings set target.max-children-count 3")468        self.setup_flags_test(469            '<field name="field_0" start="0" end="0"/>'470            '<field name="field_1" start="1" end="1"/>'471            '<field name="field_2" start="2" end="2"/>'472        )473 474        self.expect("register read cpsr", substrs=["= (field_2 = 1, field_1 = 1, ...)"])475 476    @skipIfXmlSupportMissing477    @skipIfRemote478    def test_format_disables_flags(self):479        # If asked for a specific format, don't print flags after it.480        self.setup_flags_test('<field name="field_0" start="0" end="0"/>')481 482        self.expect("register read cpsr --format X", substrs=["cpsr = 0xEEEE7777"])483        self.expect(484            "register read cpsr --format X", substrs=["field_0"], matching=False485        )486 487    @skipIfXmlSupportMissing488    @skipIfRemote489    def test_xml_includes(self):490        # Certain targets e.g. s390x QEMU split their defintions over multiple491        # files that are included into target.xml.492        self.setup_multidoc_test(493            {494                # The formatting is very specific here. lldb doesn't like leading495                # spaces, and nested tags must be indented more than their parent.496                "target.xml": dedent(497                    """\498               <?xml version="1.0"?>499               <target version="1.0">500                 <architecture>aarch64</architecture>501                 <xi:include href="core.xml"/>502               </target>"""503                ),504                "core.xml": dedent(505                    """\506                <?xml version="1.0"?>507                <feature name="org.gnu.gdb.aarch64.core">508                  <flags id="cpsr_flags" size="4">509                    <field name="B" start="0" end="0"/>510                  </flags>511                  <reg name="pc" bitsize="64"/>512                  <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>513                  <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>514                </feature>515            """516                ),517            }518        )519 520        self.expect("register read cpsr", substrs=["(B = 1)"])521 522    @skipIfXmlSupportMissing523    @skipIfRemote524    def test_xml_includes_multiple(self):525        self.setup_multidoc_test(526            {527                "target.xml": dedent(528                    """\529               <?xml version="1.0"?>530               <target version="1.0">531                 <architecture>aarch64</architecture>532                 <xi:include href="core.xml"/>533                 <xi:include href="core-2.xml"/>534               </target>"""535                ),536                "core.xml": dedent(537                    """\538                <?xml version="1.0"?>539                <feature name="org.gnu.gdb.aarch64.core">540                  <flags id="x0_flags" size="8">541                    <field name="B" start="0" end="0"/>542                  </flags>543                  <reg name="pc" bitsize="64"/>544                  <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>545                </feature>"""546                ),547                "core-2.xml": dedent(548                    """\549                <?xml version="1.0"?>550                <feature name="org.gnu.gdb.aarch64.core">551                  <flags id="cpsr_flags" size="4">552                    <field name="C" start="0" end="0"/>553                  </flags>554                  <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>555                </feature>556            """557                ),558            }559        )560 561        self.expect("register read x0 cpsr", substrs=["(B = 1)", "(C = 1)"])562 563    @skipIfXmlSupportMissing564    @skipIfRemote565    def test_xml_includes_flags_redefined(self):566        self.setup_multidoc_test(567            {568                "target.xml": dedent(569                    """\570               <?xml version="1.0"?>571               <target version="1.0">572                 <architecture>aarch64</architecture>573                 <xi:include href="core.xml"/>574                 <xi:include href="core-2.xml"/>575               </target>"""576                ),577                # Treating xi:include as a textual include, my_flags is first defined578                # in core.xml. The second definition in core-2.xml579                # is ignored.580                "core.xml": dedent(581                    """\582                <?xml version="1.0"?>583                <feature name="org.gnu.gdb.aarch64.core">584                  <flags id="my_flags" size="8">585                    <field name="correct" start="0" end="0"/>586                  </flags>587                  <reg name="pc" bitsize="64"/>588                  <reg name="x0" regnum="0" bitsize="64" type="my_flags"/>589                </feature>"""590                ),591                # The my_flags here is ignored, so x1 will use the my_flags from above.592                "core-2.xml": dedent(593                    """\594                <?xml version="1.0"?>595                <feature name="org.gnu.gdb.aarch64.core">596                  <flags id="my_flags" size="8">597                    <field name="incorrect" start="0" end="0"/>598                  </flags>599                  <reg name="x1" regnum="33" bitsize="64" type="my_flags"/>600                </feature>601            """602                ),603            }604        )605 606        self.expect("register read x0", substrs=["(correct = 1)"])607        self.expect("register read x1", substrs=["(correct = 1)"])608 609    @skipIfXmlSupportMissing610    @skipIfRemote611    def test_flags_in_register_info(self):612        # See RegisterFlags for comprehensive formatting tests.613        self.setup_flags_test(614            '<field name="D" start="0" end="7"/>'615            '<field name="C" start="8" end="15"/>'616            '<field name="B" start="16" end="23"/>'617            '<field name="A" start="24" end="31"/>'618        )619 620        # The table should split according to terminal width.621        self.runCmd("settings set term-width 17")622 623        self.expect(624            "register info cpsr",625            substrs=[626                "       Name: cpsr\n"627                "       Size: 4 bytes (32 bits)\n"628                "    In sets: general (index 0)\n"629                "\n"630                "| 31-24 | 23-16 |\n"631                "|-------|-------|\n"632                "|   A   |   B   |\n"633                "\n"634                "| 15-8 | 7-0 |\n"635                "|------|-----|\n"636                "|  C   |  D  |"637            ],638        )639 640    @skipIfXmlSupportMissing641    @skipIfRemote642    def test_flags_name_xml_reserved_characters(self):643        """Check that lldb converts reserved character replacements like &amp;644        when found in field names."""645        self.setup_flags_test(646            '<field name="E&amp;" start="0" end="0"/>'647            '<field name="D&quot;" start="1" end="1"/>'648            '<field name="C&apos;" start="2" end="2"/>'649            '<field name="B&gt;" start="3" end="3"/>'650            '<field name="A&lt;" start="4" end="4"/>'651        )652 653        self.expect(654            "register info cpsr",655            substrs=["| A< | B> | C' | D\" | E& |"],656        )657 658    @skipIfXmlSupportMissing659    @skipIfRemote660    def test_no_enum(self):661        """Check that lldb does not try to print an enum when there isn't one."""662 663        self.setup_flags_test('<field name="E" start="0" end="0">' "</field>")664 665        self.expect("register info cpsr", patterns=["E:.*$"], matching=False)666 667    @skipIfXmlSupportMissing668    @skipIfRemote669    def test_enum_type_not_found(self):670        """Check that lldb uses the default format if we don't find the enum type."""671        self.setup_register_test(672            """\673          <flags id="cpsr_flags" size="4">674            <field name="E" start="0" end="0" type="some_enum"/>675          </flags>676          <reg name="pc" bitsize="64"/>677          <reg name="x0" regnum="0" bitsize="64"/>678          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""679        )680 681        self.expect("register read cpsr", patterns=[r"\(E = 1\)$"])682 683    @skipIfXmlSupportMissing684    @skipIfRemote685    def test_enum_duplicated_evalue(self):686        """Check that lldb only uses the last instance of a evalue for each687        value."""688        self.setup_register_test(689            """\690          <enum id="some_enum" size="4">691            <evalue name="abc" value="1"/>692            <evalue name="def" value="1"/>693            <evalue name="geh" value="2"/>694          </enum>695          <flags id="cpsr_flags" size="4">696            <field name="E" start="0" end="1" type="some_enum"/>697          </flags>698          <reg name="pc" bitsize="64"/>699          <reg name="x0" regnum="0" bitsize="64"/>700          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""701        )702 703        self.expect("register info cpsr", patterns=["E: 1 = def, 2 = geh$"])704        self.expect("register read cpsr", patterns=[r"\(E = def \| geh\)$"])705 706    @skipIfXmlSupportMissing707    @skipIfRemote708    def test_enum_duplicated(self):709        """Check that lldb only uses the last instance of enums with the same710        id."""711        self.setup_register_test(712            """\713          <enum id="some_enum" size="4">714            <evalue name="abc" value="1"/>715          </enum>716          <enum id="some_enum" size="4">717            <evalue name="def" value="1"/>718          </enum>719          <flags id="cpsr_flags" size="4">720            <field name="E" start="0" end="0" type="some_enum"/>721          </flags>722          <reg name="pc" bitsize="64"/>723          <reg name="x0" regnum="0" bitsize="64"/>724          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""725        )726 727        self.expect("register info cpsr", patterns=["E: 1 = def$"])728        self.expect("register read cpsr", patterns=[r"\(E = def\)$"])729 730    @skipIfXmlSupportMissing731    @skipIfRemote732    def test_enum_use_first_valid(self):733        """Check that lldb uses the first enum that parses correctly and ignores734        the rest."""735        self.setup_register_test(736            """\737          <enum id="some_enum" size="4"/>738          <enum size="4">739            <evalue name="invalid" value="1"/>740          </enum>741          <enum id="some_enum" size="4">742            <evalue name="valid" value="1"/>743          </enum>744          <enum id="another_enum" size="4">745            <evalue name="invalid" value="1"/>746          </enum>747          <flags id="cpsr_flags" size="4">748            <field name="E" start="0" end="0" type="some_enum"/>749          </flags>750          <reg name="pc" bitsize="64"/>751          <reg name="x0" regnum="0" bitsize="64"/>752          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""753        )754 755        self.expect("register info cpsr", patterns=["E: 1 = valid$"])756 757    @skipIfXmlSupportMissing758    @skipIfRemote759    def test_evalue_empty_name(self):760        """Check that lldb ignores evalues with an empty name."""761 762        # The only potential use case for empty names is to shadow an evalue763        # declared later so that it's name is hidden should the debugger only764        # pick one of them. This behaviour would be debugger specific so the protocol765        # would probably not care or leave it up to us, and I think it's not a766        # useful thing to allow.767 768        self.setup_register_test(769            """\770          <enum id="some_enum" size="4">771            <evalue name="" value="1"/>772            <evalue name="valid" value="2"/>773          </enum>774          <flags id="cpsr_flags" size="4">775            <field name="E" start="0" end="1" type="some_enum"/>776          </flags>777          <reg name="pc" bitsize="64"/>778          <reg name="x0" regnum="0" bitsize="64"/>779          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""780        )781 782        self.expect("register info cpsr", patterns=["E: 2 = valid$"])783 784    @skipIfXmlSupportMissing785    @skipIfRemote786    def test_evalue_invalid_value(self):787        """Check that lldb ignores evalues with an invalid value."""788        self.setup_register_test(789            """\790          <enum id="some_enum" size="4">791            <evalue name="negative_dec" value="-1"/>792            <evalue name="negative_hex" value="-0x1"/>793            <evalue name="negative_bin" value="-0b1"/>794            <evalue name="negative_float" value="-0.5"/>795            <evalue name="nan" value="aardvark"/>796            <evalue name="dec" value="1"/>797            <evalue name="hex" value="0x2"/>798            <evalue name="octal" value="03"/>799            <evalue name="float" value="0.5"/>800            <evalue name="bin" value="0b100"/>801          </enum>802          <flags id="cpsr_flags" size="4">803            <field name="E" start="0" end="2" type="some_enum"/>804          </flags>805          <reg name="pc" bitsize="64"/>806          <reg name="x0" regnum="0" bitsize="64"/>807          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""808        )809 810        self.expect(811            "register info cpsr", patterns=["E: 1 = dec, 2 = hex, 3 = octal, 4 = bin$"]812        )813 814    @skipIfXmlSupportMissing815    @skipIfRemote816    def test_evalue_out_of_range(self):817        """Check that lldb will not use an enum type if one of its evalues818        exceeds the size of the field it is applied to."""819        self.setup_register_test(820            """\821          <enum id="some_enum" size="4">822            <evalue name="A" value="0"/>823            <evalue name="B" value="2"/>824          </enum>825          <flags id="cpsr_flags" size="4">826            <field name="E" start="0" end="0" type="some_enum"/>827          </flags>828          <reg name="pc" bitsize="64"/>829          <reg name="x0" regnum="0" bitsize="64"/>830          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""831        )832 833        # The whole eunm is rejected even if just 1 value is out of range.834        self.expect("register info cpsr", patterns=["E: 0 = "], matching=False)835 836    @skipIfXmlSupportMissing837    @skipIfRemote838    def test_enum_ignore_unknown_attributes(self):839        """Check that lldb ignores unknown attributes on an enum or evalue."""840        self.setup_register_test(841            """\842          <enum id="some_enum" size="4" foo=\"bar\">843            <evalue name="valid" value="1" colour=\"red"/>844          </enum>845          <flags id="cpsr_flags" size="4">846            <field name="E" start="0" end="0" type="some_enum"/>847          </flags>848          <reg name="pc" bitsize="64"/>849          <reg name="x0" regnum="0" bitsize="64"/>850          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""851        )852 853        self.expect("register info cpsr", patterns=["E: 1 = valid$"])854 855    @skipIfXmlSupportMissing856    @skipIfRemote857    def test_evalue_required_attributes(self):858        """Check that lldb rejects any evalue missing a name and/or value."""859        self.setup_register_test(860            """\861          <enum id="some_enum" size="4">862            <evalue name="foo"/>863            <evalue value="1"/>864            <evalue />865            <evalue name="valid" value="1"/>866          </enum>867          <flags id="cpsr_flags" size="4">868            <field name="E" start="0" end="0" type="some_enum"/>869          </flags>870          <reg name="pc" bitsize="64"/>871          <reg name="x0" regnum="0" bitsize="64"/>872          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""873        )874 875        self.expect("register info cpsr", patterns=["E: 1 = valid$"])876 877    @skipIfXmlSupportMissing878    @skipIfRemote879    def test_evalue_name_xml_reserved_characters(self):880        """Check that lldb converts reserved character replacements like &amp;881        when found in evalue names."""882        self.setup_register_test(883            """\884          <enum id="some_enum" size="4">885            <evalue name="A&amp;"  value="0"/>886            <evalue name="B&quot;" value="1"/>887            <evalue name="C&apos;" value="2"/>888            <evalue name="D&gt;"   value="3"/>889            <evalue name="E&lt;"   value="4"/>890          </enum>891          <flags id="cpsr_flags" size="4">892            <field name="E" start="0" end="2" type="some_enum"/>893          </flags>894          <reg name="pc" bitsize="64"/>895          <reg name="x0" regnum="0" bitsize="64"/>896          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""897        )898 899        self.expect(900            "register info cpsr",901            patterns=["E: 0 = A&, 1 = B\", 2 = C', 3 = D>, 4 = E<$"],902        )903 904    @skipIfXmlSupportMissing905    @skipIfRemote906    def test_enum_value_range(self):907        """Check that lldb ignores enums whose values would not fit into908        their field."""909 910        self.setup_register_test(911            """\912          <enum id="some_enum" size="4">913            <evalue name="A" value="0"/>914            <evalue name="B" value="1"/>915            <evalue name="C" value="2"/>916            <evalue name="D" value="3"/>917            <evalue name="E" value="4"/>918          </enum>919          <flags id="cpsr_flags" size="4">920            <field name="foo" start="0" end="1" type="some_enum"/>921            <field name="bar" start="2" end="10" type="some_enum"/>922          </flags>923          <reg name="pc" bitsize="64"/>924          <reg name="x0" regnum="0" bitsize="64"/>925          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""926        )927 928        # some_enum can apply to foo929        self.expect(930            "register info cpsr", patterns=["bar: 0 = A, 1 = B, 2 = C, 3 = D, 4 = E$"]931        )932        # but not to bar933        self.expect("register info cpsr", patterns=["foo: "], matching=False)934 935    @skipIfXmlSupportMissing936    @skipIfRemote937    def test_evalue_value_limits(self):938        """Check that lldb can handle an evalue for a field up to 64 bits939        in size and anything greater is ignored."""940 941        self.setup_register_test(942            """\943          <enum id="some_enum" size="8">944            <evalue name="min" value="0"/>945            <evalue name="max" value="0xffffffffffffffff"/>946            <evalue name="invalid" value="0xfffffffffffffffff"/>947          </enum>948          <flags id="x0_flags" size="8">949            <field name="foo" start="0" end="63" type="some_enum"/>950          </flags>951          <reg name="pc" bitsize="64"/>952          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>953          <reg name="cpsr" regnum="33" bitsize="32"/>"""954        )955 956        self.expect(957            "register info x0", patterns=["foo: 0 = min, 18446744073709551615 = max$"]958        )959 960    @skipIfXmlSupportMissing961    @skipIfRemote962    def test_field_size_limit(self):963        """Check that lldb ignores any field > 64 bits. We can't handle those964        correctly."""965 966        self.setup_register_test(967            """\968          <flags id="x0_flags" size="8">969            <field name="invalid" start="0" end="64"/>970            <field name="valid" start="0" end="63"/>971          </flags>972          <reg name="pc" bitsize="64"/>973          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>974          <reg name="cpsr" regnum="33" bitsize="32"/>"""975        )976 977        self.expect(978            "register info x0", substrs=["| 63-0  |\n" "|-------|\n" "| valid |"]979        )980 981    @skipIfXmlSupportMissing982    @skipIfRemote983    def test_many_fields_same_enum(self):984        """Check that an enum can be reused by many fields, and fields of many985        registers."""986 987        self.setup_register_test(988            """\989          <enum id="some_enum" size="8">990            <evalue name="valid" value="1"/>991          </enum>992          <flags id="x0_flags" size="8">993            <field name="f1" start="0" end="0" type="some_enum"/>994            <field name="f2" start="1" end="1" type="some_enum"/>995          </flags>996          <flags id="cpsr_flags" size="4">997            <field name="f1" start="0" end="0" type="some_enum"/>998            <field name="f2" start="1" end="1" type="some_enum"/>999          </flags>1000          <reg name="pc" bitsize="64"/>1001          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>1002          <reg name="cpsr" regnum="33" bitsize="32" type="cpsr_flags"/>"""1003        )1004 1005        expected_info = [1006            dedent(1007                """\1008             f2: 1 = valid1009 1010             f1: 1 = valid$"""1011            )1012        ]1013        self.expect("register info x0", patterns=expected_info)1014 1015        self.expect("register info cpsr", patterns=expected_info)1016 1017        expected_read = [r"\(f2 = valid, f1 = valid\)$"]1018        self.expect("register read x0", patterns=expected_read)1019        self.expect("register read cpsr", patterns=expected_read)1020 1021    @skipIfXmlSupportMissing1022    @skipIfRemote1023    def test_fields_same_name_different_enum(self):1024        """Check that lldb does something sensible when there are two fields with1025        the same name, but their enum types differ."""1026 1027        # It's unlikely anyone would do this intentionally but it is allowed by1028        # the protocol spec so we have to cope with it.1029        self.setup_register_test(1030            """\1031          <enum id="foo_enum" size="8">1032            <evalue name="foo_0" value="1"/>1033          </enum>1034          <enum id="foo_alt_enum" size="8">1035            <evalue name="foo_1" value="1"/>1036          </enum>1037          <flags id="x0_flags" size="8">1038            <field name="foo" start="0" end="0" type="foo_enum"/>1039            <field name="foo" start="1" end="1" type="foo_alt_enum"/>1040          </flags>1041          <reg name="pc" bitsize="64"/>1042          <reg name="x0" regnum="0" bitsize="64" type="x0_flags"/>1043          <reg name="cpsr" regnum="33" bitsize="32"/>"""1044        )1045 1046        self.expect(1047            "register info x0",1048            patterns=[1049                dedent(1050                    """\1051             foo: 1 = foo_11052 1053             foo: 1 = foo_0$"""1054                )1055            ],1056        )1057 1058        self.expect("register read x0", patterns=[r"\(foo = foo_1, foo = foo_0\)$"])1059