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 &644 when found in field names."""645 self.setup_flags_test(646 '<field name="E&" start="0" end="0"/>'647 '<field name="D"" start="1" end="1"/>'648 '<field name="C'" start="2" end="2"/>'649 '<field name="B>" start="3" end="3"/>'650 '<field name="A<" 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 &881 when found in evalue names."""882 self.setup_register_test(883 """\884 <enum id="some_enum" size="4">885 <evalue name="A&" value="0"/>886 <evalue name="B"" value="1"/>887 <evalue name="C'" value="2"/>888 <evalue name="D>" value="3"/>889 <evalue name="E<" 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