"ld --wrapper" but without changing legacy executable, possible?

sean yang seanatpurdue@hotmail.com
Tue Mar 21 01:23:00 GMT 2006


Actually, the title of this post should be "Is run-time wrapper with 
lightweight overhead possible?" I appreciate your patience to read and 
answer.

Suppose I want to achieve the following effect: any libc call exept malloc 
should behave as is, and malloc should behave as my wrapper function defines 
(say, printf a string before malloc).
-----------------------------------------------------------------------------
//mallocwrapper.c
void *
__wrap_ malloc(int c)
{
  printf ("any malloc should be intercepted\n", c);
  return __real_malloc (c);
}
-------------------------------------------------------------------------------

Apparently, if I have access to application source(see test.c),  I can use a 
ld -wrap (thanks to  Nick and Daniel for answering my previous question)  to 
achive such a goal. i.e., somethink like
>gcc -c mallocwrapper.c
>ar libmallocwrapper.a mallocwrapper.o
>gcc -o test test.c -lmallocwrapper --wrap malloc
-----------------------------------------------------------------------------
//test.c
#include <stdio.h>
#include <stdlib.h>
int main(){
  int i = 4;
  void *ptr;
  printf("this should invoke the original printf in libc.so\n");
  ptr= malloc(i);
  free (ptr);
  ptr= malloc(i);
  free (ptr);
}
-------------------------------------------------------------------------------


But above approach works only if I have access to the application's source 
code (test.c). If my legacy executable code (`test') has already been 
compiled and linked to libc.so.6, and I don't have test.c, then above 
approach doesn't work.

Though I can use a LD_PRELOAD variable to sepcify wrapper at runtime in this 
case, the overhead is very high, i.e., the actually wrapper need 
dlsym(RTLD_NEXT, "malloc") to open the actual malloc each time it's called. 
Please see the following code and command line.

-----------------------------------------------------------------------------
//runtimewrapper.c
     1 #define _GNU_SOURCE
      2 #include <stdio.h>
      3 #include <dlfcn.h>
      4 void* malloc(int size) {
      5     printf("wrapped malloc\n");
      6     void* (*real_malloc)(const char*, const char*) =
      7     dlsym(RTLD_NEXT, "malloc");
      8     return real_malloc(size);
      9 }
-------------------------------------------------------------------------------
>gcc -fPIC -rdynamic -c runtimewrapper.c
>gcc -shared -o libruntimewrapper.so runtimewrapper.o -lc -ldl
>LD_LIBRARY_PATH=./ LD_PRELOAD=libruntimewrapper.so ./test


But the problem of above approach is that " void* (*real_malloc)(const 
char*, const char*) = dlsym(RTLD_NEXT, "malloc");" is called each time the 
application want to use malloc(), which is the major source of overhead. As 
you can see from my example, what I really want to do is just  a 
"printf("wrapped malloc\n");" before each real malloc.

My question is: is there anyway to avoid this overhead? Hopefully, my 
question is clear and get some advice. Thanks a lot.

Sean

_________________________________________________________________
Is your PC infected? Get a FREE online computer virus scan from McAfee® 
Security. http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963



More information about the Binutils mailing list