linux dlopen: can a library be "notified" when it is loaded? - linux

Is there a way for a shared library to be "notified" when it is loaded?
In other words, let's say I use dlopen on a shared library, is there a function that is automatically called (if present) on the shared library (e.g. main?)

Libraries should export initialization
and cleanup routines using the gcc
__attribute__((constructor)) and __attribute__((destructor)) function attributes. See the gcc info pages for
information on these. Constructor
routines are executed before dlopen
returns (or before main() is started
if the library is loaded at load
time). Destructor routines are
executed before dlclose returns (or
after exit() or completion of main()
if the library is loaded at load
time). The C prototypes for these
functions are:
void __attribute__ ((constructor)) my_init(void);
void __attribute__ ((destructor)) my_fini(void);
Taken from http://tldp.org/HOWTO/Program-Library-HOWTO/index.html
THat is, you just tack on __attribute__ ((constructor)) to the functions you want to be called when the shared library is loaded. The above docuemtn also notes that the older _ini and _fini functions are considered obsolete.

Yes. When a library is opened, all static construction takes place... so, if you use C++, you can do:
// mylibrary.cpp
namespace
{
class dynamic_library_load_unload_handler
{
public:
dynamic_library_load_unload_handler(){
// Code to execute when the library is loaded
}
~dynamic_library_load_unload_handler(){
// Code to execute when the library is unloaded
}
} dynamic_library_load_unload_handler_hook;
}
Unlike the __attribute__ ((constructor)) solutions given, this will be portable. Note, though, that if you have multiple objects like this, there is no guarantee with respect to the construction/destruction order.

At least on Linux, and probably on at least some other Unix systems, if the library is dynamically opened a global function named _init, if it exists, will be called by the dynamic linker.

Related

Calling dlclose on a handle returned by dlopen(NULL)

I'm getting a handle to the main module of my executable using dlopen(NULL) as below.
void *handle = dlopen(NULL, RTLD_NOW);
Should I be calling a dlclose(handle) to decrement the ref-count to the main module?
From the manpage:
dlclose()
The function dlclose() decrements the reference count on the dynamic
library handle handle. If the reference count drops to zero and no
other loaded libraries use symbols in it, then the dynamic library is
unloaded.
Tho I bet it is noop when you call it for "main" handle

How to use exported symbols optionally only if they are present in an insmoded Linux Kernel module?

I am modifying a Linux Kernel to add some functionality to the Linux Virtual Server (LVS).
I developed a module (which I called net/netfilter/ipvs/ip_vs_utils.c) with some functions to be used when load-balancing. All the functions here are exported using EXPORT_SYMBOL().
This module, logically is not loaded all the time. My intention is to allow the user to decide if he want to use this additional functionality or not (loading or unloading the module).
My question is how could I invoke these functions OPTIONALLY (depending if the module is running or not) from a existing (and of course modified) module (net/netfilter/ipvs/ip_vs_core.c). Something like this:
if(ip_vs_utils_IsLoaded)
{
function1(arg1, arg2, arg3); // being function1 defined on ip_vs_utils.c
}
I think you need a trampoline always(or almost always) loaded into kernel.
In trampoline code, you need to such variables.
struct module *ip_vs_utils_mod;
EXPORT_SYMBOL(ip_vs_utils_mod);
/* function pointers */
ret_type (*ip_vs_utils_afunc_ptr)(func_arg_list); /* Add static if you put it in a header file! */
EXPORT_SYMBOL(ip_vs_utils_afunc_ptr); /* ******EXPORTED***** */
When the ip_vs_utils is loaded, you need to init all the variables, initialization code in ip_vs_utils.c:
ip_vs_utils_mod = THIS_MODULE;
/* init function pointers */
/* ip_vs_utils_afunc_impl is the real implementation
* of the function, it is *****NOT***** needed to export it
*/
ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl;
And add the trampoline functions in trampoline code:
ret_type ip_vs_utils_afunc(func_arg_list)
{
ret_type ret = DEFAULT_RET;
if (try_module_get(ip_vs_utils_mod)) {
ret = (*ip_vs_utils_afunc_ptr)(func_arg_list);
module_put(ip_vs_utils_mod);
}
return ret;
}
try_module_get() is needed to protect the module from being suddenly unloaded while ip_vs_utils_afunc_ptr() is being invoked.
You can also use RCU instead to reduce the overhead of try_module_get()/module_put(). (But it is hard)
Or you can used some trampoline-hack like dynamic link in userspace(you may need to change a lot in the linux kernel)

dllmain function and exported function runs as threads or as a separate processes?

