未使用的DT条目:类型0x1d arg



我正在使用android NDK-r10d构建运行在adb shell上的Android x86可执行文件(共享链接)。在运行时,我得到以下警告:

WARNING: linker: ./myapp: **unused DT entry:** type 0x1d arg 0x4a604

我正在使用一个有根的Nexus Player来测试可执行文件。

我的构建机器是Ubuntu 14.04(也在Fedora 14机器上尝试过)。

什么是"未使用的DT条目"错误?

如果你已经到达这个页面,那可能是因为你已经编译或试图在基于ARM的Android上运行一些二进制文件系统,结果是你的二进制/应用程序崩溃或生成一个你的logcat里有很多警告。通常是这样的:

WARNING: linker: /blahblah/libopenssl.so: unused DT entry: type 0x6ffffffe arg 0x1188

问:什么是"DT条目"?

简而言之,它们是文件中的描述性数组项ELF文件的结构。具体来说,它们被称为Dynamic Array Tags并且是可执行的和的需求共享对象。然而,并非所有条目都是必需的或可用的,这取决于处理器和内核架构。

在我们的例子中,我们面临一个"警告",其中一个是"未使用的"。这意味着,您的可执行文件或库(*.so)文件已经用DT编译指示了条目,但是您的内核不支持这个条目,出于各种原因。最好的例子是基于ARM的Android系统,其中系统库路径是固定的,并且用于固件(OS/内核)的交叉编译器设置为不使用这些条目。通常二进制文件仍然运行良好,但是内核在您每次使用它时都会标记此警告。

问:这是什么时候发生的?

当:

  • 你的ARM内核使用错误的标志进行交叉编译(通常意味着其他处理器架构)。
  • 您的ARM二进制文件和库使用AOS弃用的编译标志进行交叉编译。
  • 可能还有其他尚未被发现的方法…

从5.1 (API 22)开始,Android链接器警告VERNEED和VERNEEDNUM ELF动态节。

在Android设备上导致此错误的最常见标志是:
DT_RPATH        0x0f (15)       The DT_STRTAB string table offset of a null-terminated library search path string. 
This element's use has been superseded by DT_RUNPATH.
DT_RUNPATH      0x1d (29)       The DT_STRTAB string table offset of a null-terminated library search path string.
DT_VERNEED      0x6ffffffe      The address of the version dependency table. Elements within this table contain 
indexes into the string table DT_STRTAB. This element requires that the 
DT_VERNEEDNUM element also be present.
DT_VERNEEDNUM   0x6fffffff      The number of entries in the DT_VERNEEDNUM table.

跟踪上面的错误,我们发现这个消息来自bionic库链接器。

case DT_VERNEED:
verneed_ptr_ = load_bias + d->d_un.d_ptr;
break;
case DT_VERNEEDNUM:
verneed_cnt_ = d->d_un.d_val;
break;
case DT_RUNPATH:
// this is parsed after we have strtab initialized (see below).
break;
default:
if (!relocating_linker) {
DL_WARN(""%s" unused DT entry: type %p arg %p", get_realpath(),
reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
}
break;
}

支持此符号版本控制的代码(上面)于2015年4月9日提交。因此,如果您的NDK构建被设置为支持比此更早的API,或者使用链接到此更早的库的构建工具,您将得到这些警告。


问:我如何找到我的系统或二进制文件正在使用的DT条目?

有很多方法可以做到这一点:

  1. 查看<linux/elf.h>的内核源代码
  2. 查看Android NDK安装文件夹并检查:
# To find all elf.h files:
find /<path_to>/ndk/platforms/android-*/arch-arm*/usr/include/linux/ -iname "elf.h"
  1. 执行二进制文件的readelf:
$ readelf --dynamic libopenssl.so
Dynamic section at offset 0x23b960 contains 28 entries:
Tag        Type                         Name/Value
0x00000003 (PLTGOT)                     0x23ce18
0x00000002 (PLTRELSZ)                   952 (bytes)
0x00000017 (JMPREL)                     0x15e70
0x00000014 (PLTREL)                     REL
0x00000011 (REL)                        0x11c8
0x00000012 (RELSZ)                      85160 (bytes)
0x00000013 (RELENT)                     8 (bytes)
0x6ffffffa (RELCOUNT)                   10632
0x00000015 (DEBUG)                      0x0
0x00000006 (SYMTAB)                     0x148
0x0000000b (SYMENT)                     16 (bytes)
0x00000005 (STRTAB)                     0x918
0x0000000a (STRSZ)                      1011 (bytes)
0x00000004 (HASH)                       0xd0c
0x00000001 (NEEDED)                     Shared library: [libdl.so]
0x00000001 (NEEDED)                     Shared library: [libc.so]
0x0000001a (FINI_ARRAY)                 0x238458
0x0000001c (FINI_ARRAYSZ)               8 (bytes)
0x00000019 (INIT_ARRAY)                 0x238460
0x0000001b (INIT_ARRAYSZ)               16 (bytes)
0x00000020 (PREINIT_ARRAY)              0x238470
0x00000021 (PREINIT_ARRAYSZ)            0x8
0x0000001e (FLAGS)                      BIND_NOW
0x6ffffffb (FLAGS_1)                    Flags: NOW
0x6ffffff0 (VERSYM)                     0x108c
0x6ffffffe (VERNEED)                    0x1188
0x6fffffff (VERNEEDNUM)                 2
0x00000000 (NULL)                       0x0

