diff options
| author | Open-IOV <dev@open-iov.org> | 2026-09-23 05:44:08 -0400 |
|---|---|---|
| committer | Open-IOV <dev@open-iov.org> | 2026-09-23 05:46:43 -0400 |
| commit | 2302fc09080bad51c73f293294e19fd4db464eb0 (patch) | |
| tree | c722d186347fdef5a34131e9e143b1549b1daf8e /tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java | |
| download | open-iov-2302fc09080bad51c73f293294e19fd4db464eb0.tar.gz open-iov-2302fc09080bad51c73f293294e19fd4db464eb0.zip | |
Open-IOV: initial public release
Open-IOV virtualizes NVIDIA GPUs so that unmodified guest drivers run with
real GPU functionality - CUDA first, 3D and video to follow - on unmodified
hosts, without a proprietary vGPU license and without patching any driver,
firmware or hypervisor.
Core principle: emulate the interface, pass through the work.
kernel/ open-iov-vfio.ko - host VFIO mdev driver: virtual GPU device
(PCI config space, BAR shadows, MSI-X), GSP boot emulation,
GSP-RM message-queue/RPC emulation, memory model (GPU-VA to
guest-PA discovery) and the semaphore-completion service that
advances guest UVM progress.
userspace/ libiov.so management API and examples.
tools/ guest diagnostics, firmware analysis wrappers, RM probes.
scripts/ stack manager, VM harness, build/load/test automation.
config/ hardware/version profiles (the portability surface).
docs/ documentation tree - start at docs/README.md.
wiki/ long-form firmware and protocol deep dives.
Status: initialization works end to end for a stock 570.144 Linux guest on
Turing (TU104): driver probe, nvidia-smi, the full GSP-RM control battery,
object creation and the early CUDA/UVM start-up path. GPU work forwarding -
the step that makes CUDA kernels execute on real hardware - is the active
work item; see docs/04-implementation/01-known-knowns-and-unknowns.md.
License: BSD-3-Clause for the project; GPL-2.0 for kernel modules that link
GPL-only kernel interfaces. See LICENSE and docs/09-reference/legal-and-licensing.md.
Diffstat (limited to 'tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java')
| -rw-r--r-- | tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java b/tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java new file mode 100644 index 0000000..e1d78c3 --- /dev/null +++ b/tools/ghidra/gsp-tu104-570.144/scripts/DecompileFunctions.java @@ -0,0 +1,143 @@ +import ghidra.app.script.GhidraScript; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.Function; +import ghidra.program.model.listing.FunctionManager; +import ghidra.program.model.listing.Instruction; +import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.Memory; +import ghidra.app.decompiler.DecompInterface; +import ghidra.app.decompiler.DecompileResults; +import ghidra.util.task.TaskMonitor; +import java.io.*; + +public class DecompileFunctions extends GhidraScript { + + private DecompInterface decompiler; + + @Override + protected void run() throws Exception { + decompiler = new DecompInterface(); + decompiler.openProgram(currentProgram); + + String[] args = getScriptArgs(); + if (args.length == 0) { + println("Usage: DecompileFunctions.java <comma-separated-addresses>"); + return; + } + + String[] addresses = args[0].split(","); + + println("=== Targeted Decompilation ==="); + for (String addrStr : addresses) { + addrStr = addrStr.trim(); + if (addrStr.isEmpty()) continue; + + long addrVal; + try { + addrVal = Long.parseUnsignedLong(addrStr.startsWith("0x") ? addrStr.substring(2) : addrStr, 16); + } catch (NumberFormatException e) { + println("Invalid address: " + addrStr); + continue; + } + + Address addr = currentProgram.getAddressFactory().getAddress("0x" + Long.toHexString(addrVal)); + if (addr == null) { + println("Invalid address: " + addrStr); + continue; + } + + decompileFunction(addr); + } + + println("\n=== Decompilation Complete ==="); + } + + private void decompileFunction(Address entryAddr) throws Exception { + FunctionManager fm = currentProgram.getFunctionManager(); + Memory mem = currentProgram.getMemory(); + + // Manually disassemble from entry point by creating instructions + Address addr = entryAddr; + int maxBytes = 2000; + int bytes = 0; + + while (bytes < maxBytes && !monitor.isCancelled()) { + Instruction instr = currentProgram.getListing().getInstructionAt(addr); + if (instr != null) { + addr = instr.getMaxAddress().next(); + bytes += instr.getLength(); + continue; + } + + // Try to create instruction from bytes + try { + byte[] buf = new byte[4]; + int read = mem.getBytes(addr, buf); + if (read <= 0) break; + + // Create instruction prototype and try to disassemble + instr = currentProgram.getListing().createInstruction(addr, + currentProgram.getLanguage().getInstructionPrototype(buf), + new ghidra.program.model.mem.ByteMemBuffer(buf, 0, read), + currentProgram.getProgramContext(), 0); + + if (instr != null) { + addr = instr.getMaxAddress().next(); + bytes += instr.getLength(); + } else { + addr = addr.next().next(); + bytes += 2; + } + } catch (Exception e) { + addr = addr.next().next(); + bytes += 2; + } + } + println(" Disassembled " + bytes + " bytes from " + entryAddr); + + // Get or create function + Function func = fm.getFunctionAt(entryAddr); + if (func == null) { + func = fm.createFunction("FUNC_" + Long.toHexString(entryAddr.getOffset()).toUpperCase(), + entryAddr, null, ghidra.program.model.symbol.SourceType.ANALYSIS); + if (func == null) { + println("Failed to create function at " + entryAddr); + return; + } + println("Created function: " + func.getName() + " @ " + func.getEntryPoint()); + } else { + println("Existing function: " + func.getName() + " @ " + func.getEntryPoint()); + } + + // Decompile + println("\n--- Decompiling " + func.getName() + " @ " + func.getEntryPoint() + " ---"); + DecompileResults results = decompiler.decompileFunction(func, 120, monitor); + + if (results.decompileCompleted()) { + String cCode = results.getDecompiledFunction().getC(); + + // Save to file + String filename = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP/decompiled_" + + func.getName() + ".c"; + try (PrintWriter pw = new PrintWriter(new FileWriter(filename))) { + pw.println("// Function: " + func.getName()); + pw.println("// Address: " + func.getEntryPoint()); + pw.println("// Stack frame: " + func.getStackFrame().getFrameSize() + " bytes"); + pw.println(); + pw.print(cCode); + } + println(" Saved to: " + filename); + + // Print first 100 lines + String[] lines = cCode.split("\n"); + for (int i = 0; i < Math.min(100, lines.length); i++) { + println(" " + lines[i]); + } + if (lines.length > 100) { + println(" ... (" + (lines.length - 100) + " more lines)"); + } + } else { + println(" Decompilation failed: " + results.getErrorMessage()); + } + } +} |
