Sources: Run clang-format on everything.

This commit is contained in:
Emmanuel Gil Peyrot 2016-09-18 09:38:01 +09:00
parent fe948af095
commit dc8479928c
386 changed files with 19560 additions and 18080 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -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;
}

View file

@ -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

View file

@ -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;
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;
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;
NCCH_Header ncch_header;
ExeFs_Header exefs_header;
ExHeader_Header exheader_header;
std::string filepath;
std::string filepath;
};
} // namespace Loader

View file

@ -56,7 +56,7 @@ struct SMDH {
Italian = 4,
Spanish = 5,
SimplifiedChinese = 6,
Korean= 7,
Korean = 7,
Dutch = 8,
Portuguese = 9,
Russian = 10,