ELF optimization ---Analysis of linking and loading process

Put a few pictures first
Insert picture description here

ff@ubuntu:~/app/0$ readelf -a a4
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:               0x400430
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6704 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)  /** ELF文件头的大小, 对应上图的0x40 */
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         32
  Section header string table index: 29
如果想减小program的体积,可以删除一些没有必要的section,
这里增加一个section,将一个变量放入到该section中,看,他与其他section不同的是前面没有"."

这是Gcc一个特色,如,把一个函数指针放入到特定的section,然后需要的时候拿出来使用
当然了,可以使用 KEEP 来强制连接器保留一些特定的 section,
如果想让该section中的内容按照名字来排序的话,可以使用SORT

如: 
	. = ALIGN(8);
	KEEP(*(SORT(.scattered_array*)));
如:
    const initcall_t *call;
    
    for (call = initcall_begin; call < initcall_end; call++) {
	    ret = (*call)();	
	}	

Insert picture description here
Seeing the following .interp section hurts me badly. It contains the path name of the program interpreter. Because the dynamic linker is not found, the entire system hangs up
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
.

ELF Header

/usr/include/elf.h Insert picture description here
Okay, let’s take a look at how a C source code produces ELF after chemical changes in Gcc LLVM. The
magic number 8 is less than 8 bytes aligned here. Okay, move Let's get on the bench and watch the show!? Haha

Focus on the following st_value Symbol value, see how it is generated

 417 typedef struct
 418 {
    
    
 419   Elf64_Word    st_name;                /* Symbol name (string tbl index) */
 420   unsigned char st_info;                /* Symbol type and binding */
 421   unsigned char st_other;               /* Symbol visibility */
 422   Elf64_Section st_shndx;               /* Section index */
 423   Elf64_Addr    st_value;               /* Symbol value */
 424   Elf64_Xword   st_size;                /* Symbol size */
 425 } Elf64_Sym;

Symbolic address = The base address of the segment where the symbol is located + Offset within the segment where the symbol is located

/* 该符号在本文件中未定义 */
if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) {
    
      
	....
} else
	*where = rela->r_addend + sym_tab[sym_idx].st_value + vabase;

Guess you like

Origin blog.csdn.net/leesagacious/article/details/87530313