-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experimental mechanism for loading Z3 dynamically at runtime.
- Loading branch information
Showing
27 changed files
with
17,082 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
add_library(z3wrapper STATIC wrapper.cpp Z3Loader.cpp) | ||
target_include_directories(z3wrapper SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||
target_link_libraries(z3wrapper PUBLIC ${CMAKE_DL_LIBS}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include <Z3Loader.h> | ||
#include <stdexcept> | ||
#include <z3.h> | ||
|
||
Z3Loader const& Z3Loader::get() | ||
{ | ||
static Z3Loader z3; | ||
return z3; | ||
} | ||
void* Z3Loader::loadSymbol(const char* _name) const | ||
{ | ||
if (!m_handle) | ||
throw std::runtime_error("Attempted to use dynamically loaded Z3, even though it is not available."); | ||
void* sym = dlsym(m_handle, _name); | ||
if (!sym) | ||
throw std::runtime_error(std::string("Symbol \"") + _name + "\" not found in libz3.so"); | ||
return sym; | ||
} | ||
|
||
bool Z3Loader::available() const | ||
{ | ||
if (m_handle == nullptr) | ||
return false; | ||
unsigned major = 0; | ||
unsigned minor = 0; | ||
unsigned build = 0; | ||
unsigned rev = 0; | ||
Z3_get_version(&major, &minor, &build, &rev); | ||
return (major > 4 || (major == 4 && minor >= 6)); | ||
} | ||
|
||
Z3Loader::Z3Loader(): m_handle(dlmopen(LM_ID_NEWLM, "libz3.so", RTLD_NOW)) | ||
{ | ||
} | ||
Z3Loader::~Z3Loader() | ||
{ | ||
dlclose(m_handle); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#include <dlfcn.h> | ||
|
||
class Z3Loader | ||
{ | ||
public: | ||
static Z3Loader const& get(); | ||
void* loadSymbol(const char* _name) const; | ||
bool available() const; | ||
private: | ||
Z3Loader(); | ||
~Z3Loader(); | ||
void* m_handle = nullptr; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#!/usr/bin/env python | ||
|
||
import os | ||
import sys | ||
import re | ||
|
||
# Patterns to match Z3 API entry point definitions. | ||
def_pat = re.compile(" *def_API(.*)") | ||
extradef_pat = re.compile(" *extra_API(.*)") | ||
# Pattern to extract name and arguments from the above. | ||
def_args_pat = re.compile("\('(.*)'[^\(\)]*\((.*)\)\s*\)") | ||
# Pattern to extract a list of arguments from the above. | ||
arg_list_pat = re.compile("[^\(]*\([^\)]*\)[, ]*") | ||
|
||
def generateEntryPoint(line, args): | ||
m = def_args_pat.match(args) | ||
if m: | ||
name = m.group(1) | ||
num_args = len(arg_list_pat.findall(m.group(2))) | ||
arglist = '' | ||
paramlist = '' | ||
for i in range(num_args): | ||
if i != 0: | ||
arglist += ', ' | ||
paramlist += ', ' | ||
arglist += '_' + str(i) | ||
paramlist += 'ArgType<&' + name + ', ' + str(i) + '> _' + str(i) | ||
print('ResultType<&' + name + '> Z3_API ' + name + '(' + paramlist + ')') | ||
print('{') | ||
print('\t' + 'static auto sym = reinterpret_cast<decltype(&' + name + ')>(Z3Loader::get().loadSymbol(\"' + name + '\"));') | ||
print('\treturn sym(' + arglist + ');') | ||
print('}') | ||
else: | ||
raise Exception('Could not parse entry point definition: ' + line) | ||
|
||
print(r"""// This file is auto-generated from genwrapper.py | ||
#include <z3.h> | ||
#include <tuple> | ||
#include <Z3Loader.h> | ||
namespace { | ||
template<typename T> | ||
struct FunctionTrait; | ||
template<typename R, typename... Args> | ||
struct FunctionTrait<R(*)(Args...)> { | ||
using ResultType = R; | ||
template<unsigned N> | ||
using ArgType = std::tuple_element_t<N, std::tuple<Args...>>; | ||
}; | ||
template<auto F> | ||
using ResultType = typename FunctionTrait<decltype(F)>::ResultType; | ||
template<auto F, unsigned N> | ||
using ArgType = typename FunctionTrait<decltype(F)>::ArgType<N>; | ||
} | ||
extern "C" { | ||
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h) | ||
{ | ||
static auto sym = reinterpret_cast<decltype(&Z3_set_error_handler)>(Z3Loader::get().loadSymbol("Z3_set_error_handler")); | ||
sym(c, h); | ||
} | ||
""") | ||
|
||
for header in sys.argv[1:]: | ||
with open(header, 'r') as f: | ||
for line in f: | ||
line = line.strip('\r\n\t ') | ||
m = def_pat.match(line) | ||
if m: | ||
generateEntryPoint(line, m.group(1).strip('\r\n\t ')) | ||
m = extradef_pat.match(line) | ||
if m: | ||
generateEntryPoint(line, m.group(1).strip('\r\n\t ')) | ||
|
||
print('}\n') |
Oops, something went wrong.