Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent certain functions from getting stripped?

I have a static library that contains some JNICALL functions, i.e. they are expected to be called from the JVM and are never referenced by the shared library that links the static library.

However, it seems like function stripping is exterminating the JNICALL function (it's not visible in arm-eabi-objdump -t). I'm working around it by adding a dummy function with an impossible condition that calls the JNICALL function, but that's dirty. I know that there is a link option to prevent certain modules from getting their unused data stripped, but what is it? And how do I specify that option in the .mk file? I didn't see anything immediately obvious in arm-eabi-ld.

Incidentally, the function stripping doesn't strip out JNICALL functions in the shared library itself, but it will remove those from the static library that the shared library is linking. What's the reason for that?

like image 239
EboMike Avatar asked Aug 29 '10 03:08

EboMike


1 Answers

It actually looks like the NDK team started supporting that (or stopped?), and there are traces of it in the build system, but some vital parts are missing. The good news is that it can be easily implemented.

Go to the "build" directory in the NDK installation and search for all instances of LOCAL_STATIC_LIBRARIES. Copy and paste all of them and add a version that version that does the same thing with LOCAL_STATIC_WHOLE_LIBRARIES.

To be precise: In build/core/build-binary.mk, you'll need:

LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
LOCAL_STATIC_WHOLE_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_WHOLE_LIBRARIES))

[...]

static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
static_whole_libraries := $(call map,static-library-path,$(LOCAL_STATIC_WHOLE_LIBRARIES))

[...]

$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_LIBRARIES))
$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_WHOLE_LIBRARIES))

[...]

$(LOCAL_BUILT_MODULE): $(static_libraries) $(static_whole_libraries) $(shared_libraries)

[...]

$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(static_whole_libraries)

Note the discrepancy between STATIC_WHOLE and WHOLE_STATIC - that's how it is in the NDK, I chose to keep it that way even though it's inconsistent.

Now, finally, in build/toolchains/arm-eabi-4.4.0/setup.mk: There's already the PRIVATE_WHOLE_STATIC_LIBRARIES block for shared libraries. You can choose to add that for executables as well, although that's most likely not necessary.

like image 63
EboMike Avatar answered Oct 23 '22 03:10

EboMike