LDD and NM are two very useful program analysis tools under Linux. LDD is a tool used to analyze the dynamic-link library that the program runs on, and NM is the tool used to view the symbol table information in the specified program.
1 LDD
Format:ldd [options] File
Function: Lists the shared libraries required for file run
Parameters:
-D perform relocation and report all missing functions
-R performs relocation of functions and objects and reports any missing functions or objects
First, LDD is not an executable program, but a shell script. LDD is able to display the dependency of the executable module by setting a series of environment variables, as follows: Ld_trace_loaded_objects, Ld_warn, Ld_bind_now, Ld_library_version, Ld_ Verbose and so on. When the LD_TRACE_LOADED_OBJECTS environment variable is not empty, any executable program will display only the module's dependency while it is running, and the program does not actually execute. Or you can test it at the shell terminal, as follows:
(1) Export Ld_trace_loaded_objects=1
(2) Execute any program, such as LS, to see the results of the program operation.
LDD shows how the dependency of the executable module works, essentially through the ld-linux.so (the loader of the Elf Dynamic Library). We know that the Ld-linux.so module works before the executable module and gets control, so when those environment variables are set, ld-linux.so chooses the dependency that shows the executable module.
You can actually execute the ld-linux.so module directly, such as:/lib/ld-linux.so.2--list program (which is equivalent to LDD program) LDD command usage (excerpt from LDD--help)
We select the application to be tested with the following code:
//@file tooltest.c//@brief resource sharing between parent-process and Sub-Process#include <stdio.h>#include<stdlib.h>#include<unistd.h>int Global=1;/*global variable, stored at Data section*/intMainvoid) {pid_t pid;//To store PID value intstack =1;//local variable, stored at stack int*heap;//pointer to a heap variableHeap= (int*) malloc (sizeof(int)); *heap =2;//set the heap value to 2PID= Fork ();//Create a new process if(PID <0) { //ErrorPerror ("fail to fork"); Exit (-1); } Else if(PID = =0) { //sub-process, change values Global++; Stack++; (*HEAP) + +; //Print all Valuesprintf"In sub-process, Global:%d, stack:%d, heap:%d\n",Global, Stack, *heap); Exit (0); } Else { //Parent ProcessSleep2);//Sleep 2 secends to make sure the sub-process runs firstprintf"In parent-process, Global:%d, stack:%d, heap:%d\n",Global, Stack, *heap); } return 0;}
We then compile and run the LDD command:
[Email protected]:~/documents/c_code$ ldd tooltest linux-gate.so. 1 = (0xb775b000) libc.so. 6 =/lib/i386-linux-gnu/libc.so. 6 (0xb7595000) /lib/ld-linux.so. 2 (0xb775c000)
We can divide the output of LDD into 3 columns:
First column: What library does the program need to rely on
Second column: The library name that is provided by the system that corresponds to the library required by the program
Third column: The start address that relies on library loading
Through the above information, we can summarize the following purposes:
(1) By comparing the first and second columns, we can see whether the dynamic link libraries required by the program and the system actually provide a comparison.
(2) Through the third column, we can know the starting position of the symbol in the current dynamic link library in the process address space.
2 NM
Format:nm [options] File
Function: Lists all symbols in file
Parameters:
-C converts a symbol to a user-level name
-S when used with a. A file that is a static library, the output maps the symbol name to the index of the module or member name that defines the symbol
-U displays symbols that are defined outside of file or that are not defined
-L Displays the line number of each symbol, or a redefined item that defines the symbol
The following is the output of the run NM command:
[Email protected]:~/documents/c_code$ nm tooltest0804a038 b __bss_start0804a038 b completed.65900804a02c D __data_start0804a02c W data_start08048450t deregister_tm_clones080484c0 t __do_global_dtors_aux08049f0c t __do_global_dtors_aux_fini_array_entry0804a030 D __dso_handle08049f14 D _dynamic0804a038 d _edata0804a03c B _end U [email protected] @GLIBC_2.008048674T _fini U [email protected] @GLIBC_2.008048688r _fp_hw080484e0 T frame_dummy08049f08 t __frame_dummy_init_array_entry080487e0 R __frame_end__0804a034 D global0804a000 D _global_offset_table_W__gmon_start__08048354t _init08049f0c t __init_array_end08049f08 t __init_array_start0804868c R _io_stdin_usedW_itm_deregistertmclonetableW_ITM_REGISTERTMCLONETABLE08049F10 d __jcr_end__08049f10 D __jcr_list__W_jv_registerclasses08048670T __libc_csu_fini08048600T __libc_csu_init U [email protected] @GLIBC_2.00804850d T main U [email protected] @GLIBC_2.0U [email protected] @GLIBC_2.0U [email protected] @GLIBC_2.008048480T Register_tm_clones USleep@ @GLIBC_2.008048410T _start0804a038 D __tmc_end__08048440T __X86.GET_PC_THUNK.BX
Above is tooltest all the symbols in this program, first introduce the above output format:
First column: The address of the current symbol.
Second column: The type of the current symbol (for a description of the type, you can view the manual page man nm for detailed reading).
Third column: The name of the current symbol.
There are several main ways to help with NM:
(1) Determine whether the specified program has a specified symbol, the more common way is: Nm–c Programs | grep symbol
(2) Fix undefined reference error at compile time, and multiple definition error.
(3) View the address of a symbol, and the approximate location of the process space (. BSS,. Data,. Text fields, which can be judged by the type of the second column).
Partial symbol Type description
a : The value of the symbol is absolute and is not allowed to change during subsequent links. Such symbolic values often appear in interrupt vector tables, such as symbols that represent the position of individual interrupt vector functions in the interrupt vector table.
B : The value of the symbol appears in the non-initialized data segment (. BSS) . For example, define a global static int test in a file. The type of the symbol test is B and is in the BSS section. Its value represents the offset of the symbol in the BSS segment. Generally, BSS segments are allocated in RAM.
C : The symbol is common. Common symbol is an uninitialized session data segment . The symbol is not included in a common section. Allocations are only made during the link process. The value of the symbol represents the number of bytes required for the symbol. For example, in a C file, the int test is defined, and the symbol is referenced elsewhere, and the symbol type is C. Otherwise, its type is B.
D : The symbol is in the initialization data segment . In general, it is assigned to the. Data section. For example, defining global int baud_table[5] = {9600, 19200, 38400, 57600, 115200} is assigned to the initialization data segment.
G : The symbol is also in the initialization data segment . Used primarily for small object to improve access to small data object in one way.
I : This symbol is an indirect reference to another symbol.
N : The symbol is a debugging symbol.
R : The symbol is in a read-only data segment . For example, define Global const int test[] = {123, 123}, then test is the symbol for a read-only data area. Note that the test in the source file corresponds to _test and its symbol type is D, which is initialized in the data segment, if Cygwin is compiled directly into MZ format using GCC. However, if you use a cross-compilation tool such as M6812-ELF-GCC, the test in the source file corresponds to the test of the target file, which is not underlined, and its symbol type is R. Generally, it is located in Rodata section. It is worth noting that if const char *test = "ABC" is defined in a function, const char Test_int = 3. No symbolic information is obtained using NM, but the string "ABC" is assigned to read-only memory, and test is in the Rodata section with a size of 4.
S : The symbol is in a non-initialized data segment for small object.
T : The symbol is located in the Code Snippet text Section .
U : The symbol is undefined in the current file, meaning that the symbol is defined in another file. For example, the current file invokes a function defined in another file, where the called function is currently undefined, but the type in the file that defines it is t. But for global variables, in the file that defines it, the symbol type is C, and in the file that uses it, the type is U.
V : The symbol is a weak object.
W : The symbol is a weak symbol, the have not been specifically tagged as a weak object symbol.
- : This symbol is stabs symbol in the a.out format file.
? : The symbol type is not defined.
Linux Program analysis tools: LDD and NM