Alan Coopersmith wrote:
> A proposed change to Xorg upstream would use GNU ld's -wrap option
> to simplify some of the test cases that have to override functions
> with test wrappers - is there a Solaris ld equivalent of this
> functionality?   A command line equivalent would be preferable, but
> a mapfile option could be made to work.   It seems like it's a
> combination of symbol renaming, direct linking and an automatic
> dlsym alias to the function in a linked library.
> 
> The GNU ld documentation of this option:
> 
>   --wrap symbol
> 
>     Use a wrapper function for symbol. Any undefined reference to
>     symbol will be resolved to __wrap_symbol. Any undefined reference
>     to __real_symbol will be resolved to symbol.
> 
>     This can be used to provide a wrapper for a system function. The
>     wrapper function should be called __wrap_symbol. If it wishes to
>     call the system function, it should call __real_symbol.
> 
>     Here is a trivial example:
> 
>               void *
>               __wrap_malloc (size_t c)
>               {
>                 printf ("malloc called with %zu\n", c);
>                 return __real_malloc (c);
>               }
> 
> 
>     If you link other code with this file using --wrap malloc, then
>     all calls to malloc will call the function __wrap_malloc
>     instead. The call to __real_malloc in __wrap_malloc will call the
>     real malloc function.
> 
>     You may wish to provide a __real_malloc function as well, so that
>     links without the --wrap option will succeed. If you do this, you
>     should not put the definition of __real_malloc in the same file as
>     __wrap_malloc; if you do, the assembler may resolve the call
>     before the linker has a chance to wrap it to malloc.
> 
> (copied from
> http://sourceware.org/binutils/docs-2.19/ld/Options.html#index-g_t_002d_002dwrap-249
> )
> 

I can't think of any facility in the Solaris ld that
can do that as described.

The closest thing would be to preload a sharable object
that provided the wrapper functions, which then use dlsym
at runtime to find and call the real function.

I assume that the obvious idea of doing this at compile time
with macros has been rejected?

        #define malloc __wrap_malloc

----
I will mention that elfedit offers some abilities to mess with
objects. I was able to cook up the following ugly hack using elfedit,
and it does work for the little case below. However, it won't work
for sharable objects, only relocatable objects, because elfedit does
not have the ability to rewrite the hash table in a sharable object.
So it's sort of limited, but I'll put it out there as food for thought...

elfedit lets you overwrite the string table in an ELF
object, which is probably really dangerous, but I did
use it to get a similar result to that gld option...

        % cat alan.c
        #include <stdio.h>

        int
        main(int argc, char **argv)
        {
                printf("hello\n");
                return (0);
        }
        % cc -c alan.c
        % cc alan.o
        % ./a.out
        hello

Now lets use elfedit to rename printf in that object. We
can't add a new name to a relocatable object, so let's just
crush the existing string, using a replacement with the
same length:

        % elfedit -e 'str:set printf __prin' alan.o
        % cc alan.o
        Undefined                       first referenced
         symbol                             in file
        __prin                              alan.o
        ld: fatal: symbol referencing errors. No output written to a.out

Now to supply the "wrap" code:

        % cat __prin.c
        #include <stdio.h>
        #include <stdarg.h>

        int __prin(const char *restrict format, ...)
        {
                int r;
                va_list ap;
        
                va_start(ap, format);
                printf("WRAP: ");
                r = vprintf(format, ap);
                va_end(ap);
                return (r);
        }       
        % cc -c __prin.c
        % cc alan.o __prin.o
        % ./a.out
        WRAP: hello

This comes with no warranty...  :-)

- Ali

Reply via email to