nm menunjukkan nilai simbol. Beberapa simbol di perpustakaan atau file objek mungkin muncul sebagai nol hanya karena belum diberi nilai. Mereka akan mendapatkan nilai sebenarnya pada waktu penautan.
Beberapa simbol adalah simbol kode, beberapa adalah data, dll. Sebelum menautkan, nilai simbol sering kali merupakan offset di bagian tempatnya berada,
Angka hex adalah offset memori ke dalam file objek tempat simbol dapat ditemukan. Ini benar-benar jumlah byte ke dalam kode objek.
Nilai tersebut digunakan oleh penghubung untuk menemukan dan membuat salinan nilai simbol. Anda dapat melihat secara umum bagaimana tata letaknya jika Anda menambahkan -S
opsi untuk nm
, yang akan menampilkan ukuran nilai untuk setiap simbol.
Berikut cuplikan kode yang saya tulis di C:
#include
#include
void foo();
int main(int argc, char* argv[]) {
foo();
}
void foo() {
printf("Foo bar baz!");
}
Saya menjalankan gcc -c foo.c
pada kode itu. Inilah nm foo.o
menunjukkan:
000000000000001b T foo 0000000000000000 T main U printf
Untuk contoh ini saya menjalankan Ubuntu Linux 64-bit; itu sebabnya hex 8 digit yang Anda lihat adalah 16 digit di sini. :-)
Digit hex yang Anda lihat adalah alamat kode yang dimaksud di dalam file objek relatif terhadap awal .text.
bagian. (dengan asumsi kita menangani bagian dari file objek mulai dari 0x0). Jika Anda menjalankan objdump -td foo.o
, Anda akan melihat yang berikut di keluaran:
Disassembly of section .text: 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: 89 7d fc mov %edi,-0x4(%rbp) b: 48 89 75 f0 mov %rsi,-0x10(%rbp) f: b8 00 00 00 00 mov $0x0,%eax 14: e8 00 00 00 00 callq 19 19: c9 leaveq 1a: c3 retq 000000000000001b : 1b: 55 push %rbp 1c: 48 89 e5 mov %rsp,%rbp 1f: b8 00 00 00 00 mov $0x0,%eax 24: 48 89 c7 mov %rax,%rdi 27: b8 00 00 00 00 mov $0x0,%eax 2c: e8 00 00 00 00 callq 31 31: c9 leaveq 32: c3 retq
Perhatikan bahwa kedua simbol ini sejajar dengan entri yang kita lihat di tabel simbol dari nm
. Ingat, alamat ini dapat berubah jika Anda menautkan file objek ini ke file objek lain. Ingat juga bahwa callq
at 0x2c akan berubah saat Anda menautkan file ini ke libc apa pun yang disediakan sistem Anda, karena itu saat ini merupakan panggilan yang tidak lengkap ke printf (ia tidak tahu di mana letaknya sekarang).
Adapun mylib.a
Anda , masih ada lagi yang terjadi di sini. File yang Anda miliki adalah arsip; itu berisi banyak file objek, yang masing-masing dengan segmen teksnya sendiri. Sebagai contoh, ini adalah bagian dari nm terhadap /usr/lib/libm.a di kotak saya di sini
e_sinh.o: 0000000000000000 r .LC0 0000000000000008 r .LC1 0000000000000010 r .LC2 0000000000000018 r .LC3 0000000000000000 r .LC4 U __expm1 U __ieee754_exp 0000000000000000 T __ieee754_sinh e_sqrt.o: 0000000000000000 T __ieee754_sqrt e_gamma_r.o: 0000000000000000 r .LC0 U __ieee754_exp 0000000000000000 T __ieee754_gamma_r U __ieee754_lgamma_r U __rint
Anda akan melihat bahwa beberapa entri segmen teks -- ditunjukkan oleh T di kolom kedua berada di alamat 0x0, tetapi setiap file individu hanya satu simbol segmen teks pada 0x0.
Adapun file individual yang memiliki banyak simbol berada di alamat yang sama, sepertinya akan mungkin mungkin. Lagi pula, itu hanyalah sebuah entri dalam tabel yang digunakan untuk menentukan lokasi dan ukuran potongan data. Tapi saya tidak tahu pasti. Saya belum pernah melihat banyak simbol yang mereferensikan bagian yang sama dari suatu bagian sebelumnya. Siapa pun yang memiliki lebih banyak pengetahuan tentang ini daripada saya dapat bergabung. :-)
Semoga ini bisa membantu.