# How SharpEmu Parses eboot.bin Files: A Deep Dive into the SELF/ELF Loader

> Discover how SharpEmu parses eboot.bin files. Learn about SELF/ELF loading, memory mapping, NID resolution, and SelfImage construction for the CPU dispatcher.

- Repository: [Berk/sharpemu](https://github.com/par274/sharpemu)
- Tags: deep-dive
- Published: 2026-07-13

---

**SharpEmu parses eboot.bin files by detecting whether they are SELF-wrapped or raw ELF executables, extracting headers, mapping loadable segments into virtual memory, resolving import NIDs through dynamic relocation tables, and constructing a fully-prepared SelfImage for the CPU dispatcher.**

SharpEmu is an open-source PlayStation 4/5 emulator that handles commercial game executables packaged as `eboot.bin` files. According to the [par274/sharpemu](https://github.com/par274/sharpemu) source code, the emulator treats these binaries as either standard ELF executables or SELF-wrapped (Signed ELF) images requiring format detection. The parsing pipeline combines the `SharpEmuRuntime` facade with the `SelfLoader` class to validate, map, and prepare the executable for CPU emulation.

## Detecting the SELF Wrapper Format

The parsing process begins with format detection to determine if the binary uses Sony's proprietary SELF encryption wrapper or a standard ELF.

**File Loading** in `SharpEmuRuntime.LoadImage` ([[`src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs#L103-L127)) reads the binary from disk into a byte array and hands it to the loader.

**Magic Detection** occurs in `SelfLoader.ParseLayout` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L19-L48)). This method checks the first 4 bytes for the SELF magic value `0x4F153D1D`. If present, it extracts the SELF header and segment list; otherwise, the loader treats the file as a plain ELF starting at offset 0.

## Parsing ELF Headers and Program Segments

Once the format is determined, the loader validates the ELF structure and extracts the program header table.

**Header Validation** uses `ReadUnmanaged<ElfHeader>` in `SelfLoader.LoadCore` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L62-L66)) to read the ELF header located after the SELF header (or at offset 0 for raw ELF). The loader validates the ELF magic, class, and ABI version before proceeding.

**Program Header Parsing** happens in `SelfLoader.ParseProgramHeaders` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L51-L78)), which walks the program-header table to build an array of `ProgramHeader` structures describing loadable segments, dynamic sections, and proc-param regions.

## Memory Mapping and Segment Allocation

After parsing headers, the loader prepares the virtual address space for execution.

**Virtual Memory Reservation** in `SelfLoader.LoadCore` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L71-L88)) uses `PhysicalVirtualMemory` to reserve a contiguous region large enough for all loadable segments. The base address is chosen based on the image type (PS4 vs PS5) and may be forced to a specific address for SELF images.

**Segment Mapping** is handled by `SelfLoader.MapLoadSegments` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L89-L104)). For each `ProgramHeader` of type **Load**, the loader copies file bytes (or zero-fills the remainder) into virtual memory at `vaddr + imageBase`, creating the in-memory image the CPU will execute.

## Dynamic Linking and Import Resolution

Modern PlayStation executables rely heavily on dynamic imports identified by NIDs (Name IDs), which the loader must resolve before execution.

**Dynamic Section Resolution** in `SelfLoader.ResolveAndPatchImportStubs` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L59-L71)) loads the **Dynamic** program header and parses the dynamic table via `ParseDynamicInfo`. This extracts offsets for the string table, symbol table, and relocation tables (`Rela`, `JmpRel`).

**Relocation Collection** occurs in `SelfLoader.CollectRelocations` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L113-L130)), which reads all relocation entries (`ElfRelocation`) from the `Rela` and `JmpRel` sections. Each entry becomes a `RelocationDescriptor` recording the target address, addend, and import NID.

**Stub Patching** via `SelfLoader.CreateImportStubMapping` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L127-L140)) allocates a stub address for every unique import NID. The loader writes the resolved address (or addend) into the target location, handling special relocation types such as TLS module ID.

## Metadata Extraction and Symbol Registration

The loader also extracts game metadata and registers symbols for high-level emulation (HLE).

**param.json Loading** in `SelfLoader.TryLoadParamJson` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L80-L118)) looks for [`sce_sys/param.json`](https://github.com/par274/sharpemu/blob/main/sce_sys/param.json) (or [`param.json`](https://github.com/par274/sharpemu/blob/main/param.json)) if a filesystem is provided. It extracts the title, title ID, and version, storing this metadata in the `SelfImage` object.

**Runtime Symbol Registration** scans both section and dynamic symbol tables:
- `SelfLoader.RegisterSectionRuntimeSymbols` processes section headers
- `SelfLoader.RegisterDynamicRuntimeSymbols` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L190-L212)) handles dynamic symbols

Both methods add kernel exports and HLE symbols to `runtimeSymbols` with their associated NIDs for fast lookup.

## Finalization and CPU Dispatch

Before execution, the loader prepares initialization routines and packages the final image.

**Initializer Collection** in `SelfLoader.CollectInitializerFunctions` ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs#L158-L170)) resolves `.init`, `.init_array`, and `.preinit_array` entries, recording their entry points so the emulator can run module constructors before the main entry point.

**Image Construction** in `SelfLoader.LoadCore` packages all gathered data—image base, ELF header, mapped regions, import stubs, runtime symbols, relocations, init functions, and metadata—into a `SelfImage` instance.

**Execution Dispatch** via `SharpEmuRuntime.Run` ([[`src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs#L30-L48)) receives the `SelfImage`, configures video/audio, registers the main module, and calls `CpuDispatcher.DispatchEntry` with the computed entry point (`elfHeader.EntryPoint + imageBase`).

## Code Examples

### Loading and Inspecting an eboot.bin

```csharp
// Create a runtime with default options
var runtime = SharpEmuRuntime.CreateDefault(options);

// Path to the eboot file (absolute or relative)
string ebootPath = @"E:\Games\Demo\eboot.bin";

// Load the image – this parses the file and returns a SelfImage
SelfImage image = runtime.LoadImage(ebootPath);

// Inspect parsed metadata
Console.WriteLine($"Title: {image.Title ?? "unknown"}");
Console.WriteLine($"TitleID: {image.TitleId ?? "unknown"}");
Console.WriteLine($"Entry point: 0x{image.EntryPoint:X}");
Console.WriteLine($"Mapped segments: {image.MappedRegions.Count}");

```

### Running the Executable

```csharp
// Executes the eboot after all initializers have been processed
OrbisGen2Result result = runtime.Run(ebootPath);

Console.WriteLine($"Run finished with status: {result}");

```

### Querying Imported NIDs

```csharp
foreach (var kv in image.ImportStubs)
{
    Console.WriteLine($"Stub at 0x{kv.Key:X16} → NID {kv.Value}");
}

```

### Accessing Runtime Symbols

```csharp
foreach (var kv in image.RuntimeSymbols)
{
    Console.WriteLine($"{kv.Key} → 0x{kv.Value:X16}");
}

```

## Key Source Files

- **[`SharpEmuRuntime.cs`](https://github.com/par274/sharpemu/blob/main/SharpEmuRuntime.cs)** ([[`src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs)): Public façade that loads the file, creates the `SelfImage`, and drives the emulator.
- **[`SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/SelfLoader.cs)** ([[`src/SharpEmu.Core/Loader/SelfLoader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfLoader.cs)): Core parser that detects SELF, parses ELF headers, maps segments, and resolves relocations.
- **[`SelfImage.cs`](https://github.com/par274/sharpemu/blob/main/SelfImage.cs)** ([[`src/SharpEmu.Core/Loader/SelfImage.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfImage.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/SelfImage.cs)): Immutable data holder for the fully-parsed image including metadata, regions, and symbols.
- **[`ProgramHeader.cs`](https://github.com/par274/sharpemu/blob/main/ProgramHeader.cs)** ([[`src/SharpEmu.Core/Loader/ProgramHeader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/ProgramHeader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/ProgramHeader.cs)): Structure describing each ELF program-header entry.
- **[`ElfHeader.cs`](https://github.com/par274/sharpemu/blob/main/ElfHeader.cs)** ([[`src/SharpEmu.Core/Loader/ElfHeader.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/ElfHeader.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Loader/ElfHeader.cs)): Structure representing the ELF file header used for validation and table location.
- **[`CpuDispatcher.cs`](https://github.com/par274/sharpemu/blob/main/CpuDispatcher.cs)** ([[`src/SharpEmu.Core/Cpu/CpuDispatcher.cs`](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Cpu/CpuDispatcher.cs)](https://github.com/par274/sharpemu/blob/main/src/SharpEmu.Core/Cpu/CpuDispatcher.cs)): Dispatches the entry point to the CPU emulation engine after parsing completes.

## Summary

- SharpEmu treats `eboot.bin` files as either SELF-wrapped or raw ELF executables, detecting the format via magic value `0x4F153D1D` in `SelfLoader.ParseLayout`.
- The loader validates ELF headers using `ReadUnmanaged<ElfHeader>` and walks program headers to identify loadable segments.
- Virtual memory allocation and segment mapping occur through `PhysicalVirtualMemory` and `SelfLoader.MapLoadSegments`, creating the executable image at the appropriate base address.
- Dynamic imports are resolved by collecting relocations from `Rela` and `JmpRel` sections, then patching stub addresses via `SelfLoader.CreateImportStubMapping`.
- Game metadata is extracted from [`param.json`](https://github.com/par274/sharpemu/blob/main/param.json) while runtime symbols are registered for HLE functionality.
- The fully parsed image is packaged into a `SelfImage` object and dispatched through `SharpEmuRuntime.Run` to the CPU emulation engine.

## Frequently Asked Questions

### Does SharpEmu support both PS4 and PS5 eboot.bin files?

Yes. The loader handles both PS4 and PS5 executables by detecting the SELF wrapper format and adjusting the base address allocation during the `PhysicalVirtualMemory` reservation phase based on the detected image type.

### What is the difference between SELF and ELF in SharpEmu's loader?

SELF (Signed ELF) is a Sony-specific wrapper format that may contain encrypted segments. SharpEmu checks for the magic value `0x4F153D1D` in `SelfLoader.ParseLayout` to detect the SELF header; if absent, the loader treats the file as a standard ELF executable beginning at offset 0.

### How does SharpEmu handle imported functions in eboot.bin?

The loader collects relocation entries from the `Rela` and `JmpRel` sections via `SelfLoader.CollectRelocations`, then creates import stub mappings for each unique NID using `SelfLoader.CreateImportStubMapping`. These stubs are patched to point to HLE implementations or resolved kernel exports before execution begins.

### Where does SharpEmu look for game metadata like title IDs?

During the loading process, `SelfLoader.TryLoadParamJson` searches for [`sce_sys/param.json`](https://github.com/par274/sharpemu/blob/main/sce_sys/param.json) (or [`param.json`](https://github.com/par274/sharpemu/blob/main/param.json)) within the provided filesystem. It extracts the title, title ID, and version, storing this information in the `SelfImage` metadata object for later use by the emulator interface.