web-dev-qa-db-fra.com

entrée DT inutilisée: tapez 0x1d arg

J'utilise Android NDK - r10d pour construire Android x86 exécutable (partagé) liaison) qui s'exécute sur adb Shell. Au moment de l'exécution, je reçois l'avertissement suivant:

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

J'utilise un rooté Nexus Player pour tester l'exécutable.

Et ma machine de construction est Ubuntu 14.04 (également essayée sur la machine Fedora 14).

28
Sreenath P V

Que sont les erreurs "entrée DT inutilisée"?

Si vous avez atteint cette page, c'est probablement parce que vous avez compilé ou tenté d'exécuter des binaires sur votre système ARM Android, avec pour résultat que votre binaire/application se bloque ou génère beaucoup d'avertissements dans votre logcat. Généralement, quelque chose comme ça:

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

Q: Qu'est-ce qu'une "entrée DT"?

En quelques mots, ce sont des entrées de tableau descriptif dans la structure de fichier d'un fichier ELF . Plus précisément, ils sont appelés Dynamic Array Tags et sont des exigences pour les objets exécutables et partagés. Cependant, toutes les entrées ne sont pas requises ou disponibles, selon l'architecture du processeur et du noyau.

Dans notre cas, nous sommes confrontés à un "avertissement" indiquant que l'un d'entre eux est "inutilisé". Cela signifie que votre fichier exécutable ou bibliothèque (*.so) A été compilé avec le [~ # ~] dt [~ # ~] entrée indiquée, mais votre noyau ne prend pas en charge cette entrée, pour diverses raisons. Les meilleurs exemples se trouvent sur les systèmes ARM Android, où les chemins de bibliothèque système sont fixes et les compilateurs croisés utilisés pour votre micrologiciel (OS/noyau) sont configurés pour ne pas utiliser ces entrées. Habituellement, les binaires fonctionnent toujours très bien, mais le noyau signale cet avertissement chaque fois que vous l'utilisez.

Q: Quand cela se produit-il?

Cela peut se produire lorsque:

  • Votre noyau ARM est compilé de manière croisée en utilisant les mauvais indicateurs (généralement destinés aux autres architectures de processeur).
  • Vos binaires et bibliothèques ARM sont compilés de manière croisée à l'aide d'indicateurs de compilation obsolètes AOS.
  • et probablement d'autres voies à découvrir ..

À partir de 5.1 (API 22), l'éditeur de liens Android met en garde contre les sections dynamiques VERNEED et VERNEEDNUM ELF.

Les indicateurs les plus courants qui provoquent cette erreur sur les appareils Android sont:

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.

En recherchant l'erreur ci-dessus, nous constatons que ce message provient de la bibliothèque bioniclinker.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;
}

Le code (ci-dessus) supportant cette version des symboles a été validé le 9 avril 2015 . Ainsi, si votre build NDK est configuré pour prendre en charge les API plus tôt que cela, ou en utilisant des outils de build liés à cette bibliothèque antérieure, vous obtiendrez ces avertissements.


Q: Comment trouver les entrées DT que mon système ou mes binaires utilisent?

Il existe plusieurs façons de procéder:

  1. Vous recherchez dans vos sources de noyau pour <linux/elf.h>.
  2. Vous regardez dans vos dossiers d'installation de Android NDK et vérifiez:
# To find all elf.h files:
find /<path_to>/ndk/platforms/Android-*/Arch-arm*/usr/include/linux/ -iname "elf.h"
  1. Faites un readelf de votre binaire:
$ 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

Comme vous pouvez le voir d'après l'erreur ci-dessus, le type correspond à DT_VERNEED.

De CE document:

DT_RPATH

Cet élément contient l'offset de la table de chaînes d'une chaîne de chemin de recherche de bibliothèque de recherche terminée par null, décrite dans "Dépendances d'objets partagés". Le décalage est un index dans la table enregistrée dans l'entrée DT_STRTAB. DT_RPATH peut donner une chaîne contenant une liste de répertoires, séparés par des deux-points (:). Tous les répertoires LD_LIBRARY_PATH sont recherchés après ceux de DT_RPATH.

Q: Alors, comment résolvez-vous ou traitez-vous ces problèmes?

Il y a essentiellement 3 façons de gérer cela:

  1. le rapide
  2. le mauvais
  3. le moche

Le Quick (vous n'avez aucune source ou ne pouvez pas être dérangé)

Utilisez un "nettoyeur ELF" pour supprimer les entrées DT incriminées de tous vos fichiers binaires. C'est un remède facile et rapide, surtout lorsque vous n'avez pas les sources pour les recompiler correctement pour votre système. Il y a au moins deux nettoyeurs là-bas que vous pouvez utiliser.


Le mauvais (vous avez les sources)

C'est la bonne façon de le faire, car vous deviendrez un gourou du compilateur croisé ARM méchant en train de le faire fonctionner. Vous devez essentiellement trouver et régler les paramètres du compilateur dans les Makefiles utilisés.

De ici :

L'éditeur de liens Android (/ system/bin/linker) ne prend pas en charge RPATH ou RUNPATH, nous définissons donc LD_LIBRARY_PATH = $ USR/lib et essayons d'éviter de créer des entrées rpath inutiles avec les drapeaux de configuration --disable-rpath. Une autre option à éviter en fonction de LD_LIBRARY_PATH serait de fournir un éditeur de liens personnalisé - cela ne se fait pas en raison de la surcharge de maintenance d'un éditeur de liens personnalisé.


The Ugly (Vous voulez juste que votre application fonctionne avec n'importe quel binaire sale.)

Vous dites à votre application Java de ne pas paniquer lors de la vérification de null dans les gestionnaires d'erreurs et d'obtenir à la place ces avertissements, pouvant entraîner des exceptions fatales. Utilisez quelque chose comme:

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!")
        }
    }
}

C'est très mauvais et laid car cela ne résout rien, tout en gonflant votre code. De plus, les avertissements sont là pour une raison, et c'est que dans les futures versions d'AOS, cela deviendra une erreur à part entière!


Q. Quoi d'autre?

De nombreuses modifications dans les API entre 18 et 25 (J à N) ont été apportées à la façon dont le noyau Android et les bibliothèques sont compilés. Je ne peux pas fournir une explication à distance de tout cela, mais peut-être que cela vous guidera dans la bonne direction. La meilleure source est bien sûr de chercher dans les sources Android et la documentation elle-même.

Par exemple, ICI ou ICI .


Et enfin la liste complète:

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

Avec readelf -d, vous pouvez lister les entrées DT dans votre binaire:

 0x0000001d (RUNPATH)                    Library runpath: [lib]

Comme vous pouvez le voir, 0x1d correspond à RUNPATH Cette entrée est ajoutée avec l'option de l'éditeur de liens -rpath (ou -R, si suivie par le répertoire)

7
hutorny