android-ndk shared-libraries android-x86 linker-warning

android ndk - entrada de DT no utilizada: escriba 0x1d arg



android-ndk shared-libraries (2)

Estoy usando NDK- r10d de Android para compilar el ejecutable x86 de Android (enlace compartido) que se ejecuta en el shell adb. En el tiempo de ejecución, recibo la siguiente advertencia:

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

Estoy usando un Nexus Player rooteado para probar el ejecutable.

Y mi máquina de compilación es Ubuntu 14.04 (también probada en la máquina Fedora 14).


Con readelf -d puede listar las entradas de DT en su binario:

0x0000001d (RUNPATH) Library runpath: [lib]

Como puede ver, 0x1d corresponde a RUNPATH. Esa entrada se agrega con la opción de vinculador -rpath (o -R, si es seguido por el directorio)


¿Qué son los errores de "entrada DT no utilizada"?

Si ha llegado a esta página, probablemente se deba a que compiló o intentó ejecutar algunos binarios en su sistema Android basado en ARM, con el resultado de que su aplicación / binario falla o genera muchas advertencias en su logcat . Típicamente algo como esto:

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

P: ¿Qué es una "entrada DT"?

En pocas palabras, son entradas de matrices descriptivas en la estructura de archivos de un archivo ELF . Específicamente, se conocen como Dynamic Array Tags y son requisitos para objetos ejecutables y compartidos. Sin embargo, no todas las entradas son necesarias o están disponibles, dependiendo de la arquitectura del procesador y del núcleo.

En nuestro caso, nos enfrentamos a una "Advertencia" de que uno de estos está "sin usar". Lo que eso significa es que sus archivos ejecutables o de biblioteca ( *.so ) se han compilado con la entrada de DT indicada, pero su kernel no admite esa entrada, por varias razones. Los mejores ejemplos se encuentran en sistemas Android basados ​​en ARM, donde las rutas de la biblioteca del sistema son fijas y los compiladores cruzados utilizados para su firmware (SO / kernel) están configurados para no usar estas entradas. Por lo general, los binarios todavía funcionan bien, pero el kernel marca esta advertencia cada vez que lo estás utilizando.

P: ¿Cuándo sucede esto?

Esto puede suceder cuando:

  • Su kernel ARM se compila de forma cruzada utilizando los indicadores incorrectos (generalmente destinados a otras arquitecturas de procesador).
  • Los binarios y las bibliotecas de ARM se compilan de forma cruzada utilizando banderas de compilación en desuso de AOS.
  • y probablemente otras formas aún por descubrir.

A partir de 5.1 (API 22), el enlazador de Android advierte sobre las secciones dinámicas VERNEED y VERNEEDNUM ELF.

Las marcas más comunes que causan este error en los dispositivos Android son:

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.

Al rastrear el error anterior, encontramos que este mensaje proviene de la biblioteca 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; }

El código (arriba) que respalda la versión de este símbolo fue confirmado el 9 de abril de 2015 Por lo tanto, si su compilación NDK está configurada para admitir API''s anteriores a esto, o si utiliza herramientas de compilación que se vinculan con esta biblioteca anterior, recibirá estas advertencias.

P: ¿Cómo encuentro qué entradas de DT están utilizando mi sistema o los binarios?

Hay muchas maneras de hacer esto:

  1. Usted busca en las fuentes de su núcleo para <linux/elf.h> .
  2. Miras en tus carpetas de instalación de Android NDK y verificas:

# To find all elf.h files: find /<path_to>/ndk/platforms/android-*/arch-arm*/usr/include/linux/ -iname "elf.h"

  1. Haga una readelf de su binario:

$ 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

Como puede ver en el error anterior, el type corresponde a DT_VERNEED .

De THIS documento:

DT_RPATH

Este elemento contiene el desplazamiento de la tabla de cadenas de una cadena de ruta de búsqueda de la biblioteca de búsqueda terminada en nulo, que se describe en "Dependencias de objetos compartidos". El desplazamiento es un índice en la tabla registrada en la entrada DT_STRTAB. DT_RPATH puede dar una cadena que contiene una lista de directorios, separados por dos puntos (:). Todos los directorios LD_LIBRARY_PATH se buscan después de los de DT_RPATH.

P: Entonces, ¿cómo resuelves o tratas estos problemas?

Hay esencialmente 3 formas de lidiar con esto:

  1. el rapido
  2. el malo
  3. el feo

The Quick (no tiene ninguna fuente o simplemente no puede ser molestado)

Utilice un "limpiador ELF" para eliminar las entradas de DT ofensivas de todos sus archivos binarios. Este es un remedio fácil y rápido, especialmente cuando no tiene las fuentes para recompilarlas correctamente para su sistema. Hay al menos dos limpiadores por ahí que puedes usar.

Lo malo (tienes las fuentes)

Es la forma correcta de hacerlo, porque te convertirás en un gurú de compiladores cruzados ARM malintencionados en el proceso de hacer que funcione. Básicamente necesita encontrar y ajustar la configuración del compilador en los Makefiles utilizados.

Desde here

El enlazador de Android (/ system / bin / linker) no es compatible con RPATH o RUNPATH, por lo que establecemos LD_LIBRARY_PATH = $ USR / lib e intentamos evitar la creación de entradas de rpath inútiles con --disable-rpath configure flags. Otra opción para evitar depender de LD_LIBRARY_PATH sería suministrar un enlazador personalizado, esto no se hace debido a la sobrecarga de mantener un enlazador personalizado.

Lo feo (solo quieres que tu aplicación funcione con cualquier binario sucio).

Usted le dice a su aplicación Java que no se asuste al buscar nulos en los controladores de errores y en su lugar se alimenta de estas advertencias, lo que posiblemente cause excepciones fatales. Use algo como:

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

Esto es muy malo y feo, ya que no resuelve nada, mientras que hincha su código. Además, las advertencias están ahí por una razón, y es que en futuras versiones de AOS, ¡esto se convertirá en un error de pleno derecho!

P. ¿Qué más?

Se han realizado muchos cambios en las API entre 18 y 25 (de J a N) en la forma en que se compilan el kernel y las bibliotecas de Android. No puedo proporcionar una explicación remota de todo eso, pero quizás esto ayude a guiarlo en la dirección correcta. Por supuesto, las mejores fuentes son las fuentes y la documentación de Android.

Por ejemplo, HERE o HERE .

Y finalmente la lista completa:

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