8 Ocak 2018 Pazartesi

nm komutu - name list

Giriş
name list anlamına gelir. Bu komut .o, .a. .so uzantılı dosyalarda sembol aramak için kullanılır.

Açıklaması şöyle.
Nm displays the name list (symbol table) of each object file in the argument list. If an argument is an archive, a listing for each object file in the archive will be produced. File can be of the form libx.a(x.o), in which case only symbols from that member of the object file are listed. ... etc
Semboller, metod ismi olabileceği gibi global veya static değişkenler olabilirler. Hiçbir seçeneği kullanmayan basit bir örnek şöyle
$ nm ./libdynamicSimulator.so | grep sim 
0000000000102e10 T sim
1. nm çıktısı
B - bss
Değişkenin bss segmente yerleştirildiğini (değişkenin ilklendirilmediğini, değer atanmadığını belirtir) gösterir. bss başlangıcı şöyledir.
$ nm -g test
0000000000601038 B __bss_start
...
C - common
Açıklaması şöyle.
"C" The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references.
Örnek
Elimizde şöyle bir kod olsun.
enum TestEnum 
{
    A=303,
    B=808
} _TestEnum;

int foo()
{
  _TestEnum = B;
}
Şöyle yaparız.
nm test.o 
0000000000000000 T foo
0000000000000004 C _TestEnum
D - data
Değişkenin data segmente yerleştirildiğini (değişkenin ilklendirildiğini, değer atandığını belirtir)
Şöyledirr
_TERRAIN_PASSABLE                           |00000008|   D  |

_TERRAIN_SOME_WHAT_PASSABLE|00000004|   B  |
T - text
T ile başlayan satırlar text section yani kod anlamına gelir. Metodlar kod olarak kabul edilir.
Örnek
Elimizde şöyle bir kod olsun.
enum TestEnum 
{
    A=303,
    B=808
} _TestEnum;

int foo()
{
  _TestEnum = B;
}
Şöyle yaparız.
nm test.o 
0000000000000000 T foo
0000000000000004 C _TestEnum
U - undefined
Sembolün bulunamadığını gösterir.
Örnek
Şöyledir.
$ nm -g test
0000000000601048 B __bss_start
                 U conj@@GLIBC_2.2.5
...
Örnek
Kendi .so kütüphanemizi derleyelim
arm-linux-gnueabihf-gcc -fPIC -o shm.o -c shm.c
arm-linux-gnueabihf-gcc -shared shm.o -o libshm.so -lrt
Çıktı olarak şunu alırız. Sondan ikinci satırda shm_open() çağrısının U yani undefined olduğu görülür.
00000328 t $a
000002e4 t $a
00000484 t $a
...
...
00000328 t call_weak_fn
0001102c b completed.10740
         w __cxa_finalize@@GLIBC_2.4
...
...
0000034c t deregister_tm_clones
000003e0 t __do_global_dtors_aux
00010f0c t __do_global_dtors_aux_fini_array_entry
00011028 d __dso_handle
00010f10 a _DYNAMIC
00000484 t _fini
00000448 t frame_dummy
00010f08 t __frame_dummy_init_array_entry
00000498 r __FRAME_END__
0000044c T func_shm
00011000 a _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
000002e4 t _init
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
00000390 t register_tm_clones
         U shm_open@@GLIBC_2.4
0001102c d __TMC_END__
Açıklaması şöyle
This is expected: you are linking against librt.so. The definition of shm_open is in librt.so, and not in your library.
2. Seçenekler
-A seçeneği
Dosya ismini her satırın başına koyar. Örnek:
nm -A /usr/lib/libc.so | grep scanf
/lib/libc.so:0000000000042a90 T scanf
-C seçeneği
C++ sembollerini demangle eder. Şöyle yaparız.
nm -gC yourLib.a
-C yerine --demangle kullanılabilir. Şöyle yaparız.
$ nm --demangle /usr/local/lib/libboost_thread.so | grep join
-D seçeneği
Dynamic symbols için kullanılır. Yani bu seçenek shared library için kullanılır.
nm -D libNAME.so
Eğer -D seçeneğini kullanmazsak çıktı alamayız.
$ nm /lib/i386-linux-gnu/libc.so.6 
nm: /lib/i386-linux-gnu/libc.so.6: no symbols
-D seçeneği ile şu çıktıyı alırız.
$ nm -D /lib/i386-linux-gnu/libc.so.6 | tail
0011fc20 T xdr_wrapstring
001202c0 T xdrmem_create
00115540 T xdrrec_create
001157f0 T xdrrec_endofrecord
00115740 T xdrrec_eof
00115690 T xdrrec_skiprecord
00120980 T xdrstdio_create
00120c70 T xencrypt
0011d330 T xprt_register
0011d450 T xprt_unregister
-g seçeneği
Extern sembolleri gösterir.
nm -g yourLib.a
Bağımlı olduğumuz belli bir sembol örüntüsünü aramak için şöyle yaparız. C seçeneği ile C++ isimler demangle edilir.
$ nm -gC ./builds/libmemory.so | grep MEM_
0000000000009178 T MEM_exit
0000000000009343 T MEM_init
00000000000093e9 T MEM_print_leaks
00000000000095be T MEM_priv_alloc
000000000000971d T MEM_priv_free
00000000000099c1 T MEM_priv_realloc
0000000000009d26 T MEM_set_callback_leak
0000000000009d3f T MEM_set_callback_noleak
boost_program_options'ın bir çeşit std::string'e bağımlı olduğu görülebilir.
$ nm -gU /usr/local/lib/libboost_program_options.dylib | grep program_options
    ...
    0000000000023560 T __ZNK5boost15program_options...basic_string...
    ...
-U seçeneği
Undefined semboller için kullanılır.

Hiç yorum yok:

Yorum Gönder