GNU/Linux >> Tutoriales Linux >  >> Linux

10 ejemplos prácticos de comandos de Linux nm

Los comandos nm proporcionan información sobre los símbolos que se utilizan en un archivo de objeto o un archivo ejecutable.

La información predeterminada que proporciona el comando 'nm' es:

  • Dirección virtual del símbolo
  • Un carácter que representa el tipo de símbolo. Si el carácter está en minúsculas, el símbolo es local, pero si el carácter está en mayúsculas, el símbolo es externo
  • Nombre del símbolo


Los caracteres que identifican el tipo de símbolo describen:

  • A :  Símbolo absoluto global.
  • un :  Símbolo absoluto local.
  • B :Símbolo bss global.
  • b :símbolo bss local.
  • D :Símbolo de datos globales.
  • d :Símbolo de datos locales.
  • f :símbolo de nombre de archivo de origen.
  • L :símbolo local de subproceso global (TLS).
  • l :Símbolo local de subproceso estático (TLS).
  • T :símbolo de texto global.
  • t :Símbolo de texto local.
  • T :Símbolo indefinido.

Tenga en cuenta que esta lista no es exhaustiva, pero contiene algunos tipos de símbolos importantes. Para obtener información completa, consulte la página del manual de esta utilidad.

La forma predeterminada de usar la utilidad 'nm' es:

$ nm <object file or executable name>

si no se proporciona un nombre ejecutable, entonces nm asume que el nombre es 'a.out'.

Con la idea básica de esta utilidad, uno puede preguntarse por qué se requiere esta información.

Bueno, suponga que tiene un ejecutable que está hecho de muchos archivos de objetos diferentes. Ahora suponga que mientras compila el código, el enlazador da un error sobre un símbolo 'temp' no resuelto. Ahora será una pesadilla encontrar dónde está el símbolo 'temp' en el código si el código es demasiado grande e incluye muchos encabezados. Es aquí donde esta utilidad viene al rescate. Con algunas opciones adicionales, esta utilidad también proporciona el archivo en el que se encuentra el símbolo.

Ya que ahora tenemos una idea básica sobre la utilidad nm. Entendamos el uso de esta utilidad a través de algunos comandos prácticos.

1. Mostrar archivos de objetos que hacen referencia a un símbolo

El siguiente comando muestra todos los archivos de objetos que se refieren al símbolo 'func' en mi directorio actual

$ 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

Tenga en cuenta que el indicador -A se usa para mostrar el nombre del archivo junto con otra información. Entonces vemos que en la salida obtenemos todos los archivos de objetos donde se usa el símbolo 'func'. Esto podría ser extremadamente útil en los casos en que queremos saber qué archivos de objetos están usando un símbolo en particular.

2. Mostrar todos los símbolos indefinidos en un ejecutable

El siguiente comando enumera todos los símbolos no definidos en un archivo ejecutable '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

Tenga en cuenta que la bandera '-u' se usa en este caso para enumerar solo los símbolos no definidos. Esto podría ser extremadamente útil en casos en los que uno desee saber acerca de los símbolos no definidos que se utilizan en el código que realmente podrían no estar resueltos o podrían resolverse en tiempo de ejecución a través de bibliotecas compartidas.

En un tema relacionado, también debe comprender cómo funciona el proceso de vinculación de GCC.

3. Mostrar todos los símbolos en un ejecutable

El siguiente comando enumera todos los símbolos en el ejecutable 'namepid' pero en el orden de sus direcciones

$ 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
...
...
...

Vemos que al usar la bandera '-n', la salida se ordena primero con los símbolos indefinidos y luego de acuerdo con las direcciones. La clasificación podría facilitar la vida de un desarrollador que está depurando un problema.

4. Busque un símbolo y muestre su tamaño

El siguiente comando busca un símbolo 'abc' y también muestra su tamaño

$ nm  -S 1 | grep abc
0000000000601040 0000000000000004 B abc

Entonces vemos que la bandera -S muestra información adicional sobre el tamaño del símbolo 'abc'

5. Mostrar símbolos dinámicos en un ejecutable

El siguiente comando se muestra en símbolos dinámicos en el ejecutable '1'.

$ nm  -D 1
w __gmon_start__
U __libc_start_main
U free
U malloc
U printf

Esto podría ser extremadamente útil en los casos en los que uno esté interesado en conocer los símbolos que solo pueden resolver las bibliotecas compartidas en tiempo de ejecución.

6. Extraer símbolos de varios tipos

Otra característica poderosa del comando nm es poder extraer el símbolo de varios tipos de formato de archivo de objeto. Normalmente, en Linux tenemos un objeto o código ejecutable en formato 'a.out' o ELF, pero si un objeto o código ejecutable tiene algún otro formato, nm también proporciona un indicador '–target' para él.

7. Cambiar el formato de la salida nm

Por defecto, el formato de salida que muestra nm es el tipo bsd. Podemos cambiar el formato usando la bandera -f. El siguiente comando muestra la salida del comando nm en estilo 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

De manera similar, podemos usar '-f sysv' si queremos que la salida tenga el estilo systemV.

8. Mostrar solo los símbolos externos de un ejecutable

El siguiente comando enumera solo los símbolos externos en el ejecutable

$ 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
...

Tenga en cuenta que el uso de flag -g habilita la salida de solo símbolos externos. Esto podría resultar útil al depurar especialmente símbolos externos.

9. Ordene la salida nm por el tamaño del símbolo

El siguiente comando ordena la salida por el tamaño de los símbolos

$ 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

Tenga en cuenta que la marca –size-sort ordena la salida con respecto al tamaño. Como ya se explicó, -g se usa para mostrar solo símbolos externos.

10. Especificar opciones nm en un archivo

Otra característica valiosa de nm es que puede tomar la entrada de la línea de comandos de un archivo. Puede especificar todas las opciones en un archivo y especificar el nombre del archivo en el comando nm y hará el resto por usted. Por ejemplo, en el siguiente comando, la utilidad nm lee la entrada de la línea de comando del archivo 'nm_file' y produce la salida

Tenga en cuenta que se requiere el símbolo '@' si proporciona el nombre del archivo.

$ nm @nm_file
0000000000000002 T __libc_csu_fini
0000000000000004 R _IO_stdin_used
0000000000000004 B abc
0000000000000084 T main
0000000000000089 T __libc_csu_init

Linux
  1. Comando cp en Linux:7 ejemplos prácticos

  2. Comando de apagado de Linux:5 ejemplos prácticos

  3. 5 ejemplos prácticos del comando dd en Linux

  4. Ejemplos de comandos rm en Linux

  5. Ejemplos de comandos ps en Linux

12 ejemplos prácticos de In Command en Linux

15 ejemplos prácticos del comando Rsync en Linux

5 ejemplos prácticos de Tail Command en Linux

Comando echo en Linux:7 ejemplos prácticos

Ejemplos prácticos de comando ping en Linux

Ejemplos de comandos id en Linux