2015-10-19 12 views
16

Tôi đang sử dụng android NDK- r10d để tạo tệp thực thi Android x86 (liên kết được chia sẻ) chạy trên adb shell. Vào thời gian chạy, tôi nhận được cảnh báo sau đây:mục nhập DT chưa sử dụng: nhập 0x1d arg

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

Tôi đang sử dụng bắt nguồn từ Nexus Player để kiểm tra thực thi.

Và máy xây dựng của tôi là Ubuntu 14.04 (cũng đã thử trên máy Fedora 14).

+0

các [Tin đồn] (http://www.kevinboone.net/kbox3_c.html) là cảnh báo này là vô hại –

+0

RUNPATH ảnh hưởng đến đường dẫn tìm kiếm của các tệp .so. Nếu không có lỗi mà một số .so là mất tích, cảnh báo này là vô hại. –

Trả lời

5

Với readelf -d bạn có thể liệt kê các mục DT trong hệ nhị phân của bạn:

0x0000001d (RUNPATH)     Library runpath: [lib] 

Như bạn có thể thấy, 0x1d tương ứng với RUNPATH entry đó được bổ sung tùy chọn mối liên kết -rpath (hoặc -R, nếu tiếp theo thư mục)

47

Lỗi "mục nhập DT không sử dụng" là gì?

Nếu bạn đã đạt đến trang này, nó có thể là bởi vì bạn có biên soạn hoặc cố gắng để chạy một số nhị phân trên Android hệ thống ARM của bạn dựa, với kết quả là tai nạn nhị phân/ứng dụng của bạn hoặc tạo ra rất nhiều cảnh báo trong logcat của bạn. Thông thường một cái gì đó như thế này:

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

Hỏi: "Mục nhập DT" là gì?

Trong một vài từ, chúng là các mục nhập mô tả trong tệp cấu trúc của tệp ELF. Cụ thể, chúng được gọi là Dynamic Array Tags và là các yêu cầu đối với các đối tượng được chia sẻ và . Tuy nhiên, không phải tất cả các mục được yêu cầu hoặc có sẵn, tùy thuộc vào kiến ​​trúc bộ xử lý và hạt nhân.

Trong trường hợp của chúng tôi, chúng tôi đang phải đối mặt với "Cảnh báo" rằng một trong số đó là "không sử dụng". Điều đó có nghĩa là tệp thực thi hoặc thư viện (*.so) của bạn đã được được biên dịch với mục nhập DT được chỉ ra, nhưng hạt nhân của bạn không hỗ trợ mục nhập đó vì nhiều lý do khác nhau. Các ví dụ tốt nhất được tìm thấy trên ARM dựa trên hệ thống ARM, nơi các đường dẫn thư viện hệ thống được cố định và các trình biên dịch chéo được sử dụng cho chương trình cơ sở của bạn (OS/kernel) được đặt không sử dụng các mục nhập này. Thông thường các tập tin nhị phân vẫn chạy tốt, nhưng hạt nhân đang gắn cờ cảnh báo này mỗi lần bạn sử dụng nó.

Q: Khi nào điều này xảy ra?

Điều này có thể xảy ra khi:

  • hạt nhân ARM của bạn là cross-biên soạn bằng cách sử dụng lá cờ sai (thường dành cho kiến ​​trúc vi xử lý khác).
  • Các tệp nhị phân và thư viện ARM của bạn được biên dịch chéo bằng cách sử dụng các cờ biên dịch không dùng nữa.
  • và có lẽ các cách khác chưa được khám phá ..

Bắt đầu từ 5.1 (API 22) linker Android cảnh báo về VERNEED và VERNEEDNUM ELF phần năng động.

Cờ phổ biến nhất mà gây ra lỗi này trên các thiết bị Android là:

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. 

Theo dõi xuống các lỗi trên, chúng ta thấy rằng thông điệp này xuất phát từ bionic thư viện 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; 
} 

Mã (ở trên) hỗ trợ số này symbol versioning đã được cam kết trên April 9, 2015. Vì vậy, nếu xây dựng NDK của bạn hoặc là được thiết lập để hỗ trợ API sớm hơn này, hoặc sử dụng các công cụ xây dựng liên kết đến thư viện này trước đó, bạn sẽ nhận được những cảnh báo này.


