xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestXMLRegisterFlags.py (revision 208a08c3b7b00c05629c3f18811aac81f17cd81b)
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 strange
4failures. Check that the final XML is valid and each child is indented more than
5the parent tag.
6"""
7
8from textwrap import dedent
9import lldb
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test.decorators import *
12from lldbsuite.test.gdbclientutils import *
13from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
14
15
16class MultiDocResponder(MockGDBServerResponder):
17    # docs is a dictionary of filename -> file content.
18    def __init__(self, docs):
19        super().__init__()
20        self.docs = docs
21
22    def qXferRead(self, obj, annex, offset, length):
23        try:
24            return self.docs[annex], False
25        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, which
36                # is needed for a byte order test.
37                "77777777EEEEEEEE",  # 64 bit x0/r0
38                "7777EEEE",  # 32 bit cpsr/fpc
39                "0000000000000000",  # 64 bit pc/pswa
40            ]
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 ordering
80        # 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                flags
90            )
91        )
92
93    @skipIfXmlSupportMissing
94    @skipIfRemote
95    def test_no_flags(self):
96        self.setup_flags_test("")
97        self.expect("register read cpsr", substrs=["= 0xeeee7777"])
98
99    @skipIfXmlSupportMissing
100    @skipIfRemote
101    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    @skipIfXmlSupportMissing
107    @skipIfRemote
108    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    @skipIfXmlSupportMissing
113    @skipIfRemote
114    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    @skipIfXmlSupportMissing
124    @skipIfRemote
125    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    @skipIfXmlSupportMissing
143    @skipIfRemote
144    def test_field_overlap(self):
145        self.setup_flags_test(
146            '<field name="?" start="10" end="12"/>'
147            # A overlaps B
148            '<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    @skipIfXmlSupportMissing
156    @skipIfRemote
157    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 name
161            '<field start="0" end="0"/>'
162            # Missing start
163            '<field name="A" end="0"/>'
164            # Missing end
165            '<field name="B" start="0"/>'
166            # Valid
167            '<field name="C" start="0" end="0"/>'
168        )
169
170        self.expect("register read cpsr", substrs=["(C = 1)"])
171
172    @skipIfXmlSupportMissing
173    @skipIfRemote
174    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 0xE
193        # 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    @skipIfXmlSupportMissing
205    @skipIfRemote
206    # 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 on
236        # 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    @skipIfXmlSupportMissing
248    @skipIfRemote
249    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    @skipIfXmlSupportMissing
277    @skipIfRemote
278    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 allowed
281        # the later flag set, it would destroy the first definition, making the
282        # 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    @skipIfXmlSupportMissing
298    @skipIfRemote
299    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 the
307        # flags type.
308        self.expect("register read cpsr", substrs=["cpsr = 0xeeee7777"])
309        self.expect("register read cpsr", substrs=["("], matching=False)
310
311    @skipIfXmlSupportMissing
312    @skipIfRemote
313    def test_flags_invalid_size(self):
314        # We're not using the size for anything yet so just check that we handle
315        # 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    @skipIfXmlSupportMissing
335    @skipIfRemote
336    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    @skipIfXmlSupportMissing
350    @skipIfRemote
351    def test_flags_required_attributes(self):
352        # flags must have an id and size so the flags with "C" is the only valid one
353        # 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    @skipIfXmlSupportMissing
372    @skipIfRemote
373    def test_flags_register_size_mismatch(self):
374        # If the size of the flag set found does not match the size of the
375        # 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    @skipIfXmlSupportMissing
388    @skipIfRemote
389    def test_flags_set_even_if_format_set(self):
390        # lldb also sends "format". If that is set, we should still read the
391        # 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    @skipIfXmlSupportMissing
405    @skipIfRemote
406    def test_flags_set_even_if_encoding_set(self):
407        # lldb also sends "encoding". If that is set, we should still read the
408        # 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    @skipIfXmlSupportMissing
422    @skipIfRemote
423    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    @skipIfXmlSupportMissing
438    @skipIfRemote
439    def test_flags_multiple_lines(self):
440        # Since we use C types they follow lldb's usual decisions as to whether
441        # to print them on one line or many. Long field names will usually mean
442        # 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    @skipIfXmlSupportMissing
464    @skipIfRemote
465    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    @skipIfXmlSupportMissing
477    @skipIfRemote
478    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=False
485        )
486
487    @skipIfXmlSupportMissing
488    @skipIfRemote
489    def test_xml_includes(self):
490        # Certain targets e.g. s390x QEMU split their defintions over multiple
491        # files that are included into target.xml.
492        self.setup_multidoc_test(
493            {
494                # The formatting is very specific here. lldb doesn't like leading
495                # 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    @skipIfXmlSupportMissing
523    @skipIfRemote
524    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    @skipIfXmlSupportMissing
564    @skipIfRemote
565    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 defined
578                # in core.xml. The second definition in core-2.xml
579                # 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    @skipIfXmlSupportMissing
610    @skipIfRemote
611    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    @skipIfXmlSupportMissing
641    @skipIfRemote
642    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    @skipIfXmlSupportMissing
659    @skipIfRemote
660    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    @skipIfXmlSupportMissing
668    @skipIfRemote
669    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=["\(E = 1\)$"])
682
683    @skipIfXmlSupportMissing
684    @skipIfRemote
685    def test_enum_duplicated_evalue(self):
686        """Check that lldb only uses the last instance of a evalue for each
687        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=["\(E = def \| geh\)$"])
705
706    @skipIfXmlSupportMissing
707    @skipIfRemote
708    def test_enum_duplicated(self):
709        """Check that lldb only uses the last instance of enums with the same
710        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=["\(E = def\)$"])
729
730    @skipIfXmlSupportMissing
731    @skipIfRemote
732    def test_enum_use_first_valid(self):
733        """Check that lldb uses the first enum that parses correctly and ignores
734        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    @skipIfXmlSupportMissing
758    @skipIfRemote
759    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 evalue
763        # declared later so that it's name is hidden should the debugger only
764        # pick one of them. This behaviour would be debugger specific so the protocol
765        # would probably not care or leave it up to us, and I think it's not a
766        # 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    @skipIfXmlSupportMissing
785    @skipIfRemote
786    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    @skipIfXmlSupportMissing
815    @skipIfRemote
816    def test_evalue_out_of_range(self):
817        """Check that lldb will not use an enum type if one of its evalues
818        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    @skipIfXmlSupportMissing
837    @skipIfRemote
838    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    @skipIfXmlSupportMissing
856    @skipIfRemote
857    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    @skipIfXmlSupportMissing
878    @skipIfRemote
879    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    @skipIfXmlSupportMissing
905    @skipIfRemote
906    def test_enum_value_range(self):
907        """Check that lldb ignores enums whose values would not fit into
908        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 foo
929        self.expect(
930            "register info cpsr", patterns=["bar: 0 = A, 1 = B, 2 = C, 3 = D, 4 = E$"]
931        )
932        # but not to bar
933        self.expect("register info cpsr", patterns=["foo: "], matching=False)
934
935    @skipIfXmlSupportMissing
936    @skipIfRemote
937    def test_evalue_value_limits(self):
938        """Check that lldb can handle an evalue for a field up to 64 bits
939        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    @skipIfXmlSupportMissing
961    @skipIfRemote
962    def test_field_size_limit(self):
963        """Check that lldb ignores any field > 64 bits. We can't handle those
964        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    @skipIfXmlSupportMissing
982    @skipIfRemote
983    def test_many_fields_same_enum(self):
984        """Check that an enum can be reused by many fields, and fields of many
985        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 = valid
1009
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 = ["\(f2 = valid, f1 = valid\)$"]
1018        self.expect("register read x0", patterns=expected_read)
1019        self.expect("register read cpsr", patterns=expected_read)
1020
1021    @skipIfXmlSupportMissing
1022    @skipIfRemote
1023    def test_fields_same_name_different_enum(self):
1024        """Check that lldb does something sensible when there are two fields with
1025        the same name, but their enum types differ."""
1026
1027        # It's unlikely anyone would do this intentionally but it is allowed by
1028        # 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_1
1052
1053             foo: 1 = foo_0$"""
1054                )
1055            ],
1056        )
1057
1058        self.expect("register read x0", patterns=["\(foo = foo_1, foo = foo_0\)$"])
1059