| """ | |
| Tests that LLDB can correctly set up a disassembler using extensions from the .riscv.attributes section. | |
| """ | |
| import lldb | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test import lldbutil | |
| import os | |
| class TestDisassembler(TestBase): | |
| expected_zbb_instrs = ["andn", "orn", "xnor", "rol", "ror"] | |
| @skipIfLLVMTargetMissing("RISCV") | |
| def test_without_riscv_attributes(self): | |
| """ | |
| Tests disassembly of a riscv binary without the .riscv.attributes. | |
| Without the .riscv.attributes section lldb won't set up a disassembler to | |
| handle the bitmanip extension, so it is not expected to see zbb instructions | |
| in the output. | |
| """ | |
| yaml = os.path.join(self.getSourceDir(), "stripped.out.yaml") | |
| exe = self.getBuildArtifact("stripped.out") | |
| self.yaml2obj(yaml, exe) | |
| target = self.dbg.CreateTarget(exe) | |
| self.expect("disassemble --name do_zbb_stuff") | |
| output = self.res.GetOutput() | |
| for instr in self.expected_zbb_instrs: | |
| self.assertFalse( | |
| instr in output, "Zbb instructions should not be disassembled" | |
| ) | |
| self.assertEqual( | |
| output.count("unknown"), | |
| len(self.expected_zbb_instrs), | |
| "Instructions from the Zbb extension should be displayed as <unknown>", | |
| ) | |
| @skipIfLLVMTargetMissing("RISCV") | |
| def test_with_riscv_attributes(self): | |
| """ | |
| Tests disassembly of a riscv binary with the .riscv.attributes. | |
| """ | |
| yaml = os.path.join(self.getSourceDir(), "a.out.yaml") | |
| exe = self.getBuildArtifact("a.out") | |
| self.yaml2obj(yaml, exe) | |
| target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) | |
| self.expect("disassemble --name do_zbb_stuff") | |
| output = self.res.GetOutput() | |
| for instr in self.expected_zbb_instrs: | |
| self.assertTrue(instr in output, "Invalid disassembler output") | |
| @skipIfLLVMTargetMissing("RISCV") | |
| def test_conflicting_extensions(self): | |
| """ | |
| This test demonstrates the scenario where: | |
| 1. file_with_zcd.c is compiled with rv64gc (includes C and D). | |
| 2. file_with_zcmp.c is compiled with rv64imad_zcmp (includes Zcmp). | |
| 3. The linker merges .riscv.attributes, creating the union: C + D + Zcmp. | |
| The Zcmp extension is incompatible with the C extension when the D extension is enabled. | |
| Therefore, the arch string contains conflicting extensions, and LLDB should | |
| display an appropriate warning in this case. | |
| """ | |
| yaml = os.path.join(self.getSourceDir(), "conflicting.out.yaml") | |
| exe = self.getBuildArtifact("conflicting.out") | |
| self.yaml2obj(yaml, exe) | |
| target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) | |
| output = self.res.GetOutput() | |
| self.assertIn( | |
| output, | |
| "The .riscv.attributes section contains an invalid RISC-V arch string", | |
| ) |