summaryrefslogtreecommitdiff
path: root/aoe2hd/src/CodeGenerator.cpp
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-07-02 01:06:39 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-07-02 03:08:59 +0200
commitc2a2445897af17adb56a32dcf111312763a575d4 (patch)
treead459cdd682aff3a011d11b6f2a3c518c60dec6a /aoe2hd/src/CodeGenerator.cpp
initial commit
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'aoe2hd/src/CodeGenerator.cpp')
-rwxr-xr-xaoe2hd/src/CodeGenerator.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/aoe2hd/src/CodeGenerator.cpp b/aoe2hd/src/CodeGenerator.cpp
new file mode 100755
index 0000000..74149dd
--- /dev/null
+++ b/aoe2hd/src/CodeGenerator.cpp
@@ -0,0 +1,100 @@
+#include "CodeGenerator.h"
+
+#include <assert.h>
+#include <sstream>
+#include <iomanip>
+
+#include "native.h"
+#include "utils.h"
+
+
+std::vector<unsigned char> x86_relJump(unsigned long dst,
+ unsigned long src)
+{
+ std::vector<unsigned char> code(5);
+ code[0] = 0xE9;
+ unsigned long addr = dst - src;
+ code[1] = (*((unsigned char *)(&addr)+0));
+ code[2] = (*((unsigned char *)(&addr)+1));
+ code[3] = (*((unsigned char *)(&addr)+2));
+ code[4] = (*((unsigned char *)(&addr)+3));
+ return code;
+}
+
+CodeGenerator::CodeGenerator(const native_data& nd)
+ : nd(nd), codes()
+{
+}
+
+CodeGenerator::~CodeGenerator()
+{
+}
+
+CodeGenerator& CodeGenerator::addCode(const std::vector<unsigned char>& code)
+{
+ codes.push_back(code);
+ return *this;
+}
+
+CodeGenerator& CodeGenerator::setCode(int index, const std::vector<unsigned char>& code)
+{
+ codes.at(index) = code;
+ return *this;
+}
+
+CodeGenerator& CodeGenerator::setCodeSized(int index, const std::vector<unsigned char>& code)
+{
+ assert(codes.at(index).size() == code.size());
+ return setCode(index, code);
+}
+
+CodeGenerator& CodeGenerator::setRel32JMP(int index, unsigned long dst, unsigned long src, bool reversed)
+{
+ if (!reversed)
+ {
+ dst += nd.proc.modbase - diffRel32JMP(reversed, index);
+ }
+ else
+ {
+ src += nd.proc.modbase + diffRel32JMP(reversed, index);
+ }
+ auto jmp = x86_relJump(dst, src);
+ setCodeSized(index, jmp);
+ return *this;
+}
+
+std::vector<unsigned char>::size_type CodeGenerator::buildSize(int maxCodes)
+{
+ std::vector<unsigned char>::size_type total = 0;
+ for (auto& code : codes)
+ {
+ total += code.size();
+ if (maxCodes-- == 0)
+ break;
+ }
+ return total;
+}
+
+std::vector<unsigned char> CodeGenerator::build()
+{
+ std::vector<unsigned char> result;
+ for (auto& code : codes)
+ {
+ result.insert(result.end(), code.begin(), code.end());
+ }
+ return result;
+}
+
+std::vector<unsigned char> CodeGenerator::buildAndClear()
+{
+ auto result = build();
+ clear();
+ return result;
+}
+
+std::string CodeGenerator::toString()
+{
+ std::stringstream out;
+ out << "CodeBin: " << utils::convertBinToHexstr(build()) << std::endl;
+ return out.str();
+}