Perintah nm memberikan informasi tentang simbol yang digunakan dalam file objek atau file yang dapat dieksekusi.
Informasi default yang diberikan oleh perintah 'nm' adalah :
- Alamat virtual simbol
- Karakter yang menggambarkan tipe simbol. Jika karakter dalam huruf kecil maka simbol lokal tetapi jika karakter dalam huruf besar maka simbol eksternal
- Nama simbol
Karakter yang mengidentifikasi tipe simbol menggambarkan :
- A : Simbol absolut global.
- a : Simbol absolut lokal.
- B :Simbol bss global.
- b :Simbol bss lokal.
- D :Simbol data global.
- d :Simbol data lokal.
- f :Simbol nama file sumber.
- L :Simbol utas-lokal global (TLS).
- l :Simbol lokal utas statis (TLS).
- B :Simbol teks global.
- t :Simbol teks lokal.
- U :Simbol tidak terdefinisi.
Perhatikan bahwa daftar ini tidak lengkap tetapi berisi beberapa jenis simbol penting. Untuk informasi lengkap, silakan merujuk ke halaman manual utilitas ini.
Cara default untuk menggunakan utilitas 'nm' adalah:
$ nm <object file or executable name>
jika tidak ada nama yang dapat dieksekusi yang diberikan maka nm menganggap nama tersebut sebagai 'a.out'.
Dengan ide dasar tentang utilitas ini, orang mungkin mempertanyakan mengapa informasi ini diperlukan?
Nah, anggaplah Anda memiliki executable yang terbuat dari banyak file objek yang berbeda . Sekarang asumsikan bahwa saat mengkompilasi kode, tautan memberikan kesalahan tentang simbol 'temp' yang belum terselesaikan. Sekarang akan menjadi mimpi buruk untuk menemukan di mana simbol 'temp' berada dalam kode jika kodenya terlalu besar dan menyertakan banyak header. Di sinilah utilitas ini datang untuk menyelamatkan. Dengan beberapa opsi tambahan, utilitas ini juga memberikan file tempat simbol ditemukan.
Sejak sekarang kami memiliki ide dasar tentang utilitas nm. Mari kita pahami penggunaan utilitas ini melalui beberapa perintah praktis.
1. Tampilkan File Objek yang Mengacu pada Simbol
Perintah berikut menampilkan semua file objek yang mengacu pada simbol 'func' di direktori saya saat ini
$ nm -A ./*.o | grep func ./hello2.o:0000000000000000 T func_1 ./hello3.o:0000000000000000 T func_2 ./hello4.o:0000000000000000 T func_3 ./main.o: U func ./reloc.o: U func ./reloc.o:0000000000000000 T func1 ./test1.o:0000000000000000 T func ./test.o: U func
Perhatikan bahwa flag -A digunakan untuk menampilkan nama file bersama dengan informasi lainnya. Jadi kita melihat bahwa dalam output kita mendapatkan semua file objek di mana simbol 'func' digunakan. Ini bisa sangat berguna jika kita ingin mengetahui bagaimana file objek mana yang menggunakan simbol tertentu.
2. Tampilkan semua Simbol Tidak Terdefinisi dalam Eksekusi
Perintah berikut mencantumkan semua simbol yang tidak ditentukan dalam file yang dapat dieksekusi '1'
$ nm -u 1 w _Jv_RegisterClasses w __gmon_start__ U __libc_start_main@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U printf@@GLIBC_2.2.5
Perhatikan bahwa bendera '-u' digunakan dalam kasus ini untuk mendaftar hanya simbol yang tidak ditentukan. Ini bisa sangat berguna dalam kasus di mana seseorang mungkin ingin tahu tentang simbol tidak terdefinisi yang digunakan dalam kode yang dapat benar-benar tidak terselesaikan atau dapat diselesaikan pada waktu berjalan melalui pustaka bersama.
Pada topik terkait, Anda juga harus memahami cara kerja proses penautan GCC.
3. Tampilkan semua Simbol dalam Eksekusi
Perintah berikut mencantumkan semua simbol dalam 'namepid' yang dapat dieksekusi tetapi dalam urutan alamat yang diurutkan
$ nm -n namepid w _Jv_RegisterClasses w __gmon_start__ U __libc_start_main@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fclose@@GLIBC_2.2.5 U fgets@@GLIBC_2.2.5 U fopen@@GLIBC_2.2.5 U fork@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U printf@@GLIBC_2.2.5 U puts@@GLIBC_2.2.5 U signal@@GLIBC_2.2.5 U sleep@@GLIBC_2.2.5 U strchr@@GLIBC_2.2.5 U strlen@@GLIBC_2.2.5 U strncat@@GLIBC_2.2.5 U strncpy@@GLIBC_2.2.5 U system@@GLIBC_2.2.5 0000000000400778 T _init 00000000004008a0 T _start 00000000004008cc t call_gmon_start 00000000004008f0 t __do_global_dtors_aux ... ... ...
Kita melihat bahwa dengan menggunakan flag ‘-n’, output yang keluar diurutkan dengan simbol-simbol yang tidak terdefinisi terlebih dahulu dan kemudian sesuai dengan alamatnya. Penyortiran dapat mempermudah hidup pengembang yang sedang men-debug masalah.
4. Cari Simbol dan Tampilkan Ukurannya
Perintah berikut mencari simbol 'abc' dan juga menampilkan ukurannya
$ nm -S 1 | grep abc 0000000000601040 0000000000000004 B abc
Jadi kita melihat bahwa flag -S menampilkan informasi tambahan tentang ukuran simbol 'abc'
5. Menampilkan Simbol Dinamis dalam Eksekusi
Perintah berikut ditampilkan pada simbol dinamis di '1' yang dapat dieksekusi.
$ nm -D 1 w __gmon_start__ U __libc_start_main U free U malloc U printf
Ini bisa sangat berguna dalam kasus di mana seseorang tertarik untuk mengetahui tentang simbol yang hanya dapat diselesaikan oleh perpustakaan bersama pada saat dijalankan.
6. Ekstrak Simbol Berbagai Jenis
Fitur lain yang kuat dari perintah nm adalah untuk dapat mengekstrak simbol dari berbagai jenis format file objek. Biasanya di Linux kami memiliki objek format 'a.out' atau ELF atau kode yang dapat dieksekusi tetapi jika objek atau kode yang dapat dieksekusi memiliki format lain, maka nm juga menyediakan tanda '–target' untuknya.
7. Ubah Format Output nm
Secara default format output yang ditampilkan oleh nm adalah tipe bsd. Kita dapat mengubah format menggunakan flag -f. Perintah berikut menampilkan output dari perintah nm dalam gaya posix.
$ nm -u -f posix 1 _Jv_RegisterClasses w __gmon_start__ w __libc_start_main@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U printf@@GLIBC_2.2.5 U
Demikian pula kita dapat menggunakan '-f sysv' jika kita ingin output dalam gaya systemV.
8. Tampilkan Hanya Simbol Eksternal dari yang Dapat Dieksekusi
Perintah berikut hanya mencantumkan simbol eksternal dalam executable
$ nm -g 1 0000000000400728 R _IO_stdin_used w _Jv_RegisterClasses 0000000000600e30 D __DTOR_END__ 0000000000601030 A __bss_start 0000000000601020 D __data_start 0000000000601028 D __dso_handle w __gmon_start__ 0000000000400640 T __libc_csu_fini 0000000000400650 T __libc_csu_init ...
Harap dicatat bahwa penggunaan flag -g memungkinkan keluaran hanya simbol eksternal. Ini bisa berguna saat secara khusus men-debug simbol eksternal.
9. Urutkan Output nm dengan Ukuran Simbol
Perintah berikut mengurutkan output berdasarkan ukuran simbol
$ nm -g --size-sort 1 0000000000000002 T __libc_csu_fini 0000000000000004 R _IO_stdin_used 0000000000000004 B abc 0000000000000084 T main 0000000000000089 T __libc_csu_init
Perhatikan bahwa flag –size-sort mengurutkan output berdasarkan ukuran. Seperti yang sudah dijelaskan -g hanya digunakan untuk menampilkan simbol eksternal.
10. Tentukan Opsi nm dalam File
Fitur berharga lainnya dari nm adalah ia dapat mengambil input baris perintahnya dari sebuah file. Anda dapat menentukan semua opsi dalam file dan menentukan nama file ke perintah nm dan itu akan melakukan sisanya untuk Anda. Misalnya, dalam perintah berikut, utilitas nm membaca input baris perintah dari file 'nm_file' dan menghasilkan output
Harap perhatikan bahwa simbol '@' diperlukan jika Anda memberikan nama file.
$ nm @nm_file 0000000000000002 T __libc_csu_fini 0000000000000004 R _IO_stdin_used 0000000000000004 B abc 0000000000000084 T main 0000000000000089 T __libc_csu_init