mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-03 12:27:21 +12:00
feat: 3dsx loading
romFS works too, pretty neat
This commit is contained in:
parent
a18ed8778f
commit
29352d223b
8 changed files with 469 additions and 39 deletions
79
include/loader/3dsx.hpp
Normal file
79
include/loader/3dsx.hpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include "helpers.hpp"
|
||||
#include "io_file.hpp"
|
||||
#include "loader/ncch.hpp"
|
||||
|
||||
struct HB3DSX {
|
||||
// File layout:
|
||||
// - File header
|
||||
// - Code, rodata and data relocation table headers
|
||||
// - Code segment
|
||||
// - Rodata segment
|
||||
// - Loadable (non-BSS) part of the data segment
|
||||
// - Code relocation table
|
||||
// - Rodata relocation table
|
||||
// - Data relocation table
|
||||
|
||||
// Memory layout before relocations are applied:
|
||||
// [0..codeSegSize) -> code segment
|
||||
// [codeSegSize..rodataSegSize) -> rodata segment
|
||||
// [rodataSegSize..dataSegSize) -> data segment
|
||||
|
||||
// Memory layout after relocations are applied: well, however the loader sets it up :)
|
||||
// The entrypoint is always the start of the code segment.
|
||||
// The BSS section must be cleared manually by the application.
|
||||
|
||||
// File header
|
||||
struct Header {
|
||||
// minus char magic[4]
|
||||
u16 headerSize;
|
||||
u16 relocHdrSize;
|
||||
u32 formatVer;
|
||||
u32 flags;
|
||||
|
||||
// Sizes of the code, rodata and data segments +
|
||||
// size of the BSS section (uninitialized latter half of the data segment)
|
||||
u32 codeSegSize, rodataSegSize, dataSegSize, bssSize;
|
||||
};
|
||||
|
||||
// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts.
|
||||
struct RelocHdr {
|
||||
u32 cAbsolute; // # of absolute relocations (that is, fix address to post-relocation memory layout)
|
||||
u32 cRelative; // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched)
|
||||
// more?
|
||||
|
||||
// Relocations are written in this order:
|
||||
// - Absolute relocs
|
||||
// - Relative relocs
|
||||
};
|
||||
enum class RelocKind {
|
||||
Absolute,
|
||||
Relative,
|
||||
};
|
||||
|
||||
// Relocation entry: from the current pointer, skip X words and patch Y words
|
||||
struct Reloc {
|
||||
u16 skip, patch;
|
||||
};
|
||||
|
||||
// _prm structure
|
||||
static constexpr std::array<char, 4> PRM_MAGIC = {'_', 'P', 'R', 'M'};
|
||||
struct PrmStruct {
|
||||
char magic[4];
|
||||
u32 pSrvOverride;
|
||||
u32 aptAppId;
|
||||
u32 heapSize, linearHeapSize;
|
||||
u32 pArgList;
|
||||
u32 runFlags;
|
||||
};
|
||||
|
||||
IOFile file;
|
||||
|
||||
static constexpr u32 ENTRYPOINT = 0x00100000; // Initial ARM11 PC
|
||||
u32 romFSSize = 0;
|
||||
u32 romFSOffset = 0;
|
||||
|
||||
bool hasRomFs() const;
|
||||
std::pair<bool, std::size_t> readRomFSBytes(void *dst, std::size_t offset, std::size_t size);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue