Starts to implement exploader and SuperVM implementation.
This commit is contained in:
parent
b07cb36418
commit
3ec8c1dc18
4 changed files with 242 additions and 0 deletions
104
libvm/exp.cpp
Normal file
104
libvm/exp.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
#define DEBUG_VAL(x) std::cout << #x << " = " << (x) << "\n";
|
||||
|
||||
#include "include/supervm/exp.hpp"
|
||||
#include "include/streams.hpp"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char const *outfileName = "a.exp";
|
||||
char const *codefileName = nullptr;
|
||||
char const *datafileName = nullptr;
|
||||
int memsize = 65536;
|
||||
opterr = 0;
|
||||
int c;
|
||||
while ((c = getopt (argc, argv, "c:d:m:o:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'm':
|
||||
memsize = atoi(optarg);
|
||||
if(memsize <= 0) {
|
||||
fprintf(stderr, "memsize must be larger 0.\n");
|
||||
return 1;
|
||||
}
|
||||
case 'o':
|
||||
outfileName = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
codefileName = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
datafileName = optarg;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt == 'o')
|
||||
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||||
else if (isprint (optopt))
|
||||
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
||||
else
|
||||
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
|
||||
return 1;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
for (int index = optind; index < argc; index++)
|
||||
printf ("Non-option argument %s\n", argv[index]);
|
||||
|
||||
|
||||
FileStream fs(outfileName, "wb");
|
||||
|
||||
exp::File fileHeader = {
|
||||
.magicNumber = EXP_MAGIC,
|
||||
.majorVersion = 1,
|
||||
.minorVersion = 0,
|
||||
.numMeta = 0,
|
||||
.numSections = 2,
|
||||
.posMeta = 0,
|
||||
.posSections = 0,
|
||||
};
|
||||
|
||||
fileHeader.posSections = fs.write(&fileHeader, sizeof(exp::File));
|
||||
|
||||
DEBUG_VAL(fileHeader.posSections);
|
||||
|
||||
exp::Section codeSection = {
|
||||
.type = 0,
|
||||
.start = 0,
|
||||
.length = 26,
|
||||
};
|
||||
strcpy(codeSection.name, ".code");
|
||||
|
||||
exp::Section dataSection = {
|
||||
.type = 1,
|
||||
.start = 0,
|
||||
.length = 10,
|
||||
};
|
||||
strcpy(dataSection.name, ".data");
|
||||
|
||||
fs.write(&codeSection, sizeof(exp::Section));
|
||||
fs.write(&dataSection, sizeof(exp::Section));
|
||||
|
||||
codeSection.start = fs.write("abcdefghijklmnopqrstuvwxyz", 26);
|
||||
dataSection.start = fs.write("0123456789", 10);
|
||||
|
||||
DEBUG_VAL(codeSection.start);
|
||||
DEBUG_VAL(dataSection.start);
|
||||
|
||||
// Now write the header again...
|
||||
fs.rewind();
|
||||
fs.write(&fileHeader, sizeof(exp::File));
|
||||
|
||||
fs.seek(SeekMode::Start, fileHeader.posSections);
|
||||
fs.write(&codeSection, sizeof(exp::Section));
|
||||
fs.write(&dataSection, sizeof(exp::Section));
|
||||
|
||||
return 0;
|
||||
}
|
50
libvm/include/streams.hpp
Normal file
50
libvm/include/streams.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
enum class SeekMode
|
||||
{
|
||||
Start,
|
||||
Current,
|
||||
End,
|
||||
};
|
||||
|
||||
class BaseStream
|
||||
{
|
||||
public:
|
||||
virtual void rewind() = 0;
|
||||
virtual void seek(SeekMode mode, long int offset) = 0;
|
||||
virtual size_t position() const = 0;
|
||||
};
|
||||
|
||||
class InputStream :
|
||||
public BaseStream
|
||||
{
|
||||
public:
|
||||
virtual size_t read(void *ptr, size_t size) = 0;
|
||||
};
|
||||
|
||||
class OutputStream :
|
||||
public BaseStream
|
||||
{
|
||||
public:
|
||||
virtual size_t write(void const *ptr, size_t size) = 0;
|
||||
};
|
||||
|
||||
class FileStream :
|
||||
public virtual InputStream,
|
||||
public virtual OutputStream
|
||||
{
|
||||
private:
|
||||
FILE *file;
|
||||
public:
|
||||
FileStream(const char *fileName, const char *mode);
|
||||
~FileStream();
|
||||
void rewind() override;
|
||||
void seek(SeekMode mode, long int offset) override;
|
||||
size_t position() const override;
|
||||
|
||||
size_t read(void *ptr, size_t size) override;
|
||||
|
||||
size_t write(void const *ptr, size_t size) override;
|
||||
};
|
42
libvm/include/supervm/exp.hpp
Normal file
42
libvm/include/supervm/exp.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#define EXP_MAGIC 0x00505845 // 'E' 'X' 'P' '\0'
|
||||
|
||||
namespace exp
|
||||
{
|
||||
struct File
|
||||
{
|
||||
uint32_t magicNumber; // MUST BE EXP_MAGIC
|
||||
uint16_t majorVersion; // 1
|
||||
uint16_t minorVersion; // 0
|
||||
uint32_t numMeta; // Number of metadata entries
|
||||
uint32_t numSections; // Number of sections
|
||||
uint32_t posMeta; // File pointer of first metadata entry
|
||||
uint32_t posSections; // File pointer of first section definition;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct Section
|
||||
{
|
||||
uint32_t type; // Type of the section: 0 = code, 1 = data
|
||||
uint32_t start; // File pointer to the begin of the section
|
||||
uint32_t length; // Length of the section in bytes
|
||||
char name[64]; // Name of the section, null terminated c-string
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct String
|
||||
{
|
||||
uint32_t start; // File pointer to the start of the string
|
||||
uint32_t length; // Length of the string in bytes.
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct Meta
|
||||
{
|
||||
uint32_t type; // Type of the metadata: 0 = uint32_t, 1 = int32_t, 2 = ExpString
|
||||
char key[32]; // Name of the metadata, null terminated c-string
|
||||
union {
|
||||
uint32_t u; // uint32_t
|
||||
int32_t i; // int32_t
|
||||
String s; // ExpString
|
||||
} value; // Value of the metadata
|
||||
} __attribute__ ((packed));
|
||||
}
|
46
libvm/streams.cpp
Normal file
46
libvm/streams.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "include/streams.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
FileStream::FileStream(const char *fileName, const char *mode) :
|
||||
file(fopen(fileName, mode))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FileStream::~FileStream()
|
||||
{
|
||||
fclose(this->file);
|
||||
}
|
||||
|
||||
void FileStream::rewind()
|
||||
{
|
||||
::rewind(this->file);
|
||||
}
|
||||
|
||||
void FileStream::seek(SeekMode mode, long int offset)
|
||||
{
|
||||
int sm;
|
||||
switch(mode) {
|
||||
case SeekMode::Start: sm = SEEK_SET; break;
|
||||
case SeekMode::Current: sm = SEEK_CUR; break;
|
||||
case SeekMode::End: sm = SEEK_END; break;
|
||||
}
|
||||
fseek(this->file, offset, sm);
|
||||
}
|
||||
|
||||
size_t FileStream::position() const
|
||||
{
|
||||
return ftell(this->file);
|
||||
}
|
||||
|
||||
size_t FileStream::read(void *ptr, size_t size)
|
||||
{
|
||||
fread(ptr, size, 1, this->file);
|
||||
return this->position();
|
||||
}
|
||||
|
||||
size_t FileStream::write(void const *ptr, size_t size)
|
||||
{
|
||||
fwrite(ptr, size, 1, this->file);
|
||||
return this->position();
|
||||
}
|
Loading…
Reference in a new issue