Different behavior of override weak function in shared library between OS X and Android
Asked Answered
S

2

4

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?

Someplace answered 25/11, 2013 at 15:7 Comment(1)
I'm not convinced weak symbols work on Android, even though Android defines __GXX_WEAK__ in the preprocessor. Also see Does Android support weak symbols?.Is
D
1

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.

Deist answered 15/1, 2015 at 21:47 Comment(0)
S
0

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

Someplace answered 15/1, 2015 at 19:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.