I have an application (A) which calls a third-party shared library (C). I want to write a library of my own (B) that intercepts calls from A to C, and in some cases replace the calls with my own code, in some cases do some extra processing, then call the matching function in C, and in some cases just forward the calls to C directly.
The application is open-source, so I could just change each call site to call a similarly-named function in B, then call the corresponding function in C when required, but that would be a lot of work and would make merging upstream changes in the application difficult. I do not have the source to the third-party library. If it was header-only then I could just use namespaces to achieve this but I'm not sure how to go about it when both my library and the third-party library seemingly need the exact same symbols defined.
Is there even any way to make this work? I'm primarily targeting OS X, but would like it to work on linux and then eventually Windows as well.
You can use LD_PRELOAD to point to your own shared library. With LD_PRELOAD all functions in your shared library will be called instead of functions with the same name in those other libraries.
If you wish to inject code and then call the original functions you will need to call dlsym to get the original function from the third party library.
There are some examples here: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
One solution is as follows.
In a header file, #define all functions you want to intercept to your wrapper functions.
#define foo wrap_foo
#define bar wrap_bar
Stick this in some header file that is included everywhere, so that all of the code includes this header. This header should get included before the header for the library that you are intercepting. gcc also has an -include option that causes a header file to be included in all sources.
The goal here is to replace all calls to actual functions with calls to the wrapper functions.
Now define your wrapper functions somewhere, and intercept the calls as you wish. This file should not include the wrapper header that you created earlier.
int wrap_foo() {
return foo();
}
int wrap_bar() {
return bar();
}
Link it all together.
Note that this will let you intercept calls to foo() and bar() etc. only in the code that is compiled including the wrapper header. Any pre-compiled code (in libraries or objects) will link to foo() and bar() etc. directly.
Related
I have a library that provides a function func():
return_type func(type arg);
It was necessary to override it by my own implementation in my application. It was possible because the library provides a weak symbol func while the func symbol in my application is a strong one. (That is my understanding.)
Now I want to be able to call both implementations of func - library's implementatoin and my own implementation:
// The problem is that the names are the same.
func(); // Everything is OK, calling my implementation (in my application)
func(); // How can I call library's implementation now?
I can call my implementation because it overrides the implementation in the library. But how can I call the implementation in the library? How can I refer to it?
If the functions are in shared libraries, you can load them with dlopen and the obtain the symbols from dlsym. You can then have different function pointers for for the functions from each library.
If the functions are in a static library, you will need to modify the static library to change the name. This can be done with something like objcopy --prefix-symbols=foo_ foo.o. Not sure if this can be done directly on a .a in such a case, you might need to expand the archive.
Having added the prefix you will then need to modify any header files to take the new names either using a macro or something similar.
I have a library libxx and inside that library there is a static function foo().
I want to write another function bar() which uses the function foo() as a subroutine.
Is there any way to do it without writing bar() on the file which the function foo() sits on and rebuilding the library?
Declaring a function static within a translation unit (object file / library) pretty much invalidates any assertions about that function's implementation. It could be completely inlined. It might use short-cuts with the calling conventions that would be incorrect when called externally.
On some OS/ABIs, the function will not be 'visible' in the sense that a .globl directive with ELF/Mach-O would provide, and the linker will prevent it, or the loader won't resolve it. In a shared library, it might not preserve position-independence outside its local use. The point is, you just can't do this safely or portably.
In short, you need to recompile the function as non-static, i.e., a global / visible symbol in the library, or have a static version available to your bar() function. Say, via static inline.
It sounds like you have the source code to libxx. If that's the case, and you'd like bar() to exist in the same library as foo() then you'll need to recompile libxx after adding bar() to it.
If your goal is to call libxx::foo() from another program/library then you can just link libxx to your other project (which has bar() in it). Once the library is linked to your main project all you need to do is call into the correct namespace and invoke foo(). Linking a library to your main project will require using a linker. Different development systems will have different ways of invoking the linker. For researching this further, I would advise that you search for "c++ linking to static library X" where X is your development system (ex: visual studio, xcode). I'm assuming this is a static library based on the tag you put on the question, but maybe you meant that foo() was a static method. It shouldn't matter if it's a static method or not, linking will work in the same way. If you are confused about what I mean when I write "static library" then maybe researching the difference between static and dynamically linked libraries will clarify.
Not within standard C/C++.
The function has an address which is callable or other functions which may allow the foo to be called indirectly.
But these are bad solutions
I am having an assignment in which I am not allowed to include any other libraries besides the ones that are available. However, I think I really need to use a function that is stored in this particular library.
So, my question is: is there anyway you can use a function in a library without having to #include it?
Well I'm not sure why you would want to do that, but here is how you'd do it:
Say you want to use a function foo from the library that looks as follows:
int foo()
{
return 1;
}
In your code where you want to use the function, you need to write the following:
extern int foo();
and then you can use this foo function as you like, and link it when doing linking.
This works because header files are just needed for compilation to work not for linking, and by using this extern you're manually doing the work that the header did for you
This becomes harder however, if there are classes in the header file, you'll probably end up having to redeclare the whole class as done in the header file
I have some beginner's question regarding c++.
I've downloaded windows SDK and according to the documentation, all bluetooth traffic uses winsock. Windows SDK includes header files (.h) if I want to program a bluetooth interface.
a) This is a general c++ question: how does the header file winsock.h gets linked to a specific dll? I didn't specify any link. How can I detect all the .dll that are linked with this header?
Isn't the header file suppose to contain only the names of the functions and the actual implementation in the dll? I'm slightly confused.
My second goal is to replace the windows winsock functions by a modified version. I would like to keep the original functionality, unless some flag, set by a different application, is set to true. In this case, I want to modify some functions.
My approach is to create a new dll, that will have the same function names, as shown in the header file winsock.h .
b) Assume that there exists a function fff in the original winsock. I'll replace it with a new function, that unless the flag is true, calls the same function fff but in the unmodified dll, i.e.. I want in this case to "include" the original function from the unmodified dll and "overload" my modified fff function, with the original fff function. This two functions have the same parameters, and the same name. How do I that? Is there a better way to achieve the same goal?
c) what is the best way (or the easy way) to allow the flag, set by an application, to be accessible within the dll?
d) Winsocket is a very central component. Should I expect a major performance deterioration if I add one if command to every function in it?
Thanks!
a) The header file simply defines things (types, functions, classes) that are to be found elsewhere - it does not specify where. When you link the program you include .lib files which contain (among other things) the connection to the correct DLL. When the program runs the lib code will load the DLL into memory and connect to it.
b) Generate a second DLL that contains all the same functions as in winsock but with (say) ELI_ added to the start of the function name. Then inside the ELI_ function look at the flag and if it's not set call the basic winsock function, otherwise do whatever special thing you have in mind.
c) Make the flag variable a global static variable within your ELI_ DLL code, then add extra functions to set the flag (and read back its state, probably)
d) I don't know, but a single if is not going to take very much time at all. I would be more worried about what your special code does.
assume we were using gcc/g++ and a C API specified by a random committee. This specification defines the function
void foo(void);
Now, there are several implementations according to this specification. Let's pick two as a sample and call them nfoo and xfoo (provided by libnfoo and libxfoo as static and dynamic libraries respectively).
Now, we want to create a C++ framework for the foo-API. Thus, we specify an abstract class
class Foo
{
public:
virtual void foo(void) = 0;
};
and corresponding implementations
#include <nfoo.h>
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the nfoo C-API
}
};
as well as
#include <xfoo.h>
#include "Foo.h"
class XFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the xfoo C-API
}
};
Now, we are facing a problem: How do we create (i.e. link) everything into one library?
I see that there will be a symbol clash with the foo function symbols of the C API implementations.
I already tried to split the C++ wrapper implementations into separate static libraries, but then I realized (again) that static libraries is just a collection of unlinked object files. So this will not work at all, unless there is a way to fully link the C libraries into the wrapper and remove/hide their symbols.
Suggestions are highly appreciated.
Update: Optimal solutions should support both implementations at the same time.
Note: The code is not meant to be functional. Perceive it as pseudo code.
Could you use dlopen/dlsym at runtime to resolve your foo call.
something like example code from link ( may not compile):
void *handle,*handle2;
void (*fnfoo)() = null;
void (*fxfoo)() = null;
/* open the needed object */
handle = dlopen("/usr/home/me/libnfoo.so", RTLD_LOCAL | RTLD_LAZY);
handle2 = dlopen("/usr/home/me/libxfoo.so", RTLD_LOCAL | RTLD_LAZY);
fnfoo = dlsym(handle, "foo");
fxfoo = dlsym(handle, "foo");
/* invoke function */
(*fnfoo)();
(*fxfoo)();
// don't forget dlclose()'s
otherwise, the symbols in the libraries would need to be modified.
this is not portable to windows.
First thing's first, if you are going to be wrapping up a C API in C++ code, you should hide that dependency behind a compilation firewall. This is to (1) avoid polluting the global namespace with the names from the C API, and (2) freeing the user-code from the dependency to the third-party headers. In this example, a rather trivial modification can be done to isolate the dependency to the C APIs. You should do this:
// In NFoo.h:
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void);
};
// In NFoo.cpp:
#include "NFoo.h"
#include <nfoo.h>
void NFoo::foo(void) {
::foo(); // calling foo from the nfoo C-API
}
The point of the above is that the C API header, <nfoo.h>, is only included in the cpp file, not in the header file. This means that user-code will not need to provide the C API headers in order to compile code that uses your library, nor will the global namespace names from the C API risk clashing with anything else being compiled. Also, if your C API (or any other external dependency for that matter) requires creating a number of things (e.g., handles, objects, etc.) when using the API, then you can also wrap them in a PImpl (pointer to a forward-declared implementation class that is only declared-defined in the cpp file) to achieve the same isolation of the external dependency (i.e., a "compilation firewall").
Now, that the basic stuff is out of the way, we can move to the issue at hand: simultaneously linking to two C APIs with name-clashing symbols. This is a problem and there is no easy way out. The compilation firewall technique above is really about isolating and minimizing dependencies during compilation, and by that, you could easily compile code that depends on two APIs with conflicting names (which isn't true in your version), however, you will still be hit hard with ODR (One Definition Rule) errors when reaching the linking phase.
This thread has a few useful tricks to resolving C API name conflicts. In summary, you have the following choices:
If you have access to static libraries (or object files) for at least one of the two C APIs, then you can use a utility like objcopy (in Unix/Linux) to add a prefix to all the symbols in that static library (object files), e.g., with the command objcopy --prefix-symbols=libn_ libn.o to prefix all the symbols in libn.o with libn_. Of course, this implies that you will need to add the same prefix to the declarations in the API's header file(s) (or make a reduced version with only what you need), but this is not a problem from a maintenance perspective as long as you have a proper compilation firewall in place for that external dependency.
If you don't have access to static libraries (or object files) or don't want to do this above (somewhat troublesome) approach, you will have to go with a dynamic library. However, this isn't as trivial as it sounds (and I'm not even gonna go into the topic of DLL Hell). You must use dynamic loading of the dynamic link library (or shared-object file), as opposed to the more usual static loading. That is, you must use the LoadLibrary / GetProcAddress / FreeLibrary (for Windows) and the dlopen / dlsym / dlclose (all Unix-like OSes). This means that you have to individually load and set the function-pointer address for each function that you wish to use. Again, if the dependencies are properly isolated in the code, this is going to be just a matter of writing all this repetitive code, but not much danger involved here.
If your uses of the C APIs is much simpler than the C APIs themselves (i.e., you use only a few functions out of hundreds of functions), it might be a lot easier for you to create two dynamic libraries, one for each C API, that exports only the limited subset of functions, giving them unique names, that wrap calls to the C API. Then, you main application or library can be link to those two dynamic libraries directly (statically loaded). Of course, if you need to do that for all the functions in that C API, then there is no point in going through all this trouble.
So, you can choose what seems more reasonable or feasible for you, there is no doubt that it will require quite a bit a manual work to fix this up.
if you only want to access one library implementation at a time, a natural way to go about it is as a dynamic library
in Windows that also works for accessing two or more library implementations at a time, because Windows dynamic libraries provide total encapsulation of whatever's inside
IIUC ifdef is what you need
put #define _NFOO
in the nfoo lib and #define XFOO in xfoo lib.
Also remember if nfoo lib and xfoo lib both have a function called Foo then there will be error during compilation. To avoid this GCC/G++ uses function overloading through name mangling.
you can then check if xfoo is linked using ifdefs
#ifdef XFOO
//call xfoo's foo()
#endif
A linker cannot distinguish between two different definitions of the same symbol name, so if you're trying to use two functions with the same name you'll have to separate them somehow.
The way to separate them is to put them in dynamic libraries. You can choose which things to export from a dynamic library, so you can export the wrappers while leaving the underlying API functions hidden. You can also load the dynamic library at runtime and bind to symbols one at a time, so even if the same name is define in more than one they won't interfere with each other.