Author: daniilavdeev
Date: 2026-02-18T20:58:43+03:00
New Revision: 32bbb1b13c52e591d421362ba5c8ca475543ba92

URL: 
https://github.com/llvm/llvm-project/commit/32bbb1b13c52e591d421362ba5c8ca475543ba92
DIFF: 
https://github.com/llvm/llvm-project/commit/32bbb1b13c52e591d421362ba5c8ca475543ba92.diff

LOG: [lldb][RISCV] update RISCV target features in disassembler (#173047)

This patch replaces the hardcoded RISCV feature flags in disassembler
with SubtargetFeatures provided by ArchSpec, which are derived from
the .riscv.attributes ELF section. This ensures the disassembler uses
exactly the RISCV extensions present in the executable, improving the
accuracy and reliability of the disassembly output.

Added: 
    lldb/test/API/riscv/disassembler/TestDisassembler.py
    lldb/test/API/riscv/disassembler/a.out.yaml
    lldb/test/API/riscv/disassembler/conflicting.out.yaml
    lldb/test/API/riscv/disassembler/stripped.out.yaml

Modified: 
    lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp 
b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 8e495e20d254a..6384b5e1bb57c 100644
--- a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -1593,23 +1593,28 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec 
&arch,
   }
 
   if (triple.isRISCV() && !cpu_or_features_overriden) {
-    uint32_t arch_flags = arch.GetFlags();
-    if (arch_flags & ArchSpec::eRISCV_rvc)
-      features_str += "+c,";
-    if (arch_flags & ArchSpec::eRISCV_rve)
-      features_str += "+e,";
-    if ((arch_flags & ArchSpec::eRISCV_float_abi_single) ==
-        ArchSpec::eRISCV_float_abi_single)
-      features_str += "+f,";
-    if ((arch_flags & ArchSpec::eRISCV_float_abi_double) ==
-        ArchSpec::eRISCV_float_abi_double)
-      features_str += "+f,+d,";
-    if ((arch_flags & ArchSpec::eRISCV_float_abi_quad) ==
-        ArchSpec::eRISCV_float_abi_quad)
-      features_str += "+f,+d,+q,";
-    // FIXME: how do we detect features such as `+a`, `+m`?
-    // Turn them on by default now, since everyone seems to use them
-    features_str += "+a,+m,";
+    auto subtarget_features = arch.GetSubtargetFeatures().getString();
+    if (!subtarget_features.empty()) {
+      features_str += subtarget_features;
+    } else {
+      uint32_t arch_flags = arch.GetFlags();
+      if (arch_flags & ArchSpec::eRISCV_rvc)
+        features_str += "+c,";
+      if (arch_flags & ArchSpec::eRISCV_rve)
+        features_str += "+e,";
+      if ((arch_flags & ArchSpec::eRISCV_float_abi_single) ==
+          ArchSpec::eRISCV_float_abi_single)
+        features_str += "+f,";
+      if ((arch_flags & ArchSpec::eRISCV_float_abi_double) ==
+          ArchSpec::eRISCV_float_abi_double)
+        features_str += "+f,+d,";
+      if ((arch_flags & ArchSpec::eRISCV_float_abi_quad) ==
+          ArchSpec::eRISCV_float_abi_quad)
+        features_str += "+f,+d,+q,";
+      // FIXME: how do we detect features such as `+a`, `+m`?
+      // Turn them on by default now, since everyone seems to use them
+      features_str += "+a,+m,";
+    }
   }
 
   // We use m_disasm_up.get() to tell whether we are valid or not, so if this

