----------------------------------------------------- package org.stave; import java.nio.ByteBuffer; /** * Forms the native memory pipeline within Ghidra's JVM environment. * Manages execution events from the Ghidra Emulator or debug interface * and passes raw byte arrays down to the compiled Rust binary with * zero-copy overhead via DirectByteBuffer. */ public class WarlockStaveBridge { private long nativeContextHandle = 0; static { // Loads the native library (libstave_core.so / stave_core.dll) System.loadLibrary("stave_core"); } private native long initializeWarlockStave(); private native String staveIngestGhidraFrame( long contextPtr, ByteBuffer buffer, long rip, int eflags ); private native void destroyWarlockStave(long contextPtr); public void initializeComponent() { this.nativeContextHandle = initializeWarlockStave(); } public synchronized void processEmulatorStepEvent( long executionRip, byte[] memoryPageFrame, int registerEflags ) { if (this.nativeContextHandle == 0) return; // Allocate a direct Java NIO byte buffer so the underlying // memory is accessible to native code without copying ByteBuffer directBuffer = ByteBuffer.allocateDirect(memoryPageFrame.length); directBuffer.put(memoryPageFrame); directBuffer.flip(); String telemetryJsonOutput = staveIngestGhidraFrame( this.nativeContextHandle, directBuffer, executionRip, registerEflags ); dispatchToEguiWorkspace(telemetryJsonOutput); } private void dispatchToEguiWorkspace(String jsonStateFrame) { // Enqueues the serialized tracking snapshot onto // the main UI event stream } public void terminateComponent() { if (this.nativeContextHandle != 0) { destroyWarlockStave(this.nativeContextHandle); this.nativeContextHandle = 0; } } } =============================================================================== 11. BUILD AUTOMATION & CROSS-COMPILATION (build.sh)