Q: Làm thế nào để tìm thấy những gì DT mục hệ thống của tôi hay nhị phân đang sử dụng?

Có rất nhiều cách để làm điều này:

  1. Bạn trông vào nguồn kernel cho <linux/elf.h>.
  2. Bạn tìm trong thư mục cài đặt Android NDK của bạn và kiểm tra:
# To find all elf.h files: 
find /<path_to>/ndk/platforms/android-*/arch-arm*/usr/include/linux/ -iname "elf.h" 
  1. Do một readelf của nhị phân của bạn:
$ 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 

Như bạn có thể thấy từ lỗi ở trên, số type tương ứng với DT_VERNEED.

Từ THIS tài liệu:

DT_RPATH

yếu tố này giữ bảng chuỗi bù đắp của một null-chấm dứt tìm kiếm thư viện chuỗi đường dẫn tìm kiếm, thảo luận trong "Dependencies Object chia sẻ". Giá trị bù trừ là một chỉ số trong bảng được ghi trong mục nhập DT_STRTAB. DT_RPATH có thể cung cấp một chuỗi chứa danh sách các thư mục, cách nhau theo dấu hai chấm (:). Tất cả thư mục LD_LIBRARY_PATH được tìm kiếm sau thư mục từ DT_RPATH.

Q: Vậy làm thế nào để bạn giải quyết hoặc giải quyết những vấn đề này?

Có cơ bản 3 cách để đối phó với điều này:

  1. sự nhanh chóng
  2. xấu
  3. xấu xí

The Quick (bạn don' t có bất kỳ nguồn nào hoặc không thể bị làm phiền)

Sử dụng "trình dọn dẹp ELF" để xóa các mục nhập DT vi phạm khỏi tất cả các tệp nhị phân của bạn. Đây là một biện pháp khắc phục dễ dàng và nhanh chóng, đặc biệt là khi bạn không có nguồn để biên dịch lại chúng cho hệ thống của bạn. Có ít nhất two cleaners mà bạn có thể sử dụng.


The Bad (bạn có nguồn)

là đúng cách để làm điều đó, bởi vì bạn sẽ trở thành một ARM chéo biên dịch guru xấu-ass trong quá trình nhận được nó để làm việc . Về cơ bản bạn cần phải tìm và điều chỉnh các thiết lập trình biên dịch trong Makefiles được sử dụng.

Từ here:

Các mối liên kết Android (/ system/bin/linker) không hỗ trợ rPath hoặc RUNPATH, vì vậy chúng tôi thiết lập LD_LIBRARY_PATH = $ usr/lib và cố gắng tránh việc xây dựng mục rPath vô dụng với - -disable-rpath định cấu hình cờ. Một tùy chọn khác để tránh tùy thuộc vào LD_LIBRARY_PATH sẽ cung cấp một trình liên kết tùy chỉnh - điều này không được thực hiện do chi phí của việc duy trì một mối liên kết tùy chỉnh.


The Ugly (Bạn chỉ muốn ứng dụng của bạn để làm việc với bất kỳ nhị phân bẩn.)

Bạn nói với ứng dụng Java của bạn không freak ra khi kiểm tra cho null trong xử lý lỗi và thay vào đó nhận được các cảnh báo này, có thể gây ra các ngoại lệ gây tử vong. Sử dụng một cái gì đó như:

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

Điều này rất xấu và xấu khi không giải quyết được gì, trong khi làm đầy mã của bạn. Ngoài ra, các cảnh báo có lý do, và đó là trong các phiên bản AOS trong tương lai, điều này sẽ trở thành một lỗi chính thức!


Q. Còn gì nữa?

Nhiều thay đổi trong API giữa 18-25 (J đến N) đã được thực hiện theo cách cách nhân và thư viện Android được biên soạn. Tôi không thể cung cấp giải thích gần đúng về tất cả điều đó, nhưng có lẽ điều này sẽ giúp hướng dẫn bạn đi đúng hướng. Các nguồn tốt nhất là tất nhiên tìm kiếm trong các nguồn Android và tài liệu chính nó.

Ví dụ: HERE hoặc HERE.


Và cuối cùng đầy đủ danh sách:

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 
+0

Câu trả lời hay, cảm ơn bạn rất nhiều! – crezefire

Các vấn đề liên quan