Starts to implement exploader and SuperVM implementation.

This commit is contained in:
Felix Queißner 2016-06-18 11:26:50 +02:00
parent b07cb36418
commit 3ec8c1dc18
4 changed files with 242 additions and 0 deletions

104
libvm/exp.cpp Normal file
View 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
View 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;
};

View 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
View 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();
}