2012-05-11 23:43:27 +00:00
|
|
|
/* Copyright (c) 2009-2012, Avian Contributors
|
2012-04-24 22:17:52 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
|
|
|
#ifndef AVIAN_TOOLS_H_
|
|
|
|
#define AVIAN_TOOLS_H_
|
|
|
|
|
2012-05-03 14:50:22 +00:00
|
|
|
#include <stdlib.h>
|
2012-05-01 19:16:32 +00:00
|
|
|
#include "environment.h"
|
|
|
|
|
2012-04-24 22:17:52 +00:00
|
|
|
namespace avian {
|
|
|
|
|
|
|
|
namespace tools {
|
|
|
|
|
2012-04-25 14:43:51 +00:00
|
|
|
class OutputStream {
|
|
|
|
public:
|
|
|
|
virtual void writeChunk(const void* data, size_t size) = 0;
|
|
|
|
virtual void write(uint8_t byte);
|
|
|
|
virtual void writeRepeat(uint8_t byte, size_t size);
|
|
|
|
};
|
|
|
|
|
|
|
|
class FileOutputStream : public OutputStream {
|
|
|
|
private:
|
|
|
|
FILE* file;
|
|
|
|
public:
|
|
|
|
FileOutputStream(const char* name);
|
|
|
|
~FileOutputStream();
|
|
|
|
|
|
|
|
bool isValid();
|
|
|
|
|
|
|
|
virtual void writeChunk(const void* data, size_t size);
|
|
|
|
virtual void write(uint8_t byte);
|
|
|
|
};
|
|
|
|
|
2012-04-27 18:08:44 +00:00
|
|
|
class String {
|
2012-04-24 22:17:52 +00:00
|
|
|
public:
|
2012-04-27 18:08:44 +00:00
|
|
|
const char* text;
|
|
|
|
size_t length;
|
2012-04-24 22:17:52 +00:00
|
|
|
|
2012-04-27 18:08:44 +00:00
|
|
|
String(const char* text);
|
2012-05-02 16:22:44 +00:00
|
|
|
|
|
|
|
inline String(const char* text, size_t length):
|
|
|
|
text(text),
|
|
|
|
length(length) {}
|
2012-04-27 18:08:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class SymbolInfo {
|
|
|
|
public:
|
|
|
|
unsigned addr;
|
|
|
|
String name;
|
|
|
|
|
2012-05-07 16:00:59 +00:00
|
|
|
inline SymbolInfo(uint64_t addr, const String& name):
|
2012-04-27 18:08:44 +00:00
|
|
|
addr(addr),
|
|
|
|
name(name) {}
|
|
|
|
|
|
|
|
inline SymbolInfo():
|
|
|
|
name("") {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Buffer {
|
|
|
|
public:
|
|
|
|
size_t capacity;
|
|
|
|
size_t length;
|
|
|
|
uint8_t* data;
|
|
|
|
|
|
|
|
Buffer();
|
|
|
|
~Buffer();
|
|
|
|
|
|
|
|
void ensure(size_t more);
|
|
|
|
void write(const void* d, size_t size);
|
|
|
|
};
|
|
|
|
|
|
|
|
class StringTable : public Buffer {
|
|
|
|
public:
|
|
|
|
unsigned add(String str);
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
class Slice {
|
|
|
|
public:
|
|
|
|
T* items;
|
|
|
|
size_t count;
|
2012-04-24 22:17:52 +00:00
|
|
|
|
2012-04-27 18:08:44 +00:00
|
|
|
inline Slice(T* items, size_t count):
|
|
|
|
items(items),
|
|
|
|
count(count) {}
|
2012-04-24 22:17:52 +00:00
|
|
|
|
2012-05-02 15:49:31 +00:00
|
|
|
inline Slice(const Slice<T>& copy):
|
|
|
|
items(copy.items),
|
|
|
|
count(copy.count) {}
|
|
|
|
|
2012-04-27 18:08:44 +00:00
|
|
|
inline T* begin() {
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline T* end() {
|
|
|
|
return items + count;
|
|
|
|
}
|
2012-04-24 22:17:52 +00:00
|
|
|
};
|
|
|
|
|
2012-05-02 15:49:31 +00:00
|
|
|
template<class T>
|
|
|
|
class DynamicArray : public Slice<T> {
|
|
|
|
public:
|
|
|
|
size_t capacity;
|
|
|
|
|
|
|
|
DynamicArray():
|
|
|
|
Slice<T>((T*)malloc(10 * sizeof(T)), 0),
|
|
|
|
capacity(10) {}
|
|
|
|
~DynamicArray() {
|
|
|
|
free(Slice<T>::items);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ensure(size_t more) {
|
|
|
|
if(Slice<T>::count + more > capacity) {
|
|
|
|
capacity = capacity * 2 + more;
|
|
|
|
Slice<T>::items = (T*)realloc(Slice<T>::items, capacity * sizeof(T));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(const T& item) {
|
|
|
|
ensure(1);
|
|
|
|
Slice<T>::items[Slice<T>::count++] = item;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-04-24 22:17:52 +00:00
|
|
|
class PlatformInfo {
|
|
|
|
public:
|
|
|
|
enum OperatingSystem {
|
2012-05-01 19:16:32 +00:00
|
|
|
Linux = AVIAN_PLATFORM_LINUX,
|
|
|
|
Windows = AVIAN_PLATFORM_WINDOWS,
|
|
|
|
Darwin = AVIAN_PLATFORM_DARWIN,
|
2012-08-02 16:36:16 +00:00
|
|
|
FreeBSD = AVIAN_PLATFORM_FREEBSD,
|
2012-05-01 19:16:32 +00:00
|
|
|
UnknownOS = AVIAN_PLATFORM_UNKNOWN
|
2012-04-24 22:17:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum Architecture {
|
2012-05-01 19:16:32 +00:00
|
|
|
x86 = AVIAN_ARCH_X86,
|
|
|
|
x86_64 = AVIAN_ARCH_X86_64,
|
|
|
|
PowerPC = AVIAN_ARCH_POWERPC,
|
|
|
|
Arm = AVIAN_ARCH_ARM,
|
|
|
|
UnknownArch = AVIAN_ARCH_UNKNOWN
|
2012-04-24 22:17:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const OperatingSystem os;
|
|
|
|
const Architecture arch;
|
|
|
|
|
|
|
|
static OperatingSystem osFromString(const char* os);
|
|
|
|
static Architecture archFromString(const char* arch);
|
|
|
|
|
|
|
|
inline PlatformInfo(OperatingSystem os, Architecture arch):
|
|
|
|
os(os),
|
|
|
|
arch(arch) {}
|
|
|
|
|
|
|
|
inline bool operator == (const PlatformInfo& other) {
|
|
|
|
return os == other.os && arch == other.arch;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool isLittleEndian() {
|
|
|
|
return arch != PowerPC;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Platform {
|
|
|
|
private:
|
|
|
|
Platform* next;
|
|
|
|
static Platform* first;
|
|
|
|
public:
|
|
|
|
PlatformInfo info;
|
|
|
|
|
|
|
|
inline Platform(PlatformInfo info):
|
|
|
|
next(first),
|
|
|
|
info(info)
|
|
|
|
{
|
|
|
|
first = this;
|
|
|
|
}
|
|
|
|
|
2012-04-27 18:08:44 +00:00
|
|
|
enum AccessFlags {
|
|
|
|
Writable = 1 << 0,
|
|
|
|
Executable = 1 << 1
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual bool writeObject(OutputStream* out, Slice<SymbolInfo> symbols, Slice<const uint8_t> data, unsigned accessFlags, unsigned alignment) = 0;
|
2012-04-24 22:17:52 +00:00
|
|
|
|
|
|
|
static Platform* getPlatform(PlatformInfo info);
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace tools
|
|
|
|
|
|
|
|
} // namespace avian
|
|
|
|
|
2012-08-02 16:36:16 +00:00
|
|
|
#endif
|
|
|
|
|