śaṅkaradāsa

Wrapping Standard Library Function in C

It is straightforward to put print messages in user defined functions (for debugging or for logging purposes) but what if you want to do something similar to standard library functions? It is not that difficult either. GNU Linker's(ld) –wrap=symbol option helps achieving this.

Suppose, you want to wrap strlen. Here is the scheme:

Here is a complete example wrapping strlen:

#include <stdio.h>
#include <string.h>

/* call to strlen will call __wrap_strlen first */
size_t __wrap_strlen (const char *s)
{
        printf ("inside strlen wrapper\n");
        /* lib's strlen call will happen with __real_strlen */
        return __real_strlen (s);
}

int main (int argc, char *argv[])
{
        /* call to strlen remains as-is, and calls __wrap_strlen */
        printf ("program's name length: %zu\n", strlen(argv[0]));
        return 0;
}

Compile it as:

$ gcc wrap_strlen.c -Wl,--wrap=strlen -o wrap_strlen

Run:

$ ./wrap_strlen
inside strlen wrapper
program's name length: 13

Here is what ld info page says which is self-explanatory:

–wrap=symbol

Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to "_wrapsymbol". Any undefined reference to "_realsymbol" will be resolved to symbol.

This can be used to provide a wrapper for a system function. The wrapper function should be called "_wrapsymbol". If it wishes to call the system function, it should call "_realsymbol".

Here is a trivial example:

void * _wrapmalloc (sizet c) { printf ("malloc called with %zu\n", c); return _realmalloc (c); }

If you link other code with this file using –wrap malloc, then all calls to "malloc" will call the function "_wrapmalloc" instead. The call to "_realmalloc" in "_wrapmalloc" will call the real "malloc" function.

You may wish to provide a "_realmalloc" function as well, so that links without the –wrap option will succeed. If you do this, you should not put the definition of "_realmalloc" in the same file as "_wrapmalloc"; if you do, the assembler may resolve the call before the linker has a chance to wrap it to "malloc".

Well, short, wrapping it up!