24 #define LIBRARY_EXTENSION ".dylib"
26 #define LIBRARY_EXTENSION ".so"
30 #include "../include/charon-core/UnixPluginLoader.h"
33 #include "../include/charon-core/configVersion.h"
34 #include <sys/types.h>
43 const std::string & n,
44 std::vector<std::string>& plpaths,
53 std::string path, pathS;
56 for(std::vector<std::string>::const_iterator cur =
pluginPaths.begin();
72 throw PluginException(
"Failed to find the plugin \"" +
pluginName
74 +
" could not be found."
77 " (suffix disabled)"),
81 sout <<
"(DD) File: " << path << std::endl;
87 #if defined(__x86_64__)
88 typedef Elf64_Ehdr Elf_Ehdr;
89 const unsigned char elfClass = ELFCLASS64;
90 const std::string elfClassDesc =
"64 bit";
92 typedef Elf32_Ehdr Elf_Ehdr;
93 const unsigned char elfClass = ELFCLASS32;
94 const std::string elfClassDesc =
"32 bit";
96 if (
_versionCheck != PluginManagerInterface::PluginVersionIgnore) {
97 int fd = open(path.c_str(),O_RDONLY);
99 throw PluginException(
"Failed to open the plugin \"" +
pluginName
100 +
"\". Maybe you do not have read permissions.",
104 if (fstat(fd, &fStats)) {
106 throw PluginException(
"Failed to fstat the plugin \"" +
pluginName
109 char* buf =
new char[fStats.st_size];
110 if (read(fd, buf, fStats.st_size) < fStats.st_size) {
113 throw PluginException(
"Failed to read the plugin \"" +
pluginName
116 if (elf_version(EV_CURRENT) == EV_NONE) {
117 sout <<
"(WW) Elf Library is out of date!" << std::endl;
119 Elf_Ehdr* eHeader = (Elf_Ehdr*) buf;
122 eHeader->e_ident[EI_MAG0]!=ELFMAG0 ||
123 eHeader->e_ident[EI_MAG1]!=ELFMAG1 ||
124 eHeader->e_ident[EI_MAG2]!=ELFMAG2 ||
125 eHeader->e_ident[EI_MAG3]!=ELFMAG3) {
128 throw PluginException(
"ELF check failed (magic bytes): File "
129 + path +
" is no ELF file.",
133 if (eHeader->e_ident[EI_CLASS] != elfClass) {
136 throw PluginException(
"ELF check failed (architecture): File "
137 + path +
" is no " + elfClassDesc +
" ELF file.",
141 if (eHeader->e_ident[EI_VERSION] != EV_CURRENT) {
144 throw PluginException(
"ELF check failed (version): File "
145 + path +
" was compiled with another ELF version.",
148 Elf* elf = elf_begin(fd,ELF_C_READ,NULL);
151 while ((scn=elf_nextscn(elf,scn))!=0) {
153 gelf_getshdr(scn,&shdr);
154 std::string sName = elf_strptr(elf,eHeader->e_shstrndx,shdr.sh_name);
155 if (sName ==
".charon-plugin") {
160 bool checkPassed =
false;
162 std::string checkFailMsg;
165 std::ostringstream foundVersion;
168 checkFailMsg =
"No Plugin Section found in ELF file";
173 eData = elf_getdata(scn, eData);
175 if (eData->d_type != ELF_T_BYTE) {
176 checkFailMsg =
"Wrong Plugin Section Data Type";
178 else if (eData->d_size < 3) {
179 checkFailMsg =
"Wrong Plugin Section Data Size";
182 const unsigned char* content =
183 (
const unsigned char*) eData->d_buf;
184 foundVersion << (
int) content[0] <<
"."
185 << (int) content[1] <<
"." << (
int) content[2];
188 checkFailMsg =
"plugin major version mismatch";
191 checkFailMsg =
"plugin minor version mismatch";
194 checkFailMsg =
"plugin patch version mismatch";
198 sout <<
"(DD) plugin ELF check successful" << std::endl;
207 case PluginManagerInterface::PluginVersionWarn:
209 checkFailMsg = checkFailMsg
210 +
"\n(WW) \tcharon-core version: "
212 +
"\n(WW) \tplugin compiled with version: "
213 + foundVersion.str();
216 <<
"\" failed: " << checkFailMsg << std::endl;
218 case PluginManagerInterface::PluginVersionDiscard:
220 checkFailMsg = checkFailMsg
221 +
"\n\tcharon-core version: "
223 +
"\n\tplugin compiled with version: "
224 + foundVersion.str();
226 throw PluginException(
"ELF check failed: " + checkFailMsg,
237 libHandle = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
239 throw PluginException(
"Failed to load the plugin \"" +
pluginName
240 +
"\". Maybe the file is damaged."
241 +
"\n Description of the error:\n" + dlerror(),
260 throw PluginException(
261 "function \"create\" missing in shared object file",
269 throw PluginException(
270 "function \"destroy\" missing in shared object file",
279 std::ostringstream msgs;
280 msgs <<
"Error unloading plugin \"" <<
pluginName
281 <<
"\". Description of the error: " << dlerror();
282 std::string msg = msgs.str();
283 throw PluginException(
289 sout <<
"(DD) Successfully unloaded plugin \"" <<
pluginName <<
"\"."
292 throw PluginException(
"Plugin \"" +
pluginName +
"\" is not loaded.",
#define CHARON_CORE_VERSION_PATCH
charon-core patch version
File is a shared object but misses required functions.
virtual void unload()
Unloads the plugin.
#define CHARON_CORE_VERSION
charon-core version string
there is a missmatch between the current charon-core version and the version the plugin was compiled ...
#define CHARON_CORE_VERSION_MINOR
charon-core minor version
SplitStream sout
Dummy instance for usage in other files (for interface too).
File is damaged, unreadable, not a shared object or the user access rights are insufficient.
#define CHARON_CORE_VERSION_MAJOR
charon-core major version
void(* destroy)(ParameteredObject *)
Function pointer to the destructor of the plugin.
virtual void load()
Loads the plugin.
ParameteredObject *(* create)(const std::string &, ParameteredObject::template_type)
Function pointer to the constructor of the plugin.
std::vector< std::string > & pluginPaths
Paths where the plugins are stored.
std::string pluginName
The name of the Plugin (without prefix "lib" and without extension)
virtual ~UnixPluginLoader()
Default destructor.
Plugin file doesn't exist or is placed in the wrong directory.
std::string & libSuffix
Lib suffix e.g. _d for debug builds.
PluginVersionCheckLevel
info how to handle version information
While unloading a plugin or deleting an instance: The plugin is not loaded.
PluginManagerInterface::PluginVersionCheckLevel _versionCheck
should the Loader ignore embedded charon-core version strings?
UnixPluginLoader(const std::string &name, std::vector< std::string > &plpaths, std::string &lSuffix, PluginManagerInterface::PluginVersionCheckLevel versionCheck=PluginManagerInterface::PluginVersionIgnore)
Default constructor.
ErrorCode
Error Reason Enum.
Version information for the plugin is missing while explicit version check was requested.
#define LIBRARY_EXTENSION
os dependent shlib extension (.so or .dylib)
void * libHandle
Points to the loaded library.
Abstract base class for a plugin loader.