从上面的错误中可以看出,type对应于DT_VERNEED

从本文档:

DT_RPATH

此元素保存以null结尾的搜索的字符串表偏移量库搜索路径字符串,在"共享对象依赖关系"中讨论。偏移量是记录在DT_STRTAB表项中的表索引。DT_RPATH可以给出一个字符串,其中包含目录列表,分隔通过冒号(:)。之后搜索所有LD_LIBRARY_PATH目录

Q:那么你们是如何解决或者处理这些问题的呢?

基本上有三种方法来处理这个问题:

  1. 快速
  2. 丑陋的

快速(你没有任何来源或只是懒得)

使用"ELF清洁器"从所有二进制文件中删除有问题的DT条目。这是一种简单而快速的补救方法,特别是当您没有为您的系统正确重新编译它们的源代码时。至少有两种清洁剂可供你使用。


(你有来源)

是正确的方法,因为在让它工作的过程中,你将成为一个厉害的ARM交叉编译专家。您基本上需要在使用的Makefiles中找到并调整编译器设置。

从这里:

Android链接器(/system/bin/linker)不支持RPATH或RUNPATH,所以我们设置LD_LIBRARY_PATH=$USR/lib,并尽量避免使用——disable-rpath配置标志构建无用的RPATH条目。避免依赖LD_LIBRARY_PATH的另一种选择是提供自定义链接器——由于维护自定义链接器的开销,不这样做。


丑陋的(你只是想让你的应用程序与任何肮脏的二进制文件一起工作。)

你告诉你的Java应用程序在检查null时不要崩溃在错误处理程序中,可能会得到这些警告导致致命异常。例如:

class OpensslErrorThread extends Thread {
@Override
public void run() {
try {
while(true){
String line = opensslStderr.readLine();
if(line == null){
// OK
return;
}
if(line.contains("unused DT entry")){
Log.i(TAG, "Ignoring "unused DT entry" error from openssl: " + line);
} else {
// throw exception!
break;
}
}
} catch(Exception e) {
Log.e(TAG, "Exception!")
}
}
}

这是非常糟糕和丑陋的,因为它不能解决任何问题,同时使您的代码膨胀。此外,出现警告是有原因的,那就是在未来的AOS版本中,这将成为一个完全成熟的错误!


Q。还有什么?

在18-25 (J到N)之间的API进行了许多更改Android内核和库的编译方式。我不能对这一切提供一个非常接近的解释,但也许这个会指引你走向正确的方向。最好的来源是当然要看Android的源代码和文档本身。

例如HERE或HERE.


最后是完整的列表:

