2008-08-29 29 views
344

Làm cách nào để liệt kê các biểu tượng được xuất từ ​​tệp .so. Nếu có thể, tôi cũng muốn biết nguồn của họ (ví dụ: nếu chúng được lấy từ một thư viện tĩnh).Làm cách nào để liệt kê các biểu tượng trong một tệp .so

Tôi đang sử dụng gcc 4.0.2, nếu mà làm cho một sự khác biệt

+0

Nền tảng làm nên sự khác biệt. Apple cung cấp một GCC 4.0, nhưng 'nm' của nó không đáp ứng với một số tùy chọn, như' -D' và '-g' (IIRC). – jww

+0

Điều này sẽ không in được gì trên Mac OS. –

+3

@jww vì đó là BSD 'nm', chứ không phải GNU' nm'. – OrangeDog

Trả lời

419

Các công cụ tiêu chuẩn cho các ký hiệu niêm yết là nm, bạn có thể sử dụng nó chỉ đơn giản như thế này:

nm -g yourLib.so 

Nếu bạn muốn xem biểu tượng của C++ thư viện, thêm tùy chọn "C" mà demangle những biểu tượng (nó dễ bị đọc nhiều hơn).

nm -gC yourLib.so 

Nếu tập tin .so của bạn là ở định dạng tinh, bạn có hai lựa chọn:

Hoặc objdump (-C cũng hữu ích cho demangling C++):

$ objdump -TC libz.so 

libz.so:  file format elf64-x86-64 

DYNAMIC SYMBOL TABLE: 
0000000000002010 l d .init 0000000000000000    .init 
0000000000000000  DF *UND* 0000000000000000 GLIBC_2.2.5 free 
0000000000000000  DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location 
0000000000000000 w D *UND* 0000000000000000    _ITM_deregisterTMCloneTable 

Hoặc sử dụng readelf:

$ readelf -Ws libz.so 
Symbol table '.dynsym' contains 112 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000002010  0 SECTION LOCAL DEFAULT 10 
    2: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (14) 
    3: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (14) 
    4: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
+23

Điều này không phải lúc nào cũng hoạt động với các tệp .so, do đó bạn có thể phải sử dụng giải pháp "đọc" được đề cập trong câu trả lời khác. –

+0

Câu trả lời tuyệt vời - nhưng tôi không nhận được các chữ ký chức năng từ nm, objdump hoặc readelf. Bạn có biết làm thế nào tôi có thể nhận được chữ ký chức năng (tham số) không? –

+7

Lưu ý rằng các phiên bản OS X của nm thiếu tùy chọn '-C' cho các biểu tượng demangling. C++ filt có thể được sử dụng thay thế. Ví dụ tập lệnh tại đây: http://v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | C++ filt -p -i – fredbaba

9

Bạn có thể sử dụng công cụ nm -g từ binutils toolchain. Tuy nhiên, nguồn của họ không phải lúc nào cũng sẵn có. và tôi thậm chí không chắc chắn rằng thông tin này luôn có thể được truy xuất. Có lẽ objcopy tiết lộ thêm thông tin.

/EDIT: Tên của công cụ là tất nhiên nm. Cờ -g được sử dụng để chỉ hiển thị các biểu tượng đã xuất.

11

Thử thêm -l vào cờ nm để g et nguồn của mỗi biểu tượng. Nếu thư viện được biên dịch với thông tin gỡ lỗi (gcc -g) thì đây phải là tệp nguồn và số dòng. Như Konrad cho biết, các tập tin đối tượng/thư viện tĩnh có lẽ không rõ tại thời điểm này.

+0

'nm: Đối số dòng lệnh không xác định '-l'' –

64

Nếu tệp .so của bạn ở định dạng elf, bạn có thể sử dụng chương trình đọc để trích xuất thông tin biểu tượng từ tệp nhị phân. Lệnh này sẽ cung cấp cho bạn bảng biểu tượng:

readelf -Ws /usr/lib/libexample.so 

Bạn chỉ nên trích những người được quy định tại .so tập tin này, không phải trong thư viện tham chiếu bởi nó. Cột thứ bảy phải chứa một số trong trường hợp này.Bạn có thể giải nén nó bằng cách sử dụng một regex đơn giản:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+' 

hoặc theo đề nghị của Caspin,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}'; 
+14

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; regexes là tuyệt vời nhưng đôi khi một chút awk đi một chặng đường dài. –

39
objdump -TC /usr/lib/libexample.so 
+3

Tốt nhất. Cung cấp các tên bị phân loại chứng tỏ hữu ích – deepdive

28

tôi cứ tự hỏi tại sao -fvisibility = ẩn#pragma GCC khả năng hiển thị dường như không có bất kỳ ảnh hưởng nào vì tất cả các biểu tượng luôn hiển thị với nm - cho đến khi tôi tìm thấy bài đăng này đã chỉ cho tôi readelfobjdump, mà làm cho tôi nhận ra rằng có vẻ như thực sự có hai bảng biểu tượng:

  • Một bạn có thể liệt với nm
  • Một bạn có thể liệt với readelfobjdump

Tôi nghĩ rằng trước đây chứa debuggi Các biểu tượng có thể bị tước bằng dải hoặc nút chuyển đổi -s mà bạn có thể cung cấp cho trình liên kết hoặc lệnh cài đặt. Và ngay cả khi nm không liệt kê bất cứ điều gì nữa, các biểu tượng xuất khẩu của bạn vẫn được xuất khẩu bởi vì chúng nằm trong bảng "biểu tượng động" ELF, cái sau.

+2

Cảm ơn bạn! Điều này giải thích tại sao đôi khi "nm" không hiển thị bất kỳ biểu tượng nào cho các tệp .so. –

+5

nm -D - cho phép bạn liệt kê bảng ký hiệu động – pt123

5

nm -g liệt kê biến ngoài, không phải biểu tượng được xuất cần thiết. Bất kỳ biến phạm vi tệp không tĩnh nào (trong C) đều là biến ngoại lệ.

nm -D sẽ liệt kê biểu tượng trong bảng động mà bạn có thể tìm thấy địa chỉ đó bằng dlsym.

nm --version

GNU nm 2.17.50.0.6-12.el5 20061020

30

Đối với các thư viện chia sẻ libNAME.so switch -D là cần thiết để xem các biểu tượng trong Linux tôi

nm -D libNAME.so 

và cho thư viện tĩnh theo báo cáo của người khác

nm -g libNAME.a 
7

đối với Android .so tệp, chuỗi công cụ NDK đi kèm với các công cụ được yêu cầu được đề cập trong các câu trả lời khác: readelf, objdumpnm.

3

Đối với C++ .so file, cuối cùng nm lệnh là nm --demangle --dynamic --defined-only --extern-only <my.so>

# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add 
0000000000049500 T proton::work_queue::add(proton::internal::v03::work) 
0000000000049580 T proton::work_queue::add(proton::void_function0&) 
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work) 
000000000002b1f0 T proton::container::impl::add_work_queue() 
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work) 
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work) 

nguồn: https://stackoverflow.com/a/43257338

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