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.
_______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils