58 #elif ETISS_USE_GETPROC
64 using namespace etiss;
127 #if ETISS_USE_DLSYM || ETISS_USE_GETPROC
129 std::mutex ETISS_SharedLibraryInterface_mu_;
130 std::set<void *> ETISS_SharedLibraryInterface_handles_;
132 static std::string ETISS_sdlerror()
135 const char *e = dlerror();
137 return std::string(e);
141 static void *ETISS_dlsym(
void *handle, std::string name, std::string symbol,
bool printNotFoundWarning =
false)
144 std::string fullsymbol = (name +
"_" + symbol);
145 void *ret = dlsym(handle, fullsymbol.c_str());
146 if (ret == 0 && handle != 0)
148 std::string error = ETISS_sdlerror();
149 ret = dlsym(handle, symbol.c_str());
153 "_" + symbol +
"\" and not just as \"" + symbol +
"\"");
155 else if (printNotFoundWarning)
158 "[secondary: " + ETISS_sdlerror() +
"]");
162 #elif ETISS_USE_GETPROC
163 std::string fullsymbol = (name +
"_" + symbol);
169 HMODULE hmodule =
NULL;
170 ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
171 reinterpret_cast<LPCTSTR
>(&ETISS_dlsym), &hmodule);
174 return reinterpret_cast<void *
>(
reinterpret_cast<intptr_t>(GetProcAddress(hmodule, TEXT(fullsymbol.c_str()))));
178 return reinterpret_cast<void *
>(
179 reinterpret_cast<intptr_t>(GetProcAddress((HMODULE)handle, TEXT(fullsymbol.c_str()))));
184 static void *ETISS_dlopen(
const std::string &path,
const std::string &name)
187 std::string fullname = path +
"lib" + name +
193 void *ret = dlopen(fullname.c_str(), RTLD_GLOBAL | RTLD_NOW
200 std::string err = ETISS_sdlerror();
201 ret = dlopen(name.c_str(), RTLD_GLOBAL | RTLD_NOW
211 ret = dlopen(fullname.c_str(), RTLD_GLOBAL | RTLD_NOW
219 #elif ETISS_USE_GETPROC
220 return LoadLibrary(TEXT((path + name).c_str()));
223 static void ETISS_dlclose(
void *handle)
227 #elif ETISS_USE_GETPROC
228 FreeLibrary((HMODULE)handle);
235 ETISS_SharedLibraryInterface(std::string path, std::string name,
void *handle)
239 , wd_(
etiss::
cfg().get<std::string>(
"etiss_wd",
"~/.etiss"))
246 typedef unsigned (*version)();
247 version vfunc = (version)ETISS_dlsym(handle_, name_,
"etissversion");
252 name +
"_etissversion() to check for compability.");
256 unsigned v = vfunc();
257 if (
v != getCurrentLibraryVersion())
261 std::string(
"the library ") +
"lib" + name +
".so" +
262 " was compiled with an incompatible version of etiss. Loading aborted");
269 typedef void (*publicateLocation)(
const char *path);
270 publicateLocation fnc = (publicateLocation)ETISS_dlsym(handle_, name_,
"publicateLocation");
274 "lib" + name +
".so may implement \'void " + name +
275 "_publicateLocation(const char * path)\' to get the library location at runtime. The "
276 "passed string pointer remains valid as long as the library is loaded.");
280 (*fnc)(path_.c_str());
286 typedef void (*publicateWorkdir)(
const char *path);
287 publicateWorkdir fnc = (publicateWorkdir)ETISS_dlsym(handle_, name_,
"publicateWorkdir");
291 "lib" + name +
".so may implement \'void " + name +
292 "_publicateWorkdir(const char * path)\' to get the working directory at runtime (path "
293 "will be etiss::cfg().get<std::string>(\"etiss_wd\",\"~/.etiss\")). The passed string "
294 "pointer remains valid as long as the library is loaded.");
302 version_info_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"versionInfo");
303 if (isvalid_ && !version_info_)
306 "_versionInfo()\' to provide version/build information about the library");
309 count_plugin_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"countPlugin");
310 count_jit_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"countJIT");
311 count_cpuarch_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"countCPUArch");
313 name_jit_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"nameJIT", count_jit_ != 0);
314 name_plugin_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"namePlugin", count_plugin_ != 0);
315 name_cpuarch_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"nameCPUArch", count_cpuarch_ != 0);
317 create_plugin_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"createPlugin", count_plugin_ != 0);
318 create_jit_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"createJIT", count_jit_ != 0);
319 create_cpuarch_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"createCPUArch", count_cpuarch_ != 0);
321 delete_plugin_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"deletePlugin", count_plugin_ != 0);
322 delete_jit_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"deleteJIT", count_jit_ != 0);
323 delete_cpuarch_ = (!isvalid_) ? 0 : ETISS_dlsym(handle_, name_,
"deleteCPUArch", count_cpuarch_ != 0);
325 virtual ~ETISS_SharedLibraryInterface()
328 std::lock_guard<std::mutex> lock(ETISS_SharedLibraryInterface_mu_);
329 ETISS_SharedLibraryInterface_handles_.erase(handle_);
332 ETISS_dlclose(handle_);
334 virtual std::string versionInfo()
336 typedef const char *(*vi)();
339 return ((vi)version_info_)();
346 virtual unsigned countPlugins()
348 typedef unsigned (*count)();
349 if (count_plugin_ && name_plugin_ && create_plugin_)
351 return ((count)count_plugin_)();
358 virtual unsigned countCPUArchs()
360 typedef unsigned (*count)();
361 if (count_cpuarch_ && name_cpuarch_ && create_cpuarch_)
363 return ((count)count_cpuarch_)();
370 virtual unsigned countJITs()
372 typedef unsigned (*count)();
373 if (count_jit_ && name_jit_ && create_jit_)
375 return ((count)count_jit_)();
383 virtual std::string nameJIT(
unsigned index)
385 typedef const char *(*name)(
unsigned index);
388 return std::string(((name)name_jit_)(index));
395 virtual std::string namePlugin(
unsigned index)
397 typedef const char *(*name)(
unsigned index);
400 return std::string(((name)name_plugin_)(index));
407 virtual std::string nameCPUArch(
unsigned index)
409 typedef const char *(*name)(
unsigned index);
412 return std::string(((name)name_cpuarch_)(index));
420 virtual etiss::JIT *createJIT(
unsigned index, std::map<std::string, std::string>
options)
422 typedef etiss::JIT *(*create)(
unsigned index, std::map<std::string, std::string>
options);
425 return ((create)create_jit_)(index,
options);
437 return ((create)create_cpuarch_)(index,
options);
449 return ((create)create_plugin_)(index,
options);
462 ((del)delete_jit_)(o);
466 std::cout <<
"Warning: " << (
"lib" + name_ +
".so") <<
" does not implement void " << name_
467 <<
"_deleteJIT(etiss::JIT*). Memory leaked." << std::endl;
475 ((del)delete_cpuarch_)(o);
479 std::cout <<
"Warning: " << (
"lib" + name_ +
".so") <<
" does not implement void " << name_
480 <<
"_deleteCPUArch(etiss::CPUArch *). Memory leaked." << std::endl;
488 ((del)delete_plugin_)(o);
492 std::cout <<
"Warning: " << (
"lib" + name_ +
".so") <<
" does not implement void " << name_
493 <<
"_deletePlugin(etiss::Plugin*). Memory leaked." << std::endl;
497 virtual bool isValid() {
return isvalid_; }
500 const std::string name_;
501 const std::string path_;
502 const std::string wd_;
510 void *count_cpuarch_;
516 void *create_plugin_;
518 void *create_cpuarch_;
520 void *delete_plugin_;
522 void *delete_cpuarch_;
529 #if ETISS_USE_DLSYM || ETISS_USE_GETPROC
534 if (ETISS_dlsym(0, name,
"_etissversion"))
537 std::string(
"Failed to load library because the name ") + name +
" is already in use.");
544 if (path[path.size() - 1] !=
'/')
545 path = path + std::string(
"/");
547 handle = ETISS_dlopen(path, name);
550 std::string err = ETISS_sdlerror();
551 if (ETISS_dlsym(0, name,
"etissversion"))
554 std::string(
"Failed to load library: ") + (path +
"lib" + name +
".so") +
": " + err);
560 std::string(
"Failed to load library: ") + (path +
"lib" + name +
".so") +
": " + err);
562 return std::shared_ptr<LibraryInterface>(0);
568 if (ETISS_SharedLibraryInterface_handles_.find(handle) != ETISS_SharedLibraryInterface_handles_.end())
571 ETISS_dlclose(handle);
576 ETISS_SharedLibraryInterface_handles_.insert(handle);
581 ETISS_SharedLibraryInterface *retptr =
new ETISS_SharedLibraryInterface(
584 std::shared_ptr<LibraryInterface> ret(retptr);
586 if (!(retptr->isValid()))
590 std::lock_guard<std::mutex> lock(ETISS_SharedLibraryInterface_mu_);
591 ETISS_SharedLibraryInterface_handles_.erase(handle);
599 "etiss::loadLibrary was compiled without any library loading support. library cannot be loaded.",
608 #if ETISS_USE_GETPROC
609 int len = (
int)path.length() + 1;
610 int newlen = MultiByteToWideChar(CP_ACP, 0, path.c_str(), len, 0, 0);
611 std::vector<wchar_t> buf(newlen);
612 MultiByteToWideChar(CP_ACP, 0, path.c_str(), len, buf.data(), newlen);
614 SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
615 AddDllDirectory(buf.data());
ETISS_PLUGIN_EXPORT etiss::CPUArch std::map< std::string, std::string > options
create new instance of the CPUArch type at index
class for simple library access.
general configuration and logging
#define ETISS_VARVAL(VAR)
the interface to translate instructions of and processor architecture
compiler interface for just in time compilation of generated C code
interface class for libraries.
virtual void deletePlugin(etiss::Plugin *)
virtual bool isEmpty()
returns true if this library provides nothing
virtual etiss::CPUArch * createCPUArch(unsigned index, std::map< std::string, std::string > options=std::map< std::string, std::string >())
virtual unsigned countPlugins()
virtual etiss::Plugin * createPlugin(unsigned index, std::map< std::string, std::string > options=std::map< std::string, std::string >())
LibraryInterface(std::string name)
virtual ~LibraryInterface()
virtual void deleteCPUArch(etiss::CPUArch *)
virtual std::string versionInfo()
simple version info string. intended to present information in a human readable way.
static void addSearchPath(const std::string &path)
virtual void deleteJIT(etiss::JIT *)
virtual unsigned countJITs()
static std::shared_ptr< LibraryInterface > openSharedLibrary(std::string path, std::string name)
virtual std::string nameCPUArch(unsigned index)
virtual unsigned countCPUArchs()
virtual std::string namePlugin(unsigned index)
virtual std::string nameJIT(unsigned index)
virtual const std::string & getName()
virtual etiss::JIT * createJIT(unsigned index, std::map< std::string, std::string > options=std::map< std::string, std::string >())
base plugin class that provides access to different plugin functions if present
#define ETISS_USE_DLSYM_DEEPBIND
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Configuration & cfg(const std::string &cfgName)
Get reference of the global ETISS configuration object.
void log(Verbosity level, std::string msg)
write log message at the given level.
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type,...