前言
在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题。
示例程序
我们的示例程序如下:
- #include<stdio.h>
- int main(int argc,char *argv[])
- {
- printf("hello shouwangxiansheng\n");
- return 0 ;
- }
编译:
- $ gcc -o hello hello.c
得到hello可执行文件。
查看文件类型
file命令可以用来查看文件类型:
- $ 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
从结果中,我们可以知道,它是ELF可执行文件,且是64位程序,有动态链接,最后的not stripped也表明了它保留了符号表信息或者调试信息。
如果不是可执行文件,它的信息是怎样的呢?举个例子:
- $ file hello.c
- hello.c: C source, UTF-8 Unicode text
看到了吧。
查看ELF头
readelf用于查看ELF文件,而:
- $ 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
- (略)
可以看到它是EXEC,即可执行文件,且小端程序,运行于X86-64。在交叉编译的时候,这个文件头的信息也非常有用。例如你在x86的机器上交叉编译出powerpc的可执行文件,在powerpc上却不被识别,不能运行,不如用readelf看看它的Machine字段,是不是没有编译好。
查找ELF文件中的字符串
例如,你在文件中写入了版本号或者特殊字符串,可以通过strings命令搜索到:
- $ strings hello|grep shouwang
- hello shouwangxiansheng
查看ELF文件各段大小
- $ size hello
- text data bss dec hex filename
- 1210 552 8 1770 6ea hello
这里可以看到代码段,数据段各自占多少,必要时候还可以根据需要优化代码,减少磁盘空间占用。
查看链接的动态库
运行时出现找不到动态库?不如看看它链接了哪些库吧:
- $ 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)
可以看到它链接的动态库是/lib/x86_64-linux-gnu/libc.so.6,而如果该文件不存在,则运行时将会出错。这里也可以参考《动态库的制作和使用》。
查看符号表
(编辑:ASP站长网)
|