okutane
okutane

Reputation: 14260

Wrapping symbols during linking on OS X

I'm trying to wrap one symbol by another during link. As I understand this is easily done with ld --wrap option, but on OS X it's not available. There is '-idefinition:indirection', here how I'm trying to cheat main so it will print 42:

a.cpp:

int foo() {
    return 1;
}

b.cpp:

int wrap_foo() {
    return 42;
}

main.cpp:

#include <cstdio>

int foo();
int wrap_foo();

int main() {
    printf("%d\n", foo());
}

How I build and link them:

$ gcc -c *.cpp
$ gcc -Wl,-i__Z3foov:__Z8wrap_foov *.o
duplicate symbol __Z3foov in:
    a.o
    b.o
ld: 1 duplicate symbol for architecture x86_64

Is it even possible to achieve what I want?


EDIT: In my task I don't have control over a.cpp and main.cpp (have only objects for them), but I can write any code and do whatever I need with the objects before link.

I've found following quistion before which related to similar task (and describes it better) GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file Rereading the answers I see that the case is same, symbol already present and I will have a collision.

How to remove foo from a.o without touching source code?

Upvotes: 2

Views: 2400

Answers (1)

Mobile Ben
Mobile Ben

Reputation: 7341

Does this have to be done at link versus runtime? Note entirely sure what you're trying to do, so just asking.

The problem with using that linker command is that it creates a new symbol, which is why you get the duplicate symbol.

-alias symbol_name alternate_symbol_name
                 Create an alias named alternate_symbol_name for the symbol
                 symbol_name.  By default the alias symbol has global visibil-
                 ity.  This option was previous the -idef:indir option.

If you don't have a.cpp which defines foo (ie. you are omitting foo), you can do something like this:

tmp$ gcc -Wl,-alias,__Z8wrap_foov,__Z3foov b.o main.o
tmp$ ./a.out
42

What you could always do is have a.cpp have another foo like original_foo. This way if you wanted that implementation, you could use alias to map that to foo. Not perfect, but it would achieve roughly what you want. You're already going through the effort of adjusting it at link, so it would seem potentially acceptable.

Upvotes: 3

Related Questions