Introdução ao comando nm no linux

De um modo geral, as pessoas envolvidas no desenvolvimento do Linux usarão o comando nm, mas os não-desenvolvedores não devem usá-lo. Embora nm seja simples, ainda é necessário escrever algumas palavras e falar sobre seu coração.

  

        nm não é uma abreviação de ni ma. Obviamente, não é uma abreviação de ni mei, mas uma abreviação de nomes. O comando nm é usado principalmente para listar símbolos em determinados arquivos (em outras palavras, algumas funções e variáveis ​​globais, etc.). Abaixo, vamos dar uma olhada.

       test.h é:

void print ();
      test.c é:

#include <stdio.h>
#include "test.h"
 
void print ()
{
    printf ("dias chuvosos \ n");
}
       main.c:

#include "test.h"
 
int main ()
{
    print ();
    return 0;
}
      Ok, vamos ver o efeito do comando nm, da seguinte maneira:
[taoge @ localhost learn_nm] $ nm *
nm: main.c: formato de arquivo não reconhecido
nm: test.c: formato de arquivo não reconhecido
nm: test.h: formato de arquivo não reconhecido
[taoge @ localhost learn_nm] $ 
      ni ma, nada, isso significa que nm é inútil para esses arquivos.


       Continue para ver se nm pode ler o arquivo de destino e o arquivo executável:

[taoge @ localhost learn_nm] $ ls
main.c test.c test.h
[taoge @ localhost learn_nm] $ gcc -c test.c main.c 
[taoge @ localhost learn_nm] $ gcc test.o main.o
[taoge @ localhost learn_nm] $ ./a.out 
dias chuvosos
[taoge @ localhost learn_nm] $ nm *

a.out:
08049564 d _DYNAMIC
08049630 d _GLOBAL_OFFSET_TABLE_
0804849c R _IO_stdin_used
         w _Jv_RegisterClasses
08049554 d __CTOR_END__
08049550 d __CTOR_LIST__
0804955c D __DTOR_END__
08049558 d __DTOR_LIST__
0804854c r __FRAME_END__
08049560 d __JCR_END__
08049560 d __JCR_LIST__
0804964c Um __bss_start
08049648 D __data_start
08048450 t __do_global_ctors_aux
08048330 t __do_global_dtors_aux
080484a0 R __dso_handle
         w __gmon_start__
0804844a T __i686.get_pc_thunk.bx
08049550 d __init_array_end
08049550 d __init_array_start
080483e0 T __libc_csu_fini
080483f0 t __libc_csu_init
         L __libc_start_main @@ GLIBC_2.0
0804964c Um _edata
08049654 Um _END
0804847c T _fini
08048498 R _fp_hw
08048290 T _init
08048300 T _start
0804964c b completed.5963
08049648 W data_start
08049650 b dtor_idx.5965
08048390 t frame_dummy
080483c8 T principal
de impressão T 080483b4
         U coloca @@ GLIBC_2.0
nm: main.c: formato de arquivo não reconhecido

main.o:
00000000 T principal
         U imprimir
nm: test.c: formato de arquivo não reconhecido
nm: test.h: formato de arquivo não reconhecido

test.o:
00000000 T print
         U coloca
[taoge @ localhost learn_nm] $ Como 
        você pode ver, o arquivo de destino e o arquivo executável podem obter as funções, como a função de impressão.


        Continuamos a examinar a biblioteca estática e a biblioteca dinâmica, da seguinte maneira:

[taoge @ localhost learn_nm] $ ls
main.c test.c test.h
[taoge @ localhost learn_nm] $ gcc -c test.c
[taoge @ localhost learn_nm] $ ar rcs libtest.a test.o
[taoge @ localhost learn_nm ] $ gcc -shared -fPIC -o libtest.so test.o
[taoge @ localhost learn_nm] $ ls
libtest.a libtest.so main.c test.c test.c test.h test.o
[taoge @ localhost learn_nm] $ nm lib *

libtest.a:

test.o:
00000000 T impressão
         U coloca

libtest.so:
000014bc um _DYNAMIC
00001590 um _GLOBAL_OFFSET_TABLE_
         w _Jv_RegisterClasses
