[ create a new paste ] login | about

Link: http://codepad.org/iibBeWKw    [ raw code | fork ]

C++, pasted on Jun 1:
// g++ -o um -O3 -Xlinker -pagezero_size -Xlinker 4000000 umdir.cpp 

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/mman.h>

class Machine
{
	std::vector<unsigned int> data;
public:
	Machine(char *fname);
	int Run();
};


Machine::Machine(char *fname):data()
{
	std::cout << "Loading..." << std::endl;
	FILE * f = fopen(fname, "r");
	int c1;
	while ((c1 = fgetc(f)) != EOF)
	{
		int c2, c3, c4;
		c2 = fgetc(f);
		c3 = fgetc(f);
		c4 = fgetc(f);
		unsigned int instr = ((unsigned int)c1 << 24) + ((unsigned int)c2 << 16) + ((unsigned int)c3 << 8) + (unsigned int)c4;

		data.push_back(instr);
	}
	std::cout << "Loaded" << std::endl;
}

#define regA registers[(instruction >> 6) & 7]
#define regB  registers[(instruction >> 3) & 7]
#define regC registers[instruction & 7]
#define Next instruction = *finger++; goto *ops[instruction >> 28];

int Machine::Run()
{
	
	void* ops[] = {&&op_0, &&op_1, &&op_2, &&op_3, &&op_4, &&op_5, &&op_6, &&op_7, &&op_8, &&op_9, &&op_10, &&op_11, &&op_12, &&op_13};
	
	unsigned int * finger = 0;
	unsigned int registers[8];
	memset(registers, 0, 8*sizeof(unsigned int));
	unsigned int zsize = data.size();
	unsigned int zactual = 4096*(1 + 4*zsize/4096);
	

	if (mmap(0, zactual, PROT_READ | PROT_WRITE, MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0) == (unsigned int*)-1)
	{
	    printf("Whoops!\n");
		return 0;
	}


	for (unsigned int i = 0; i <  zsize; ++i)
		*(unsigned int*)(4*i)=data[i];
	
	
	
	unsigned int instruction;
	unsigned int * tmp;
	unsigned int sz;
	Next;

op_0:
		if (regC != 0) regA = regB;
		Next;
op_1:
		regA =  ((unsigned int*)(regB))[regC];
		Next;
op_2:
		((unsigned int*)(regA))[regB] = regC;
		Next;
op_3:
		regA = regB + regC;
		Next;
op_4:
		regA = regB * regC;
		Next;
op_5:
		regA = regB / regC;
		Next;
op_6:
		regA = ~(regB & regC);
		Next;
		
op_7:
		return 0;
op_8:
			sz = regC;
		tmp = (unsigned int*) calloc(1+sz,4);
		*tmp++ = sz;
		regB = (unsigned int)tmp;
		Next;
	op_9:
		free((unsigned int*)(regC) - 1);
		Next;
	op_10:
		putchar(regC);
		Next;
	op_11:
		regC = getchar();
		if (regC == EOF) clearerr(stdin);
		Next;
	op_12:
		tmp =  (unsigned int*)(regB);
		if (tmp)
		{
			sz = tmp[-1];
			if (sz > zsize)
			{
				zsize = sz;
				zactual = 4096*(1 + 4*zsize/4096);
				mmap(0, zactual, PROT_READ | PROT_WRITE, MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);

			}
			memcpy(0, tmp, sz*4);
		}
		finger = (unsigned int*)(4 * regC);
		Next;
	op_13:
		registers[(instruction >> 25) & 7] = (instruction & ((1 << 25) - 1));
		Next;

}

int main(int argc, char **argv)
{
	if (argc != 2)
	{
		std::cout << "Usage: um inputfile\n";
		return 1;
	}
	Machine(argv[1]).Run();
	return 0;
}


Create a new paste based on this one


Comments: