1 #include "debug_jit.hpp"
2 #include <dlfcn.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string>
6
7 using namespace std;
8
9 namespace JIT
10 {
11
12 struct DebugBlock::Impl
13 {
14 Impl() = default;
15 Impl(Impl &&) = delete;
16 void operator=(Impl &&) = delete;
17 ~Impl();
18
19 void *dylib = nullptr;
20 Func block = nullptr;
21 string name, soname;
22
23 bool compile(uint64_t hash, const std::string &source);
24 };
25
DebugBlock(const unordered_map<string,uint64_t> &)26 DebugBlock::DebugBlock(const unordered_map<string, uint64_t> &)
27 {
28 }
29
~DebugBlock()30 DebugBlock::~DebugBlock()
31 {
32 }
33
~Impl()34 DebugBlock::Impl::~Impl()
35 {
36 if (dylib)
37 dlclose(dylib);
38
39 remove(soname.c_str());
40 remove(name.c_str());
41 }
42
compile(uint64_t hash,const std::string & source)43 bool DebugBlock::compile(uint64_t hash, const std::string &source)
44 {
45 impl = unique_ptr<Impl>(new Impl);
46 bool ret = impl->compile(hash, source);
47 if (ret)
48 block = impl->block;
49 return ret;
50 }
51
compile(uint64_t hash,const std::string & source)52 bool DebugBlock::Impl::compile(uint64_t hash, const std::string &source)
53 {
54 name = "/tmp/";
55 name += to_string(hash);
56 soname = name;
57 name += ".c";
58 soname += ".so";
59
60 FILE *file = fopen(name.c_str(), "w");
61 if (!file)
62 return false;
63
64 fputs(source.c_str(), file);
65 fclose(file);
66
67 char command[256];
68 if (sizeof(size_t) == 8)
69 {
70 sprintf(command, "gcc -o %s %s -shared -fpic -O0 -g -std=c99 -Wl,--unresolved-symbols=ignore-all",
71 soname.c_str(),
72 name.c_str());
73 }
74 else if (sizeof(size_t) == 4)
75 {
76 sprintf(command, "gcc -m32 -o %s %s -shared -fpic -O0 -g -std=c99 -Wl,--unresolved-symbols=ignore-all",
77 soname.c_str(),
78 name.c_str());
79 }
80 int ret = system(command);
81 if (ret != 0)
82 return false;
83
84 dylib = dlopen(soname.c_str(), RTLD_LOCAL | RTLD_LAZY);
85 if (!dylib)
86 return false;
87
88 block = reinterpret_cast<Func>(dlsym(dylib, "block_entry"));
89 if (!dylib)
90 return false;
91 return true;
92 }
93
94 } // namespace JIT
95