this is more of conceptual question and it may be rather basic , i am not really finding good resources to learn about dll ,
i need to create dll(Load-time dynamic linking) which requires function1 to start on loading of dll and run at background
for whole time ,
while function2 needs to exported which is going to be invoked several times by application,
function1 provides object which needs to be used in function2,
i am planning to use function1 as entry-point function(dllmain) while export function2.
as dllmain function called by system while exported function invoked by application ,do they run as two threads or as two separate processes?
also is it right to use dllmain and export as explained above to accomplish what i need?
"Advanced Windows" by Jeffrey Richter is one good place to learn about DLLs.
In your case something like this will do the job.
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
//start thread with function1()
begin_thread_ex(..., &function1, ....)
}
}
__declspec(dllexport) function2()
{
....
}

VC++: Using DLLs as "subprograms"

So I just began to try my hand at emulation after years of putting it off and not knowing where to start and I have managed to successfully write my first emulator! Now I am organizing my code in so that I can reuse the code to emulate other systems. I've been toying with the idea of having a shared frontend "platform handler" of sorts that I will compile as my executable whereas I will compile my emulated system code into dlls that the platform handler will use to identify what is available and instantiate from. This would allow me to separate my code into different projects and to leave the option open of using a bulkier front-end with more features or a streamlined "game only" and to share the same dlls between them rather than make two different solutions.
I know how to compile dlls vs executables but I don't know how to link the executable to the custom dll in such a way that I can instantiate a class from it. I'm not even sure what I'm trying to do is technically possible. Do the dll classes need to be static? I've never coded anything like this before or even done much with custom dlls so any help or ideas would be appreciated. I'm using Visual C++ 2010 by the way. Thanks in advance for any advice anyone may have.
You don't really have to do much different. Just export your classes from the dll like you do for functions. In your app, include the header and link to the generated lib like you usually do. See this page: http://msdn.microsoft.com/en-us/library/81h27t8c%28v=vs.80%29.aspx
Example.h
#ifdef DLL_EXPORT
#define EXPORT_API __declspec(dllexport)
#else
#define EXPORT_API __declspec(dllimport)
#endif
class EXPORT_API Example
{
public:
Example();
~Example();
int SomeMethod();
};
int EXPORT_API ExampleFuncion();
Example.cpp
#include "Example.h"
Example::Example()
{
// construct stuff
}
Example::~Example()
{
// destruct stuff
}
int Example::SomeMethod()
{
// do stuff
return 0;
}
int EXPORT_API ExampleFunction()
{
return 0;
}
In your dll project, define DLL_EXPORT and build. You will get a .lib and .dll output. In your main project where you will be using the dll you do not have to do anything except include the header and link against the .lib. Do not define the DLL_EXPORT symbol in your main project and be sure the .dll is somewhere your application can find it.
If you really want to get clever, this problem is screaming for the factory design pattern. If you design your interface well enough, you can have your dlls register their implementation with your application when they are loaded. You can extend forever without even rebuilding your main executable.

Stack issues when calling a DLL compiled with Visual C++ in GCC

I'm trying to call some functions in a DLL compiled with (I believe) Visual C++ from my program, which is compiled using GCC.
To call the functions in the DLL, I do a LoadLibrary() on the DLL, and then a GetProcAddress() to get the address of a particular function, which I then call. This function returns a list of pointers to the functions in the DLL I'm to call.
Well, when I try to call those functions, they don't work properly. I ran my program through a debugger, and it looks like the DLL library function is looking for one of the passed arguments at ebp+8, even though GCC has put it at ebp-24.
It looks definitely like a stack issue. What's more, when the GCC program function which calls the DLL function returns, my program crashes -- so something screwey is going on with the stack. Does anyone know what I need to do in order to fix this? I'm not able to access the DLL code.
Also: I tried putting __cdecl and __stdcall before the DLL function definition in my program's source file, but this changes nothing.
Looks like a calling convention problem. Make sure you're putting the calling convention tag in the right place. With GCC, it should look like this:
typedef int (__stdcall *MyFunctionType)(int arg1, const char *arg2);
MyFunctionType myFunction = (MyFunctionType)GetProcAddress(myModule, "MyFunction");
// check for errors...
int x = myFunction(3, "hello, world!");
[EDIT]
Looks like your problem has nothing to do with calling conventions (although getting them right is important). You're misusing BSTRs -- a BSTR is not a simple char* pointer. It's a pointer to a Unicode string (wchar_t*), and furthermore, there is a 4-byte length prefix hidden before the first characters of the string. See MSDN for full details. So, the call to SetLicense() should look like this:
BSTR User = SysAllocString(L""); // Not sure if you can use the same object here,
BSTR Key = SysAllocString(L""); // that depends on if SetLicense() modifies its
// arguments; using separate objects to be safe
// check for errors, although it's pretty unlikely
(textCapLib.sdk)->lpVtbl->SetLicense((textCapLib.sdk), User, Key);
SysFreeString(User); // Hopefully the SDK doesn't hang on to pointers to these
SysFreeString(Key); // strings; if it does, you may have to wait until later to
// free them

Resources