Làm cách nào để liệt kê các ký hiệu đang đượ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 kéo vào từ thư viện tĩnh).
Tôi đang sử dụng gcc 4.0.2, nếu điều đó tạo ra sự khác biệt.
nm
, không phải GNU nm
.
Làm cách nào để liệt kê các ký hiệu đang đượ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 kéo vào từ thư viện tĩnh).
Tôi đang sử dụng gcc 4.0.2, nếu điều đó tạo ra sự khác biệt.
nm
, không phải GNU nm
.
Câu trả lời:
Công cụ tiêu chuẩn để liệt kê các biểu tượng là nm
, bạn có thể sử dụng nó đơn giản như thế này:
nm -gD yourLib.so
Nếu bạn muốn xem các ký hiệu của thư viện C ++, hãy thêm tùy chọn "-C" để giải mã các ký hiệu (nó dễ đọc hơn rất nhiều).
nm -gDC yourLib.so
Nếu tệp .so của bạn ở định dạng elf, bạn có hai tùy chọn:
Hoặc objdump
( -C
cũng hữu ích cho việc gỡ rối 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 free@GLIBC_2.2.5 (14)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5 (14)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
readelf -Ws
sẽ hiển thị cho bạn tất cả các biểu tượng và nm -g
chỉ hiển thị các biểu tượng hiển thị bên ngoài. Điều này có thể gây nhầm lẫn nếu bạn đang kiểm tra nhiều tệp biểu tượng và bắt đầu trao đổi các lệnh của bạn.
objectdump -TC
vào danh sách. Ngược lại readelf -Ws
, nó không hiển thị tên xéo.
.so
các tệp bạn có thể cần thêm --dynamic
vào nm
dòng lệnh.
Nếu .so
tệp của bạn ở định dạng elf, bạn có thể sử dụng chương trình readelf để trích xuất thông tin ký hiệu 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 xuất những cái được định nghĩa trong .so
tệp này , không phải trong các thư viện được tham chiếu bởi nó. Cột thứ bảy nên 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 regex đơn giản:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
hoặc, theo đề xuất của Caspin ,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
Tôi liên tục tự hỏi tại sao -fvisibility = ẩn và tầm nhìn #pragma GCC đã dường như không có bất kỳ ảnh hưởng, như tất cả những biểu tượng luôn có thể nhìn thấy với nm - cho đến khi tôi tìm thấy bài này mà chỉ tôi readelf và objdump , mà làm cho tôi nhận ra rằng có dường như thực sự là hai bảng biểu tượng:
Tôi nghĩ rằng trước đây có chứa các biểu tượng gỡ lỗi có thể được tước bằng dải hoặc 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 của bạn vẫn được xuất vì chúng nằm trong "bảng biểu tượng động" ELF, là biểu tượng sau.
Đối với .so
các tệp C ++ , nm
lệnh cuối cùng 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)
Đối với Android .so
file, chuỗi công cụ NDK đi kèm với các công cụ cần thiết được đề cập trong câu trả lời khác: readelf
, objdump
và nm
.
Bạn có thể sử dụng nm -g
công cụ từ chuỗi công cụ binutils. Tuy nhiên, nguồn của họ không phải lúc nào cũng có sẵn. và tôi thực sự thậm chí không chắc chắn rằng thông tin này luôn có thể được lấy. 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 khẩu.
Nếu bạn chỉ muốn biết nếu có là biểu tượng trình bày , bạn có thể sử dụng
objdump -h /path/to/object
hoặc để liệt kê thông tin gỡ lỗi
objdump -g /path/to/object
nm
không đáp ứng với một số tùy chọn, như-D
và-g
(IIRC).