неиспользуемая запись 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).


person Sreenath P V    schedule 19.10.2015    source источник
comment
ходят слухи, что это предупреждение безвредно   -  person Alex Cohn    schedule 29.10.2015
comment
RUNPATH влияет на путь поиска файлов .so. Если нет ошибки, что какой-то .so отсутствует, это предупреждение безвредно.   -  person Chih-Hsuan Yen    schedule 21.03.2016


Ответы (2)


Что такое ошибки "неиспользуемая запись DT"?

Если вы попали на эту страницу, возможно, это связано с тем, что вы скомпилировали или попытались запустить некоторые двоичные файлы в своей системе Android на базе ARM, в результате чего ваш двоичный файл/приложение дает сбой или генерирует множество предупреждений в файле logcat. Обычно что-то вроде этого:

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

В: Что такое "запись DT"?

В двух словах, это описательные элементы массива в файловой структуре файла ELF. В частности, они известны как Dynamic Array Tags и являются обязательными для исполняемых и общих объектов. Однако не все записи необходимы или доступны, в зависимости от процессора и архитектуры ядра.

В нашем случае мы сталкиваемся с «Предупреждением» о том, что один из них «не используется». Это означает, что ваши исполняемые или библиотечные (*.so) файлы были скомпилированы с указанной записью DT, но ваше ядро ​​не поддерживает эту запись по разным причинам. Лучшие примеры можно найти в системах Android на базе ARM, где пути системных библиотек фиксированы, а кросс-компиляторы, используемые для вашей прошивки (ОС/ядро), не используют эти записи. Обычно бинарные файлы работают нормально, но ядро ​​помечает это предупреждение каждый раз, когда вы его используете.

В: Когда это происходит?

Это может произойти, когда:

  • Ваше ядро ​​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;
}

Код (выше), поддерживающий эту версию символа, был зафиксирован 9 апреля 2015 г.. Таким образом, если ваша сборка 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

Этот элемент содержит смещение таблицы строк строки пути поиска в библиотеке поиска с завершающим нулем, обсуждаемой в разделе «Зависимости общих объектов». Смещение является индексом в таблице, записанной в записи DT_STRTAB. DT_RPATH может дать строку, содержащую список каталогов, разделенных двоеточиями (:). Все каталоги LD_LIBRARY_PATH просматриваются после каталогов из DT_RPATH.

В: Как вы решаете эти проблемы?

По сути, есть 3 способа справиться с этим:

  1. быстрый
  2. плохо
  3. уродливый

The Quick (у вас нет источников или вас просто не беспокоит)

Используйте «очиститель ELF», чтобы удалить оскорбительные записи DT из всех ваших двоичных файлов. Это простое и быстрое средство, особенно если у вас нет исходных кодов, чтобы правильно перекомпилировать их для вашей системы. Существует как минимум два чистящих средства, которые вы можете использовать.


Плохое (у вас есть исходники)

Это правильный способ сделать это, потому что вы станете крутым гуру кросс-компилятора ARM в процессе его работы. В основном вам нужно найти и настроить параметры компилятора в используемых файлах Makefile.

Из здесь:

Компоновщик Android (/system/bin/linker) не поддерживает RPATH или RUNPATH, поэтому мы устанавливаем LD_LIBRARY_PATH=$USR/lib и пытаемся избежать создания бесполезных записей rpath с флагами конфигурации --disable-rpath. Другим вариантом, чтобы избежать зависимости от LD_LIBRARY_PATH, является предоставление пользовательского компоновщика — это не делается из-за накладных расходов на поддержку пользовательского компоновщика.


Уродство (Вы просто хотите, чтобы ваше приложение работало с любым грязным двоичным файлом.)

Вы говорите своему Java-приложению, чтобы оно не волновалось при проверке нулевого значения в обработчиках ошибок, и вместо этого получаете эти предупреждения, которые могут вызывать фатальные исключения. Используйте что-то вроде:

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 это станет полноценной ошибкой!


В. Что еще?

Многие изменения в API между 18-25 (от J до N) были внесены в способ компиляции ядра Android и библиотек. Я не могу дать даже близкого объяснения всего этого, но, возможно, это поможет вам в правильном направлении. Лучшие источники, конечно же, искать в исходниках Android и самой документации.

Например, ЗДЕСЬ или ЗДЕСЬ.


И, наконец, полный список:

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
person not2qubit    schedule 27.01.2017
comment
Самый точный и подробный ответ, который я видел здесь. Кстати, # 2 помогите мне, не забудьте добавить путь, выполнив: export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH, это поможет мне запустить собственное приложение. Спасибо! - person Aviram Fireberger; 19.07.2018

С помощью readelf -d вы можете перечислить записи DT в вашем двоичном файле:

 0x0000001d (RUNPATH)                    Library runpath: [lib]

Как видите, 0x1d соответствует RUNPATH. Эта запись добавляется с параметром компоновщика -rpath (или -R, если за ним следует каталог)

person hutorny    schedule 04.01.2016