In Linux, the executable file format is ELF format, and there are some commands that can help us understand more of their "secrets" to help us solve problems.
Sample program
Our sample program is as follows:
//hello.c
#include<stdio.h>
int main(int argc,char *argv[])
{
printf("hello shouwangxiansheng\n");
return 0 ;
}
Compile and get the hello executable file.
$ gcc -o hello hello.c
View file type
The file command can be used to view file types:
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=8f1de0f59bdfe9aaff85ade6898173aa436b296a, not stripped
From the results, we can know that it is an ELF executable file and a 64-bit program with dynamic linking. The last not stripped also indicates that it retains symbol table information or debugging information.
If it is not an executable file, what is its information? for example:
$ file hello.c
hello.c: C source, UTF-8 Unicode text
View ELF header
readelf is used to view ELF files, as shown below:
$ readelf -h hello
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
You can see that it is EXEC, you can execute the file, and the little endian program runs on X86-64. The information in this file header is also very useful during cross-compilation. For example, if you cross-compile the powerpc executable file on an x86 machine, it is not recognized and cannot be run on powerpc. It is better to use readelf to see if its Machine field is not compiled properly.
Find the string in the ELF file
For example, if you write a version number or a special string in the file, you can search it through the strings command:
$ strings hello|grep shouwang
hello shouwangxiansheng
View the size of each segment of the ELF file
$ size hello
text data bss dec hex filename
1210 552 8 1770 6ea hello
Here you can see how much the code segment and data segment occupies, and when necessary, you can optimize the code as needed to reduce disk space usage.
View the linked dynamic library
Can't find the dynamic library when running? Why not take a look at which libraries it links:
$ ldd hello
linux-vdso.so.1 => (0x00007ffd16386000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f507e083000)
/lib64/ld-linux-x86-64.so.2 (0x00007f507e44d000)
You can see that the dynamic library it links is /lib/x86_64-linux-gnu/libc.so.6, and if the file does not exist, an error will occur during runtime. Here you can also refer to " The Production and Use of Dynamic Library ".
View symbol table
I wonder if the newly added function or global variable is compiled in? How to see if there is any in the symbol table (provided that the symbol table is not removed):
$ nm hello |grep main #符号表中查找main函数
U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main
If it is not found or is preceded by U and no address, it means that this function is not defined in the elf file, which is useful when there is a problem with the link.
Slimming ELF files
When I checked the file through file, I saw the word not stripped, because it contains some symbol table information, because the file will be slightly larger, if you remove it, the binary file will become smaller, but the symbol table information inside will not be. , It will affect the problem location.
$ ls -lh hello #瘦身前
-rwxrwxr-x 1 root root 8.4K
$ strip hello
$ ls -lh hello #瘦身后
-rwxrwxr-x 1 root root 6.2K
As you can see, the binary file becomes smaller after weight loss. When the executable file is larger, the slimming effect will be more obvious. Of course rest assured, this will not affect the normal operation of the program, but only affect debugging and problem location.
Look at the symbol table at this time:
$ nm hello
nm: hello: no symbols
Print file checksum
Whether the binary file is damaged or the same version during the transfer process, take a look at the checksum and block count:
$ sum hello
33513 7
Of course you can also use:
$ md5sum hello
521efed706c3b485dd3b5e96e48b138a hello
To compare the md5 value.
to sum up
The ELF file hides a wealth of information, as long as it is used properly, it will help us better develop or locate problems.