Adjust the project to be able to be installed

Cleans up file locations
This commit is contained in:
Ryan Houdek committed 2019-11-14 23:10:13 -08:00
1 parent 43ec043478
commit 33daca99e2
11 files changed
+43 -81

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
static inline uint64_t AlignUp(uint64_t value, uint64_t size) {
return value + (size - value % size) % size;
};
static inline uint64_t AlignDown(uint64_t value, uint64_t size) {
return value - value % size;
};
+97
View File
@@ -0,0 +1,97 @@
#pragma once
#include <elf.h>
#include <functional>
#include <map>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
namespace ELFLoader {
struct ELFSymbol {
uint64_t FileOffset;
uint64_t Address;
uint64_t Size;
uint8_t Type;
uint8_t Bind;
uint16_t SectionIndex;
char const *Name;
};
class ELFContainer {
public:
ELFContainer(std::string const &Filename, bool CustomInterpreter);
~ELFContainer();
uint64_t GetEntryPoint() const { return Header.e_entry; }
using MemoryLayout = std::tuple<uint64_t, uint64_t, uint64_t>;
MemoryLayout GetLayout() const {
return std::make_tuple(MinPhysicalMemoryLocation, MaxPhysicalMemoryLocation,
PhysicalMemorySize);
}
// Data, Physical, Size
using MemoryWriter = std::function<void(void *, uint64_t, uint64_t)>;
void WriteLoadableSections(MemoryWriter Writer, uint64_t Offset = 0);
ELFSymbol const *GetSymbol(char const *Name);
ELFSymbol const *GetSymbol(uint64_t Address);
using RangeType = std::pair<uint64_t, uint64_t>;
ELFSymbol const *GetSymbolInRange(RangeType Address);
bool WasDynamic() const { return DynamicProgram; }
std::string &InterpreterLocation() { return DynamicLinker; }
std::vector<char const*> const *GetNecessaryLibs() const { return &NecessaryLibs; }
void PrintRelocationTable() const;
using SymbolGetter = std::function<ELFSymbol*(char const*, uint8_t)>;
void FixupRelocations(void *ELFBase, uint64_t GuestELFBase, SymbolGetter Getter);
using SymbolAdder = std::function<void(ELFSymbol*)>;
void AddSymbols(SymbolAdder Adder);
void GetInitLocations(uint64_t GuestELFBase, std::vector<uint64_t> *Locations);
bool HasTLS() const { return TLSHeader != nullptr; }
uint64_t InitializeThreadSlot(void *ELFBase, std::function<void(void const*, uint64_t)> Writer) const;
private:
bool LoadELF(std::string const &Filename);
void CalculateMemoryLayouts();
void CalculateSymbols();
void GetDynamicLibs();
// Information functions
void PrintHeader() const;
void PrintSectionHeaders() const;
void PrintProgramHeaders() const;
void PrintSymbolTable() const;
void PrintInitArray() const;
void PrintDynamicTable() const;
std::vector<char> RawFile;
Elf64_Ehdr Header;
std::vector<Elf64_Shdr*> SectionHeaders;
std::vector<Elf64_Phdr*> ProgramHeaders;
std::vector<ELFSymbol> Symbols;
std::unordered_map<std::string, ELFSymbol *> SymbolMap;
std::map<uint64_t, ELFSymbol *> SymbolMapByAddress;
std::vector<char const*> NecessaryLibs;
uint64_t MinPhysicalMemoryLocation{0};
uint64_t MaxPhysicalMemoryLocation{0};
uint64_t PhysicalMemorySize{0};
Elf64_Phdr* InterpreterHeader{};
bool DynamicProgram{false};
std::string DynamicLinker;
Elf64_Phdr const *TLSHeader{};
};
} // namespace ELFLoader
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include "ELFLoader.h"
#include <vector>
#include <unordered_map>
namespace ELFLoader {
class ELFSymbolDatabase final {
public:
ELFSymbolDatabase(::ELFLoader::ELFContainer *file);
~ELFSymbolDatabase();
::ELFLoader::ELFContainer::MemoryLayout GetFileLayout() const;
void MapMemoryRegions(std::function<void*(uint64_t, uint64_t)> Mapper);
void WriteLoadableSections(::ELFLoader::ELFContainer::MemoryWriter Writer);
uint64_t DefaultRIP() const;
using RangeType = std::pair<uint64_t, uint64_t>;
::ELFLoader::ELFSymbol const *GetSymbolInRange(RangeType Address);
::ELFLoader::ELFSymbol const *GetGlobalSymbolInRange(RangeType Address);
::ELFLoader::ELFSymbol const *GetNoWeakSymbolInRange(RangeType Address);
void GetInitLocations(std::vector<uint64_t> *Locations);
uint64_t InitializeThreadSlot(std::function<void(void const*, uint64_t)> Writer) const;
private:
::ELFLoader::ELFContainer *File;
struct ELFInfo {
std::string Name;
::ELFLoader::ELFContainer* Container;
::ELFLoader::ELFContainer::MemoryLayout CustomLayout;
void *ELFBase;
uint64_t GuestBase;
};
ELFInfo LocalInfo;
std::vector<ELFInfo*> DynamicELFInfo;
std::vector<ELFInfo*> InitializationOrder;
std::unordered_map<std::string, ELFInfo*> NameToELF;
std::vector<std::string> LibrarySearchPaths;
// Symbols
std::vector<ELFLoader::ELFSymbol*> Symbols;
using SymbolTableType = std::unordered_map<std::string, ELFLoader::ELFSymbol *>;
SymbolTableType SymbolMap;
SymbolTableType SymbolMapGlobalOnly;
SymbolTableType SymbolMapNoWeak;
SymbolTableType SymbolMapNoMain;
SymbolTableType SymbolMapNoMainNoWeak;
std::map<uint64_t, ELFLoader::ELFSymbol *> SymbolMapByAddress;
bool FindLibraryFile(std::string *Result, const char *Library);
void FillLibrarySearchPaths();
void FillMemoryLayouts();
void FillInitializationOrder();
void FillSymbols();
void HandleRelocations();
::ELFLoader::ELFSymbol const *GetSymbolFromTable(RangeType Address, std::unordered_map<std::string, ELFLoader::ELFSymbol *> &Table);
};
}
+101
View File
@@ -0,0 +1,101 @@
#pragma once
#include <functional>
#include <sstream>
#include <stdarg.h>
namespace LogMan {
enum DebugLevels {
NONE = 0, ///< Expect zero messages
ASSERT = 1, ///< Assert throwing
ERROR = 2, ///< Only Errors printed
DEBUG = 3, ///< Debug messages added
INFO = 4, ///< Info messages added
STDOUT = 5, ///< Meant to go to STDOUT
STDERR = 6, ///< Meant to go to STDERR
};
constexpr DebugLevels MSG_LEVEL = INFO;
namespace Throw {
using ThrowHandler = void(*)(char const *Message);
void InstallHandler(ThrowHandler Handler);
[[noreturn]] void M(const char *fmt, va_list args);
#ifdef NDEBUG
static inline void A(bool, const char*, ...) {}
#else
static inline void A(bool Value, const char *fmt, ...) {
if (MSG_LEVEL >= ASSERT && !Value) {
va_list args;
va_start(args, fmt);
M(fmt, args);
va_end(args);
}
}
#endif
} // namespace Throw
namespace Msg {
using MsgHandler = void(*)(DebugLevels Level, char const *Message);
void InstallHandler(MsgHandler Handler);
void M(DebugLevels Level, const char *fmt, va_list args);
#ifdef NDEBUG
static inline void A(const char*, ...) {}
#else
static inline void A(const char *fmt, ...) {
if (MSG_LEVEL >= ASSERT) {
va_list args;
va_start(args, fmt);
M(ASSERT, fmt, args);
va_end(args);
}
__builtin_trap();
}
#endif
static inline void E(const char *fmt, ...) {
if (MSG_LEVEL >= ERROR) {
va_list args;
va_start(args, fmt);
M(ERROR, fmt, args);
va_end(args);
}
}
static inline void D(const char *fmt, ...) {
if (MSG_LEVEL >= DEBUG) {
va_list args;
va_start(args, fmt);
M(DEBUG, fmt, args);
va_end(args);
}
}
static inline void I(const char *fmt, ...) {
if (MSG_LEVEL >= INFO) {
va_list args;
va_start(args, fmt);
M(INFO, fmt, args);
va_end(args);
}
}
static inline void OUT(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
M(STDOUT, fmt, args);
va_end(args);
}
static inline void ERR(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
M(STDERR, fmt, args);
va_end(args);
}
} // namespace Msg
} // namespace LogMan
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <stdint.h>
namespace SU::VM {
class VMInstance {
public:
struct RegisterState {
uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
uint64_t rip, rflags;
};
struct SpecialRegisterState {
struct {
uint64_t base;
} fs, gs;
};
static VMInstance* Create();
virtual ~VMInstance() {}
virtual void SetPhysicalMemorySize(uint64_t Size) = 0;
virtual void AddMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) = 0;
virtual void *GetPhysicalMemoryPointer() = 0;
virtual void SetVMRIP(uint64_t VirtualAddress) = 0;
virtual bool SetStepping(bool Step) = 0;
virtual bool Run() = 0;
virtual bool Initialize() = 0;
virtual int ExitReason() = 0;
virtual uint64_t GetFailEntryReason() = 0;
virtual RegisterState GetRegisterState() = 0;
virtual SpecialRegisterState GetSpecialRegisterState() = 0;
virtual void SetRegisterState(RegisterState &State) = 0;
virtual void SetSpecialRegisterState(SpecialRegisterState &State) = 0;
virtual void Debug() = 0;
};
}