Android NDK-r10dを使用してビルドしますAndroid x86実行可能(共有リンク)adbシェルで実行されます。実行時に、次の警告が表示されます。
WARNING: linker: ./myapp: **unused DT entry:** type 0x1d arg 0x4a604
ルート化された Nexus Player を使用して実行可能ファイルをテストしています。
私のビルドマシンはUbuntu 14.04です(Fedora 14マシンでも試しました)。
「未使用のDTエントリ」エラーとは何ですか?
このページに到達した場合、おそらく、ARM based Androidシステムでバイナリを実行した結果、コンパイルまたは実行しようとしたためです。/appがクラッシュするか、logcat
で多くの警告が生成されます。通常、次のようなものです。
WARNING: linker: /blahblah/libopenssl.so: unused DT entry: type 0x6ffffffe arg 0x1188
Q:「DTエントリ」とは何ですか?
簡単に言うと、これらは [〜#〜] elf [〜#〜] ファイルのファイル構造内の記述配列エントリです。具体的には、Dynamic Array Tags
として知られ、実行可能オブジェクトおよび共有オブジェクトの要件です。ただし、プロセッサとカーネルのアーキテクチャに応じて、すべてのエントリが必須または使用可能というわけではありません。
私たちの場合、これらの1つが「未使用」であるという「警告」に直面しています。つまり、実行可能ファイルまたはライブラリ(*.so
)ファイルは[〜#〜] dt [〜#〜]エントリを指定してコンパイルされていますが、カーネルはさまざまな理由でそのエントリをサポートしていません。最良の例はARM based Androidシステムであり、システムライブラリパスは修正され、ファームウェア(OS /カーネル)に使用されるクロスコンパイラは通常、バイナリは正常に実行されますが、カーネルは使用するたびにこの警告にフラグを立てています。
Q:これはいつ発生しますか?
これは次の場合に発生する可能性があります。
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
ライブラリに由来することがわかります linker.cpp :
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;
}
これをサポートするコード(上記)は、 symbol versioning でコミットされました April 9、2015 。したがって、NDKビルドがこれより前のAPIをサポートするように設定されている場合、またはこの以前のライブラリにリンクしているビルドツールを使用している場合、これらの警告が表示されます。
Q:システムまたはバイナリが使用しているDTエントリを見つけるにはどうすればよいですか?
これを行うには多くの方法があります。
<linux/elf.h>
のカーネルソースを調べます。# To find all elf.h files:
find /<path_to>/ndk/platforms/Android-*/Arch-arm*/usr/include/linux/ -iname "elf.h"
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
に対応しています。
[〜#〜] this [〜#〜] document:
DT_RPATH
この要素は、「共有オブジェクトの依存関係」で説明されているヌル終了検索ライブラリ検索パス文字列の文字列テーブルオフセットを保持します。オフセットは、DT_STRTABエントリに記録されたテーブルへのインデックスです。 DT_RPATHは、コロン(:)で区切られたディレクトリのリストを保持する文字列を提供する場合があります。すべてのLD_LIBRARY_PATHディレクトリは、DT_RPATHからのディレクトリの後に検索されます。
Q:これらの問題をどのように解決または対処しますか?
これに対処するには、基本的に3つの方法があります。
クイック(ソースがないか、気にすることはできません)
「ELFクリーナー」を使用して、問題のあるDTエントリをすべてのバイナリから削除します。これは、特にシステムに合わせて適切に再コンパイルするためのソースがない場合に、簡単で迅速な解決策です。少なくとも 2つのクリーナー を使用できます。
悪い(ソースがあります)
あなたはそれを行う正しいプロセスです。あなたはそれを動作させる過程で悪いお尻ARMクロスコンパイラの第一人者になるでしょう。あなたは基本的にコンパイラ設定を見つけて調整する必要があります使用されるMakefile。
ここ から:
Androidリンカー(/ system/bin/linker)はRPATHまたはRUNPATHをサポートしないため、LD_LIBRARY_PATH = $ USR/libを設定し、-disable-rpathを使用して不要なrpathエントリを作成しないようにします。フラグを構成します。LD_LIBRARY_PATHに依存することを回避する別のオプションは、カスタムリンカーを提供することです-これは、カスタムリンカーを維持するオーバーヘッドのために行われません。
The Ugly(ダーティバイナリでアプリを動作させたいだけです。)
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 to 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)で追加されます。