How the CpuDispatcher Orchestrates Execution with Import Stubs in SharpEmu

The CpuDispatcher prepares the guest CPU context, constructs a mutable import-stub mapping table, and delegates to the native backend to resolve imported function calls during guest execution.

The CpuDispatcher in SharpEmu serves as the central orchestrator for launching guest code. It bridges the high-level emulator entry points with the native execution backend by preparing memory regions, initializing CPU registers, and managing a dictionary that maps import stub addresses to runtime routine names.

Entry Point Handling and Context Preparation

Execution begins when the emulator calls DispatchEntry in src/SharpEmu.Core/Cpu/CpuDispatcher.cs (lines 82‑89). This public method accepts an optional importStubs dictionary from the caller, which maps guest virtual addresses to runtime stub identifiers (NIDs). The dispatcher immediately forwards this dictionary to the private DispatchEntryCore routine.

Inside DispatchEntryCore, the dispatcher prepares the execution environment by mapping three critical memory regions:

  • Stack space for guest execution
  • Thread-local storage (TLS) respecting the TlsPrefixSize defined in GuestTlsTemplate.cs
  • A return‑to‑host stub region that allows the guest to safely exit back to the emulator

Following the memory mapping, the method creates a CpuContext instance and initializes its registers (lines 184‑190). This context object encapsulates the complete CPU state that the native backend will execute.

Building the Import-Stub Mapping Table

Before handing control to the native layer, the dispatcher constructs a mutable working copy of the import stub map. As implemented in lines 14‑16 of CpuDispatcher.cs:

var effectiveImportStubs = importStubs is null
    ? new Dictionary<ulong, string>()
    : new Dictionary<ulong, string>(importStubs);

This effectiveImportStubs dictionary serves as the authoritative lookup table during execution. The dispatcher creates a mutable copy because the bootstrap payload installation may need to inject additional entries dynamically.

Injecting Bootstrap Payload Stubs

When the entry point appears to be the start of a bootstrap payload, TryInstallBootstrapPayload (lines 33‑39) executes automatically. This routine performs specialized setup:

  1. Maps a bootstrap stub region and a payload region into guest memory
  2. Writes a small bridge stub that transitions between the bootstrap code and the host runtime
  3. Adds two entries to effectiveImportStubs that map the stub addresses to RuntimeStubNids.BootstrapBridge (lines 63‑65)

The injection ensures that when the guest code calls these specific addresses, the native backend interprets them as requests to execute the bootstrap bridge routine rather than attempting to execute unmapped guest code.

Native Backend Execution and Resolution

With the context prepared and the stub map finalized, the dispatcher invokes the native execution layer. At lines 75‑83, the code calls:

var executionResult = _nativeCpuBackend.TryExecute(
    cpuContext,
    effectiveImportStubs,
    runtimeSymbols);

The DirectExecutionBackend (defined in src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.cs) consumes this data to drive actual CPU execution. When the running guest code encounters a call instruction targeting an imported function, the backend pauses execution and resolves the import by looking up the current instruction pointer (RIP) in the effectiveImportStubs dictionary. The value retrieved—such as RuntimeStubNids.ScePthreadCreate or RuntimeStubNids.SceAudioOutOpen—tells the backend which high-level runtime routine to invoke.

Execution Result Handling

After the native backend returns, the dispatcher evaluates the result at lines 105‑112. If TryExecute succeeds, the dispatcher records a successful CpuSessionSummary. If the backend encounters an unimplemented instruction or an unresolved import—meaning the RIP was not present in the stub map—the dispatcher generates a CpuNotImplementedInfo object that references the missing import handling, enabling developers to identify which stubs require implementation.

Summary

  • DispatchEntry receives the optional importStubs dictionary and forwards it to the core dispatch routine.
  • DispatchEntryCore creates a mutable effectiveImportStubs copy and prepares the CpuContext with mapped stack, TLS, and return-to-host regions.
  • TryInstallBootstrapPayload optionally injects bootstrap bridge entries into the stub map when the entry point indicates a payload header.
  • DirectExecutionBackend uses the stub map to resolve every imported call by looking up the guest RIP and translating it to a runtime routine name defined in RuntimeStubNids.cs.

Frequently Asked Questions

What is the role of the importStubs dictionary in SharpEmu?

The importStubs dictionary acts as a translation layer between guest virtual addresses and host runtime services. It maps a specific memory address—where the guest expects to find an imported function—to a string identifier (NID) that the native backend recognizes, such as RuntimeStubNids.ScePthreadCreate. Without this mapping, the backend cannot resolve external calls and will generate a CpuNotImplementedInfo error.

How does the CpuDispatcher handle bootstrap payloads?

When DispatchEntryCore detects a bootstrap payload header, it calls TryInstallBootstrapPayload (lines 33‑39). This method maps additional memory regions for the bootstrap code and injects two entries into the effectiveImportStubs dictionary (lines 63‑65). These entries point specific stub addresses to RuntimeStubNids.BootstrapBridge, allowing the native backend to intercept early initialization calls and hand them off to the emulator's bootstrap bridge logic.

Which backend consumes the import-stub mapping?

The DirectExecutionBackend class located in src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.cs consumes the mapping. During execution, it uses the dictionary to resolve every imported function call by querying the current RIP against the prepared stub table, ensuring that guest calls to runtime services are correctly redirected to the appropriate host implementations.

What happens when an import stub is not resolved?

If the native backend encounters a call to an address that does not exist in the effectiveImportStubs dictionary, it cannot complete the execution. The backend returns a failure result, causing the CpuDispatcher to create a CpuNotImplementedInfo record (lines 105‑112) that identifies the missing stub, allowing developers to extend the import mapping with the required runtime routine.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →