mirror of
https://github.com/RKX1209/nsemu.git
synced 2024-06-23 14:43:16 -04:00
Add NSO binary loader
This commit is contained in:
parent
186bc1ed5f
commit
aa4cd7ac53
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -50,3 +50,6 @@ modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
.*
|
||||||
|
core
|
||||||
|
nsemu
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -1,12 +1,12 @@
|
||||||
CXX := g++
|
CXX := g++
|
||||||
SRC_FILES := $(wildcard *.cpp)
|
SRC_FILES := $(wildcard *.cpp)
|
||||||
OBJ_FILES := $(SRC_FILES:.cpp=.o)
|
OBJ_FILES := $(SRC_FILES:.cpp=.o)
|
||||||
CXX_FLAGS := -Iinclude
|
CXX_FLAGS := -std=c++11 -Iinclude
|
||||||
LD_FLAGS := -llz4
|
LD_FLAGS := -llz4
|
||||||
|
|
||||||
all: nsemu
|
all: nsemu
|
||||||
nsemu: $(OBJ_FILES)
|
nsemu: $(OBJ_FILES)
|
||||||
$(CXX) -o nsemu $(LD_FLAGS) $(OBJ_FILES)
|
$(CXX) -o nsemu $(OBJ_FILES) $(LD_FLAGS)
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CXX_FLAGS) -c -g -o $@ $<
|
$(CXX) $(CXX_FLAGS) -c -g -o $@ $<
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
|
/* nsemu - LGPL - Copyright 2017 rkx1209<rkx1209dev@gmail.com> */
|
||||||
|
|
||||||
#include "Nsemu.hpp"
|
#include "Nsemu.hpp"
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
|
|
||||||
NintendoObject::NintendoObject(string path) {
|
NintendoObject::NintendoObject(string path) {
|
||||||
fp.open(path, ios::in | ios::binary);
|
fp.open(path.c_str(), ios::in | ios::binary);
|
||||||
fp.seekg(0, ios_base::end);
|
fp.seekg(0, ios_base::end);
|
||||||
length = (uint32_t) fp.tellg();
|
length = (uint32_t) fp.tellg();
|
||||||
fp.seekg(0);
|
fp.seekg(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NintendoObject::~NintendoObject() {
|
||||||
|
fp.close();
|
||||||
|
}
|
||||||
|
|
||||||
char *decompress(ifstream &fp, uint32_t offset, uint32_t csize, uint32_t usize) {
|
char *decompress(ifstream &fp, uint32_t offset, uint32_t csize, uint32_t usize) {
|
||||||
fp.seekg(offset);
|
fp.seekg(offset);
|
||||||
char *buf = new char[csize];
|
char *buf = new char[csize];
|
||||||
|
@ -18,10 +24,29 @@ char *decompress(ifstream &fp, uint32_t offset, uint32_t csize, uint32_t usize)
|
||||||
return obuf;
|
return obuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Nso::load (Nsemu *nsemu, uint64_t *base) {
|
int Nso::load (Nsemu *nsemu, uint64_t base) {
|
||||||
|
NsoHeader hdr;
|
||||||
|
fp.read((char *) &hdr, sizeof(NsoHeader));
|
||||||
|
if (hdr.magic != host_order32("NSO0"))
|
||||||
|
return 0;
|
||||||
|
uint32_t size = hdr.dataLoc + hdr.dataSize + hdr.bssSize;
|
||||||
|
if (size & 0xfff)
|
||||||
|
size = (size & ~0xfff) + 0x1000;
|
||||||
|
char *text = decompress(fp, hdr.textOff, hdr.rdataOff - hdr.textOff, hdr.textSize);
|
||||||
|
bindump ((uint8_t*)text, 105);
|
||||||
|
delete[] text;
|
||||||
|
|
||||||
|
char *rdata = decompress(fp, hdr.rdataOff, hdr.dataOff - hdr.rdataOff, hdr.rdataSize);
|
||||||
|
|
||||||
|
delete[] rdata;
|
||||||
|
|
||||||
|
char *data = decompress(fp, hdr.dataOff, length - hdr.dataOff, hdr.dataSize);
|
||||||
|
|
||||||
|
delete[] data;
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Nro::load (Nsemu *nsemu, uint64_t *base) {
|
int Nro::load (Nsemu *nsemu, uint64_t base) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
/* nsemu - LGPL - Copyright 2017 rkx1209<rkx1209dev@gmail.com> */
|
||||||
|
#include "Nsemu.hpp"
|
||||||
|
Nsemu *Nsemu::inst = nullptr;
|
1
Util.cpp
Normal file
1
Util.cpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/* nsemu - LGPL - Copyright 2017 rkx1209<rkx1209dev@gmail.com> */
|
|
@ -5,8 +5,8 @@ class Nsemu;
|
||||||
class NintendoObject {
|
class NintendoObject {
|
||||||
public:
|
public:
|
||||||
NintendoObject(std::string path);
|
NintendoObject(std::string path);
|
||||||
~NintendoObject() {}
|
~NintendoObject();
|
||||||
virtual int load (Nsemu *nsemu, uint64_t *base) = 0;
|
virtual int load (Nsemu *nsemu, uint64_t base) = 0;
|
||||||
protected:
|
protected:
|
||||||
std::ifstream fp;
|
std::ifstream fp;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
|
@ -15,7 +15,7 @@ protected:
|
||||||
class Nso : NintendoObject {
|
class Nso : NintendoObject {
|
||||||
public:
|
public:
|
||||||
Nso(std::string path) : NintendoObject(path) {}
|
Nso(std::string path) : NintendoObject(path) {}
|
||||||
int load (Nsemu *nsemu, uint64_t *base);
|
int load (Nsemu *nsemu, uint64_t base);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -29,7 +29,7 @@ typedef struct {
|
||||||
class Nro : NintendoObject {
|
class Nro : NintendoObject {
|
||||||
public:
|
public:
|
||||||
Nro(std::string path) : NintendoObject(path) {}
|
Nro(std::string path) : NintendoObject(path) {}
|
||||||
int load (Nsemu *nsemu, uint64_t *base);
|
int load (Nsemu *nsemu, uint64_t base);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,16 +4,44 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#include "Util.hpp"
|
||||||
#include "NintendoObject.hpp"
|
#include "NintendoObject.hpp"
|
||||||
|
|
||||||
|
/* Global NSEMU singleton class .*/
|
||||||
class Nsemu {
|
class Nsemu {
|
||||||
|
private:
|
||||||
|
Nsemu() = default;
|
||||||
|
~Nsemu() = default;
|
||||||
|
|
||||||
|
static Nsemu *inst;
|
||||||
public:
|
public:
|
||||||
Nsemu();
|
Nsemu(const Nsemu&) = delete;
|
||||||
|
Nsemu& operator=(const Nsemu&) = delete;
|
||||||
|
Nsemu(Nsemu&&) = delete;
|
||||||
|
Nsemu& operator=(Nsemu&&) = delete;
|
||||||
|
|
||||||
|
static Nsemu* get_instance() {
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create() {
|
||||||
|
if ( !inst ) {
|
||||||
|
inst = new Nsemu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy() {
|
||||||
|
if ( inst ) {
|
||||||
|
delete inst;
|
||||||
|
inst= nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
46
include/Util.hpp
Normal file
46
include/Util.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef _UTIL_HPP
|
||||||
|
#define _UTIL_HPP
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define LINE_BREAK 15
|
||||||
|
|
||||||
|
enum RunLevel{
|
||||||
|
RUN_LEVEL_RELEASE = 0,
|
||||||
|
RUN_LEVEL_DEBUG,
|
||||||
|
};
|
||||||
|
|
||||||
|
static RunLevel curlevel = RUN_LEVEL_DEBUG;
|
||||||
|
|
||||||
|
static void util_print(RunLevel level, const char *format, ...) {
|
||||||
|
if (curlevel >= level) {
|
||||||
|
va_list va;
|
||||||
|
va_start (va, format);
|
||||||
|
vprintf (format, va);
|
||||||
|
va_end (va);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define debug_print(format, ...) util_print (RUN_LEVEL_DEBUG, format, ##__VA_ARGS__)
|
||||||
|
#define print(format, ...) util_print (RUN_LEVEL_RELEASE, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
inline void bindump(uint8_t *ptr, size_t size) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < size) {
|
||||||
|
debug_print ("%02x", ptr[i]);
|
||||||
|
if ((i + 1) % LINE_BREAK == 0)
|
||||||
|
debug_print ("\n");
|
||||||
|
else
|
||||||
|
debug_print (" ");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i % LINE_BREAK != 0)
|
||||||
|
debug_print ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t host_order32(const char *b) {
|
||||||
|
return ((b[3]) << 24) | ((b[2]) << 16) | ((b[1]) << 8) | (b[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
main.cpp
15
main.cpp
|
@ -1,3 +1,4 @@
|
||||||
|
/* nsemu - LGPL - Copyright 2017 rkx1209<rkx1209dev@gmail.com> */
|
||||||
#include "Nsemu.hpp"
|
#include "Nsemu.hpp"
|
||||||
#include "optionparser.h"
|
#include "optionparser.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -42,13 +43,20 @@ struct Arg: public option::Arg
|
||||||
enum optionIndex { UNKNOWN, HELP };
|
enum optionIndex { UNKNOWN, HELP };
|
||||||
const option::Descriptor usage[] =
|
const option::Descriptor usage[] =
|
||||||
{
|
{
|
||||||
{UNKNOWN, 0, "", "",Arg::None, "USAGE: nsemu [options] <nro-binary>\n\n"
|
{UNKNOWN, 0, "", "",Arg::None, "USAGE: nsemu [options] <nso-binary>\n\n"
|
||||||
"Options:" },
|
"Options:" },
|
||||||
{HELP, 0,"","help",Arg::None, " --help \tUnsurprisingly, print this message." },
|
{HELP, 0,"","help",Arg::None, " --help \tUnsurprisingly, print this message." },
|
||||||
{0,0,nullptr,nullptr,nullptr,nullptr}
|
{0,0,nullptr,nullptr,nullptr,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void load_nso(Nsemu *nsemu, string path, uint64_t addr) {
|
||||||
|
Nso nso(path);
|
||||||
|
nso.load(nsemu, addr);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
Nsemu::create();
|
||||||
|
Nsemu *nsemu = Nsemu::get_instance();
|
||||||
argc -= argc > 0;
|
argc -= argc > 0;
|
||||||
argv += argc > 0;
|
argv += argc > 0;
|
||||||
|
|
||||||
|
@ -79,6 +87,9 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
string nso_path = parse.nonOption(0);
|
||||||
|
debug_print ("NSO path=%s\n", nso_path.c_str());
|
||||||
|
load_nso(nsemu, nso_path, 0x1000);
|
||||||
|
Nsemu::destroy();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue