首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux中ELF格式文件介绍(5)

Linux中ELF格式文件介绍(5)

*以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出  :
# objdump -x main
输入之后,输出信息类似如下:
main:     file format elf32-i386
main
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08048580

Program Header:
PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x00000100 memsz 0x00000100 flags r-x
INTERP off    0x00000134 vaddr 0x08048134 paddr 0x08048134 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000914 memsz 0x00000914 flags r-x
LOAD off    0x00000914 vaddr 0x08049914 paddr 0x08049914 align 2**12
filesz 0x00000130 memsz 0x000001cc flags rw-
DYNAMIC off    0x0000092c vaddr 0x0804992c paddr 0x0804992c align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags rw-
NOTE off    0x00000148 vaddr 0x08048148 paddr 0x08048148 align 2**2
filesz 0x00000020 memsz 0x00000020 flags r--
EH_FRAME off    0x000007e8 vaddr 0x080487e8 paddr 0x080487e8 align 2**2
filesz 0x0000003c memsz 0x0000003c flags r--
STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
...省略...
Dynamic Section:
NEEDED      libstdc++.so.6
NEEDED      libm.so.6
NEEDED      libgcc_s.so.1
NEEDED      libc.so.6
INIT        0x80484c0
FINI        0x80487b8
GNU_HASH    0x8048168
...省略...
Version References:
required from libstdc++.so.6:
0x056bafd3 0x00 05 CXXABI_1.3
0x08922974 0x00 03 GLIBCXX_3.4
required from libc.so.6:
0x0d696910 0x00 04 GLIBC_2.0
0x09691f73 0x00 02 GLIBC_2.1.3

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
0 .interp       00000013  08048134  08048134  00000134  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .gnu.hash     00000030  08048168  08048168  00000168  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .dynsym       000000d0  08048198  08048198  00000198  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynstr       00000183  08048268  08048268  00000268  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .gnu.version  0000001a  080483ec  080483ec  000003ec  2**1
...省略...
SYMBOL TABLE:
08048134 l    d  .interp        00000000              .interp
08048148 l    d  .note.ABI-tag  00000000              .note.ABI-tag
08048168 l    d  .gnu.hash      00000000              .gnu.hash
08048198 l    d  .dynsym        00000000              .dynsym
08048268 l    d  .dynstr        00000000              .dynstr
080483ec l    d  .gnu.version   00000000              .gnu.version
08048408 l    d  .gnu.version_r 00000000              .gnu.version_r
...省略...
这里可知,分别显示出各个段相关的信息。

*输出指定段的信息:
# objdump  -j .text -S  main
输入之后,输出类似如下:

main:     file format elf32-i386

Disassembly of section .text:

08048580 <_start>:
8048580:       31 ed                   xor    %ebp,%ebp
8048582:       5e                      pop    %esi
8048583:       89 e1                   mov    %esp,%ecx
8048585:       83 e4 f0                and    $0xfffffff0,%esp
8048588:       50                      push   %eax
8048589:       54                      push   %esp
...省略...
这里,反汇编会用到类似的命令。

4 nm工具
这个命令可以用来查看库中的符号。
nm列出的符号有很多,常见的有三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。

*假设开发者希望知道hello库中是否定义了 printf():
$nm libhello.so |grep printf
U printf
U表示符号printf被引用,但是并没有在函数内定义,由此可以推断,要正常使用hello库,必须有其它库支持。

5 ldd工具
ldd命令可以用来查看一个可执行文件或者库依赖哪些其他的文件。
*使用ldd命令查看hello依赖于哪些库:
$ldd hello
libc.so.6=>/lib/libc.so.6(0x400la000)
/lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000)
这里,结合nm,从上面的结果可以继续查看printf最终在哪里被定义.
继承事业,薪火相传
返回列表