mirror of
https://github.com/jakcron/nstool
synced 2024-11-22 21:49:30 +00:00
[hac] Add IniHeader & KernelInitialProcessHeader
This commit is contained in:
parent
44a9f7744c
commit
bac8fb57ff
6 changed files with 729 additions and 0 deletions
46
lib/libhac/include/nn/hac/IniHeader.h
Normal file
46
lib/libhac/include/nn/hac/IniHeader.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <fnd/List.h>
|
||||||
|
#include <fnd/IByteModel.h>
|
||||||
|
#include <nn/hac/define/ini.h>
|
||||||
|
|
||||||
|
namespace nn
|
||||||
|
{
|
||||||
|
namespace hac
|
||||||
|
{
|
||||||
|
class IniHeader :
|
||||||
|
public fnd::IByteModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IniHeader();
|
||||||
|
IniHeader(const IniHeader& other);
|
||||||
|
|
||||||
|
void operator=(const IniHeader& other);
|
||||||
|
bool operator==(const IniHeader& other) const;
|
||||||
|
bool operator!=(const IniHeader& other) const;
|
||||||
|
|
||||||
|
// IByteModel
|
||||||
|
void toBytes();
|
||||||
|
void fromBytes(const byte_t* data, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
uint32_t getSize() const;
|
||||||
|
void setSize(uint32_t size);
|
||||||
|
|
||||||
|
uint32_t getKipNum() const;
|
||||||
|
void setKipNum(uint32_t num);
|
||||||
|
private:
|
||||||
|
const std::string kModuleName = "INI_HEADER";
|
||||||
|
|
||||||
|
// raw binary
|
||||||
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
uint32_t mSize;
|
||||||
|
uint32_t mKipNum;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
137
lib/libhac/include/nn/hac/KernelInitialProcessHeader.h
Normal file
137
lib/libhac/include/nn/hac/KernelInitialProcessHeader.h
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <fnd/List.h>
|
||||||
|
#include <fnd/IByteModel.h>
|
||||||
|
#include <nn/hac/define/kip.h>
|
||||||
|
#include <nn/hac/KernelCapabilityControl.h>
|
||||||
|
|
||||||
|
namespace nn
|
||||||
|
{
|
||||||
|
namespace hac
|
||||||
|
{
|
||||||
|
class KernelInitialProcessHeader :
|
||||||
|
public fnd::IByteModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct sLayout
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
void operator=(const sLayout& other)
|
||||||
|
{
|
||||||
|
offset = other.offset;
|
||||||
|
size = other.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const sLayout& other) const
|
||||||
|
{
|
||||||
|
return (offset == other.offset) \
|
||||||
|
&& (size == other.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const sLayout& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sCodeSegment
|
||||||
|
{
|
||||||
|
sLayout file_layout;
|
||||||
|
sLayout memory_layout;
|
||||||
|
bool is_compressed;
|
||||||
|
|
||||||
|
void operator=(const sCodeSegment& other)
|
||||||
|
{
|
||||||
|
file_layout = other.file_layout;
|
||||||
|
memory_layout = other.memory_layout;
|
||||||
|
is_compressed = other.is_compressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const sCodeSegment& other) const
|
||||||
|
{
|
||||||
|
return (file_layout == other.file_layout) \
|
||||||
|
&& (memory_layout == other.memory_layout) \
|
||||||
|
&& (is_compressed == other.is_compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const sCodeSegment& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
KernelInitialProcessHeader();
|
||||||
|
KernelInitialProcessHeader(const KernelInitialProcessHeader& other);
|
||||||
|
|
||||||
|
void operator=(const KernelInitialProcessHeader& other);
|
||||||
|
bool operator==(const KernelInitialProcessHeader& other) const;
|
||||||
|
bool operator!=(const KernelInitialProcessHeader& other) const;
|
||||||
|
|
||||||
|
// export/import binary
|
||||||
|
void toBytes();
|
||||||
|
void fromBytes(const byte_t* data, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
const std::string& getName() const;
|
||||||
|
void setName(const std::string& name);
|
||||||
|
|
||||||
|
uint64_t getTitleId() const;
|
||||||
|
void setTitleId(uint64_t title_id);
|
||||||
|
|
||||||
|
kip::ProcessCategory getProcessCategory() const;
|
||||||
|
void setProcessCategory(kip::ProcessCategory cat);
|
||||||
|
|
||||||
|
const fnd::List<kip::HeaderFlags>& getFlagList() const;
|
||||||
|
void setFlagList(const fnd::List<kip::HeaderFlags>& flags);
|
||||||
|
|
||||||
|
byte_t getMainThreadPriority() const;
|
||||||
|
void setMainThreadPriority(byte_t priority);
|
||||||
|
|
||||||
|
byte_t getMainThreadCpuId() const;
|
||||||
|
void setMainThreadCpuId(byte_t cpu_id);
|
||||||
|
|
||||||
|
uint32_t getMainThreadStackSize() const;
|
||||||
|
void setMainThreadStackSize(uint32_t size);
|
||||||
|
|
||||||
|
const sCodeSegment& getTextSegmentInfo() const;
|
||||||
|
void setTextSegmentInfo(const sCodeSegment& info);
|
||||||
|
|
||||||
|
const sCodeSegment& getRoSegmentInfo() const;
|
||||||
|
void setRoSegmentInfo(const sCodeSegment& info);
|
||||||
|
|
||||||
|
const sCodeSegment& getDataSegmentInfo() const;
|
||||||
|
void setDataSegmentInfo(const sCodeSegment& info);
|
||||||
|
|
||||||
|
uint32_t getBssSize() const;
|
||||||
|
void setBssSize(uint32_t size);
|
||||||
|
|
||||||
|
const nn::hac::KernelCapabilityControl& getKernelCapabilities() const;
|
||||||
|
void setKernelCapabilities(const KernelCapabilityControl& kc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string kModuleName = "KERNEL_INITIAL_PROCESS_HEADER";
|
||||||
|
|
||||||
|
// raw binary
|
||||||
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
std::string mName;
|
||||||
|
uint64_t mTitleId;
|
||||||
|
kip::ProcessCategory mProcessCategory;
|
||||||
|
fnd::List<kip::HeaderFlags> mFlagList;
|
||||||
|
byte_t mMainThreadPriority;
|
||||||
|
byte_t mMainThreadCpuId;
|
||||||
|
uint32_t mMainThreadStackSize;
|
||||||
|
sCodeSegment mTextInfo;
|
||||||
|
sCodeSegment mRoInfo;
|
||||||
|
sCodeSegment mDataInfo;
|
||||||
|
uint32_t mBssSize;
|
||||||
|
nn::hac::KernelCapabilityControl mKernelCapabilities;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
26
lib/libhac/include/nn/hac/define/ini.h
Normal file
26
lib/libhac/include/nn/hac/define/ini.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fnd/types.h>
|
||||||
|
#include <fnd/sha.h>
|
||||||
|
#include <nn/hac/define/macro.h>
|
||||||
|
|
||||||
|
namespace nn
|
||||||
|
{
|
||||||
|
namespace hac
|
||||||
|
{
|
||||||
|
namespace ini
|
||||||
|
{
|
||||||
|
static const uint32_t kIniStructMagic = _MAKE_STRUCT_MAGIC_U32("INI1");
|
||||||
|
static const size_t kMaxKipNum = 0x50;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
struct sIniHeader
|
||||||
|
{
|
||||||
|
le_uint32_t st_magic;
|
||||||
|
le_uint32_t size;
|
||||||
|
le_uint32_t kip_num;
|
||||||
|
byte_t reserved_01[0x4];
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
}
|
||||||
|
}
|
65
lib/libhac/include/nn/hac/define/kip.h
Normal file
65
lib/libhac/include/nn/hac/define/kip.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fnd/types.h>
|
||||||
|
#include <fnd/sha.h>
|
||||||
|
#include <nn/hac/define/macro.h>
|
||||||
|
|
||||||
|
namespace nn
|
||||||
|
{
|
||||||
|
namespace hac
|
||||||
|
{
|
||||||
|
namespace kip
|
||||||
|
{
|
||||||
|
static const uint32_t kKipStructMagic = _MAKE_STRUCT_MAGIC_U32("KIP1");
|
||||||
|
static const size_t kNameMaxLen = 0xC;
|
||||||
|
static const size_t kKernCapabilityNum = 0x20;
|
||||||
|
static const size_t kKernCapabilitySize = kKernCapabilityNum * sizeof(uint32_t);
|
||||||
|
|
||||||
|
enum ProcessCategory
|
||||||
|
{
|
||||||
|
PROCCAT_REGULAR,
|
||||||
|
PROCCAT_KERNAL_KIP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HeaderFlags
|
||||||
|
{
|
||||||
|
FLAG_TEXT_COMPRESS,
|
||||||
|
FLAG_RO_COMPRESS,
|
||||||
|
FLAG_DATA_COMPRESS,
|
||||||
|
FLAG_INSTRUCTION_64BIT,
|
||||||
|
FLAG_ADDR_SPACE_64BIT,
|
||||||
|
FLAG_USE_SYSTEM_POOL_PARTITION
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
struct sKipCodeSegment
|
||||||
|
{
|
||||||
|
le_uint32_t memory_offset;
|
||||||
|
le_uint32_t memory_size;
|
||||||
|
le_uint32_t file_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sKipHeader
|
||||||
|
{
|
||||||
|
le_uint32_t st_magic;
|
||||||
|
char name[kip::kNameMaxLen];
|
||||||
|
le_uint64_t title_id;
|
||||||
|
le_uint32_t process_category;
|
||||||
|
byte_t main_thread_priority;
|
||||||
|
byte_t main_thread_cpu_id;
|
||||||
|
byte_t reserved_01;
|
||||||
|
byte_t flags;
|
||||||
|
sKipCodeSegment text;
|
||||||
|
byte_t reserved_02[4];
|
||||||
|
sKipCodeSegment ro;
|
||||||
|
le_uint32_t main_thread_stack_size;
|
||||||
|
sKipCodeSegment data;
|
||||||
|
byte_t reserved_03[4];
|
||||||
|
sKipCodeSegment bss;
|
||||||
|
byte_t reserved_04[4];
|
||||||
|
byte_t reserved_05[0x20];
|
||||||
|
byte_t capabilities[kip::kKernCapabilitySize];
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
}
|
||||||
|
}
|
114
lib/libhac/source/IniHeader.cpp
Normal file
114
lib/libhac/source/IniHeader.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include <nn/hac/IniHeader.h>
|
||||||
|
|
||||||
|
nn::hac::IniHeader::IniHeader()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
nn::hac::IniHeader::IniHeader(const IniHeader& other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::operator=(const IniHeader& other)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
this->mSize = other.mSize;
|
||||||
|
this->mKipNum = other.mKipNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn::hac::IniHeader::operator==(const IniHeader& other) const
|
||||||
|
{
|
||||||
|
return (this->mSize == other.mSize) \
|
||||||
|
&& (this->mKipNum == other.mKipNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn::hac::IniHeader::operator!=(const IniHeader& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::toBytes()
|
||||||
|
{
|
||||||
|
mRawBinary.alloc(sizeof(sIniHeader));
|
||||||
|
nn::hac::sIniHeader* hdr = (nn::hac::sIniHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
// set header identifers
|
||||||
|
hdr->st_magic = ini::kIniStructMagic;
|
||||||
|
|
||||||
|
if (mKipNum > ini::kMaxKipNum)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Cannot generate INI Header (Too many KIPs)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// write variables
|
||||||
|
hdr->size = mSize;
|
||||||
|
hdr->kip_num = mKipNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
|
{
|
||||||
|
// check input data size
|
||||||
|
if (len < sizeof(sIniHeader))
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "INI header corrupt (header size is too small)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear internal members
|
||||||
|
clear();
|
||||||
|
|
||||||
|
// allocate internal local binary copy
|
||||||
|
mRawBinary.alloc(sizeof(sIniHeader));
|
||||||
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
|
// get sIniHeader ptr
|
||||||
|
const nn::hac::sIniHeader* hdr = (const nn::hac::sIniHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
// check INI signature
|
||||||
|
if (hdr->st_magic.get() != ini::kIniStructMagic)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "INI header corrupt (unrecognised header signature)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check KIP num
|
||||||
|
if (hdr->kip_num.get() > ini::kMaxKipNum)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "INI header corrupt (too many KIPs)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// save variables
|
||||||
|
mSize = hdr->size.get();
|
||||||
|
mKipNum = hdr->kip_num.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nn::hac::IniHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::clear()
|
||||||
|
{
|
||||||
|
mRawBinary.clear();
|
||||||
|
mSize = 0;
|
||||||
|
mKipNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nn::hac::IniHeader::getSize() const
|
||||||
|
{
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::setSize(uint32_t size)
|
||||||
|
{
|
||||||
|
mSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nn::hac::IniHeader::getKipNum() const
|
||||||
|
{
|
||||||
|
return mKipNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::IniHeader::setKipNum(uint32_t num)
|
||||||
|
{
|
||||||
|
mKipNum = num;
|
||||||
|
}
|
341
lib/libhac/source/KernelInitialProcessHeader.cpp
Normal file
341
lib/libhac/source/KernelInitialProcessHeader.cpp
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
#include <nn/hac/KernelInitialProcessHeader.h>
|
||||||
|
|
||||||
|
nn::hac::KernelInitialProcessHeader::KernelInitialProcessHeader()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
nn::hac::KernelInitialProcessHeader::KernelInitialProcessHeader(const KernelInitialProcessHeader& other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::operator=(const KernelInitialProcessHeader& other)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
this->mName = other.mName;
|
||||||
|
this->mTitleId = other.mTitleId;
|
||||||
|
this->mProcessCategory = other.mProcessCategory;
|
||||||
|
this->mFlagList = other.mFlagList;
|
||||||
|
this->mMainThreadPriority = other.mMainThreadPriority;
|
||||||
|
this->mMainThreadCpuId = other.mMainThreadCpuId;
|
||||||
|
this->mMainThreadStackSize = other.mMainThreadStackSize;
|
||||||
|
this->mTextInfo = other.mTextInfo;
|
||||||
|
this->mRoInfo = other.mRoInfo;
|
||||||
|
this->mDataInfo = other.mDataInfo;
|
||||||
|
this->mBssSize = other.mBssSize;
|
||||||
|
this->mKernelCapabilities = other.mKernelCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn::hac::KernelInitialProcessHeader::operator==(const KernelInitialProcessHeader& other) const
|
||||||
|
{
|
||||||
|
return (this->mName == other.mName) \
|
||||||
|
&& (this->mTitleId == other.mTitleId) \
|
||||||
|
&& (this->mProcessCategory == other.mProcessCategory) \
|
||||||
|
&& (this->mFlagList == other.mFlagList) \
|
||||||
|
&& (this->mMainThreadPriority == other.mMainThreadPriority) \
|
||||||
|
&& (this->mMainThreadCpuId == other.mMainThreadCpuId) \
|
||||||
|
&& (this->mMainThreadStackSize == other.mMainThreadStackSize) \
|
||||||
|
&& (this->mTextInfo == other.mTextInfo) \
|
||||||
|
&& (this->mRoInfo == other.mRoInfo) \
|
||||||
|
&& (this->mDataInfo == other.mDataInfo) \
|
||||||
|
&& (this->mBssSize == other.mBssSize) \
|
||||||
|
&& (this->mKernelCapabilities == other.mKernelCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nn::hac::KernelInitialProcessHeader::operator!=(const KernelInitialProcessHeader& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::toBytes()
|
||||||
|
{
|
||||||
|
mRawBinary.alloc(sizeof(sKipHeader));
|
||||||
|
nn::hac::sKipHeader* hdr = (nn::hac::sKipHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
// set header identifers
|
||||||
|
hdr->st_magic = kip::kKipStructMagic;
|
||||||
|
|
||||||
|
// variable to store flags before commiting to header
|
||||||
|
byte_t flags = 0;
|
||||||
|
|
||||||
|
// properties
|
||||||
|
strncpy(hdr->name, mName.c_str(), kip::kNameMaxLen);
|
||||||
|
hdr->title_id = mTitleId;
|
||||||
|
hdr->process_category = mProcessCategory;
|
||||||
|
hdr->main_thread_priority = mMainThreadPriority;
|
||||||
|
hdr->main_thread_cpu_id = mMainThreadCpuId;
|
||||||
|
hdr->main_thread_stack_size = mMainThreadStackSize;
|
||||||
|
|
||||||
|
// kernel caps
|
||||||
|
mKernelCapabilities.toBytes();
|
||||||
|
if (mKernelCapabilities.getBytes().size() > kip::kKernCapabilitySize)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Too many kernel capabilities");
|
||||||
|
}
|
||||||
|
memcpy(hdr->capabilities, mKernelCapabilities.getBytes().data(), mKernelCapabilities.getBytes().size());
|
||||||
|
//memset(hdr->capabilities + mKernelCapabilities.getBytes().size(), 0xff, kip::kKernCapabilitySize - mKernelCapabilities.getBytes().size());
|
||||||
|
|
||||||
|
// flags
|
||||||
|
for (size_t i = 0; i < mFlagList.size(); i++)
|
||||||
|
{
|
||||||
|
switch(mFlagList[i])
|
||||||
|
{
|
||||||
|
case (kip::FLAG_TEXT_COMPRESS) :
|
||||||
|
case (kip::FLAG_RO_COMPRESS) :
|
||||||
|
case (kip::FLAG_DATA_COMPRESS) :
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flags |= _BIT(mFlagList[i] & 7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set bss size
|
||||||
|
hdr->bss.file_size = 0;
|
||||||
|
hdr->bss.memory_offset = 0;
|
||||||
|
hdr->bss.memory_size = mBssSize;
|
||||||
|
|
||||||
|
// set text segment
|
||||||
|
hdr->text.memory_offset = mTextInfo.memory_layout.offset;
|
||||||
|
hdr->text.memory_size = mTextInfo.memory_layout.size;
|
||||||
|
hdr->text.file_size = mTextInfo.file_layout.size;
|
||||||
|
if (mTextInfo.is_compressed)
|
||||||
|
{
|
||||||
|
flags |= _BIT(kip::FLAG_TEXT_COMPRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set ro segment
|
||||||
|
hdr->ro.memory_offset = mRoInfo.memory_layout.offset;
|
||||||
|
hdr->ro.memory_size = mRoInfo.memory_layout.size;
|
||||||
|
hdr->ro.file_size = mRoInfo.file_layout.size;
|
||||||
|
if (mRoInfo.is_compressed)
|
||||||
|
{
|
||||||
|
flags |= _BIT(kip::FLAG_TEXT_COMPRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set data segment
|
||||||
|
hdr->data.memory_offset = mDataInfo.memory_layout.offset;
|
||||||
|
hdr->data.memory_size = mDataInfo.memory_layout.size;
|
||||||
|
hdr->data.file_size = mDataInfo.file_layout.size;
|
||||||
|
if (mDataInfo.is_compressed)
|
||||||
|
{
|
||||||
|
flags |= _BIT(kip::FLAG_TEXT_COMPRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
|
{
|
||||||
|
// check input data size
|
||||||
|
if (len < sizeof(sKipHeader))
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "KIP header size is too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear internal members
|
||||||
|
clear();
|
||||||
|
|
||||||
|
// allocate internal local binary copy
|
||||||
|
mRawBinary.alloc(sizeof(sKipHeader));
|
||||||
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
|
// get sKipHeader ptr
|
||||||
|
const nn::hac::sKipHeader* hdr = (const nn::hac::sKipHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
// check KIP signature
|
||||||
|
if (hdr->st_magic.get() != kip::kKipStructMagic)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "KIP header corrupt (unrecognised header signature)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties
|
||||||
|
if (hdr->name[0] != 0)
|
||||||
|
mName = std::string(hdr->name, _MIN(strlen(hdr->name), kip::kNameMaxLen));
|
||||||
|
mTitleId = hdr->title_id.get();
|
||||||
|
mProcessCategory = (kip::ProcessCategory)hdr->process_category.get();
|
||||||
|
mMainThreadPriority = hdr->main_thread_priority;
|
||||||
|
mMainThreadCpuId = hdr->main_thread_cpu_id;
|
||||||
|
mMainThreadStackSize = hdr->main_thread_stack_size.get();
|
||||||
|
mKernelCapabilities.fromBytes(hdr->capabilities, kip::kKernCapabilitySize);
|
||||||
|
|
||||||
|
for (byte_t i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (_HAS_BIT(hdr->flags, i))
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case (kip::FLAG_TEXT_COMPRESS) :
|
||||||
|
case (kip::FLAG_RO_COMPRESS) :
|
||||||
|
case (kip::FLAG_DATA_COMPRESS) :
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mFlagList.addElement((kip::HeaderFlags)i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// code segment info
|
||||||
|
mTextInfo.file_layout.offset = sizeof(sKipHeader);
|
||||||
|
mTextInfo.file_layout.size = hdr->text.file_size.get();
|
||||||
|
mTextInfo.memory_layout.offset = hdr->text.memory_offset.get();
|
||||||
|
mTextInfo.memory_layout.size = hdr->text.memory_size.get();
|
||||||
|
mTextInfo.is_compressed = _HAS_BIT(hdr->flags, kip::FLAG_TEXT_COMPRESS);
|
||||||
|
|
||||||
|
mRoInfo.file_layout.offset = mTextInfo.file_layout.offset + mTextInfo.file_layout.size;
|
||||||
|
mRoInfo.file_layout.size = hdr->ro.file_size.get();
|
||||||
|
mRoInfo.memory_layout.offset = hdr->ro.memory_offset.get();
|
||||||
|
mRoInfo.memory_layout.size = hdr->ro.memory_size.get();
|
||||||
|
mRoInfo.is_compressed = _HAS_BIT(hdr->flags, kip::FLAG_RO_COMPRESS);
|
||||||
|
|
||||||
|
mDataInfo.file_layout.offset = mRoInfo.file_layout.offset + mRoInfo.file_layout.size;
|
||||||
|
mDataInfo.file_layout.size = hdr->data.file_size.get();
|
||||||
|
mDataInfo.memory_layout.offset = hdr->data.memory_offset.get();
|
||||||
|
mDataInfo.memory_layout.size = hdr->data.memory_size.get();
|
||||||
|
mDataInfo.is_compressed = _HAS_BIT(hdr->flags, kip::FLAG_DATA_COMPRESS);
|
||||||
|
|
||||||
|
mBssSize = hdr->bss.memory_size.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nn::hac::KernelInitialProcessHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::clear()
|
||||||
|
{
|
||||||
|
mRawBinary.clear();
|
||||||
|
mName.clear();
|
||||||
|
mTitleId = 0;
|
||||||
|
mProcessCategory = (kip::ProcessCategory)0;
|
||||||
|
mFlagList.clear();
|
||||||
|
mMainThreadPriority = 0;
|
||||||
|
mMainThreadCpuId = 0;
|
||||||
|
mMainThreadStackSize = 0;
|
||||||
|
mTextInfo = sCodeSegment();
|
||||||
|
mRoInfo = sCodeSegment();
|
||||||
|
mDataInfo = sCodeSegment();
|
||||||
|
mBssSize = 0;
|
||||||
|
mKernelCapabilities.clear();;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& nn::hac::KernelInitialProcessHeader::getName() const
|
||||||
|
{
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setName(const std::string& name)
|
||||||
|
{
|
||||||
|
mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t nn::hac::KernelInitialProcessHeader::getTitleId() const
|
||||||
|
{
|
||||||
|
return mTitleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setTitleId(uint64_t title_id)
|
||||||
|
{
|
||||||
|
mTitleId = title_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn::hac::kip::ProcessCategory nn::hac::KernelInitialProcessHeader::getProcessCategory() const
|
||||||
|
{
|
||||||
|
return mProcessCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setProcessCategory(kip::ProcessCategory cat)
|
||||||
|
{
|
||||||
|
mProcessCategory = cat;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::List<nn::hac::kip::HeaderFlags>& nn::hac::KernelInitialProcessHeader::getFlagList() const
|
||||||
|
{
|
||||||
|
return mFlagList;
|
||||||
|
}
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setFlagList(const fnd::List<kip::HeaderFlags>& flags)
|
||||||
|
{
|
||||||
|
mFlagList = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t nn::hac::KernelInitialProcessHeader::getMainThreadPriority() const
|
||||||
|
{
|
||||||
|
return mMainThreadPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setMainThreadPriority(byte_t priority)
|
||||||
|
{
|
||||||
|
mMainThreadPriority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t nn::hac::KernelInitialProcessHeader::getMainThreadCpuId() const
|
||||||
|
{
|
||||||
|
return mMainThreadCpuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setMainThreadCpuId(byte_t cpu_id)
|
||||||
|
{
|
||||||
|
mMainThreadCpuId = cpu_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nn::hac::KernelInitialProcessHeader::getMainThreadStackSize() const
|
||||||
|
{
|
||||||
|
return mMainThreadStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setMainThreadStackSize(uint32_t size)
|
||||||
|
{
|
||||||
|
mMainThreadStackSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nn::hac::KernelInitialProcessHeader::sCodeSegment& nn::hac::KernelInitialProcessHeader::getTextSegmentInfo() const
|
||||||
|
{
|
||||||
|
return mTextInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setTextSegmentInfo(const sCodeSegment& info)
|
||||||
|
{
|
||||||
|
mTextInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nn::hac::KernelInitialProcessHeader::sCodeSegment& nn::hac::KernelInitialProcessHeader::getRoSegmentInfo() const
|
||||||
|
{
|
||||||
|
return mRoInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setRoSegmentInfo(const sCodeSegment& info)
|
||||||
|
{
|
||||||
|
mRoInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nn::hac::KernelInitialProcessHeader::sCodeSegment& nn::hac::KernelInitialProcessHeader::getDataSegmentInfo() const
|
||||||
|
{
|
||||||
|
return mDataInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setDataSegmentInfo(const sCodeSegment& info)
|
||||||
|
{
|
||||||
|
mDataInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nn::hac::KernelInitialProcessHeader::getBssSize() const
|
||||||
|
{
|
||||||
|
return mBssSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setBssSize(uint32_t size)
|
||||||
|
{
|
||||||
|
mBssSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nn::hac::KernelCapabilityControl& nn::hac::KernelInitialProcessHeader::getKernelCapabilities() const
|
||||||
|
{
|
||||||
|
return mKernelCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nn::hac::KernelInitialProcessHeader::setKernelCapabilities(const KernelCapabilityControl& kc)
|
||||||
|
{
|
||||||
|
mKernelCapabilities = kc;
|
||||||
|
}
|
Loading…
Reference in a new issue