webdevqa.jp.net

未使用のDTエントリ:タイプ0x1d arg

Android NDK-r10dを使用してビルドしますAndroid x86実行可能(共有リンク)adbシェルで実行されます。実行時に、次の警告が表示されます。

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

ルート化された Nexus Player を使用して実行可能ファイルをテストしています。

私のビルドマシンはUbuntu 14.04です(Fedora 14マシンでも試しました)。

28
Sreenath P V

「未使用の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:これはいつ発生しますか?

これは次の場合に発生する可能性があります。

  • 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ライブラリに由来することがわかります 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エントリを見つけるにはどうすればよいですか?

これを行うには多くの方法があります。

  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

上記のエラーからわかるように、typeDT_VERNEEDに対応しています。

[〜#〜] this [〜#〜] document:

DT_RPATH

この要素は、「共有オブジェクトの依存関係」で説明されているヌル終了検索ライブラリ検索パス文字列の文字列テーブルオフセットを保持します。オフセットは、DT_STRTABエントリに記録されたテーブルへのインデックスです。 DT_RPATHは、コロン(:)で区切られたディレクトリのリストを保持する文字列を提供する場合があります。すべてのLD_LIBRARY_PATHディレクトリは、DT_RPATHからのディレクトリの後に検索されます。

Q:これらの問題をどのように解決または対処しますか?

これに対処するには、基本的に3つの方法があります。

  1. クイック
  2. 悪い人
  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
72
not2qubit

Readelf -dを使用すると、バイナリのDTエントリをリストできます。

 0x0000001d (RUNPATH)                    Library runpath: [lib]

ご覧のとおり、0x1dはRUNPATHに対応します。このエントリは、リンカーオプション-rpath(またはディレクトリが続く場合は-R)で追加されます。

7
hutorny