ELF文件说明

ELF文件包括三个索引表:(常用elf文件: .a文件、.o文件、.so文件以及可执行文件)

1、ELF header: 描述整个文件的组织
2、Program header table: 告诉系统如何创建进程映像
3、Section header table: 包含各个section的属性信息

可以 vi /usr/include/elf.h 查看各个头格式,以及各section 表的格式

1、读取ELF header: readelf -h app

[root@localhost l1]# readelf -h app
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
  Version:                           0x1
  Entry point address:               0x407f40
  Start of program headers:          64 (bytes into file)
  Start of section headers:          12200016 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         10
  Size of section headers:           64 (bytes)
  Number of section headers:         45
  Section header string table index: 44
[root@localhost l1]#

elf header格式

/* ELF Header */
typedef struct elfhdr {
	unsigned char	e_ident[EI_NIDENT]; /* ELF Identification */
	Elf32_Half	e_type;		/* object file type */
	Elf32_Half	e_machine;	/* machine */
	Elf32_Word	e_version;	/* object file version */
	Elf32_Addr	e_entry;	/* virtual entry point */
	Elf32_Off	e_phoff;	/* program header table offset */
	Elf32_Off	e_shoff;	/* section header table offset */
	Elf32_Word	e_flags;	/* processor-specific flags */
	Elf32_Half	e_ehsize;	/* ELF header size */
	Elf32_Half	e_phentsize;	/* program header entry size */
	Elf32_Half	e_phnum;	/* number of program header entries */
	Elf32_Half	e_shentsize;	/* section header entry size */
	Elf32_Half	e_shnum;	/* number of section header entries */
	Elf32_Half	e_shstrndx;	/* section header table's "section 
					   header string table" entry offset */
} Elf32_Ehdr;

2、查看elf文件的头64个字节

[root@localhost l1]# hexdump -x -n 64 app
0000000    457f    464c    0102    0001    0000    0000    0000    0000
0000010    0002    003e    0001    0000    7f40    0040    0000    0000
0000020    0040    0000    0000    0000    2850    00ba    0000    0000
0000030    0000    0000    0040    0038    000a    0040    002d    002c
0000040
[root@localhost l1]#

3、读取Program header table: readelf --segments app

[root@localhost l1]# readelf --segments app

Elf file type is EXEC (Executable file)
Entry point 0x407f40
There are 10 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040       0x0000000000000230 0x0000000000000230  R E    8
  INTERP         0x0000000000000270 0x0000000000400270 0x0000000000400270       0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000       0x000000000071d5d8 0x000000000071d5d8  R E    200000
  LOAD           0x000000000071de40 0x0000000000d1de40 0x0000000000d1de40       0x0000000000021800 0x0000000014ec5700  RW     200000
  DYNAMIC        0x000000000071ebc0 0x0000000000d1ebc0 0x0000000000d1ebc0       0x0000000000000300 0x0000000000000300  RW     8
  NOTE           0x000000000000028c 0x000000000040028c 0x000000000040028c       0x0000000000000044 0x0000000000000044  R      4
  TLS            0x000000000071de40 0x0000000000d1de40 0x0000000000d1de40       0x0000000000000018 0x0000000000000880  R      40
  GNU_EH_FRAME   0x00000000006215e0 0x0000000000a215e0 0x0000000000a215e0       0x000000000000c164 0x000000000000c164  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000       0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x000000000071de40 0x0000000000d1de40 0x0000000000d1de40       0x00000000000011c0 0x00000000000011c0  R      1

 Section to Segment mapping:
  Segment Sections...
   00
   01     .interp
   02     .interp .note.ABI-tag .note.gnu.build-id .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text text.unlikely .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table
   03     .tdata .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss .lbss
   04     .dynamic
   05     .note.ABI-tag .note.gnu.build-id
   06     .tdata .tbss
   07     .eh_frame_hdr
   08
   09     .tdata .init_array .fini_array .jcr .data.rel.ro .dynamic .got
[root@localhost l1]#

头格式

/* Program segment header.  */

typedef struct
{
  Elf32_Word    p_type;                 /* Segment type */
  Elf32_Off     p_offset;               /* Segment file offset */
  Elf32_Addr    p_vaddr;                /* Segment virtual address */
  Elf32_Addr    p_paddr;                /* Segment physical address */
  Elf32_Word    p_filesz;               /* Segment size in file */
  Elf32_Word    p_memsz;                /* Segment size in memory */
  Elf32_Word    p_flags;                /* Segment flags */
  Elf32_Word    p_align;                /* Segment alignment */
} Elf32_Phdr;

4、读取section header table: readelf -S app

[root@localhost l1]# readelf -S app
There are 45 section headers, starting at offset 0xba2850:

Section Headers:
  [Nr] Name              Type             Address           Offset         Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400270  00000270       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             000000000040028c  0000028c       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             00000000004002ac  000002ac       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .hash             HASH             00000000004002d0  000002d0       00000000000009ec  0000000000000004   A       5     0     8
  [ 5] .dynsym           DYNSYM           0000000000400cc0  00000cc0       00000000000022b0  0000000000000018   A       6     4     8
  [ 6] .dynstr           STRTAB           0000000000402f70  00002f70       00000000000015ac  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           000000000040451c  0000451c       00000000000002e4  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000404800  00004800       0000000000000220  0000000000000000   A       6     9     8
  [ 9] .rela.dyn         RELA             0000000000404a20  00004a20       0000000000000528  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000404f48  00004f48       0000000000001c98  0000000000000018  AI       5    28     8
  [11] .init             PROGBITS         0000000000406be0  00006be0       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         0000000000406c00  00006c00       0000000000001320  0000000000000010  AX       0     0     16
  [13] .text             PROGBITS         0000000000407f40  00007f40       00000000005009a2  0000000000000000  AX       0     0     64
  [14] text.unlikely     PROGBITS         00000000009088f0  005088f0       0000000000008af0  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         00000000009113e0  005113e0       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         0000000000911400  00511400       00000000001101e0  0000000000000000   A       0     0     64
  [17] .eh_frame_hdr     PROGBITS         0000000000a215e0  006215e0       000000000000c164  0000000000000000   A       0     0     4
  [18] .eh_frame         PROGBITS         0000000000a2d748  0062d748       00000000000eed24  0000000000000000   A       0     0     8
  [19] .gcc_except_table PROGBITS         0000000000b1c46c  0071c46c       000000000000116c  0000000000000000   A       0     0     4
  [20] .tdata            PROGBITS         0000000000d1de40  0071de40       0000000000000018  0000000000000000 WAT       0     0     64
  [21] .tbss             NOBITS           0000000000d1de80  0071de58       0000000000000840  0000000000000000 WAT       0     0     64
  [22] .init_array       INIT_ARRAY       0000000000d1de80  0071de80       00000000000003d0  0000000000000008  WA       0     0     8
  [23] .fini_array       FINI_ARRAY       0000000000d1e250  0071e250       0000000000000008  0000000000000008  WA       0     0     8
  [24] .jcr              PROGBITS         0000000000d1e258  0071e258       0000000000000008  0000000000000000  WA       0     0     8
  [25] .data.rel.ro      PROGBITS         0000000000d1e260  0071e260       0000000000000960  0000000000000000  WA       0     0     32
  [26] .dynamic          DYNAMIC          0000000000d1ebc0  0071ebc0       0000000000000300  0000000000000010  WA       6     0     8
  [27] .got              PROGBITS         0000000000d1eec0  0071eec0       0000000000000128  0000000000000008  WA       0     0     8
  [28] .got.plt          PROGBITS         0000000000d1f000  0071f000       00000000000009a0  0000000000000008  WA       0     0     8
  [29] .data             PROGBITS         0000000000d1f9c0  0071f9c0       000000000001fc80  0000000000000000  WA       0     0     64
  [30] .bss              NOBITS           0000000000d3f640  0073f640       000000000f0a0fa8  0000000000000000  WA       0     0     64
  [31] .lbss             NOBITS           000000000fde0600  0073f640       0000000005e02f40  0000000000000000 WAl       0     0     64
  [32] .comment          PROGBITS         0000000000000000  0073f640       000000000000002d  0000000000000001  MS       0     0     1
  [33] .debug_aranges    PROGBITS         0000000000000000  0073f66d       0000000000000030  0000000000000000           0     0     1
  [34] .debug_info       PROGBITS         0000000000000000  0073f69d       000000000019598a  0000000000000000           0     0     1
  [35] .debug_abbrev     PROGBITS         0000000000000000  008d5027       00000000000108d8  0000000000000000           0     0     1
  [36] .debug_line       PROGBITS         0000000000000000  008e58ff       000000000011511c  0000000000000000           0     0     1
  [37] .debug_frame      PROGBITS         0000000000000000  009faa1b       0000000000024ca0  0000000000000000           0     0     1
  [38] .debug_str        PROGBITS         0000000000000000  00a1f6bb       0000000000080d2c  0000000000000001  MS       0     0     1
  [39] .debug_loc        PROGBITS         0000000000000000  00aa03e7       0000000000004230  0000000000000000           0     0     1
  [40] .debug_ranges     PROGBITS         0000000000000000  00aa4617       0000000000043990  0000000000000000           0     0     1
  [41] .debug_opt_report PROGBITS         0000000000000000  00ae7fa7       0000000000032118  0000000000000000           0     0     1
  [42] .symtab           SYMTAB           0000000000000000  00b1a0c0       0000000000045b70  0000000000000018          43   6898     8
  [43] .strtab           STRTAB           0000000000000000  00b5fc30       0000000000042a64  0000000000000000           0     0     1
  [44] .shstrtab         STRTAB           0000000000000000  00ba2694       00000000000001bc  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)
[root@localhost l1]#

Section header 头格式

/* Section header.  */

typedef struct
{
  Elf32_Word    sh_name;                /* Section name (string tbl index) */
  Elf32_Word    sh_type;                /* Section type */
  Elf32_Word    sh_flags;               /* Section flags */
  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
  Elf32_Off     sh_offset;              /* Section file offset */
  Elf32_Word    sh_size;                /* Section size in bytes */
  Elf32_Word    sh_link;                /* Link to another section */
  Elf32_Word    sh_info;                /* Additional section information */
  Elf32_Word    sh_addralign;           /* Section alignment */
  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
} Elf32_Shdr;

5、由elf header可知:Start of section headers: 12200016

即section表的起始地址为 0xba2850(12200016)
大小为:64*45 = 2880
Size of section headers: 64 (bytes)
Number of section headers: 45

hexdump -s 12200016 -n 2880 -C l1app

6、查看反汇编代码: objdump -d app

7、由以上分析可以得出app结构为

------------------------------
|Section header table |
------------------------------- -->>addr:0xba2850
|    . . .    |
|    . . .    |
|    . . .    |
------------------------------- -->>addr:4002ac
|  .note.ABI-tag  |
------------------------------- -->>addr:40028c
|    .interp    |
------------------------------- -->> addr:400270
|           |
|           |
------------------------------- -->>addr:0x270
|Program header table|
------------------------------- -->> addr:0x40
|   ELF header  |
------------------------------- -->> addr:0x00

借用其它文章的图片:
在这里插入图片描述

8、动态库so文件中重要的Section:符号表、重定位表、GOT表

a)动态符号表(.dynsym) 可用 nm 命令查看符号表

typedef struct {  
     Elf32_Word st_name;     //符号表项名称。如果该值非0,则表示符号名的字符串表索引(offset),否则符号表项没有名称。
     Elf32_Addr st_value;    //符号的取值。依赖于具体的上下文,可能是一个绝对值、一个地址等等。
     Elf32_Word st_size;     //符号的尺寸大小。例如一个数据对象的大小是对象中包含的字节数。
     unsigned char st_info;  //符号的类型和绑定属性。
     unsigned char st_other; //该成员当前包含 0,其含义没有定义。
     Elf32_Half st_shndx;    //每个符号表项都以和其他节区的关系的方式给出定义。此成员给出相关的节区头部表索引。
} Elf32_sym;

b)字符串表(.dynstr)
c)全局偏移表(.got)
d)符号表(.symtab) .dynsym 是 .symtab 的一个子集

[root@localhost l1]# gdb l1app
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/lihongfu/Flexran1910_test_oamok/bin/nr5g/gnb/l1/l1app...done.
(gdb) info func phy_gnb_bbupool_unlock_ul_tasks
All functions matching regular expression "phy_gnb_bbupool_unlock_ul_tasks":

File nr5g/gnb_ul/gnb_ul_phy_bbu_tasks.c:
uint32_t phy_gnb_bbupool_unlock_ul_tasks(uint16_t, uint32_t, uint32_t, TaskBypassEnum);
(gdb)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Big Bear 12

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值