blocxx
dlSharedLibrary.cpp
Go to the documentation of this file.
1/*******************************************************************************
2* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3* Copyright (C) 2006, Novell, Inc. All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7*
8* * Redistributions of source code must retain the above copyright notice,
9* this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of
14* Vintela, Inc.,
15* nor Novell, Inc.,
16* nor the names of its contributors or employees may be used to
17* endorse or promote products derived from this software without
18* specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30* POSSIBILITY OF SUCH DAMAGE.
31*******************************************************************************/
32
33
37
38#include "blocxx/BLOCXX_config.h"
39#if defined(BLOCXX_USE_DL)
41#include "blocxx/Format.hpp"
42#include "blocxx/Mutex.hpp"
43#include "blocxx/MutexLock.hpp"
45#include <dlfcn.h>
46#ifdef BLOCXX_HAVE_FCNTL_H
47// For O_RDONLY
48#include <fcntl.h>
49#endif
50
51#include "blocxx/Types.hpp"
52
53#if defined(BLOCXX_USE_FAKE_LIBS)
55#include "blocxx/FileSystem.hpp"
56#include "blocxx/File.hpp"
57#include "blocxx/Array.hpp"
58
59#define BLOCXX_FAKELIB_HEADING "FAKE"
60#define BLOCXX_FAKELIB_HEADING_LENGTH 4
61
62#endif
63
64#include <iostream>
65
66namespace BLOCXX_NAMESPACE
67{
68
69// static
70bool dlSharedLibrary::s_call_dlclose = true;
71
72GlobalMutex dlSharedLibrary_guard = BLOCXX_GLOBAL_MUTEX_INIT();
73
74dlSharedLibrary::dlSharedLibrary(void * libhandle, const String& libName)
75 : SharedLibrary(), m_libhandle( libhandle ), m_libName(libName)
76{
77#if defined(BLOCXX_USE_FAKE_LIBS)
78 // Find out if it is a fake library.
79 m_fakeLibrary = dlSharedLibrary::isFakeLibrary(libName);
80
81 if ( m_fakeLibrary )
82 {
83 initializeSymbolMap();
84 }
85#endif /* defined(BLOCXX_USE_FAKE_LIBS) */
86}
87
88dlSharedLibrary::~dlSharedLibrary()
89{
90#if !defined(BLOCXX_VALGRIND_SUPPORT) // dlclose()ing shared libs make it impossible to see where memory leaks occurred with valgrind.
91 if (s_call_dlclose)
92 {
93 dlclose( m_libhandle );
94 }
95#endif
96}
97bool dlSharedLibrary::doGetFunctionPointer(const String& functionName,
98 void** fp) const
99{
100 MutexLock l(dlSharedLibrary_guard);
101#if defined(BLOCXX_USE_FAKE_LIBS)
102 String realFunctionName = functionName;
103 // If this is a fake library, extract convert the requested function
104 // name into the proper function name for the main executable.
105 if ( m_fakeLibrary )
106 {
107 Map<String,String>::const_iterator symIter = m_symbolMap.find(functionName);
108 if ( symIter == m_symbolMap.end() )
109 {
110 return false;
111 }
112 realFunctionName = symIter->second;
113 }
114 *fp = dlsym( m_libhandle, realFunctionName.c_str() );
115#else
116 *fp = dlsym( m_libhandle, functionName.c_str() );
117#endif /* defined(BLOCXX_USE_FAKE_LIBS) */
118
119 if (!*fp)
120 {
121 return false;
122 }
123 return true;
124}
125
126bool dlSharedLibrary::isFakeLibrary(const String& library_path)
127{
128 bool fake = false;
129#if defined(BLOCXX_USE_FAKE_LIBS)
130 if ( FileSystem::canRead(library_path) )
131 {
132 // Read the beginning of the file and see if it
133 // contains the fake library heading.
134 int libfd = open(library_path.c_str(), O_RDONLY);
135
136 if ( libfd )
137 {
138 char buffer[(BLOCXX_FAKELIB_HEADING_LENGTH) + 1];
139 size_t num_read = read(libfd, buffer,(BLOCXX_FAKELIB_HEADING_LENGTH));
140 if ( num_read == (BLOCXX_FAKELIB_HEADING_LENGTH) )
141 {
142 // Null terminate it.
143 buffer[BLOCXX_FAKELIB_HEADING_LENGTH] = '\0';
144 if ( String(BLOCXX_FAKELIB_HEADING) == buffer )
145 {
146 // Yes, it's a fake library.
147 fake = true;
148 }
149 }
150 close(libfd);
151 }
152 }
153#endif
154 return fake;
155}
156
157#if defined(BLOCXX_USE_FAKE_LIBS)
158void dlSharedLibrary::initializeSymbolMap()
159{
160 if ( ! m_fakeLibrary )
161 {
162 return;
163 }
164 // Read the contents of the file to find out what the function names
165 // (normally available from dlsym) are mapped to functions in the main
166 // program.
167 StringArray lines = FileSystem::getFileLines(m_libName);
168
169 for ( StringArray::const_iterator iter = lines.begin();
170 iter != lines.end();
171 ++iter )
172 {
173 // Skip commented lines.
174 if ( iter->startsWith('#') )
175 {
176 continue;
177 }
178 StringArray current_line = iter->tokenize("=");
179 // Skip invalid lines.
180 if ( current_line.size() != 2 )
181 {
182 continue;
183 }
184 // Add the data into the map.
185 String option = String(current_line[0]).trim();
186 String value = String(current_line[1]).trim();
187 m_symbolMap[option] = value;
188 }
189}
190#endif /* defined(BLOCXX_USE_FAKE_LIBS) */
191
192} // end namespace BLOCXX_NAMESPACE
193
194#endif
195
#define BLOCXX_GLOBAL_MUTEX_INIT()
SharedLibrary is a base class for platform classes that implement the functionality of loading and qu...
This String class is an abstract data type that represents as NULL terminated string of characters.
Definition String.hpp:67
void read(std::streambuf &istrm, void *dataIn, size_t dataInLen)
BLOCXX_COMMON_API int close(const FileHandle &hdl)
Close file handle.
Taken from RFC 1321.
Array< String > StringArray
Definition CommonFwd.hpp:73
LazyGlobal< Mutex, int, GlobalMutexFactory > GlobalMutex