Update with current status
[gnash.git] / libbase / sharedlib.cpp
blob028eb55686ce8cfb8c6c3fa7cfac4de6a2673420
1 // sharedlib.cpp: Shared Library support, for Gnash.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
26 #include "log.h"
27 #include "sharedlib.h"
29 #include <sys/stat.h>
30 #include <unistd.h>
32 #include <string>
33 #include <cstdlib>
35 #if defined(WIN32) || defined(_WIN32)
36 # define LIBLTDL_DLL_IMPORT 1
37 #endif
38 #ifdef HAVE_DLFCN_H
39 # include <dlfcn.h>
40 #endif
41 #ifdef HAVE_LIBGEN_H
42 # include <libgen.h>
43 #endif
45 #include <ltdl.h>
46 #include <mutex>
48 #if defined(WIN32) || defined(_WIN32)
49 int lt_dlsetsearchpath (const char *search_path);
50 int lt_dlinit (void);
51 void * lt_dlsym (lt_dlhandle handle, const char *name);
52 const char *lt_dlerror (void);
53 int lt_dlclose (lt_dlhandle handle);
54 int lt_dlmakeresident (lt_dlhandle handle);
55 lt_dlhandle lt_dlopenext (const char *filename);
56 #endif
58 namespace gnash {
60 SharedLib::SharedLib(const std::string& filespec)
61 #ifdef HAVE_LTDL
62 : _dlhandle(nullptr)
63 #endif
65 _filespec = filespec;
66 scoped_lock lock(_libMutex);
68 // Initialize libtool's dynamic library loader
69 #ifdef HAVE_LTDL
70 int errors = lt_dlinit ();
71 if (errors) {
72 log_error(_("Couldn't initialize ltdl: %s"), lt_dlerror());
74 #else
75 # warning "libltdl not enabled in build".
76 #endif
79 bool
80 SharedLib::closeLib()
82 #ifdef HAVE_LTDL
83 return lt_dlclose(_dlhandle);
84 #else
85 return true;
86 #endif
89 bool
90 SharedLib::openLib()
92 return openLib(_filespec);
95 bool
96 SharedLib::openLib (const std::string& filespec)
99 scoped_lock lock(_libMutex);
101 log_debug(_("Trying to open shared library \"%s\""), filespec);
103 #ifdef HAVE_LTDL
104 _dlhandle = lt_dlopenext (filespec.c_str());
106 if (_dlhandle == nullptr) {
107 log_error("lt_dlopenext(\"%s\") failed: %s", filespec.c_str(), lt_dlerror());
108 return false;
111 // Make this module unloadable
112 lt_dlmakeresident(_dlhandle);
113 #endif
115 log_debug (_("Opened dynamic library \"%s\""), filespec);
117 _filespec = filespec;
119 return true;
122 SharedLib::initentry *
123 SharedLib::getInitEntry (const std::string& symbol)
125 // GNASH_REPORT_FUNCTION;
126 lt_ptr run = nullptr;
128 scoped_lock lock(_libMutex);
130 #ifdef HAVE_LTDL
131 run = lt_dlsym (_dlhandle, symbol.c_str());
133 if (run == nullptr) {
134 log_error(_("Couldn't find symbol: %s"), symbol);
135 return nullptr;
136 } else {
137 log_debug(_("Found symbol %s @ %p"), symbol, (void *)run);
139 #else
140 (void)symbol;
141 #endif
143 return (initentry*)(run);
146 SharedLib::entrypoint *
147 SharedLib::getDllSymbol(const std::string& symbol)
149 GNASH_REPORT_FUNCTION;
151 lt_ptr run = nullptr;
153 scoped_lock lock(_libMutex);
155 #ifdef HAVE_LTDL
156 run = lt_dlsym (_dlhandle, symbol.c_str());
157 #endif
160 Realistically, we should never get a valid pointer with a value of 0
161 Markus: 'Id est NULL.'
163 if (run == nullptr) {
164 log_error("Couldn't find symbol: %s", symbol);
165 return nullptr;
166 } else {
167 log_debug("Found symbol %s @ %p", symbol, (void *)run);
170 return (entrypoint*)(run);
173 } // end of gnash namespace