""" 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 ", ) @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", )