000014a8 d __CTOR_END__
000014a4 d __CTOR_LIST__
000014b0 d __DTOR_END__
000014ac d __DTOR_LIST__
000004a0 r __FRAME_END__
000014b4 d __JCR_END__
000014b4 d __JCR_LIST__
000015a4 Um __bss_start
         w __cxa_finalize @@ GLIBC_2.1.3
00000440 t __do_global_ctors_aux
00000350 t __do_global_dtors_aux
000014b8 d __dso_handle
         w __gmon_start__
00000419 t __i686.get_pc_thunk.bx
000015a4 A _edata
000015ac A _end
00000478 T _fini
000002ec T _init
000015a4 b concluído.5963
000015a8 b dtor_idx.5965
000003e0 t frame_dummy
00000420 T print
         U puts @@ GLIBC_2.0
[taoge @ localhost learn_nm] $ Como 
        você pode ver, podemos obter o nome da função da biblioteca estática e da biblioteca dinâmica, como print Função

        Ok, vamos dar uma olhada na situação das variáveis ​​globais.Nós mudamos main.c para:

#include <stdio.h>
 
int add (int x, int y)
{
    retorno x + y;
}
 
int aaa;
int bbb = 1;
char szTest [] = "bom";
 
int main ()
{
    int ccc = 2;
    return 0;
}
       Em seguida, use nm para analisar a.out (observe que, se houver apenas o comando nm, o a.out padrão será o arquivo a ser processado):
[taoge @ localhost learn_nm] $ ls
main.c
[taoge @ localhost learn_nm] $ main.ce GCC 
[Taoge @ localhost learn_nm] $ ./a.out 
[Taoge @ localhost learn_nm] o a.out nm $ 
08049538 D o _DYNAMIC
08049604 D _GLOBAL_OFFSET_TABLE_
0804847c P & lt _IO_stdin_used
         W _Jv_RegisterClasses
08049528 D __CTOR_END__
08049524 D __CTOR_LIST__
08049530 D __DTOR_END__
0804952c d __DTOR_LIST__
08048520 r __FRAME_END__
08049534 d __JCR_END__
08049534 d __JCR_LIST__
08049628 Um __bss_start
08049618 D __data_start
08048430 t __do_global_ctors_aux
08048310 t __do_global_dtors_aux
08048480 R __dso_handle
         w __gmon_start__
0804842a T __i686.get_pc_thunk.bx
08049524 d __init_array_end
08049524 d __init_array_start
080483c0 T __libc_csu_fini
080483d0 t __libc_csu_init
         U __libc_start_main @@ GLIBC_2.0
08049628 A _edata
08049634 A _end
0804845c T _fini
08048478 R _fp_hw
08048274 T _init
080482e0 T _start
08049630 B aaa
08048394 T adiciona
0804961c D bbb
08049628 b concluída.5963
08049618 W data_start
0804962c b dtor_idx.5965
08048370 t frame_dummy
080483a2 T principal
08049320 D a função
local 
        não está disponível; Também existem variáveis ​​globais aaa, bbb e szTest. Observe que aaa não foi inicializado, portanto está na seção Bss e bbb e szTest são inicializados, assim como na seção Dados. Vale ressaltar que não há ccc, porque ccc é uma variável local e nm não pode vê-lo. 
        Também devemos notar que "bom" não é visível nele, por quê? Porque nm é usado para examinar o szTest em vez de "bom". Não se esqueça, o comando strings que introduzimos anteriormente pode fazer isso, da seguinte maneira:

[taoge @ localhost learn_nm] $ ls
a.out main.c
[taoge @ localhost learn_nm] $ strings a.out 
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
__libc_start_main
GLIBC_2.0
PTRh
[^ _ ]
bom
[taoge @ localhost learn_nm] $ 


        O comando nm lista principalmente as informações do símbolo no arquivo de características.Para um uso mais detalhado, pergunte ao homem, não vou apresentar muito.

———————————————
Declaração de direitos autorais: este artigo é um artigo original do blogger do CSDN "stpeace", seguindo o contrato de direitos autorais do CC 4.0 BY-SA, por favor, anexe o link da fonte original e esta declaração para reimprimir .
Link original: https://blog.csdn.net/stpeace/article/details/47089585

Publicado 13 artigos originais · Curtidas6 · Visitantes 10.000+

Acho que você gosta

Origin blog.csdn.net/majianting/article/details/104970217
Recomendado
Clasificación