I am encountering a different behavior between OS X and Android:
- There is a weak function
foo
in my shared library, - I want to override it with strong function defined in my executable.
- I expect the the overridden also affect the calling inside the library
Result: I got expected result on OS X, but failed on Android.
Here is my test project:
File: shared.h
void library_call_foo();
void __attribute__((weak)) foo();
File: shared.c
#include "shared.h"
#include <stdio.h>
void library_call_foo()
{
printf("shared library call foo -> ");
foo();
}
void foo()
{
printf("weak foo in library\n");
}
File: main.c
#include <stdio.h>
#include <shared.h>
void foo()
{
printf("strong foo in main\n");
}
int main()
{
library_call_foo();
printf("main call foo -> ");
foo();
return 0;
}
I compile & run it in OS X use commands:
clang -shared -fPIC -o libshared.so shared.c
clang -I. -L. -lshared -o test main.c
./test
which return results as I expected:
shared library call foo -> strong foo in main
main call foo -> strong foo in main
But when I compile it for Android with NDK toolchains use same commands:
arm-linux-androideabi-clang -shared -fPIC -o libshared.so shared.c
arm-linux-androideabi-clang -I. -L. -lshared -o test main.c
and run it on device, I got different results:
shared library call foo -> weak foo in library
main call foo -> strong foo in main
Why is the behaviors are different, and how could I fix it?
Android dynamic linker does in fact support weak symbols. The problem is this particular case is that library is compiled with -Bsymbolic (to check this run "readelf -d libshared.so").
The work around this is to use '-Wl,-shared' instead of '-shared' when linking the library.
Please see https://code.google.com/p/android/issues/detail?id=68956 for details and workaround.
Android doesn't support weak symbol override.
In the recent release android-5.0.2_r1, see the comment at line 539 in linker.cpp source code
/*
*
* Notes on weak symbols:
* The ELF specs are ambigious about treatment of weak definitions in
* dynamic linking. Some systems return the first definition found
* and some the first non-weak definition. This is system dependent.
* Here we return the first definition found for simplicity.
*/
This comment exists from version 2.2_r1 (which is in linker.c) to newest version 5.0.2_r1
来源:https://stackoverflow.com/questions/20196368/different-behavior-of-override-weak-function-in-shared-library-between-os-x-and