diff  --git a/lldb/test/API/riscv/disassembler/TestDisassembler.py 
b/lldb/test/API/riscv/disassembler/TestDisassembler.py
new file mode 100644
index 0000000000000..2f01283786b1f
--- /dev/null
+++ b/lldb/test/API/riscv/disassembler/TestDisassembler.py
@@ -0,0 +1,79 @@
+"""
+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"]
+
+    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>",
+        )
+
+    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")
+
+    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",
+        )

diff  --git a/lldb/test/API/riscv/disassembler/a.out.yaml 
b/lldb/test/API/riscv/disassembler/a.out.yaml
new file mode 100644
index 0000000000000..5823ded9606c8
--- /dev/null
+++ b/lldb/test/API/riscv/disassembler/a.out.yaml
@@ -0,0 +1,32 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_RISCV
+  Flags:           [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_DOUBLE ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x550
+    AddressAlign:    0x4
+    Content:         
EF002002AA87172500000335A5A782653000137101FF814601470A88EFF05FFD029097210000938161298280010017250000130525A9972700009387A7A86388A7009727000083B7E7A491C38287828017250000130505A797250000938585A6898D93D73540FD91BE95858599C59727000083B7A7A291C3828782809727000083C747A49DE7411106E49727000083B7E79F91C717250000033545A28297EFF01FF9A260854717270000230DF7A041018280828071BF411106E422E000083376B5403366B5403346B5403316B5603356B560A260026441018280011106EC22E8001001452330A4FE2326A4FEEFF0BFFC033504FEE260426405618280
+  - Name:            .riscv.attributes
+    Type:            SHT_RISCV_ATTRIBUTES
+    AddressAlign:    0x1
+    Content:         
416C000000726973637600016200000004100572763634693270315F6D3270305F613270315F663270325F643270325F633270305F7A696373723270305F7A6966656E6365693270305F7A6D6D756C3170305F7A61616D6F3170305F7A616C7273633170305F7A626231703000
+Symbols:
+  - Name:            _Z12do_zbb_stuffv
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x606
+    Size:            0x24
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x62A
+    Size:            0x22
+...

diff  --git a/lldb/test/API/riscv/disassembler/conflicting.out.yaml 
b/lldb/test/API/riscv/disassembler/conflicting.out.yaml
new file mode 100644
index 0000000000000..2e0a155f3d0ce
--- /dev/null
+++ b/lldb/test/API/riscv/disassembler/conflicting.out.yaml
@@ -0,0 +1,38 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_RISCV
+  Flags:           [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_DOUBLE ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x550
+    AddressAlign:    0x4
+    Content:         
EF002002AA87172500000335A5A782653000137101FF814601470A88EFF05FFD029097210000938161298280010017250000130525A9972700009387A7A86388A7009727000083B7E7A491C38287828017250000130505A797250000938585A6898D93D73540FD91BE95858599C59727000083B7A7A291C3828782809727000083C747A49DE7411106E49727000083B7E79F91C717250000033545A28297EFF01FF9A260854717270000230DF7A041018280828071BF011106EC22E8001001452330A4FE2326A4FEEF004001EF008002033504FEE260426405618280411106E422E0000802A006A42AA82EACA260026441018280411106E422E0000872B866AC26AC72BEA260026441018280
+  - Name:            .riscv.attributes
+    Type:            SHT_RISCV_ATTRIBUTES
+    AddressAlign:    0x1
+    Content:         
4174000000726973637600016A00000004100572763634693270315F6D3270305F613270315F663270325F643270325F633270305F7A696373723270305F7A6966656E6365693270305F7A6D6D756C3170305F7A61616D6F3170305F7A616C7273633170305F7A63613170305F7A636D7031703000
+Symbols:
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x606
+    Size:            0x26
+  - Name:            function_with_zcd_instructions
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x62C
+    Size:            0x18
+  - Name:            function_with_zcmp_extension
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x644
+    Size:            0x18
+...

diff  --git a/lldb/test/API/riscv/disassembler/stripped.out.yaml 
b/lldb/test/API/riscv/disassembler/stripped.out.yaml
new file mode 100644
index 0000000000000..7c94fa577abc7
--- /dev/null
+++ b/lldb/test/API/riscv/disassembler/stripped.out.yaml
@@ -0,0 +1,28 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_RISCV
+  Flags:           [ EF_RISCV_RVC, EF_RISCV_FLOAT_ABI_DOUBLE ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x550
+    AddressAlign:    0x4
+    Content:         
EF002002AA87172500000335A5A782653000137101FF814601470A88EFF05FFD029097210000938161298280010017250000130525A9972700009387A7A86388A7009727000083B7E7A491C38287828017250000130505A797250000938585A6898D93D73540FD91BE95858599C59727000083B7A7A291C3828782809727000083C747A49DE7411106E49727000083B7E79F91C717250000033545A28297EFF01FF9A260854717270000230DF7A041018280828071BF411106E422E000083376B5403366B5403346B5403316B5603356B560A260026441018280011106EC22E8001001452330A4FE2326A4FEEFF0BFFC033504FEE260426405618280
+Symbols:
+  - Name:            _Z12do_zbb_stuffv
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x606
+    Size:            0x24
+  - Name:            main
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x62A
+    Size:            0x22
+...


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to