211 lines
5.7 KiB
C++
211 lines
5.7 KiB
C++
/*******************************************************************************
|
|
HARPtools by Chad D. Kersey, Summer 2011
|
|
*******************************************************************************/
|
|
#ifndef __OBJ_H
|
|
#define __OBJ_H
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <list>
|
|
#include <stdlib.h>
|
|
|
|
#include "types.h"
|
|
#include "archdef.h"
|
|
#include "instruction.h"
|
|
#include "enc.h"
|
|
#include "asm-tokens.h"
|
|
|
|
namespace Harp {
|
|
class Decoder;
|
|
class Encoder;
|
|
|
|
class Ref {
|
|
public:
|
|
std::string name;
|
|
Ref(const std::string &n, bool r, Size ib = 0):
|
|
name(n), bound(false), relative(r), ibase(ib) { }
|
|
virtual ~Ref() { }
|
|
virtual void bind(Addr addr, Addr base = 0) = 0;
|
|
virtual Addr getAddr() const = 0;
|
|
|
|
bool bound, relative;
|
|
Size ibase;
|
|
};
|
|
|
|
/* Used in not-yet-encoded code objects, plain old data. */
|
|
class SimpleRef : public Ref {
|
|
public:
|
|
SimpleRef(const std::string &name, Addr &addr, bool rel = false) :
|
|
Ref(name, rel), addr(addr) { }
|
|
virtual void bind(Addr addr, Addr base = 0) {
|
|
std::cout << "Attempted to bind a SimpleRef.\n";
|
|
exit(1);
|
|
}
|
|
virtual Addr getAddr() const { return this->addr; }
|
|
Byte *getAddrPtr() { return (Byte*)&addr; }
|
|
|
|
private:
|
|
Addr &addr;
|
|
};
|
|
|
|
// /* Used in already-encoded code objects. */
|
|
// class OffsetRef : public Ref {
|
|
// public:
|
|
// OffsetRef(
|
|
// const std::string &name, std::vector<Byte> &v, Size offset, Size bits,
|
|
// Size ws, bool rel = false, Size ibase = 0
|
|
// ) : Ref(name, rel, ibase), data(v), offset(offset), bits(bits), wordSize(ws)
|
|
// {}
|
|
|
|
// virtual void bind(Addr addr, Addr base = 0) {
|
|
// Size bytes(bits/8), remainder(bits%8);
|
|
|
|
// if (relative) {
|
|
// addr = addr - base;
|
|
// Word_s addr_s(addr);
|
|
// if ((addr_s >> bits) != ~0ull && (addr_s >> bits) != 0) goto noFit;
|
|
// } else {
|
|
// Addr mask = (1ull<<bits)-1;
|
|
// if (addr > mask) goto noFit;
|
|
// }
|
|
|
|
// { Byte mask((1ull<<remainder) - 1);
|
|
// Size i;
|
|
// for (i = 0; i < bytes; i++) {
|
|
// data[offset+i] = addr & 0xff;
|
|
// addr >>= 8;
|
|
// }
|
|
// data[offset+i] &= ~mask;
|
|
// data[offset+i] |= (addr&mask);
|
|
// bound = true;
|
|
// }
|
|
|
|
// return;
|
|
// noFit:
|
|
// std::cout << "Attempt to bind a " << bits << "-bit "
|
|
// << (relative?"":"non-") << "relative symbol to an address"
|
|
// " it cannot reach.\n";
|
|
// exit(1);
|
|
// }
|
|
|
|
// virtual Addr getAddr() const {
|
|
// Size bytes = bits/8, remainder = bits%8;
|
|
// Byte mask((1<<remainder)-1);
|
|
// Addr a(data[offset]&mask);
|
|
|
|
// for (Size i = 0; i < bytes-1; i++) {
|
|
// a |= data[offset + bytes - i - 1];
|
|
// a <<= 8;
|
|
// }
|
|
// return a;
|
|
// }
|
|
|
|
// Size getOffset() const { return offset; }
|
|
// Size getBits() const { return bits; }
|
|
|
|
// private:
|
|
// std::vector<Byte> &data;
|
|
// Size offset, bits, wordSize;
|
|
// };
|
|
|
|
// class Chunk {
|
|
// public:
|
|
// Chunk(std::string n, Size a = 0, Word f = 0) :
|
|
// name(n), alignment(a), bound(false), flags(f), global(false) {}
|
|
// virtual ~Chunk() { for (Size i = 0; i < refs.size(); i++) delete refs[i]; }
|
|
// void bind(Addr a) { address = a; bound = true; }
|
|
// void setGlobal() { global = true; }
|
|
// bool isGlobal() const { return global; }
|
|
// std::string name;
|
|
// Size alignment;
|
|
// bool bound, global;
|
|
// Addr address;
|
|
// Word flags;
|
|
// std::vector<Ref*> refs;
|
|
// };
|
|
|
|
// class TextChunk : public Chunk {
|
|
// public:
|
|
// TextChunk(std::string n, Size a = 0, Word f = 0)
|
|
// : Chunk(n, a, f), instructions() {}
|
|
|
|
// ~TextChunk() {
|
|
// for (Size i = 0; i < instructions.size(); i++) delete instructions[i];
|
|
// }
|
|
|
|
// std::vector<Instruction*> instructions;
|
|
// };
|
|
|
|
// class DataChunk : public Chunk {
|
|
// public:
|
|
// DataChunk(std::string n, Size a = 0, Word f = 0)
|
|
// : Chunk(n, a, f), size(0), contents() {}
|
|
// Size size;
|
|
// std::vector<Byte> contents; /* 0 to size bytes in length. */
|
|
// };
|
|
|
|
// class Obj {
|
|
// public:
|
|
// ~Obj() { for (Size i = 0; i < chunks.size(); i++) delete chunks[i]; }
|
|
// std::vector<Chunk*> chunks;
|
|
// Size entry;
|
|
// };
|
|
|
|
// class DynObj : public Obj {
|
|
// public:
|
|
// std::vector<std::string> deps;
|
|
// };
|
|
|
|
// class ObjReader {
|
|
// public:
|
|
// virtual Obj *read(std::istream &input) = 0;
|
|
// private:
|
|
// };
|
|
|
|
// class ObjWriter {
|
|
// public:
|
|
// virtual void write(std::ostream &output, const Obj &o) = 0;
|
|
// private:
|
|
// };
|
|
|
|
// class AsmReader : public ObjReader {
|
|
// public:
|
|
// AsmReader(ArchDef arch) :
|
|
// wordSize(arch.getWordSize()), nRegs(arch.getNRegs()) {}
|
|
// virtual Obj *read(std::istream &input);
|
|
// private:
|
|
// Size wordSize, nRegs;
|
|
|
|
// // Operand type sequences indexed by argument class
|
|
// enum ArgType {AT_END, AT_REG, AT_PREG, AT_LIT};
|
|
// static ArgType operandtype_table[][4]; // ArgClass -> ArgType[arg_idx]
|
|
// };
|
|
|
|
// class HOFReader : public ObjReader {
|
|
// public:
|
|
// HOFReader(ArchDef &arch) : arch(arch) {}
|
|
// Obj *read(std::istream &input);
|
|
// private:
|
|
// const ArchDef &arch;
|
|
// };
|
|
|
|
// class AsmWriter : public ObjWriter {
|
|
// public:
|
|
// AsmWriter(ArchDef arch): wordSize(arch.getWordSize()) {}
|
|
// virtual void write(std::ostream &output, const Obj &obj);
|
|
// private:
|
|
// Size wordSize;
|
|
// };
|
|
|
|
// class HOFWriter : public ObjWriter {
|
|
// public:
|
|
// HOFWriter(ArchDef &arch) : arch(arch) {}
|
|
// virtual void write(std::ostream &output, const Obj &obj);
|
|
// private:
|
|
// const ArchDef &arch;
|
|
// };
|
|
};
|
|
|
|
#endif
|