summaryrefslogtreecommitdiffstats
path: root/src/core/loader
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
committerEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
commitdc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch)
tree569a7f13128450bbab973236615587ff00bced5f /src/core/loader
parentTravis: Import Dolphin’s clang-format hook. (diff)
downloadyuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.bz2
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.lz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.zst
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip
Diffstat (limited to 'src/core/loader')
-rw-r--r--src/core/loader/3dsx.cpp85
-rw-r--r--src/core/loader/3dsx.h9
-rw-r--r--src/core/loader/elf.cpp231
-rw-r--r--src/core/loader/elf.h3
-rw-r--r--src/core/loader/loader.cpp15
-rw-r--r--src/core/loader/loader.h11
-rw-r--r--src/core/loader/ncch.cpp62
-rw-r--r--src/core/loader/ncch.h39
-rw-r--r--src/core/loader/smdh.h2
9 files changed, 249 insertions, 208 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index a16411e14..c2e87f592 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -37,20 +37,14 @@ namespace Loader {
* The BSS section must be cleared manually by the application.
*/
-enum THREEDSX_Error {
- ERROR_NONE = 0,
- ERROR_READ = 1,
- ERROR_FILE = 2,
- ERROR_ALLOC = 3
-};
+enum THREEDSX_Error { ERROR_NONE = 0, ERROR_READ = 1, ERROR_FILE = 2, ERROR_ALLOC = 3 };
static const u32 RELOCBUFSIZE = 512;
static const unsigned int NUM_SEGMENTS = 3;
// File header
#pragma pack(1)
-struct THREEDSX_Header
-{
+struct THREEDSX_Header {
u32 magic;
u16 header_size, reloc_hdr_size;
u32 format_ver;
@@ -66,11 +60,11 @@ struct THREEDSX_Header
};
// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts.
-struct THREEDSX_RelocHdr
-{
+struct THREEDSX_RelocHdr {
// # of absolute relocations (that is, fix address to post-relocation memory layout)
u32 cross_segment_absolute;
- // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched)
+ // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be
+ // patched)
u32 cross_segment_relative;
// more?
@@ -80,21 +74,18 @@ struct THREEDSX_RelocHdr
};
// Relocation entry: from the current pointer, skip X words and patch Y words
-struct THREEDSX_Reloc
-{
+struct THREEDSX_Reloc {
u16 skip, patch;
};
#pragma pack()
-struct THREEloadinfo
-{
+struct THREEloadinfo {
u8* seg_ptrs[3]; // code, rodata & data
u32 seg_addrs[3];
u32 seg_sizes[3];
};
-static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets)
-{
+static u32 TranslateAddr(u32 addr, const THREEloadinfo* loadinfo, u32* offsets) {
if (addr < offsets[0])
return loadinfo->seg_addrs[0] + addr;
if (addr < offsets[1])
@@ -105,8 +96,8 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets)
using Kernel::SharedPtr;
using Kernel::CodeSet;
-static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset)
-{
+static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr,
+ SharedPtr<CodeSet>* out_codeset) {
if (!file.IsOpen())
return ERROR_FILE;
@@ -118,13 +109,14 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
return ERROR_READ;
THREEloadinfo loadinfo;
- //loadinfo segments must be a multiple of 0x1000
- loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) &~0xFFF;
- loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) &~0xFFF;
- loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) &~0xFFF;
- u32 offsets[2] = { loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] };
+ // loadinfo segments must be a multiple of 0x1000
+ loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) & ~0xFFF;
+ loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) & ~0xFFF;
+ loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) & ~0xFFF;
+ u32 offsets[2] = {loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1]};
u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32);
- std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]);
+ std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] +
+ loadinfo.seg_sizes[2]);
loadinfo.seg_addrs[0] = base_addr;
loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0];
@@ -149,7 +141,8 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
return ERROR_READ;
if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size)
return ERROR_READ;
- if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != hdr.data_seg_size - hdr.bss_size)
+ if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) !=
+ hdr.data_seg_size - hdr.bss_size)
return ERROR_READ;
// BSS clear
@@ -157,11 +150,12 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
// Relocate the segments
for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) {
- for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) {
+ for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables;
+ current_segment_reloc_table++) {
u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table];
if (current_segment_reloc_table >= 2) {
// We are not using this table - ignore it because we don't know what it dose
- file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR);
+ file.Seek(n_relocs * sizeof(THREEDSX_Reloc), SEEK_CUR);
continue;
}
THREEDSX_Reloc reloc_table[RELOCBUFSIZE];
@@ -173,17 +167,20 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
u32 remaining = std::min(RELOCBUFSIZE, n_relocs);
n_relocs -= remaining;
- if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != remaining * sizeof(THREEDSX_Reloc))
+ if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) !=
+ remaining * sizeof(THREEDSX_Reloc))
return ERROR_READ;
- for (unsigned current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) {
+ for (unsigned current_inprogress = 0;
+ current_inprogress < remaining && pos < end_pos; current_inprogress++) {
const auto& table = reloc_table[current_inprogress];
LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)", current_segment_reloc_table,
static_cast<u32>(table.skip), static_cast<u32>(table.patch));
pos += table.skip;
s32 num_patches = table.patch;
while (0 < num_patches && pos < end_pos) {
- u32 in_addr = static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data());
+ u32 in_addr =
+ static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data());
u32 addr = TranslateAddr(*pos, &loadinfo, offsets);
LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)",
base_addr + in_addr, addr, current_segment_reloc_table, *pos);
@@ -195,7 +192,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
*pos = static_cast<u32>(addr - in_addr);
break;
default:
- break; //this should never happen
+ break; // this should never happen
}
pos++;
num_patches--;
@@ -209,23 +206,24 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared
SharedPtr<CodeSet> code_set = CodeSet::Create("", 0);
code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data();
- code_set->code.addr = loadinfo.seg_addrs[0];
- code_set->code.size = loadinfo.seg_sizes[0];
+ code_set->code.addr = loadinfo.seg_addrs[0];
+ code_set->code.size = loadinfo.seg_sizes[0];
code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data();
- code_set->rodata.addr = loadinfo.seg_addrs[1];
- code_set->rodata.size = loadinfo.seg_sizes[1];
+ code_set->rodata.addr = loadinfo.seg_addrs[1];
+ code_set->rodata.size = loadinfo.seg_sizes[1];
code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data();
- code_set->data.addr = loadinfo.seg_addrs[2];
- code_set->data.size = loadinfo.seg_sizes[2];
+ code_set->data.addr = loadinfo.seg_addrs[2];
+ code_set->data.size = loadinfo.seg_sizes[2];
code_set->entrypoint = code_set->code.addr;
code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]);
LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]);
- LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size);
+ LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2],
+ hdr.bss_size);
*out_codeset = code_set;
return ERROR_NONE;
@@ -260,17 +258,20 @@ ResultStatus AppLoader_THREEDSX::Load() {
Kernel::g_current_process->address_mappings = default_address_mappings;
// Attach the default resource limit (APPLICATION) to the process
- Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
+ Kernel::g_current_process->resource_limit =
+ Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE);
- Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS);
+ Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this),
+ Service::FS::ArchiveIdCode::RomFS);
is_loaded = true;
return ResultStatus::Success;
}
-ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
+ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file,
+ u64& offset, u64& size) {
if (!file.IsOpen())
return ResultStatus::Error;
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h
index 90b20c61c..09a788a1c 100644
--- a/src/core/loader/3dsx.h
+++ b/src/core/loader/3dsx.h
@@ -17,8 +17,10 @@ namespace Loader {
/// Loads an 3DSX file
class AppLoader_THREEDSX final : public AppLoader {
public:
- AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename, const std::string& filepath)
- : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {}
+ AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename,
+ const std::string& filepath)
+ : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {
+ }
/**
* Returns the type of the file
@@ -55,7 +57,8 @@ public:
* @param size Size of the RomFS in bytes
* @return ResultStatus result of function
*/
- ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override;
+ ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
+ u64& size) override;
private:
std::string filename;
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 69df94324..53c10a456 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -3,8 +3,8 @@
// Refer to the license.txt file included.
#include <cstring>
-#include <string>
#include <memory>
+#include <string>
#include "common/common_types.h"
#include "common/file_util.h"
@@ -24,112 +24,111 @@ using Kernel::CodeSet;
// File type
enum ElfType {
- ET_NONE = 0,
- ET_REL = 1,
- ET_EXEC = 2,
- ET_DYN = 3,
- ET_CORE = 4,
+ ET_NONE = 0,
+ ET_REL = 1,
+ ET_EXEC = 2,
+ ET_DYN = 3,
+ ET_CORE = 4,
ET_LOPROC = 0xFF00,
ET_HIPROC = 0xFFFF,
};
// Machine/Architecture
enum ElfMachine {
- EM_NONE = 0,
- EM_M32 = 1,
+ EM_NONE = 0,
+ EM_M32 = 1,
EM_SPARC = 2,
- EM_386 = 3,
- EM_68K = 4,
- EM_88K = 5,
- EM_860 = 7,
- EM_MIPS = 8
+ EM_386 = 3,
+ EM_68K = 4,
+ EM_88K = 5,
+ EM_860 = 7,
+ EM_MIPS = 8
};
// File version
-#define EV_NONE 0
+#define EV_NONE 0
#define EV_CURRENT 1
// Identification index
-#define EI_MAG0 0
-#define EI_MAG1 1
-#define EI_MAG2 2
-#define EI_MAG3 3
-#define EI_CLASS 4
-#define EI_DATA 5
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
#define EI_VERSION 6
-#define EI_PAD 7
+#define EI_PAD 7
#define EI_NIDENT 16
// Sections constants
// Section types
-#define SHT_NULL 0
-#define SHT_PROGBITS 1
-#define SHT_SYMTAB 2
-#define SHT_STRTAB 3
-#define SHT_RELA 4
-#define SHT_HASH 5
-#define SHT_DYNAMIC 6
-#define SHT_NOTE 7
-#define SHT_NOBITS 8
-#define SHT_REL 9
-#define SHT_SHLIB 10
-#define SHT_DYNSYM 11
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7FFFFFFF
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xFFFFFFFF
// Section flags
-enum ElfSectionFlags
-{
- SHF_WRITE = 0x1,
- SHF_ALLOC = 0x2,
+enum ElfSectionFlags {
+ SHF_WRITE = 0x1,
+ SHF_ALLOC = 0x2,
SHF_EXECINSTR = 0x4,
- SHF_MASKPROC = 0xF0000000,
+ SHF_MASKPROC = 0xF0000000,
};
// Segment types
-#define PT_NULL 0
-#define PT_LOAD 1
-#define PT_DYNAMIC 2
-#define PT_INTERP 3
-#define PT_NOTE 4
-#define PT_SHLIB 5
-#define PT_PHDR 6
-#define PT_LOPROC 0x70000000
-#define PT_HIPROC 0x7FFFFFFF
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7FFFFFFF
// Segment flags
-#define PF_X 0x1
-#define PF_W 0x2
-#define PF_R 0x4
+#define PF_X 0x1
+#define PF_W 0x2
+#define PF_R 0x4
#define PF_MASKPROC 0xF0000000
-typedef unsigned int Elf32_Addr;
+typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
-typedef unsigned int Elf32_Off;
-typedef signed int Elf32_Sword;
-typedef unsigned int Elf32_Word;
+typedef unsigned int Elf32_Off;
+typedef signed int Elf32_Sword;
+typedef unsigned int Elf32_Word;
////////////////////////////////////////////////////////////////////////////////////////////////////
// ELF file header
struct Elf32_Ehdr {
unsigned char e_ident[EI_NIDENT];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry;
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
};
// Section header
@@ -138,7 +137,7 @@ struct Elf32_Shdr {
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
+ Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
@@ -149,7 +148,7 @@ struct Elf32_Shdr {
// Segment header
struct Elf32_Phdr {
Elf32_Word p_type;
- Elf32_Off p_offset;
+ Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
@@ -160,12 +159,12 @@ struct Elf32_Phdr {
// Symbol table entry
struct Elf32_Sym {
- Elf32_Word st_name;
- Elf32_Addr st_value;
- Elf32_Word st_size;
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
- Elf32_Half st_shndx;
+ Elf32_Half st_shndx;
};
// Relocation entries
@@ -181,35 +180,51 @@ typedef int SectionID;
class ElfReader {
private:
- char *base;
- u32 *base32;
+ char* base;
+ u32* base32;
- Elf32_Ehdr *header;
- Elf32_Phdr *segments;
- Elf32_Shdr *sections;
+ Elf32_Ehdr* header;
+ Elf32_Phdr* segments;
+ Elf32_Shdr* sections;
- u32 *sectionAddrs;
+ u32* sectionAddrs;
bool relocate;
u32 entryPoint;
public:
- ElfReader(void *ptr);
+ ElfReader(void* ptr);
- u32 Read32(int off) const { return base32[off >> 2]; }
+ u32 Read32(int off) const {
+ return base32[off >> 2];
+ }
// Quick accessors
- ElfType GetType() const { return (ElfType)(header->e_type); }
- ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
- u32 GetEntryPoint() const { return entryPoint; }
- u32 GetFlags() const { return (u32)(header->e_flags); }
+ ElfType GetType() const {
+ return (ElfType)(header->e_type);
+ }
+ ElfMachine GetMachine() const {
+ return (ElfMachine)(header->e_machine);
+ }
+ u32 GetEntryPoint() const {
+ return entryPoint;
+ }
+ u32 GetFlags() const {
+ return (u32)(header->e_flags);
+ }
SharedPtr<CodeSet> LoadInto(u32 vaddr);
bool LoadSymbols();
- int GetNumSegments() const { return (int)(header->e_phnum); }
- int GetNumSections() const { return (int)(header->e_shnum); }
- const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
- const char *GetSectionName(int section) const;
- const u8 *GetSectionDataPtr(int section) const {
+ int GetNumSegments() const {
+ return (int)(header->e_phnum);
+ }
+ int GetNumSections() const {
+ return (int)(header->e_shnum);
+ }
+ const u8* GetPtr(int offset) const {
+ return (u8*)base + offset;
+ }
+ const char* GetSectionName(int section) const;
+ const u8* GetSectionDataPtr(int section) const {
if (section < 0 || section >= header->e_shnum)
return nullptr;
if (sections[section].sh_type != SHT_NOBITS)
@@ -220,19 +235,23 @@ public:
bool IsCodeSection(int section) const {
return sections[section].sh_type == SHT_PROGBITS;
}
- const u8 *GetSegmentPtr(int segment) {
+ const u8* GetSegmentPtr(int segment) {
return GetPtr(segments[segment].p_offset);
}
- u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
- unsigned int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
- SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
+ u32 GetSectionAddr(SectionID section) const {
+ return sectionAddrs[section];
+ }
+ unsigned int GetSectionSize(SectionID section) const {
+ return sections[section].sh_size;
+ }
+ SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found
bool DidRelocate() const {
return relocate;
}
};
-ElfReader::ElfReader(void *ptr) {
+ElfReader::ElfReader(void* ptr) {
base = (char*)ptr;
base32 = (u32*)ptr;
header = (Elf32_Ehdr*)ptr;
@@ -245,7 +264,7 @@ ElfReader::ElfReader(void *ptr) {
LoadSymbols();
}
-const char *ElfReader::GetSectionName(int section) const {
+const char* ElfReader::GetSectionName(int section) const {
if (sections[section].sh_type == SHT_NULL)
return nullptr;
@@ -303,12 +322,15 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
} else if (permission_flags == (PF_R | PF_W)) {
codeset_segment = &codeset->data;
} else {
- LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, p->p_flags);
+ LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i,
+ p->p_flags);
continue;
}
if (codeset_segment->size != 0) {
- LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra segment (id %i)", i);
+ LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra "
+ "segment (id %i)",
+ i);
continue;
}
@@ -332,9 +354,9 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
return codeset;
}
-SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const {
+SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const {
for (int i = firstSection; i < header->e_shnum; i++) {
- const char *secname = GetSectionName(i);
+ const char* secname = GetSectionName(i);
if (secname != nullptr && strcmp(name, secname) == 0)
return i;
@@ -347,9 +369,9 @@ bool ElfReader::LoadSymbols() {
SectionID sec = GetSectionByName(".symtab");
if (sec != -1) {
int stringSection = sections[sec].sh_link;
- const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection));
+ const char* stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection));
- //We have a symbol table!
+ // We have a symbol table!
const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec));
unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
for (unsigned sym = 0; sym < numSymbols; sym++) {
@@ -359,7 +381,7 @@ bool ElfReader::LoadSymbols() {
int type = symtab[sym].st_info & 0xF;
- const char *name = stringBase + symtab[sym].st_name;
+ const char* name = stringBase + symtab[sym].st_name;
Symbols::Add(symtab[sym].st_value, name, size, type);
@@ -411,7 +433,8 @@ ResultStatus AppLoader_ELF::Load() {
Kernel::g_current_process->address_mappings = default_address_mappings;
// Attach the default resource limit (APPLICATION) to the process
- Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
+ Kernel::g_current_process->resource_limit =
+ Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE);
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h
index cb3724f9d..0b1456c64 100644
--- a/src/core/loader/elf.h
+++ b/src/core/loader/elf.h
@@ -18,7 +18,8 @@ namespace Loader {
class AppLoader_ELF final : public AppLoader {
public:
AppLoader_ELF(FileUtil::IOFile&& file, std::string filename)
- : AppLoader(std::move(file)), filename(std::move(filename)) { }
+ : AppLoader(std::move(file)), filename(std::move(filename)) {
+ }
/**
* Returns the type of the file
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 9719d30d5..b392bf544 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -18,17 +18,17 @@
namespace Loader {
const std::initializer_list<Kernel::AddressMapping> default_address_mappings = {
- { 0x1FF50000, 0x8000, true }, // part of DSP RAM
- { 0x1FF70000, 0x8000, true }, // part of DSP RAM
- { 0x1F000000, 0x600000, false }, // entire VRAM
+ {0x1FF50000, 0x8000, true}, // part of DSP RAM
+ {0x1FF70000, 0x8000, true}, // part of DSP RAM
+ {0x1F000000, 0x600000, false}, // entire VRAM
};
FileType IdentifyFile(FileUtil::IOFile& file) {
FileType type;
-#define CHECK_TYPE(loader) \
- type = AppLoader_##loader::IdentifyType(file); \
- if (FileType::Error != type) \
+#define CHECK_TYPE(loader) \
+ type = AppLoader_##loader::IdentifyType(file); \
+ if (FileType::Error != type) \
return type;
CHECK_TYPE(THREEDSX)
@@ -100,7 +100,8 @@ const char* GetFileTypeString(FileType type) {
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
*/
static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileType type,
- const std::string& filename, const std::string& filepath) {
+ const std::string& filename,
+ const std::string& filepath) {
switch (type) {
// 3DSX file format.
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 77d87afe1..5f48d2ffe 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -30,7 +30,7 @@ enum class FileType {
CXI,
CIA,
ELF,
- THREEDSX, //3DSX
+ THREEDSX, // 3DSX
};
/**
@@ -81,8 +81,10 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) {
/// Interface for loading an application
class AppLoader : NonCopyable {
public:
- AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) { }
- virtual ~AppLoader() { }
+ AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) {
+ }
+ virtual ~AppLoader() {
+ }
/**
* Returns the type of this file
@@ -140,7 +142,8 @@ public:
* @param size The size of the romfs
* @return ResultStatus result of function
*/
- virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
+ virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
+ u64& size) {
return ResultStatus::ErrorNotImplemented;
}
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index fca091ff9..5b996d671 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -22,8 +22,8 @@
namespace Loader {
-static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs
-static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes)
+static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs
+static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes)
/**
* Get the decompressed size of an LZSS compressed ExeFS file
@@ -44,7 +44,8 @@ static u32 LZSS_GetDecompressedSize(const u8* buffer, u32 size) {
* @param decompressed_size Size of decompressed buffer
* @return True on success, otherwise false
*/
-static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed, u32 decompressed_size) {
+static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed,
+ u32 decompressed_size) {
const u8* footer = compressed + compressed_size - 8;
u32 buffer_top_and_bottom = *reinterpret_cast<const u32*>(footer);
u32 out = decompressed_size;
@@ -55,7 +56,7 @@ static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decom
memcpy(decompressed, compressed, compressed_size);
while (index > stop_index) {
- u8 control = compressed[--index];
+ u8 control = compressed[--index];
for (unsigned i = 0; i < 8; i++) {
if (index <= stop_index)
@@ -128,7 +129,7 @@ ResultStatus AppLoader_NCCH::LoadExec() {
std::vector<u8> code;
if (ResultStatus::Success == ReadCode(code)) {
std::string process_name = Common::StringFromFixedZeroTerminatedBuffer(
- (const char*)exheader_header.codeset_info.name, 8);
+ (const char*)exheader_header.codeset_info.name, 8);
SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, ncch_header.program_id);
@@ -147,7 +148,8 @@ ResultStatus AppLoader_NCCH::LoadExec() {
codeset->data.offset = codeset->rodata.offset + codeset->rodata.size;
codeset->data.addr = exheader_header.codeset_info.data.address;
- codeset->data.size = exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size;
+ codeset->data.size =
+ exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size;
codeset->entrypoint = codeset->code.addr;
codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
@@ -155,15 +157,18 @@ ResultStatus AppLoader_NCCH::LoadExec() {
Kernel::g_current_process = Kernel::Process::Create(std::move(codeset));
// Attach a resource limit to the process based on the resource limit category
- Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(
- static_cast<Kernel::ResourceLimitCategory>(exheader_header.arm11_system_local_caps.resource_limit_category));
+ Kernel::g_current_process->resource_limit =
+ Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>(
+ exheader_header.arm11_system_local_caps.resource_limit_category));
// Set the default CPU core for this process
- Kernel::g_current_process->ideal_processor = exheader_header.arm11_system_local_caps.ideal_processor;
+ Kernel::g_current_process->ideal_processor =
+ exheader_header.arm11_system_local_caps.ideal_processor;
// Copy data while converting endianess
std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps;
- std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps));
+ std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(),
+ begin(kernel_caps));
Kernel::g_current_process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size());
s32 priority = exheader_header.arm11_system_local_caps.priority;
@@ -192,7 +197,8 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>&
LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", section_number,
section.offset, section.size, section.name);
- s64 section_offset = (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset);
+ s64 section_offset =
+ (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset);
file.Seek(section_offset, SEEK_SET);
if (strcmp(section.name, ".code") == 0 && is_compressed) {
@@ -254,25 +260,25 @@ ResultStatus AppLoader_NCCH::LoadExeFS() {
if (file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)) != sizeof(ExHeader_Header))
return ResultStatus::Error;
- is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1;
- entry_point = exheader_header.codeset_info.text.address;
- code_size = exheader_header.codeset_info.text.code_size;
- stack_size = exheader_header.codeset_info.stack_size;
- bss_size = exheader_header.codeset_info.bss_size;
- core_version = exheader_header.arm11_system_local_caps.core_version;
- priority = exheader_header.arm11_system_local_caps.priority;
+ is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1;
+ entry_point = exheader_header.codeset_info.text.address;
+ code_size = exheader_header.codeset_info.text.code_size;
+ stack_size = exheader_header.codeset_info.stack_size;
+ bss_size = exheader_header.codeset_info.bss_size;
+ core_version = exheader_header.arm11_system_local_caps.core_version;
+ priority = exheader_header.arm11_system_local_caps.priority;
resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category;
- LOG_INFO(Loader, "Name: %s" , exheader_header.codeset_info.name);
- LOG_INFO(Loader, "Program ID: %016llX" , ncch_header.program_id);
- LOG_DEBUG(Loader, "Code compressed: %s" , is_compressed ? "yes" : "no");
+ LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name);
+ LOG_INFO(Loader, "Program ID: %016llX", ncch_header.program_id);
+ LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no");
LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point);
LOG_DEBUG(Loader, "Code size: 0x%08X", code_size);
LOG_DEBUG(Loader, "Stack size: 0x%08X", stack_size);
LOG_DEBUG(Loader, "Bss size: 0x%08X", bss_size);
- LOG_DEBUG(Loader, "Core version: %d" , core_version);
- LOG_DEBUG(Loader, "Thread priority: 0x%X" , priority);
- LOG_DEBUG(Loader, "Resource limit category: %d" , resource_limit_category);
+ LOG_DEBUG(Loader, "Core version: %d", core_version);
+ LOG_DEBUG(Loader, "Thread priority: 0x%X", priority);
+ LOG_DEBUG(Loader, "Resource limit category: %d", resource_limit_category);
if (exheader_header.arm11_system_local_caps.program_id != ncch_header.program_id) {
LOG_ERROR(Loader, "ExHeader Program ID mismatch: the ROM is probably encrypted.");
@@ -309,7 +315,8 @@ ResultStatus AppLoader_NCCH::Load() {
if (ResultStatus::Success != result)
return result;
- Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS);
+ Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this),
+ Service::FS::ArchiveIdCode::RomFS);
return ResultStatus::Success;
}
@@ -329,7 +336,8 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector<u8>& buffer) {
return LoadSectionExeFS("logo", buffer);
}
-ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
+ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
+ u64& size) {
if (!file.IsOpen())
return ResultStatus::Error;
@@ -341,7 +349,7 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_
LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset);
LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size);
- if (file.GetSize () < romfs_offset + romfs_size)
+ if (file.GetSize() < romfs_offset + romfs_size)
return ResultStatus::Error;
// We reopen the file, to allow its position to be independent from file's
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h
index 75609ee57..0cd70f70c 100644
--- a/src/core/loader/ncch.h
+++ b/src/core/loader/ncch.h
@@ -164,7 +164,8 @@ namespace Loader {
class AppLoader_NCCH final : public AppLoader {
public:
AppLoader_NCCH(FileUtil::IOFile&& file, const std::string& filepath)
- : AppLoader(std::move(file)), filepath(filepath) { }
+ : AppLoader(std::move(file)), filepath(filepath) {
+ }
/**
* Returns the type of the file
@@ -222,10 +223,10 @@ public:
* @param size Size of the RomFS in bytes
* @return ResultStatus result of function
*/
- ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override;
+ ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
+ u64& size) override;
private:
-
/**
* Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.)
* @param name Name of section to read out of NCCH file
@@ -246,24 +247,24 @@ private:
*/
ResultStatus LoadExeFS();
- bool is_exefs_loaded = false;
- bool is_compressed = false;
-
- u32 entry_point = 0;
- u32 code_size = 0;
- u32 stack_size = 0;
- u32 bss_size = 0;
- u32 core_version = 0;
- u8 priority = 0;
- u8 resource_limit_category = 0;
- u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header
- u32 exefs_offset = 0;
-
- NCCH_Header ncch_header;
- ExeFs_Header exefs_header;
+ bool is_exefs_loaded = false;
+ bool is_compressed = false;
+
+ u32 entry_point = 0;
+ u32 code_size = 0;
+ u32 stack_size = 0;
+ u32 bss_size = 0;
+ u32 core_version = 0;
+ u8 priority = 0;
+ u8 resource_limit_category = 0;
+ u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header
+ u32 exefs_offset = 0;
+
+ NCCH_Header ncch_header;
+ ExeFs_Header exefs_header;
ExHeader_Header exheader_header;
- std::string filepath;
+ std::string filepath;
};
} // namespace Loader
diff --git a/src/core/loader/smdh.h b/src/core/loader/smdh.h
index 2011abda2..ab665ea82 100644
--- a/src/core/loader/smdh.h
+++ b/src/core/loader/smdh.h
@@ -56,7 +56,7 @@ struct SMDH {
Italian = 4,
Spanish = 5,
SimplifiedChinese = 6,
- Korean= 7,
+ Korean = 7,
Dutch = 8,
Portuguese = 9,
Russian = 10,