2

I'm trying to wrap a library function with the GCC linker option -wrap. As far as I've read up, this should replace the symbol libfoo with __wrap_libfoo and give access to the original definition by __real_libfoo.

I've implemented it like this:

original.h

#ifndef ORIGINAL_H
#define ORIGINAL_H

void libfoo();

#endif //ORIGINAL_H

original.cpp

#include "original.h"
#include <iostream>

void libfoo()
{
  std::cout<<"Original libfoo called from original.cpp"<<std::endl;
  return;
};

And compiled to a static lib with g++ --std=c++11 -c original.cpp -o liboriginal.o, packed up with ar rcs liboriginal.a liboriginal.o and moved to a location known to the linker.

wrapper.h

#ifndef WRAPPER_H
#define WRAPPER_H

// should not need anything here

#endif //WRAPPER_H

wrapper.cpp

#include "wrapper.h"
#include <iostream>

//forward declaration to suppress compiler error
void __real_libfoo();

void __wrap_libfoo()
{
  std::cout<<"Wrapper libfoo called from wrapper.cpp"<<std::endl;
  __real_libfoo();
  return;
};

Compiled again to a static lib with g++ --std=c++11 -c wrapper.cpp -o libwrapper.o, packed up with ar rcs libwrapper.a libwrapper.o.

main.cpp

#include "original.h"

int main()
{
  libfoo();
  return 0;
}

Compiled with g++ --std=c++11 -c main.cpp -o main.o and linked everything together with g++ -L. -Wl,-wrap=libfoo -o test ./main.o -loriginal -lwrapper

On execution, I only get Original libfoo called from original.cpp at the console.

Why does the linker not replace the symbol so the call is redirected to __wrap_libfoo()?

And, if this is solved, how do I handle multiple, overloaded functions, which all should be wrapped? Do I need just one -wrap=function_name or do I need to somehow add a more detailed signature to the linker option?

Update: I've also tried not linking the wrapper as a lib, but as an object file instead. This gives me a undefined ref error from the linker regarding the missing __real_libfoo() implementation.

Chaos_99
  • 2,284
  • 2
  • 25
  • 29
  • 2
    A problem here is that function names in C++ are *mangled*, and you pass the unmangled `libfoo` name to the linkers `wrap` option. Try to use e.g. `extern "C"` for all functions (the original, and the wrapped). – Some programmer dude Feb 09 '17 at 09:12
  • This indeed works and also answers my second question about the overloaded functions. But of course in the real world, I have no control over the original library code. Seems I need to figure out the name mangling instead. Care to make your comment into an answer? – Chaos_99 Feb 09 '17 at 09:24
  • 2
    You might want to check [Getting mangled name from demangled name](http://stackoverflow.com/q/12400105/440558). – Some programmer dude Feb 09 '17 at 09:34
  • 1
    See https://stackoverflow.com/questions/12400105/getting-mangled-name-from-demangled-name how to mangle. Even when the mangled name is used for the linker option, the `extern "C"` has to be used in the wrapper. – Chaos_99 Feb 09 '17 at 09:34

0 Answers0