Name                    Value           d_un            Executable              Shared Object
---------------------------------------------------------------------------------------------
DT_NULL                 0               Ignored         Mandatory               Mandatory
DT_NEEDED               1               d_val           Optional                Optional
DT_PLTRELSZ             2               d_val           Optional                Optional
DT_PLTGOT               3               d_ptr           Optional                Optional
DT_HASH                 4               d_ptr           Mandatory               Mandatory
DT_STRTAB               5               d_ptr           Mandatory               Mandatory
DT_SYMTAB               6               d_ptr           Mandatory               Mandatory
DT_RELA                 7               d_ptr           Mandatory               Optional
DT_RELASZ               8               d_val           Mandatory               Optional
DT_RELAENT              9               d_val           Mandatory               Optional
DT_STRSZ                0x0a (10)       d_val           Mandatory               Mandatory
DT_SYMENT               0x0b (11)       d_val           Mandatory               Mandatory
DT_INIT                 0x0c (12)       d_ptr           Optional                Optional
DT_FINI                 0x0d (13)       d_ptr           Optional                Optional
DT_SONAME               0x0e (14)       d_val           Ignored                 Optional
DT_RPATH                0x0f (15)       d_val           Optional                Optional
DT_SYMBOLIC             0x10 (16)       Ignored         Ignored                 Optional
DT_REL                  0x11 (17)       d_ptr           Mandatory               Optional
DT_RELSZ                0x12 (18)       d_val           Mandatory               Optional
DT_RELENT               0x13 (19)       d_val           Mandatory               Optional
DT_PLTREL               0x14 (20)       d_val           Optional                Optional
DT_DEBUG                0x15 (21)       d_ptr           Optional                Ignored
DT_TEXTREL              0x16 (22)       Ignored         Optional                Optional
DT_JMPREL               0x17 (23)       d_ptr           Optional                Optional
DT_BIND_NOW             0x18 (24)       Ignored         Optional                Optional
DT_INIT_ARRAY           0x19 (25)       d_ptr           Optional                Optional
DT_FINI_ARRAY           0x1a (26)       d_ptr           Optional                Optional
DT_INIT_ARRAYSZ         0x1b (27)       d_val           Optional                Optional
DT_FINI_ARRAYSZ         0x1c (28)       d_val           Optional                Optional
DT_RUNPATH              0x1d (29)       d_val           Optional                Optional
DT_FLAGS                0x1e (30)       d_val           Optional                Optional
DT_ENCODING             0x1f (32)       Unspecified     Unspecified             Unspecified
DT_PREINIT_ARRAY        0x20 (32)       d_ptr           Optional                Ignored
DT_PREINIT_ARRAYSZ      0x21 (33)       d_val           Optional                Ignored
DT_MAXPOSTAGS           0x22 (34)       Unspecified     Unspecified             Unspecified
DT_LOOS                 0x6000000d      Unspecified     Unspecified             Unspecified
DT_SUNW_AUXILIARY       0x6000000d      d_ptr           Unspecified             Optional
DT_SUNW_RTLDINF         0x6000000e      d_ptr           Optional                Optional
DT_SUNW_FILTER          0x6000000e      d_ptr           Unspecified             Optional
DT_SUNW_CAP             0x60000010      d_ptr           Optional                Optional
DT_SUNW_SYMTAB          0x60000011      d_ptr           Optional                Optional
DT_SUNW_SYMSZ           0x60000012      d_val           Optional                Optional
DT_SUNW_ENCODING        0x60000013      Unspecified     Unspecified             Unspecified
DT_SUNW_SORTENT         0x60000013      d_val           Optional                Optional
DT_SUNW_SYMSORT         0x60000014      d_ptr           Optional                Optional
DT_SUNW_SYMSORTSZ       0x60000015      d_val           Optional                Optional
DT_SUNW_TLSSORT         0x60000016      d_ptr           Optional                Optional
DT_SUNW_TLSSORTSZ       0x60000017      d_val           Optional                Optional
DT_SUNW_CAPINFO         0x60000018      d_ptr           Optional                Optional
DT_SUNW_STRPAD          0x60000019      d_val           Optional                Optional
DT_SUNW_CAPCHAIN        0x6000001a      d_ptr           Optional                Optional
DT_SUNW_LDMACH          0x6000001b      d_val           Optional                Optional
DT_SUNW_CAPCHAINENT     0x6000001d      d_val           Optional                Optional
DT_SUNW_CAPCHAINSZ      0x6000001f      d_val           Optional                Optional
DT_HIOS                 0x6ffff000      Unspecified     Unspecified             Unspecified
DT_VALRNGLO             0x6ffffd00      Unspecified     Unspecified             Unspecified
DT_CHECKSUM             0x6ffffdf8      d_val           Optional                Optional
DT_PLTPADSZ             0x6ffffdf9      d_val           Optional                Optional
DT_MOVEENT              0x6ffffdfa      d_val           Optional                Optional
DT_MOVESZ               0x6ffffdfb      d_val           Optional                Optional
DT_POSFLAG_1            0x6ffffdfd      d_val           Optional                Optional
DT_SYMINSZ              0x6ffffdfe      d_val           Optional                Optional
DT_SYMINENT             0x6ffffdff      d_val           Optional                Optional
DT_VALRNGHI             0x6ffffdff      Unspecified     Unspecified             Unspecified
DT_ADDRRNGLO            0x6ffffe00      Unspecified     Unspecified             Unspecified
DT_CONFIG               0x6ffffefa      d_ptr           Optional                Optional
DT_DEPAUDIT             0x6ffffefb      d_ptr           Optional                Optional
DT_AUDIT                0x6ffffefc      d_ptr           Optional                Optional
DT_PLTPAD               0x6ffffefd      d_ptr           Optional                Optional
DT_MOVETAB              0x6ffffefe      d_ptr           Optional                Optional
DT_SYMINFO              0x6ffffeff      d_ptr           Optional                Optional
DT_ADDRRNGHI            0x6ffffeff      Unspecified     Unspecified             Unspecified
DT_RELACOUNT            0x6ffffff9      d_val           Optional                Optional
DT_RELCOUNT             0x6ffffffa      d_val           Optional                Optional
DT_FLAGS_1              0x6ffffffb      d_val           Optional                Optional
DT_VERDEF               0x6ffffffc      d_ptr           Optional                Optional
DT_VERDEFNUM            0x6ffffffd      d_val           Optional                Optional
DT_VERNEED              0x6ffffffe      d_ptr           Optional                Optional
DT_VERNEEDNUM           0x6fffffff      d_val           Optional                Optional
DT_LOPROC               0x70000000      Unspecified     Unspecified             Unspecified
DT_SPARC_REGISTER       0x70000001      d_val           Optional                Optional
DT_AUXILIARY            0x7ffffffd      d_val           Unspecified             Optional
DT_USED                 0x7ffffffe      d_val           Optional                Optional
DT_FILTER               0x7fffffff      d_val           Unspecified             Optional
DT_HIPROC               0x7fffffff      Unspecified     Unspecified             Unspecified

使用readelf -d,您可以在二进制文件中列出DT条目:

0x0000001d (RUNPATH)                    Library runpath: [lib]

可以看到,0x1d对应于RUNPATH该条目添加了链接器选项-rpath(或-R,如果后面跟着目录)

最新更新