bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ld -wrap does not apply to symbols referenced in same file as the symbol


From: Steve Kaufmann
Subject: ld -wrap does not apply to symbols referenced in same file as the symbol's defintion
Date: Wed, 11 May 2005 15:50:40 -0500
User-agent: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7.5) Gecko/20050320

The ld -wrap option works well for only those symbols whose references are not in the same translation unit as the symbol's defintion. This is a serious drawback for users who do not want to restructure their code to use this option. There are also tools that exist that generate the -wrap option in order to provide tracing capabilities as part of a performance analysis tool. The usefulness of the -wrap option would be greatly enhanced if it supported the wrapping of ALL symbol references, regardless of their proximity to the symbol definition. The performance tool we developed and maintain limits the user capability in tracing their own functions because, especially for Fortran, the program is self-contained in a single translation unit so all REFs and DEFs of the symbol are in the same file. Restructuring the source code is not an option since recompilation is not required with our tool.

This is request to binutils to fix -wrap to work properly with all symbol references. It is unclear whether the best place to facilitate this fix is in the assembler, linker, or the libbfd library. For example, one way for the assembler to accomplish this is to place each function in its own compilation unit. This would result in REFs being separated from DEFs. This would not work for recursive functions, of course.

This demostrates how -wrap does not apply to those references in the same file as the definition:

$ cat foo.c
extern void foo();
main()
{
    foo();
}
void foo()
{
    printf("Hi from foo.\n");
}
$ gcc -c foo.c
$ gcc -o foo foo.o -Wl,-wrap,foo
$ nm foo | grep foo
00000000004004c8 T foo

You'd expect a linker error that says "__wrap_foo is undefined", but there is none since "foo" was not changed.

As an example, the following illustrates IF an undefined symbol is added to the symbol table if the symbol definition was in the same file as the reference. This mimics what the assembler might issue.

1.  Make a .o with a DEF of foo and a REF to foo1.

$ cat foo.c
extern void foo1();
main()
{
    foo1();
}
void foo()
{
    printf("Hi from foo.\n");
}

$ gcc -c foo.c
$ nm -p foo.o
0000000000000000 T main
                                U foo1
0000000000000010 T foo
                                U printf

------------------------------------------------------------
2.  Modify the .o by nulling out the '1' in "foo1".  This gives
   us a .o with both a DEF and a REF to foo.

$  cat zap1.c
#include <stdio.h>
main()
{
    int n;
    int i;
    char buf[10000];
    FILE *in = fopen("foo.o", "r");
    FILE *out = fopen("foo1.o", "w");
    n = fread ( buf, 1, 10000, in);
    for ( i=0; i<n-4; i++ ) {
      if ( buf[i] == 'f' &&
           buf[i+1] == 'o' &&
           buf[i+2] == 'o' &&
           buf[i+3] == '1' ) {
        buf[i+3] = '\0';
      }
   }
   fwrite(buf, 1, n, out);
}
$ gcc -o zap1 zap1.c
$ ./zap1 foo.o foo1.o
$ nm -p foo1.o
0000000000000000 T main
                                U foo
0000000000000010 T foo
                                U printf

------------------------------------------------------------
3.  Verify that this links and executes as expected.

$  gcc -o foo1 foo1.o
$ ./foo1
Hi from foo.

------------------------------------------------------------
4.  Make a .o with a wrapper for foo, and verify that a wrapping
   link works as expected.

$ cat wrap_foo.c
void __wrap_foo()
{
    printf("Hi from __wrap_foo.\n");
    __real_foo();
}
$ gcc -c wrap_foo.c
$ gcc -o foo1w -Wl,-wrap,foo foo1.o wrap_foo.o
$ ./foo1w
Hi from __wrap_foo.
Hi from foo.

Thank you for your attention to this matter.

Steve Kaufmann
Bill Homer
Luiz DeRose
Programming Environments
Cray Inc.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]