Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ghidra does not recognize the RISC-V fli.s instruction #7451

Open
gemesa opened this issue Feb 6, 2025 · 6 comments
Open

Ghidra does not recognize the RISC-V fli.s instruction #7451

gemesa opened this issue Feb 6, 2025 · 6 comments
Assignees
Labels
Feature: Processor/RISC-V Status: Triage Information is being gathered Type: Bug Something isn't working

Comments

@gemesa
Copy link
Contributor

gemesa commented Feb 6, 2025

Is your feature request related to a problem? Please describe.
Ghidra does not recognize the RISC-V fli.s instruction which is part of the standard Zfa extension.

$ llvm-objdump --disassemble-symbols=test test.o

test.o:	file format elf32-littleriscv

Disassembly of section .text:

00000000 <test>:
       0: 1141         	addi	sp, sp, -0x10
       2: c606         	sw	ra, 0xc(sp)
       4: c422         	sw	s0, 0x8(sp)
       6: 0800         	addi	s0, sp, 0x10
       8: fea42a27     	fsw	fa0, -0xc(s0)
       c: ff442787     	flw	fa5, -0xc(s0)
      10: f0140753     	fli.s	fa4, 0.25
      14: 10e7f553     	fmul.s	fa0, fa5, fa4
      18: 40b2         	lw	ra, 0xc(sp)
      1a: 4422         	lw	s0, 0x8(sp)
      1c: 0141         	addi	sp, sp, 0x10
      1e: 8082         	ret

Ghidra listing:

                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined test()
             undefined         <UNASSIGNED>   <RETURN>
             undefined4        Stack[-0xc]:4  local_c                                 XREF[2]:     00010008(*), 
                                                                                                   0001000c(*)  
                             $x                                              XREF[2]:     Entry Point(*), 
                             test                                                         _elfSectionHeaders::0000005c(*)  
        00010000 41 11           c.addi     sp,-0x10
        00010002 06 c6           c.swsp     ra,0xc(sp)
        00010004 22 c4           c.swsp     s0,0x8(sp)
        00010006 00 08           c.addi4spn s0,sp,0x10
        00010008 27 2a a4 fe     fsw        fa0,-0xc=>local_c(s0)
        0001000c 87 27 44 ff     flw        fa5,-0xc=>local_c(s0)
        00010010 53              ??         53h    S
        00010011 07              ??         07h
        00010012 14              ??         14h
        00010013 f0              ??         F0h
        00010014 53 f5 e7 10     fmul.s     fa0,fa5,fa4,dyn
        00010018 b2 40           c.lwsp     ra,0xc(sp)
        0001001a 22 44           c.lwsp     s0,0x8(sp)
        0001001c 41 01           c.addi     sp,0x10
        0001001e 82 80           ret

test.zip

Describe the solution you'd like
The machine code is disassembled into fli.s.

Describe alternatives you've considered
N/A

Additional context
I think none of the Zfa extension instructions are recognized.

@thixotropist
Copy link
Contributor

I can add fli.s support to the other riscv extension support in PR #5778 if you like. Does the unofficial RISCV Ghidra interest group have any suggestions on the way it is implemented? The default solution involves adding sleigh definitions for the zfa extension such that Ghidra's disassembler matches the binutils test cases binutils-gdb/gas/testsuite/gas/riscv/zfa*.

There are some design questions here:

  • What should the semantics look like for the half-precision floating point instructions like fli.h? Ghidra's decompiler doesn't appear to support either of the two RISCV half-precision floating point formats.
  • Ignore or implement NaN boxing for half-precision encoding in full precision registers?
  • How does support for the zfa extension get mapped into Ghidra RISCV language selection? The default for PR Update RISCV-64 sleigh files to support vector, bit manipulation, and crypto extensions #5778 is to include all z* extensions, while the binutils disassembler default is to include only those extensions identified on the command line or within the ELF file

@GhidorahRex
Copy link
Collaborator

My two cents:

  • Unless there's a pressing need for half-precision to be implemented, I would use pcodeops for those instructions.
  • The details of the NaN boxing can be left to the pcodeop implementation, as well.
  • If they don't conflict, we normally default to including extensions. There are exceptions, though.

@thixotropist
Copy link
Contributor

@GhidorahRex - thanks! I can work within those suggestions. Pushing details into the pcodeops swamp is the right thing to do so long as nobody expects to drain that swamp (type inference, context management, user rules and transforms, ...) anytime soon.

@thixotropist
Copy link
Contributor

I expect to push supporting code to https://github.com/thixotropist/ghidra/tree/isa_ext later this week. Here's what your test.o example looks like at the moment:

Image

Most of the zfa extension implements semantics that Ghidra doesn't attempt to handle - exception generation, rounding options, NaN processing, and quad- and half-precision floating point. I've taken the lazy approach of adding just enough to the sleigh semantics to let the Ghidra user glance at the decompiler window and decide whether or not they care about a code block. In your test case, that means adding a user pcodeop so that the decompiler shows a constant is loaded but not bothering to show what that constant was. A glance at the disassembler window will show that answer.

The new zfa support in riscv.zfa.sinc tracks the binutils zfa.s testsuite example - some of the fli.s instruction code points don't exist in that test suite, so I haven't tested them here. Similarly zfa.s includes reference instructions from other ISA extensions, so I'm adding support for a few of them too.

That means I've added semantics for half- and quad-precision floating point instructions that are incorrect from an emulation point of view, often using the semantics of vanilla single or double precision ops instead.

@gemesa
Copy link
Contributor Author

gemesa commented Feb 11, 2025

Awesome news, thank you for your work.

@thixotropist
Copy link
Contributor

I've pushed draft support for zfa to https://github.com/thixotropist/ghidra/tree/isa_ext, a Ghidra fork collecting many riscv instruction set extensions. There is a long-running PR #5778 under review by @GhidorahRex. If accepted, this support will be merged into the master branch and then part of a formal release.

Other possible paths forward:

  • you clone the isa_ext fork locally to see if it meets your needs, with special attention to the decompiler view displaying instruction semantics in a C-like way.
  • you clone the RISCV language definitions only and use the distribution's support/sleigh utility to install them inside a regular Ghidra release
  • the Ghidra developers ask for a minimal cherry-picked PR that covers only the zfa extension
  • the Ghidra developers defer merging zfa support until everyone has a clear understanding of how conflicting RISCV extensions should be supported within the core Ghidra release. For example, merging PR Update RISCV-64 sleigh files to support vector, bit manipulation, and crypto extensions #5778 would disable existing Ghidra support for the xuantie c906 and c910 processors, which use a pre-standard version of the RISCV vector instruction set.

@GhidorahRex GhidorahRex self-assigned this Feb 12, 2025
@GhidorahRex GhidorahRex added Type: Bug Something isn't working Status: Triage Information is being gathered labels Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Processor/RISC-V Status: Triage Information is being gathered Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants