跳过导航链接 | |
退出打印视图 | |
Oracle Solaris 11.1 链接程序和库指南 Oracle Solaris 11.1 Information Library (简体中文) |
可以使用各种工具分析 ELF 文件的内容,包括标准的 Unix 实用程序 dump(1)、nm(1) 和 size(1)。在 Oracle Solaris 中,这些工具大都已被 elfdump(1) 取代。
使用 eldump 诊断 ELF 目标文件的内容对于调查以下几节中介绍的各种性能问题很有用。
ELF 格式可以将数据组织到多个节中。各节会被依次指定给称为段的单元。段描述如何将文件的各部分映射到内存。请参见mmapobj(2)。可以通过使用 elfdump(1) 命令并检查 PT_LOAD 项来显示这些可装入段。
$ elfdump -p -NPT_LOAD libfoo.so.1 Program Header[0]: p_vaddr: 0 p_flags: [ PF_X PF_R ] p_paddr: 0 p_type: [ PT_LOAD ] p_filesz: 0x53c p_memsz: 0x53c p_offset: 0 p_align: 0x10000 Program Header[1]: p_vaddr: 0x1053c p_flags: [ PF_X PF_W PF_R ] p_paddr: 0 p_type: [ PT_LOAD ] p_filesz: 0x114 p_memsz: 0x13c p_offset: 0x53c p_align: 0x10000
在 libfoo.so.1 共享目标文件中存在两种可装入段,通常称为文本段和数据段。对文本段进行了映射以允许读取和执行其内容(PF_X 和 PF_R)。数据段映射的目的是允许同时修改其内容 PF_W。数据段的内存大小 p_memsz 不同于文件大小 p_filesz。该差异说明存在 .bss 节,此节属于数据段并在装入数据段时动态创建。
程序员通常根据定义其代码中的函数和数据元素的符号来考虑文件。通过在 elfdump 命令中使用 -s 选项可显示这些符号。
$ elfdump -sN.symtab libfoo.so.1 Symbol Table Section: .symtab index value size type bind oth ver shndx name .... [36] 0x00010628 0x00000028 OBJT GLOB D 0 .data data .... [38] 0x00010650 0x00000028 OBJT GLOB D 0 .bss bss .... [40] 0x00000520 0x0000000c FUNC GLOB D 0 .init _init .... [44] 0x00000508 0x00000014 FUNC GLOB D 0 .text foo .... [46] 0x0000052c 0x0000000c FUNC GLOB D 0 .fini _fini
elfdump 显示的符号表信息包括与符号关联的节。elfdump -c 选项可用于显示与这些节有关的信息。
$ elfdump -c libfoo.so.1 .... Section Header[6]: sh_name: .text sh_addr: 0x4f8 sh_flags: [ SHF_ALLOC SHF_EXECINSTR ] sh_size: 0x28 sh_type: [ SHT_PROGBITS ] sh_offset: 0x4f8 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x8 Section Header[7]: sh_name: .init sh_addr: 0x520 sh_flags: [ SHF_ALLOC SHF_EXECINSTR ] sh_size: 0xc sh_type: [ SHT_PROGBITS ] sh_offset: 0x520 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header[8]: sh_name: .fini sh_addr: 0x52c sh_flags: [ SHF_ALLOC SHF_EXECINSTR ] sh_size: 0xc sh_type: [ SHT_PROGBITS ] sh_offset: 0x52c sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 .... Section Header[12]: sh_name: .data sh_addr: 0x10628 sh_flags: [ SHF_WRITE SHF_ALLOC ] sh_size: 0x28 sh_type: [ SHT_PROGBITS ] sh_offset: 0x628 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 .... Section Header[14]: sh_name: .bss sh_addr: 0x10650 sh_flags: [ SHF_WRITE SHF_ALLOC ] sh_size: 0x28 sh_type: [ SHT_NOBITS ] sh_offset: 0x650 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 ....
以上示例中的 elfdump(1) 输出显示 _init、foo 和 _fini 函数与 .init、.text 和 .fini 节的关联关系。这些节由于具有只读性质,因此属于文本段。
同样,数据数组 data 和 bss 分别与节 .data 和 .bss 关联。这些节由于具有可写性质,因此属于数据段。