mirror of
https://github.com/RKX1209/nsemu.git
synced 2024-06-15 18:57:39 -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
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
.*
|
||||
core
|
||||
nsemu
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,12 +1,12 @@
|
|||
CXX := g++
|
||||
SRC_FILES := $(wildcard *.cpp)
|
||||
OBJ_FILES := $(SRC_FILES:.cpp=.o)
|
||||
CXX_FLAGS := -Iinclude
|
||||
CXX_FLAGS := -std=c++11 -Iinclude
|
||||
LD_FLAGS := -llz4
|
||||
|
||||
all: nsemu
|
||||
nsemu: $(OBJ_FILES)
|
||||
$(CXX) -o nsemu $(LD_FLAGS) $(OBJ_FILES)
|
||||
$(CXX) -o nsemu $(OBJ_FILES) $(LD_FLAGS)
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXX_FLAGS) -c -g -o $@ $<
|
||||
clean:
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
/* nsemu - LGPL - Copyright 2017 rkx1209<rkx1209dev@gmail.com> */
|
||||
|
||||
#include "Nsemu.hpp"
|
||||
#include <lz4.h>
|
||||
|
||||
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);
|
||||
length = (uint32_t) fp.tellg();
|
||||
fp.seekg(0);
|
||||
}
|
||||
|
||||
NintendoObject::~NintendoObject() {
|
||||
fp.close();
|
||||
}
|
||||
|
||||
char *decompress(ifstream &fp, uint32_t offset, uint32_t csize, uint32_t usize) {
|
||||
fp.seekg(offset);
|
||||
char *buf = new char[csize];
|
||||
|
@ -18,10 +24,29 @@ char *decompress(ifstream &fp, uint32_t offset, uint32_t csize, uint32_t usize)
|
|||
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 {
|
||||
public:
|
||||
NintendoObject(std::string path);
|
||||
~NintendoObject() {}
|
||||
virtual int load (Nsemu *nsemu, uint64_t *base) = 0;
|
||||
~NintendoObject();
|
||||
virtual int load (Nsemu *nsemu, uint64_t base) = 0;
|
||||
protected:
|
||||
std::ifstream fp;
|
||||
uint32_t length;
|
||||
|
@ -15,7 +15,7 @@ protected:
|
|||
class Nso : NintendoObject {
|
||||
public:
|
||||
Nso(std::string path) : NintendoObject(path) {}
|
||||
int load (Nsemu *nsemu, uint64_t *base);
|
||||
int load (Nsemu *nsemu, uint64_t base);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -29,7 +29,7 @@ typedef struct {
|
|||
class Nro : NintendoObject {
|
||||
public:
|
||||
Nro(std::string path) : NintendoObject(path) {}
|
||||
int load (Nsemu *nsemu, uint64_t *base);
|
||||
int load (Nsemu *nsemu, uint64_t base);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,16 +4,44 @@
|
|||
#include <stdint.h>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "Util.hpp"
|
||||
#include "NintendoObject.hpp"
|
||||
|
||||
/* Global NSEMU singleton class .*/
|
||||
class Nsemu {
|
||||
private:
|
||||
Nsemu() = default;
|
||||
~Nsemu() = default;
|
||||
|
||||
static Nsemu *inst;
|
||||
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
|
||||
|
|
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 "optionparser.h"
|
||||
using namespace std;
|
||||
|
@ -42,13 +43,20 @@ struct Arg: public option::Arg
|
|||
enum optionIndex { UNKNOWN, HELP };
|
||||
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:" },
|
||||
{HELP, 0,"","help",Arg::None, " --help \tUnsurprisingly, print this message." },
|
||||
{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) {
|
||||
Nsemu::create();
|
||||
Nsemu *nsemu = Nsemu::get_instance();
|
||||
argc -= argc > 0;
|
||||
argv += argc > 0;
|
||||
|
||||
|
@ -79,6 +87,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
#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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue