I am using android NDK-r10d to build Android x86 executable (shared linking) that runs on adb shell. On run time, I am getting the following warning:
WARNING: linker: ./myapp: **unused DT entry:** type 0x1d arg 0x4a604
I am using a rooted Nexus Player to test the executable.
And my build machine is Ubuntu 14.04 (also tried on Fedora 14 machine).
What are "unused DT entry" errors?
If you have reached this page, it's probably because you have compiled or attempted to run some binaries on your ARM based Android system, with the result that your binary/app crashes or generates a lot of warnings in your
logcat
. Typically something like this:Q: What is a "DT entry"?
In a few words, they are descriptive array entries in the file structure of an ELF file. Specifically they are known as
Dynamic Array Tags
and are requirements for executable and shared objects. However, not all entries are required or available, depending on the processor and kernel architecture.In our case we are faced with a "Warning" that one of these are "unused". What that means is, that your executable or library (
*.so
) files has been compiled with the DT entry indicated, but your kernel is not supporting that entry, for various reasons. The best examples are found on ARM based Android systems, where the system library paths are fixed and the cross compilers used for your firmware (OS/kernel) are set not to use these entries. Usually the binaries still run just fine, but the kernel is flagging this warning every time you're using it.Q: When does this happen?
This can happen when:
The most common flags that cause this error on Android devices are:
Tracking down the error above, we find that this message comes from the
bionic
library linker.cpp:The code (above) supporting this symbol versioning was committed on April 9, 2015. Thus if your NDK build is either set to support API's earlier than this, or using build tools linking to this earlier library, you will get these warnings.
Q: How do I find what DT entries my system or binaries are using?
There are many ways to do this:
<linux/elf.h>
.readelf
of your binary:As you can see from the error above, the
type
corresponds toDT_VERNEED
.From THIS document:
Q: So how do you solve or deal with these issues?
There are essentially 3 ways to deal with this:
The Quick (you don't have any sources or just can't be bothered)
Use an "ELF cleaner" to remove the offending DT entries from a all your binaries. This is an easy and quick remedy, especially when you don't have the sources to recompile them properly for your system. There are at least two cleaners out there that you can use.
The Bad (you have the sources)
Is the right way to do it, because you'll become a bad-ass ARM cross compiler guru in the process of getting it to work. You basically need to find and tune the compiler settings in the Makefiles used.
From here:
The Ugly (You just want your app to work with any dirty binary.)
You tell your Java app not to freak out when checking for null in error handlers and instead get fed these warnings, possibly causing fatal exceptions. Use something like:
This is very bad and ugly as it doesn't solve anything, while bloating your code. In addition, the warnings are there for a reason, and that is that in future AOS versions, this will become a full fledged error!
Q. What else?
Many changes in the API's between 18-25 (J to N) has been made in way the Android kernel and libraries are compiled. I cannot provide a remotely close explanation of all that, but perhaps this will help guide you in the right direction. The best sources is of course looking in the Android sources and documentation itself.
For example, HERE or HERE.
And finally the full list:
With readelf -d you may list DT entries in your binary:
As you may see, 0x1d corresponds to RUNPATH That entry is added with linker option -rpath (or -R, if followed by directory)