mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
[nx|nstool] Integrate NpdmHeader into NpdmBinary
This commit is contained in:
parent
4d113b9a0b
commit
1e08495f5d
7 changed files with 260 additions and 399 deletions
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nx/NpdmHeader.h>
|
#include <fnd/ISerialisable.h>
|
||||||
|
#include <nx/npdm.h>
|
||||||
#include <nx/AccessControlInfoBinary.h>
|
#include <nx/AccessControlInfoBinary.h>
|
||||||
#include <nx/AccessControlInfoDescBinary.h>
|
#include <nx/AccessControlInfoDescBinary.h>
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class NpdmBinary :
|
class NpdmBinary :
|
||||||
public NpdmHeader
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NpdmBinary();
|
NpdmBinary();
|
||||||
|
@ -27,6 +28,30 @@ namespace nx
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
npdm::InstructionType getInstructionType() const;
|
||||||
|
void setInstructionType(npdm::InstructionType type);
|
||||||
|
|
||||||
|
npdm::ProcAddrSpaceType getProcAddressSpaceType() const;
|
||||||
|
void setProcAddressSpaceType(npdm::ProcAddrSpaceType type);
|
||||||
|
|
||||||
|
byte_t getMainThreadPriority() const;
|
||||||
|
void setMainThreadPriority(byte_t priority);
|
||||||
|
|
||||||
|
byte_t getMainThreadCpuId() const;
|
||||||
|
void setMainThreadCpuId(byte_t cpu_id);
|
||||||
|
|
||||||
|
uint32_t getVersion() const;
|
||||||
|
void setVersion(uint32_t version);
|
||||||
|
|
||||||
|
uint32_t getMainThreadStackSize() const;
|
||||||
|
void setMainThreadStackSize(uint32_t size);
|
||||||
|
|
||||||
|
const std::string& getName() const;
|
||||||
|
void setName(const std::string& name);
|
||||||
|
|
||||||
|
const std::string& getProductCode() const;
|
||||||
|
void setProductCode(const std::string& product_code);
|
||||||
|
|
||||||
const AccessControlInfoBinary& getAci() const;
|
const AccessControlInfoBinary& getAci() const;
|
||||||
void setAci(const AccessControlInfoBinary& aci);
|
void setAci(const AccessControlInfoBinary& aci);
|
||||||
|
|
||||||
|
@ -39,6 +64,14 @@ namespace nx
|
||||||
fnd::Vec<byte_t> mRawBinary;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
|
npdm::InstructionType mInstructionType;
|
||||||
|
npdm::ProcAddrSpaceType mProcAddressSpaceType;
|
||||||
|
byte_t mMainThreadPriority;
|
||||||
|
byte_t mMainThreadCpuId;
|
||||||
|
uint32_t mVersion;
|
||||||
|
uint32_t mMainThreadStackSize;
|
||||||
|
std::string mName;
|
||||||
|
std::string mProductCode;
|
||||||
AccessControlInfoBinary mAci;
|
AccessControlInfoBinary mAci;
|
||||||
AccessControlInfoDescBinary mAcid;
|
AccessControlInfoDescBinary mAcid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <string>
|
|
||||||
#include <fnd/types.h>
|
|
||||||
#include <fnd/ISerialisable.h>
|
|
||||||
#include <nx/npdm.h>
|
|
||||||
|
|
||||||
namespace nx
|
|
||||||
{
|
|
||||||
class NpdmHeader :
|
|
||||||
public fnd::ISerialisable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct sSection
|
|
||||||
{
|
|
||||||
size_t offset;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
void operator=(const sSection& other)
|
|
||||||
{
|
|
||||||
offset = other.offset;
|
|
||||||
size = other.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const sSection& other) const
|
|
||||||
{
|
|
||||||
return (offset == other.offset) \
|
|
||||||
&& (size == other.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const sSection& other) const
|
|
||||||
{
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NpdmHeader();
|
|
||||||
NpdmHeader(const NpdmHeader& other);
|
|
||||||
|
|
||||||
void operator=(const NpdmHeader& other);
|
|
||||||
bool operator==(const NpdmHeader& other) const;
|
|
||||||
bool operator!=(const NpdmHeader& other) const;
|
|
||||||
|
|
||||||
// export/import binary
|
|
||||||
void toBytes();
|
|
||||||
void fromBytes(const byte_t* bytes, size_t len);
|
|
||||||
const fnd::Vec<byte_t>& getBytes() const;
|
|
||||||
|
|
||||||
// variables
|
|
||||||
void clear();
|
|
||||||
size_t getNpdmSize() const;
|
|
||||||
|
|
||||||
npdm::InstructionType getInstructionType() const;
|
|
||||||
void setInstructionType(npdm::InstructionType type);
|
|
||||||
|
|
||||||
npdm::ProcAddrSpaceType getProcAddressSpaceType() const;
|
|
||||||
void setProcAddressSpaceType(npdm::ProcAddrSpaceType type);
|
|
||||||
|
|
||||||
byte_t getMainThreadPriority() const;
|
|
||||||
void setMainThreadPriority(byte_t priority);
|
|
||||||
|
|
||||||
byte_t getMainThreadCpuId() const;
|
|
||||||
void setMainThreadCpuId(byte_t cpu_id);
|
|
||||||
|
|
||||||
uint32_t getVersion() const;
|
|
||||||
void setVersion(uint32_t version);
|
|
||||||
|
|
||||||
uint32_t getMainThreadStackSize() const;
|
|
||||||
void setMainThreadStackSize(uint32_t size);
|
|
||||||
|
|
||||||
const std::string& getName() const;
|
|
||||||
void setName(const std::string& name);
|
|
||||||
|
|
||||||
const std::string& getProductCode() const;
|
|
||||||
void setProductCode(const std::string& product_code);
|
|
||||||
|
|
||||||
const sSection& getAciPos() const;
|
|
||||||
void setAciSize(size_t size);
|
|
||||||
|
|
||||||
const sSection& getAcidPos() const;
|
|
||||||
void setAcidSize(size_t size);
|
|
||||||
private:
|
|
||||||
const std::string kModuleName = "NPDM_HEADER";
|
|
||||||
|
|
||||||
// raw binary
|
|
||||||
fnd::Vec<byte_t> mRawBinary;
|
|
||||||
|
|
||||||
// variables
|
|
||||||
npdm::InstructionType mInstructionType;
|
|
||||||
npdm::ProcAddrSpaceType mProcAddressSpaceType;
|
|
||||||
byte_t mMainThreadPriority;
|
|
||||||
byte_t mMainThreadCpuId;
|
|
||||||
uint32_t mVersion;
|
|
||||||
uint32_t mMainThreadStackSize;
|
|
||||||
std::string mName;
|
|
||||||
std::string mProductCode;
|
|
||||||
sSection mAciPos;
|
|
||||||
sSection mAcidPos;
|
|
||||||
|
|
||||||
void calculateOffsets();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace nx
|
||||||
static const size_t kNameMaxLen = 0x10;
|
static const size_t kNameMaxLen = 0x10;
|
||||||
static const size_t kProductCodeMaxLen = 0x10;
|
static const size_t kProductCodeMaxLen = 0x10;
|
||||||
static const uint32_t kMaxPriority = BIT(6) - 1;
|
static const uint32_t kMaxPriority = BIT(6) - 1;
|
||||||
static const size_t kNpdmAlignSize = 0x10;
|
static const size_t kSectionAlignSize = 0x10;
|
||||||
static const uint32_t kDefaultMainThreadStackSize = 4096;
|
static const uint32_t kDefaultMainThreadStackSize = 4096;
|
||||||
|
|
||||||
enum InstructionType
|
enum InstructionType
|
||||||
|
|
|
@ -2,37 +2,42 @@
|
||||||
|
|
||||||
#include <fnd/SimpleTextOutput.h>
|
#include <fnd/SimpleTextOutput.h>
|
||||||
|
|
||||||
nx::NpdmBinary::NpdmBinary() :
|
nx::NpdmBinary::NpdmBinary()
|
||||||
mAci(),
|
|
||||||
mAcid()
|
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) :
|
nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) :
|
||||||
mAci(),
|
NpdmBinary()
|
||||||
mAcid()
|
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmBinary::operator=(const NpdmBinary & other)
|
void nx::NpdmBinary::operator=(const NpdmBinary & other)
|
||||||
{
|
{
|
||||||
if (other.getBytes().size())
|
mRawBinary = other.mRawBinary;
|
||||||
{
|
mInstructionType = other.mInstructionType;
|
||||||
fromBytes(other.getBytes().data(), other.getBytes().size());
|
mProcAddressSpaceType = other.mProcAddressSpaceType;
|
||||||
}
|
mMainThreadPriority = other.mMainThreadPriority;
|
||||||
else
|
mMainThreadCpuId = other.mMainThreadCpuId;
|
||||||
{
|
mVersion = other.mVersion;
|
||||||
NpdmHeader::operator=(other);
|
mMainThreadStackSize = other.mMainThreadStackSize;
|
||||||
|
mName = other.mName;
|
||||||
|
mProductCode = other.mProductCode;
|
||||||
mAci = other.mAci;
|
mAci = other.mAci;
|
||||||
mAcid = other.mAcid;
|
mAcid = other.mAcid;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmBinary::operator==(const NpdmBinary & other) const
|
bool nx::NpdmBinary::operator==(const NpdmBinary & other) const
|
||||||
{
|
{
|
||||||
return (NpdmHeader::operator==(other)) \
|
return (mInstructionType == other.mInstructionType) \
|
||||||
|
&& (mProcAddressSpaceType == other.mProcAddressSpaceType) \
|
||||||
|
&& (mMainThreadPriority == other.mMainThreadPriority) \
|
||||||
|
&& (mMainThreadCpuId == other.mMainThreadCpuId) \
|
||||||
|
&& (mVersion == other.mVersion) \
|
||||||
|
&& (mMainThreadStackSize == other.mMainThreadStackSize) \
|
||||||
|
&& (mName == other.mName) \
|
||||||
|
&& (mProductCode == other.mProductCode) \
|
||||||
&& (mAci == other.mAci) \
|
&& (mAci == other.mAci) \
|
||||||
&& (mAcid == other.mAcid);
|
&& (mAcid == other.mAcid);
|
||||||
}
|
}
|
||||||
|
@ -44,35 +49,121 @@ bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const
|
||||||
|
|
||||||
void nx::NpdmBinary::toBytes()
|
void nx::NpdmBinary::toBytes()
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "toBytes() not implemented.");
|
if (mAcid.getBytes().size() == 0)
|
||||||
|
mAcid.toBytes();
|
||||||
|
|
||||||
|
if (mAci.getBytes().size() == 0)
|
||||||
|
mAci.toBytes();
|
||||||
|
|
||||||
|
|
||||||
|
// determine section layout
|
||||||
|
struct sLayout {
|
||||||
|
uint32_t offset, size;
|
||||||
|
} acid, aci;
|
||||||
|
|
||||||
|
acid.offset = align(sizeof(sNpdmHeader), npdm::kSectionAlignSize);
|
||||||
|
acid.size = (uint32_t)mAcid.getBytes().size();
|
||||||
|
aci.offset = acid.offset + align(acid.size, npdm::kSectionAlignSize);
|
||||||
|
aci.size = (uint32_t)mAci.getBytes().size();
|
||||||
|
|
||||||
|
|
||||||
|
// get total size
|
||||||
|
size_t total_size = _MAX(_MAX(acid.offset + acid.size, aci.offset + aci.size), align(sizeof(sNpdmHeader), npdm::kSectionAlignSize));
|
||||||
|
|
||||||
|
mRawBinary.alloc(total_size);
|
||||||
|
sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
// set type
|
||||||
|
hdr->st_magic = npdm::kNpdmStructMagic;
|
||||||
|
|
||||||
|
// set variables
|
||||||
|
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf;
|
||||||
|
hdr->flags = flag;
|
||||||
|
hdr->main_thread_priority = mMainThreadPriority;
|
||||||
|
hdr->main_thread_cpu_id = mMainThreadCpuId;
|
||||||
|
hdr->version = mVersion;
|
||||||
|
hdr->main_thread_stack_size = mMainThreadStackSize;
|
||||||
|
strncpy(hdr->name, mName.c_str(), npdm::kNameMaxLen);
|
||||||
|
strncpy(hdr->product_code, mProductCode.c_str(), npdm::kProductCodeMaxLen);
|
||||||
|
|
||||||
|
// set offset/size
|
||||||
|
hdr->aci.offset = aci.offset;
|
||||||
|
hdr->aci.size = aci.size;
|
||||||
|
hdr->acid.offset = acid.offset;
|
||||||
|
hdr->acid.size = acid.size;
|
||||||
|
|
||||||
|
// write aci & acid
|
||||||
|
if (mAci.getBytes().size() > 0)
|
||||||
|
{
|
||||||
|
memcpy(mRawBinary.data() + aci.offset, mAci.getBytes().data(), mAci.getBytes().size());
|
||||||
|
}
|
||||||
|
if (mAcid.getBytes().size() > 0)
|
||||||
|
{
|
||||||
|
memcpy(mRawBinary.data() + acid.offset, mAcid.getBytes().data(), mAcid.getBytes().size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len)
|
void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// clear
|
// check size
|
||||||
|
if (len < sizeof(sNpdmHeader))
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "NPDM binary is too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear variables
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// import header
|
// save a copy of the header
|
||||||
NpdmHeader::fromBytes(data, len);
|
sNpdmHeader hdr;
|
||||||
|
memcpy((void*)&hdr, data, sizeof(sNpdmHeader));
|
||||||
|
|
||||||
|
// check magic
|
||||||
|
if (hdr.st_magic.get() != npdm::kNpdmStructMagic)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "NPDM header corrupt");
|
||||||
|
}
|
||||||
|
|
||||||
|
// save variables
|
||||||
|
byte_t flag = hdr.flags & 0xf;
|
||||||
|
mInstructionType = (npdm::InstructionType)(flag & 1);
|
||||||
|
mProcAddressSpaceType = (npdm::ProcAddrSpaceType)((flag >> 1) & 3);
|
||||||
|
mMainThreadPriority = hdr.main_thread_priority;
|
||||||
|
mMainThreadCpuId = hdr.main_thread_cpu_id;
|
||||||
|
mVersion = hdr.version.get();
|
||||||
|
mMainThreadStackSize = hdr.main_thread_stack_size.get();
|
||||||
|
mName = std::string(hdr.name, npdm::kNameMaxLen);
|
||||||
|
if (mName[0] == '\0')
|
||||||
|
{
|
||||||
|
mName.clear();
|
||||||
|
}
|
||||||
|
mProductCode = std::string(hdr.product_code, npdm::kProductCodeMaxLen);
|
||||||
|
if (mProductCode[0] == '\0')
|
||||||
|
{
|
||||||
|
mProductCode.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// total size
|
||||||
|
size_t total_size = _MAX(_MAX(hdr.acid.offset.get() + hdr.acid.size.get(), hdr.aci.offset.get() + hdr.aci.size.get()), sizeof(sNpdmHeader));
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
if (getNpdmSize() > len)
|
if (total_size > len)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "NPDM binary too small");
|
throw fnd::Exception(kModuleName, "NPDM binary too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
// save local copy
|
// save local copy
|
||||||
mRawBinary.alloc(getNpdmSize());
|
mRawBinary.alloc(total_size);
|
||||||
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// import Aci/Acid
|
// import Aci/Acid
|
||||||
if (getAciPos().size)
|
if (hdr.aci.size.get())
|
||||||
{
|
{
|
||||||
mAci.fromBytes(mRawBinary.data() + getAciPos().offset, getAciPos().size);
|
mAci.fromBytes(mRawBinary.data() + hdr.aci.offset.get(), hdr.aci.size.get());
|
||||||
}
|
}
|
||||||
if (getAcidPos().size)
|
if (hdr.acid.size.get())
|
||||||
{
|
{
|
||||||
mAcid.fromBytes(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
|
mAcid.fromBytes(mRawBinary.data() + hdr.acid.offset.get(), hdr.acid.size.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +174,114 @@ const fnd::Vec<byte_t>& nx::NpdmBinary::getBytes() const
|
||||||
|
|
||||||
void nx::NpdmBinary::clear()
|
void nx::NpdmBinary::clear()
|
||||||
{
|
{
|
||||||
NpdmHeader::clear();
|
mRawBinary.clear();
|
||||||
|
mInstructionType = npdm::INSTR_64BIT;
|
||||||
|
mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT;
|
||||||
|
mMainThreadPriority = 0;
|
||||||
|
mMainThreadCpuId = 0;
|
||||||
|
mVersion = 0;
|
||||||
|
mMainThreadStackSize = 0;
|
||||||
|
mName.clear();
|
||||||
|
mProductCode.clear();
|
||||||
mAci.clear();
|
mAci.clear();
|
||||||
mAcid.clear();
|
mAcid.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nx::npdm::InstructionType nx::NpdmBinary::getInstructionType() const
|
||||||
|
{
|
||||||
|
return mInstructionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setInstructionType(npdm::InstructionType type)
|
||||||
|
{
|
||||||
|
mInstructionType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
nx::npdm::ProcAddrSpaceType nx::NpdmBinary::getProcAddressSpaceType() const
|
||||||
|
{
|
||||||
|
return mProcAddressSpaceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setProcAddressSpaceType(npdm::ProcAddrSpaceType type)
|
||||||
|
{
|
||||||
|
mProcAddressSpaceType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t nx::NpdmBinary::getMainThreadPriority() const
|
||||||
|
{
|
||||||
|
return mMainThreadPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setMainThreadPriority(byte_t priority)
|
||||||
|
{
|
||||||
|
if (priority > npdm::kMaxPriority)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Illegal main thread priority (range 0-63)");
|
||||||
|
}
|
||||||
|
|
||||||
|
mMainThreadPriority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t nx::NpdmBinary::getMainThreadCpuId() const
|
||||||
|
{
|
||||||
|
return mMainThreadCpuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setMainThreadCpuId(byte_t core_num)
|
||||||
|
{
|
||||||
|
mMainThreadCpuId = core_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nx::NpdmBinary::getVersion() const
|
||||||
|
{
|
||||||
|
return mVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setVersion(uint32_t version)
|
||||||
|
{
|
||||||
|
mVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nx::NpdmBinary::getMainThreadStackSize() const
|
||||||
|
{
|
||||||
|
return mMainThreadStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setMainThreadStackSize(uint32_t size)
|
||||||
|
{
|
||||||
|
mMainThreadStackSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & nx::NpdmBinary::getName() const
|
||||||
|
{
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setName(const std::string & name)
|
||||||
|
{
|
||||||
|
if (name.length() > npdm::kNameMaxLen)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Name is too long");
|
||||||
|
}
|
||||||
|
|
||||||
|
mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & nx::NpdmBinary::getProductCode() const
|
||||||
|
{
|
||||||
|
return mProductCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::setProductCode(const std::string & product_code)
|
||||||
|
{
|
||||||
|
if (product_code.length() > npdm::kProductCodeMaxLen)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Product Code is too long");
|
||||||
|
}
|
||||||
|
|
||||||
|
mProductCode = product_code;
|
||||||
|
}
|
||||||
|
|
||||||
const nx::AccessControlInfoBinary & nx::NpdmBinary::getAci() const
|
const nx::AccessControlInfoBinary & nx::NpdmBinary::getAci() const
|
||||||
{
|
{
|
||||||
return mAci;
|
return mAci;
|
||||||
|
|
|
@ -1,264 +0,0 @@
|
||||||
#include <nx/NpdmHeader.h>
|
|
||||||
|
|
||||||
nx::NpdmHeader::NpdmHeader()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
nx::NpdmHeader::NpdmHeader(const NpdmHeader & other)
|
|
||||||
{
|
|
||||||
*this = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::operator=(const NpdmHeader & other)
|
|
||||||
{
|
|
||||||
if (other.getBytes().size())
|
|
||||||
{
|
|
||||||
fromBytes(other.getBytes().data(), other.getBytes().size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
mInstructionType = other.mInstructionType;
|
|
||||||
mProcAddressSpaceType = other.mProcAddressSpaceType;
|
|
||||||
mMainThreadPriority = other.mMainThreadPriority;
|
|
||||||
mMainThreadCpuId = other.mMainThreadCpuId;
|
|
||||||
mVersion = other.mVersion;
|
|
||||||
mMainThreadStackSize = other.mMainThreadStackSize;
|
|
||||||
mName = other.mName;
|
|
||||||
mProductCode = other.mProductCode;
|
|
||||||
mAciPos = other.mAciPos;
|
|
||||||
mAcidPos = other.mAcidPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmHeader::operator==(const NpdmHeader & other) const
|
|
||||||
{
|
|
||||||
return (mInstructionType == other.mInstructionType) \
|
|
||||||
&& (mProcAddressSpaceType == other.mProcAddressSpaceType) \
|
|
||||||
&& (mMainThreadPriority == other.mMainThreadPriority) \
|
|
||||||
&& (mMainThreadCpuId == other.mMainThreadCpuId) \
|
|
||||||
&& (mVersion == other.mVersion) \
|
|
||||||
&& (mMainThreadStackSize == other.mMainThreadStackSize) \
|
|
||||||
&& (mName == other.mName) \
|
|
||||||
&& (mProductCode == other.mProductCode) \
|
|
||||||
&& (mAciPos == other.mAciPos) \
|
|
||||||
&& (mAcidPos == other.mAcidPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmHeader::operator!=(const NpdmHeader & other) const
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::toBytes()
|
|
||||||
{
|
|
||||||
mRawBinary.alloc(sizeof(sNpdmHeader));
|
|
||||||
sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
|
|
||||||
|
|
||||||
hdr->st_magic = npdm::kNpdmStructMagic;
|
|
||||||
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf;
|
|
||||||
hdr->flags = flag;
|
|
||||||
hdr->main_thread_priority = mMainThreadPriority;
|
|
||||||
hdr->main_thread_cpu_id = mMainThreadCpuId;
|
|
||||||
hdr->version = mVersion;
|
|
||||||
hdr->main_thread_stack_size = mMainThreadStackSize;
|
|
||||||
strncpy(hdr->name, mName.c_str(), npdm::kNameMaxLen);
|
|
||||||
strncpy(hdr->product_code, mProductCode.c_str(), npdm::kProductCodeMaxLen);
|
|
||||||
|
|
||||||
calculateOffsets();
|
|
||||||
hdr->aci.offset = (uint32_t)mAciPos.offset;
|
|
||||||
hdr->aci.size = (uint32_t)mAciPos.size;
|
|
||||||
hdr->acid.offset = (uint32_t)mAcidPos.offset;
|
|
||||||
hdr->acid.size = (uint32_t)mAcidPos.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::fromBytes(const byte_t* data, size_t len)
|
|
||||||
{
|
|
||||||
if (len < sizeof(sNpdmHeader))
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "NPDM header too small");
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear internal members
|
|
||||||
clear();
|
|
||||||
|
|
||||||
mRawBinary.alloc(sizeof(sNpdmHeader));
|
|
||||||
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
|
||||||
sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
|
|
||||||
|
|
||||||
if (hdr->st_magic.get() != npdm::kNpdmStructMagic)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "NPDM header corrupt");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_t flag = hdr->flags & 0xf;
|
|
||||||
mInstructionType = (npdm::InstructionType)(flag & 1);
|
|
||||||
mProcAddressSpaceType = (npdm::ProcAddrSpaceType)((flag >> 1) & 3);
|
|
||||||
mMainThreadPriority = hdr->main_thread_priority;
|
|
||||||
mMainThreadCpuId = hdr->main_thread_cpu_id;
|
|
||||||
mVersion = hdr->version.get();
|
|
||||||
mMainThreadStackSize = hdr->main_thread_stack_size.get();
|
|
||||||
mName = std::string(hdr->name, npdm::kNameMaxLen);
|
|
||||||
if (mName[0] == '\0')
|
|
||||||
{
|
|
||||||
mName.clear();
|
|
||||||
}
|
|
||||||
mProductCode = std::string(hdr->product_code, npdm::kProductCodeMaxLen);
|
|
||||||
if (mProductCode[0] == '\0')
|
|
||||||
{
|
|
||||||
mProductCode.clear();
|
|
||||||
}
|
|
||||||
mAciPos.offset = hdr->aci.offset.get();
|
|
||||||
mAciPos.size = hdr->aci.size.get();
|
|
||||||
mAcidPos.offset = hdr->acid.offset.get();
|
|
||||||
mAcidPos.size = hdr->acid.size.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
const fnd::Vec<byte_t>& nx::NpdmHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mRawBinary;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::clear()
|
|
||||||
{
|
|
||||||
mRawBinary.clear();
|
|
||||||
mInstructionType = npdm::INSTR_64BIT;
|
|
||||||
mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT;
|
|
||||||
mMainThreadPriority = 0;
|
|
||||||
mMainThreadCpuId = 0;
|
|
||||||
mVersion = 0;
|
|
||||||
mMainThreadStackSize = 0;
|
|
||||||
mName.clear();
|
|
||||||
mProductCode.clear();
|
|
||||||
mAciPos.offset = 0;
|
|
||||||
mAciPos.size = 0;
|
|
||||||
mAcidPos.offset = 0;
|
|
||||||
mAcidPos.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::NpdmHeader::getNpdmSize() const
|
|
||||||
{
|
|
||||||
return _MAX(mAcidPos.offset + mAcidPos.size, mAciPos.offset + mAciPos.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
nx::npdm::InstructionType nx::NpdmHeader::getInstructionType() const
|
|
||||||
{
|
|
||||||
return mInstructionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setInstructionType(npdm::InstructionType type)
|
|
||||||
{
|
|
||||||
mInstructionType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
nx::npdm::ProcAddrSpaceType nx::NpdmHeader::getProcAddressSpaceType() const
|
|
||||||
{
|
|
||||||
return mProcAddressSpaceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setProcAddressSpaceType(npdm::ProcAddrSpaceType type)
|
|
||||||
{
|
|
||||||
mProcAddressSpaceType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_t nx::NpdmHeader::getMainThreadPriority() const
|
|
||||||
{
|
|
||||||
return mMainThreadPriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setMainThreadPriority(byte_t priority)
|
|
||||||
{
|
|
||||||
if (priority > npdm::kMaxPriority)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "Illegal main thread priority (range 0-63)");
|
|
||||||
}
|
|
||||||
|
|
||||||
mMainThreadPriority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_t nx::NpdmHeader::getMainThreadCpuId() const
|
|
||||||
{
|
|
||||||
return mMainThreadCpuId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setMainThreadCpuId(byte_t core_num)
|
|
||||||
{
|
|
||||||
mMainThreadCpuId = core_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t nx::NpdmHeader::getVersion() const
|
|
||||||
{
|
|
||||||
return mVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setVersion(uint32_t version)
|
|
||||||
{
|
|
||||||
mVersion = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t nx::NpdmHeader::getMainThreadStackSize() const
|
|
||||||
{
|
|
||||||
return mMainThreadStackSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setMainThreadStackSize(uint32_t size)
|
|
||||||
{
|
|
||||||
mMainThreadStackSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & nx::NpdmHeader::getName() const
|
|
||||||
{
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setName(const std::string & name)
|
|
||||||
{
|
|
||||||
if (name.length() > npdm::kNameMaxLen)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "Name is too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
mName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & nx::NpdmHeader::getProductCode() const
|
|
||||||
{
|
|
||||||
return mProductCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setProductCode(const std::string & product_code)
|
|
||||||
{
|
|
||||||
if (product_code.length() > npdm::kProductCodeMaxLen)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "Product Code is too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
mProductCode = product_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nx::NpdmHeader::sSection & nx::NpdmHeader::getAciPos() const
|
|
||||||
{
|
|
||||||
return mAciPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setAciSize(size_t size)
|
|
||||||
{
|
|
||||||
mAciPos.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nx::NpdmHeader::sSection & nx::NpdmHeader::getAcidPos() const
|
|
||||||
{
|
|
||||||
return mAcidPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::setAcidSize(size_t size)
|
|
||||||
{
|
|
||||||
mAcidPos.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::calculateOffsets()
|
|
||||||
{
|
|
||||||
mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize);
|
|
||||||
mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize);
|
|
||||||
}
|
|
|
@ -529,7 +529,7 @@ void NpdmProcess::validateAciFromAcid(const nx::AccessControlInfoBinary& aci, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpdmProcess::displayNpdmHeader(const nx::NpdmHeader& hdr)
|
void NpdmProcess::displayNpdmHeader(const nx::NpdmBinary& hdr)
|
||||||
{
|
{
|
||||||
printf("[NPDM HEADER]\n");
|
printf("[NPDM HEADER]\n");
|
||||||
printf(" Process Architecture Params:\n");
|
printf(" Process Architecture Params:\n");
|
||||||
|
|
|
@ -35,7 +35,7 @@ private:
|
||||||
void validateAcidSignature(const nx::AccessControlInfoDescBinary& acid);
|
void validateAcidSignature(const nx::AccessControlInfoDescBinary& acid);
|
||||||
void validateAciFromAcid(const nx::AccessControlInfoBinary& aci, const nx::AccessControlInfoDescBinary& acid);
|
void validateAciFromAcid(const nx::AccessControlInfoBinary& aci, const nx::AccessControlInfoDescBinary& acid);
|
||||||
|
|
||||||
void displayNpdmHeader(const nx::NpdmHeader& hdr);
|
void displayNpdmHeader(const nx::NpdmBinary& hdr);
|
||||||
void displayAciHdr(const nx::AccessControlInfoBinary& aci);
|
void displayAciHdr(const nx::AccessControlInfoBinary& aci);
|
||||||
void displayAciDescHdr(const nx::AccessControlInfoDescBinary& aci);
|
void displayAciDescHdr(const nx::AccessControlInfoDescBinary& aci);
|
||||||
void displayFac(const nx::FileSystemAccessControlBinary& fac);
|
void displayFac(const nx::FileSystemAccessControlBinary& fac);
|
||||||
|
|
Loading…
Reference in a new issue