linux下的三种可执行文件格式的比较

aix xcoff可执行文件分析1 注意:分析中没有明确说明32bit,64bit模式,仅记录本人学习过程,其数据、说明可能不正确、准确,请自行核实。如果许久以后,恰逢本人无聊,也许会重新整理一个标准的说明系列出来,当然,这是遥遥无期的事情,您千万别有期待。 如果有对xcoff兴趣的同道想深入分析,欢迎留言探讨。 看起来XCOFF比ELF复杂不少,但ELF有自己的先进特点,例如自带interceptor,所以所谓复杂,并不代表xco... 阅读详情
本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editoroutput
汇编器和链接编辑器的输出)、COFF(Common Object File Format通用对象文件格式)、ELF(Executable
and Linking Format 可执行和链接格式)。首先是对可执行文件格式的一个综述,并通过描述 ELF
文件加载过程以揭示可执行文件内容与加载运行操作之间的关系。随后依此讨论了此三种文件格式,并着重讨论 ELF
文件的动态连接机制,其间也穿插了对各种文件格式优缺点的评价。最后对三种可执行文件格式有一个简单总结,并提出作者对可文件格式评价的一些感想。
可执行文件格式综述
相
对于其它文件类型,可执行文件可能是一个操作系统中最重要的文件类型,因为它们是完成操作的真正执行者。可执行文件的大小、运行速度、资源占用情况以及可
扩展性、可移植性等与文件格式的定义和文件加载过程紧密相关。研究可执行文件的格式对编写高性能程序和一些黑客技术的运用都是非常有意义的。
不
管何种可执行文件格式,一些基本的要素是必须的,显而易见的,文件中应包含代码和数据。因为文件可能引用外部文件定义的符号(变量和函数),因此重定位信
息和符号信息也是需要的。一些辅助信息是可选的,如调试信息、硬件信息等。基本上任意一种可执行文件格式都是按区间保存上述信息,称为段
(Segment)或节(Section)。不同的文件格式中段和节的含义可能有细微区别,但根据上下文关系可以很清楚的理解,这不是关键问题。最后,可
执行文件通常都有一个文件头部以描述本文件的总体结构。
相
对可执行文件有三个重要的概念:编译(compile)、连接(link,也可称为链接、联接)、加载(load)。源程序文件被编译成目标文件,多个目
标文件被连接成一个最终的可执行文件,可执行文件被加载到内存中运行。因为本文重点是讨论可执行文件格式,因此加载过程也相对重点讨论。下面是LINUX
平台下ELF文件加载过程的一个简单描述。
1:
内核首先读ELF文件的头部,然后根据头部的数据指示分别读入各种数据结构,找到标记为可加载(loadable)的段,并调用函数
mmap()把段内容加载到内存中。在加载之前,内核把段的标记直接传递给
mmap(),段的标记指示该段在内存中是否可读、可写,可执行。显然,文本段是只读可执行,而数据段是可读可写。这种方式是利用了现代操作系统和处理器
对内存的保护功能。著名的Shellcode(参考资料 17)的编写技巧则是突破此保护功能的一个实际例子。
2:内核分析出ELF文件标记为PT_INTERP 的段中所对应的动态连接器名称,并加载动态连接器。现代 LINUX 系统的动态连接器通常是/lib/ld-linux.so.2,相关细节在后面有详细描述。
3:内核在新进程的堆栈中设置一些标记-值对,以指示动态连接器的相关操作。
4:内核把控制传递给动态连接器。
5:动态连接器检查程序对外部文件(共享库)的依赖性,并在需要时对其进行加载。
6:动态连接器对程序的外部引用进行重定位,通俗的讲,就是告诉程序其引用的外部变量/函数的地址,此地址位于共享库被加载在内存的区间内。动态连接还有一个延迟(Lazy)定位的特性,即只在"真正"需要引用符号时才重定位,这对提高程序运行效率有极大帮助。
7:动态连接器执行在ELF文件中标记为.init 的节的代码,进行程序运行的初始化。在早期系统中,初始化代码对应函数_init(void)(函数名强制固定),在现代系统中,则对应形式为
void
__attribute((constructor))
init_function(void)
{
……
}其中函数名为任意。LdeLinux联盟

8:动态连接器把控制传递给程序,从 ELF文件头部中定义的程序进入点开始执行。在 a.out 格式和ELF格式中,程序进入点的值是显式存在的,在 COFF格式中则是由规范隐含定义。
从
上面的描述可以看出,加载文件最重要的是完成两件事情:加载程序段和数据段到内存;进行外部定义符号的重定位。重定位是程序连接中一个重要概念。我们知
道,一个可执行程序通常是由一个含有 main() 的主程序文件、若干目标文件、若干共享库(Shared
Libraries)组成。(注:采用一些特别的技巧,也可编写没有 main 函数的程序,请参阅参考资料 2)一个 C
程序可能引用共享库定义的变量或函数,换句话说就是程序运行时必须知道这些变量/函数的地址。在静态连接中,程序所有需要使用的外部定义都完全包含在可执
行程序中,而动态连接则只在可执行文件中设置相关外部定义的一些引用信息,真正的重定位是在程序运行之时。静态连接方式有两个大问题:如果库中变量或函数
有任何变化都必须重新编译连接程序;如果多个程序引用同样的变量/函数,则此变量/函数会在文件/内存中出现多次,浪费硬盘/内存空间。比较两种连接方式
生成的可执行文件的大小,可以看出有明显的区别。
a.out文件格式分析
a.out格式在不同的机器平台和不同的 UNIX 操作系统上有轻微的不同,例如在 MC680x0 平台上有 6 个section。下面我们讨论的是最"标准"的格式。
a.out文件包含 7 个 section,格式如下:
execheader(执行头部,也可理解为文件头部)
textsegment(文本段)
datasegment(数据段)
textrelocations(文本重定位段)
datarelocations(数据重定位段)
symboltable(符号表)
stringtable(字符串表)
执行头部的数据结构:
struct exec {
 
     unsignedlong  a_midmag;  
       unsignedlong   a_text;     
       unsignedlong   a_data;     
       unsignedlong   a_bss;     
       unsignedlong   a_syms;     
       unsignedlong   a_entry;    
       unsignedlong  a_trsize;  
       unsignedlong  a_drsize;  
};文
件头部主要描述了各个 section 的长度,比较重要的字段是
a_entry(程序进入点),代表了系统在加载程序并初试化各种环境后开始执行程序代码的入口。这个字段在后面讨论的 ELF
文件头部中也有出现。由 a.out 格式和头部数据结构我们可以看出,a.out
的格式非常紧凑,只包含了程序运行所必须的信息(文本、数据、BSS),而且每个 section
的顺序是固定的。这种结构缺乏扩展性,如不能包含"现代"可执行文件中常见的调试信息,最初的 UNIX 黑客对 a.out文件调试使用的工具是
adb,而 adb 是一种机器语言调试器! LdeLinux联盟
a.out
文件中包含符号表和两个重定位表,这三个表的内容在连接目标文件以生成可执行文件时起作用。在最终可执行的 a.out文件中,这三个表的长度都为
0。a.out
文件在连接时就把所有外部定义包含在可执行程序中,如果从程序设计的角度来看,这是一种硬编码方式,或者可称为模块之间是强藕和的。在后面的讨论中,我们
将会具体看到ELF格式和动态连接机制是如何对此进行改进的。
a.out
是早期UNIX系统使用的可执行文件格式,由 AT&T 设计,现在基本上已被 ELF文件格式代替。a.out
的设计比较简单,但其设计思想明显的被后续的可执行文件格式所继承和发扬。可以参阅参考资料 16 和阅读参考资料 15 源代码加深对a.out
格式的理解。参考资料 12 讨论了如何在"现代"的红帽LINUX运行 a.out 格式文件。
COFF文件格式分析
COFF 格式比a.out 格式要复杂一些,最重要的是包含一个节段表(section table),因此除了 .text,.data,和 .bss区段以外,还可以包含其它的区段。另外也多了一个可选的头部,不同的操作系统可一对此头部做特定的定义。
COFF文件格式如下:
File Header(文件头部)
Optional Header(可选文件头部)
Section 1 Header(节头部)
………
Section n Header(节头部)
Raw Data for Section 1(节数据)
Raw Data for Section n(节数据)
Relocation Info for Sect. 1(节重定位数据)
Relocation Info for Sect. n(节重定位数据)
Line Numbers for Sect. 1(节行号数据)
Line Numbers for Sect. n(节行号数据)
Symbol table(符号表)
String table(字符串表)文件头部的数据结构:
struct filehdr
   {
    unsignedshort  f_magic;  
      unsignedshort  f_nscns;  
      long        f_timdat;  
      long        f_symptr;  
      long        f_nsyms;  
      unsignedshort  f_opthdr;  
      unsignedshort  f_flags;  
   };COFF
文件头部中魔数与其它两种格式的意义不太一样,它是表示针对的机器类型,例如 0x014c 相对于 I386 平台,而 0x268相对于
Motorola 68000系列等。当 COFF 文件为可执行文件时,字段 f_flags 的值为
F_EXEC(0X00002),同时也表示此文件没有未解析的符号,换句话说,也就是重定位在连接时就已经完成。由此也可以看出,原始的COFF
格式不支持动态连接。为了解决这个问题以及增加一些新的特性,一些操作系统对 COFF 格式进行了扩展。Microsoft设计了名为
PE(Portable Executable)的文件格式,主要扩展是在 COFF文件头部之上增加了一些专用头部,具体细节请参阅参考资料
18,某些 UNIX 系统也对 COFF 格式进行了扩展,如 XCOFF(extended common objectfile
format)格式,支持动态连接,请参阅参考资料 5。
紧接文件头部的是可选头部,COFF文件格式规范中规定可选头部的长度可以为 0,但在 LINUX 系统下可选头部是必须存在的。下面是 LINUX下可选头部的数据结构:
typedef struct
{
    char  magic[2];  
    char  vstamp[2];  
    char  tsize[4];  
    char  dsize[4];  
    char  bsize[4];  
    char  entry[4];  
    char  text_start[4];     
    char  data_start[4];     
}
COFF_AOUTHDR;
字段 magic为 0413 时表示 COFF 文件是可执行的,注意到可选头部中显式定义了程序进入点,标准的 COFF文件没有明确的定义程序进入点的值,通常是从 .text 节开始执行,但这种设计并不好。
前
面我们提到,COFF 格式比 a.out 格式多了一个节段表,一个节头条目描述一个节数据的细节,因此 COFF
格式能包含更多的节,或者说可以根据实际需要,增加特定的节,具体表现在 COFF 格式本身的定义以及稍早提及的 COFF
格式扩展。我个人认为,节段表的出现可能是 COFF 格式相对 a.out 格式最大的进步。下面我们将简单描述 COFF
文件中节的数据结构,因为节的意义更多体现在程序的编译和连接上,所以本文不对其做更多的描述。此外,ELF 格式和
COFF格式对节的定义非常相似,在随后的 ELF 格式分析中,我们将省略相关讨论。
struct COFF_scnhdr
{
    chars_name[8];    
    chars_paddr[4];   
   chars_vaddr[4];   
    chars_size[4];    
   chars_scnptr[4];   
    chars_relptr[4];   
    chars_lnnoptr[4];   
    chars_nreloc[2];   
    chars_nlnno[2];   
    chars_flags[4];   
};有
一点需要注意:LINUX系统中头文件coff.h中对字段 s_paddr的注释是"physical
address",但似乎应该理解为"节被加载到内存中所占用的空间长度"。字段s_flags标记该节的类型,如文本段、数据段、BSS段等。在
COFF的节中也出现了行信息,行信息描述了二进制代码与源代码的行号之间的对映关系,在调试时很有用。
参考资料19是一份对COFF格式详细描述的中文资料,更详细的内容请参阅参考资料 20。
ELF文件格式分析
ELF
文件有三种类型:可重定位文件:也就是通常称的目标文件,后缀为.o。共享文件:也就是通常称的库文件,后缀为.so。可执行文件:本文主要讨论的文件格
式,总的来说,可执行文件的格式与上述两种文件的格式之间的区别主要在于观察的角度不同:一种称为连接视图(Linking
View),一种称为执行视图(Execution View)。
首先看看ELF文件的总体布局:
ELF header(ELF头部)
Program header table(程序头表)
Segment1(段1)
Segment2(段2)
………
Sengmentn(段n)
Setion header table(节头表,可选)段
由若干个节(Section)构成,节头表对每一个节的信息有相关描述。对可执行程序而言,节头表是可选的。参考资料
1中作者谈到把节头表的所有数据全部设置为0,程序也能正确运行!ELF头部是一个关于本文件的路线图(road
map),从总体上描述文件的结构。下面是ELF头部的数据结构:
typedef struct
{
    unsigned chare_ident[EI_NIDENT];    
    Elf32_Half   e_type;            
    Elf32_Half   e_machine;          
    Elf32_Word   e_version;          
    Elf32_Addr   e_entry;           
    Elf32_Off    e_phoff;           
    Elf32_Off    e_shoff;           
    Elf32_Word   e_flags;           
    Elf32_Half   e_ehsize;           
    Elf32_Half   e_phentsize;         
    Elf32_Half   e_phnum;           
    Elf32_Half   e_shentsize;         
    Elf32_Half   e_shnum;           
    Elf32_Half   e_shstrndx;         
} Elf32_Ehdr;下面我们对ELF头表中一些重要的字段作出相关说明,完整的ELF定义请参阅参考资料6和参考资料7。
e_ident[0]-e_ident[3]
包含了ELF文件的魔数,依次是0x7f、'E'、'L'、'F'。注意,任何一个ELF文件必须包含此魔数。参考资料
3中讨论了利用程序、工具、/Proc文件系统等多种查看ELF魔数的方法。e_ident[4]表示硬件系统的位数,1代表32位,2代表64位。
e_ident[5]表示数据编码方式,1代表小印第安排序(最大有意义的字节占有最低的地址),2代表大印第安排序(最大有意义的字节占有最高的地
址)。e_ident[6]指定ELF头部的版本,当前必须为1。e_ident[7]到e_ident[14]是填充符,通常是0。ELF格式规范中定
义这几个字节是被忽略的,但实际上是这几个字节完全可以可被利用。如病毒Lin/Glaurung.676/666(参考资料
1)设置e_ident[7]为0x21,表示本文件已被感染;或者存放可执行代码(参考资料
2)。ELF头部中大多数字段都是对子头部数据的描述,其意义相对比较简单。值得注意的是某些病毒可能修改字段e_entry(程序进入点)的值,以指向
病毒代码,例如上面提到的病毒Lin/Glaurung.676/666。
一个实际可执行文件的文件头部形式如下:(利用命令readelf)
ELF Header:
   Magic:  7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 0000
   Class:                    ELF32
   Data:                     2'scomplement, little endian
   Version:                   1(current)
   OS/ABI:                    UNIX -System V
   ABI Version:                0
   Type:                     EXEC(Executable file)
   Machine:                   Intel80386
   Version:                   0x1
   Entry pointaddress:           0x80483cc
   Start of programheaders:         52 (bytesinto file)
   Start of sectionheaders:         14936(bytes into file)
   Flags:                    0x0
   Size of thisheader:            52(bytes)
   Size of programheaders:         32(bytes)
   Number of programheaders:        6
   Size of sectionheaders:         40(bytes)
   Number of sectionheaders:        34
   Section header string tableindex: 31紧接ELF头部的是程序头表,它是一个结构数组,包含了ELF头表中字段e_phnum定义的条目,结构描述一个段或其他系统准备执行该程序所需要的信息。
typedef struct {
     Elf32_Word  p_type;  
     Elf32_Off  p_offset;      
     Elf32_Addr  p_vaddr;     
     Elf32_Addr  p_paddr;     
     Elf32_Word  p_filesz;  
     Elf32_Word  p_memsz;  
     Elf32_Word  p_flags;  
     Elf32_Word  p_align;  
  } Elf32_Phdr;在详细讨论可执行文件程序头表之前,首先查看一个实际文件的输出:
Program Headers:
Type         Offset  VirtAddr  PhysAddr  FileSizMemSiz  Flg Align
PHDR         0x0000340x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
INTERP        0x0000f40x080480f4 0x080480f4 0x00013 0x00013 R  0x1
     [Requesting program interpreter:/lib/ld-linux.so.2]
   LOAD        0x0000000x08048000 0x08048000 0x00684 0x00684 R E 0x1000
   LOAD        0x0006840x08049684 0x08049684 0x00118 0x00130RW  0x1000
   DYNAMIC      0x0006900x08049690 0x08049690 0x000c8 0x000c8RW  0x4
   NOTE        0x0001080x08048108 0x08048108 0x00020 0x00020 R  0x4
  Section to Segmentmapping:
  Segment Sections...
   00    
   01    .interp
   02    .interp.note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.
version_r .rel.dyn .rel.plt
.init .plt .text .fini .rodata .eh_frame
   03    .data.dynamic .ctors .dtors .jcr .got .bss
   04    .dynamic
05    .note.ABI-tag
Section Headers:
  [Nr] Name          Type        Addr    Off   Size   ES FlgLk Inf Al
  [ 0]             NULL          00000000000000 000000 00    0  0  0
  [ 1] .interp        PROGBITS      080480f40000f4 000013 00  A  0  0  1
  [ 2].note.ABI-tag    NOTE         08048108000108 000020 00  A  0  0  4
  [ 3] .hash         HASH          08048128000128 000040 04  A  4  0  4
  [ 4] .dynsym        DYNSYM        08048168000168 0000b0 10  A  5  1  4
  [ 5] .dynstr        STRTAB        08048218000218 00007b 00  A  0  0  1
  [ 6].gnu.version     VERSYM        08048294000294 000016 02  A  4  0  2
  [ 7].gnu.version_r   VERNEED        080482ac0002ac 000030 00  A  5  1  4
  [ 8] .rel.dyn       REL           080482dc0002dc 000008 08  A  4  0  4
  [ 9] .rel.plt       REL           080482e40002e4 000040 08  A  4  b  4
  [10] .init         PROGBITS       08048324000324 00001700  AX  0  0  4
  [11] .plt          PROGBITS      0804833c00033c 00009004  AX  0  0  4
  [12] .text         PROGBITS       080483cc0003cc 0001f800  AX  0  0  4
  [13] .fini         PROGBITS       080485c40005c4 00001b00  AX  0  0  4
  [14] .rodata        PROGBITS      080485e00005e0 00009f 00  A  0  0 32
  [15].eh_frame       PROGBITS      08048680000680 000004 00  A  0  0  4
  [16] .data         PROGBITS       08049684000684 00000c00  WA  0  0  4
  [17] .dynamic       DYNAMIC        08049690000690 0000c808  WA  5  0  4
  [18] .ctors        PROGBITS      08049758000758 00000800  WA  0  0  4
  [19] .dtors        PROGBITS      08049760000760 00000800  WA  0  0  4
  [20] .jcr          PROGBITS      08049768000768 00000400  WA  0  0  4
  [21] .got          PROGBITS      0804976c00076c 00003004  WA  0  0  4
  [22] .bss          NOBITS        0804979c00079c 00001800  WA  0  0  4
  [23] .comment       PROGBITS       0000000000079c 000132 00    0  0  1
  [24].debug_aranges   PROGBITS       000000000008d0 000098 00    0  0  8
  [25].debug_pubnames  PROGBITS      00000000000968 000040 00    0  0  1
  [26].debug_info      PROGBITS      000000000009a8 001cc6 00    0  0  1
  [27].debug_abbrev    PROGBITS      0000000000266e 0002cc 00    0  0  1
  [28].debug_line      PROGBITS      0000000000293a 0003dc 00    0  0  1
  [29].debug_frame     PROGBITS      00000000002d18 000048 00    0  0  4
  [30].debug_str       PROGBITS      00000000002d60 000bcd01  MS  0  0  1
  [31].shstrtab       STRTAB        0000000000392d 00012b 00    0  0  1
  [32] .symtab        SYMTAB        00000000003fa8 000740 10    33  56  4
  [33] .strtab        STRTAB        000000000046e8 000467 00    0  0  1对
一个ELF可执行程序而言,一个基本的段是标记p_type为PT_INTERP的段,它表明了运行此程序所需要的程序解释器(/lib/ld-
linux.so.2),实际上也就是动态连接器(dynamic
linker)。最重要的段是标记p_type为PT_LOAD的段,它表明了为运行程序而需要加载到内存的数据。查看上面实际输入,可以看见有两个可
LOAD段,第一个为只读可执行(FLg为R
E),第二个为可读可写(Flg为RW)。段1包含了文本节.text,注意到ELF文件头部中程序进入点的值为0x80483cc,正好是指向节.
text在内存中的地址。段二包含了数据节.data,此数据节中数据是可读可写的,相对的只读数据节.rodata包含在段1中。ELF格式可以比
COFF格式包含更多的调试信息,如上面所列出的形式为.debug_xxx的节。在I386平台LINUX系统下,用命令file查看一个ELF可执行
程序的可能输出是:a.out: ELF 32-bit LSB executable, Intel 80386, version1
(SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs),not
stripped。
ELF文件中包含了动态连接器的全路径,内核定位"正确"的动态连接器在内存中的地址是"正确"运行可执行文件的保证,参考资料13讨论了如何通过查找动态连接器在内存中的地址以达到颠覆(Subversiver)动态连接机制的方法。
最
后我们讨论ELF文件的动态连接机制。每一个外部定义的符号在全局偏移表(Global Offset Table
GOT)中有相应的条目,如果符号是函数则在过程连接表(Procedure Linkage Table
PLT)中也有相应的条目,且一个PLT条目对应一个GOT条目。对外部定义函数解析可能是整个ELF文件规范中最复杂的,下面是函数符号解析过程的一个
描述。
1:代码中调用外部函数func,语句形式为call0xaabbccdd,地址0xaabbccdd实际上就是符号func在PLT表中对应的条目地址(假设地址为标号.PLT2)。
2:PLT表的形式如下
.PLT0: pushl  4(�x)   

jmp    *8(�x)
         nop;nop
         nop;nop
   .PLT1: jmp    *name1@GOT(�x)
        pushl   $offset
        jmp    .PLT0@PC
   .PLT2: jmp    *func@GOT(�x)
        pushl   $offset
        jmp    .PLT0@PC3:查看标号.PLT2的语句,实际上是跳转到符号func在GOT表中对应的条目。
4:在符号没有重定位前,GOT表中此符号对应的地址为标号.PLT2的下一条语句,即是pushl$offset,其中$offset是符号func的重定位偏移量。注意到这是一个二次跳转。
5:在符号func的重定位偏移量压栈后,控制跳到PLT表的第一条目,把GOT[1]的内容压栈,并跳转到GOT[2]对应的地址。LdeLinux联盟

6:GOT[2]对应的实际上是动态符号解析函数的代码,在对符号func的地址解析后,会把func在内存中的地址设置到GOT表中此符号对应的条目中。
7:当第二次调用此符号时,GOT表中对应的条目已经包含了此符号的地址,就可直接调用而不需要利用PLT表进行跳转。
动态连接是比较复杂的,但为了获得灵活性的代价通常就是复杂性。其最终目的是把GOT表中条目的值修改为符号的真实地址,这也可解释节.got包含在可读可写段中。
动
态连接是一个非常重要的进步,这意味着库文件可以被升级、移动到其他目录等等而不需要重新编译程序(当然,这不意味库可以任意修改,如函数入参的个数、数
据类型应保持兼容性)。从很大程度上说,动态连接机制是ELF格式代替a.out格式的决定性原因。如果说面对对象的编程本质是面对接口
(interface)的编程,那么动态连接机制则是这种思想的地一个非常典型的应用,具体的讲,动态连接机制与设计模式中的桥接(BRIDGE)方法比
较类似,而它的LAZY特性则与代理(PROXY)方法非常相似。动态连接操作的细节描述请参阅参考资料
8,9,10,11。通过阅读命令readelf、objdump 的源代码以及参考资料
14中所提及的相关软件源代码,可以对ELF文件的格式有更彻底的了解。
总结
不
同时期的可执行文件格式深刻的反映了技术进步的过程,技术进步通常是针对解决存在的问题和适应新的环境。早期的UNIX系统使用a.out格式,随着操作
系统和硬件系统的进步,a.out格式的局限性越来越明显。新的可执行文件格式COFF在UNIX System
VR3中出现,COFF格式相对a.out格式最大变化是多了一个节头表(section head
table),能够在包含基础的文本段、数据段、BSS段之外包含更多的段,但是COFF对动态连接和C++程序的支持仍然比较困难。为了解决上述问题,
UNIX系统实验室(UNIX SYSTEM Laboratories USL)
开发出ELF文件格式,它被作为应用程序二进制接口(Application binary Interface
ABI)的一部分,其目的是替代传统的a.out格式。例如,ELF文件格式中引入初始化段.init和结束段.fini(分别对应构造函数和析构函数)
则主要是为了支持C++程序。1994年6月ELF格式出现在LINUX系统上,现在ELF格式作为UNIX/LINUX最主要的可执行文件格式。当然我
们完全有理由相信,在将来还会有新的可执行文件格式出现。
上
述三种可执行文件格式都很好的体现了设计思想中分层的概念,由一个总的头部刻画了文件的基本要素,再由若干子头部/条目刻画了文件的若干细节。比较一下可
执行文件格式和以太数据包中以太头、IP头、TCP头的设计,我想我们能很好的感受分层这一重要的设计思想。参考资料
21从全局的角度讨论了各种文件的格式,并提出一个比较夸张的结论:Everything Is Byte!
最
后的题外话:大多数资料中对a.out格式的评价较低,常见的词语有黑暗年代(dark
ages)、丑陋(ugly)等等,当然,从现代的观点来看,的确是比较简单,但是如果没有曾经的简单何来今天的精巧?正如我们今天可以评价石器时代的技
术是ugly,那么将来的人们也可以嘲讽今天的技术是非常ugly。我想我们也许应该用更平和的心态来对曾经的技术有一个公正的评价。

执行XCOFF(AIX)程序的两种方案比较 最后更新2021/12/17 xcoff程序与AIX(OS)、Power服务器、Power ISA紧密绑定,尽管没有任何硬性规定xcoff不能跑在别的OS或者CPU之上,但到目前为止,这四者差不多四位一体,主体上是捆在一起的。 Power ISA,只有IBM Power CPU一种实现,甚至用于嵌入式的PowerPC产品都越来越少了。当然IBM借助于OpenPower基金会,也做了若干努力,例如搞了一些新的开源产品,包括Microwatt等,这是在对抗x86和ARM扬汤止沸动作中,又拼命想移除RISC-V 阅读详情

相关推荐

PE和ELF可执行文件格式

PE: 是目前Windows平台上主流的可执行文件格式,包括常见的可执行程序.EXE文件/动态链接库.DLL文件等等。详见:PE可执行文件格式详解 - 知乎 ELF:是一种用于二进制文件、可执行文件、目标代码、共享库和core转存格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。详见:ELF文件格式 - 知乎 ...

vily_lei的专栏 2247

sqlite3 not found 或者 not executable:32-bit ELF file解决办法

首先,基于真机情况下出现的此错误,手机已经root过. 问题: sqlite3 not found是因为当我们执行 sqlite3 .. 的命令时,就会去系统的可执行区域 即 system/xbin 目录下查找 sqlite3 .如果该文件不存在,就会报这个错。 解决方式: 提醒: 建议先去 打开shell 环境 cd /proc 然后 cat cpuinfo 查看一下系统的 ...

派派的生活 5184

RK3568 MIPI屏幕启动异常:从uboot logo到黑屏的排查与修复

本文详细分析了RK3568平台MIPI屏幕在启动过程中,从uboot阶段正常显示logo到内核阶段黑屏的典型故障。通过硬件测量与软件调试,最终定位问题根源在于电源时序,并提供了在设备树中为屏幕供电的regulator节点添加`regulator-boot-on`属性的关键解决方案,有效解决了因内核启动早期电源管理导致的显示异常。

weixin_29161719的博客 544

编译中使用strip的介绍

E-MAIL: huangxiaolong@mails.ccnu.edu.cn 什么是strip? strip经常用来去除目标文件中的一些符号表、调试符号表信息,以减小程序的大小。 Strip的原理? strip 命令减少 XCOFF(Common Object File Format) 对象文件的大小。strip 命令从 XCOFF 对象文件中有选择地除去行号信息、重定位信息、调试段、typ...

sevennineeleven的博客 2万+

KIBANA可视化管理界面说明

更说明转自https://blog.youkuaiyun.com/IT_ZRS/article/details/125496588 1 主要结构功能 使用浏览器访问 ip:5601 默认端口,进入首页 Discover:日志管理视图 主要进行搜索和查询 Visualize:统计视图 构建可视化的图表 Dashboard:仪表视图 将构建的图表组合形成图表盘 Timelion:时间轴视图 随着时间流逝的数据 APM:性能管理视图 应用程序的性能管理系统 Canvas:大屏展示

tian830937的专栏 7086

基于Python大数据的智能交通分析系统

该系统能够实时监测交通状况,分析交通流量,预测交通趋势,为交通管理部门提供决策支持,帮助缓解交通拥堵,提高交通运行效率,减少交通事故发生率,改善市民出行体验。它能够为交通管理部门提供决策支持,帮助缓解交通拥堵,提高交通运行效率,减少交通事故发生率,改善市民出行体验,促进交通产业的健康发展。数据采集层:通过传感器、GPS设备、交通摄像头等数据源,实时采集交通数据,如车辆速度、位置、道路拥堵情况等。数据分析层:运用统计学方法、机器学习算法等,对处理后的数据进行深入分析,挖掘交通规律,预测交通趋势。

qq3828614760的博客 2969

strip 命令的使用方法

用途 通过除去绑定程序和符号调试程序使用的信息,降低扩展公共对象文件格式(XCOFF)的对象文件的大小。 语法 strip [ -V ] [ -r [ -l ] | -x [ -l ] | -t | -H | -e | -E ] [ -X {32 |64 |32...

weixin_34195546的博客 339

陀螺仪与加速度计的姿态融合——互补滤波

本篇文章我们来讲讲如何将陀螺仪和加速度计的数据结合起来,获取更准确的姿态数据,使用的是互补滤波的方法。

小白白学电子 2万+

LINUX 平台可执行文件格式分析

   级别: 初级施聪 (memncmp@yahoo.com.cn), 高级程序员、网络设计师 本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Exe

steadyman_wang的专栏 981

【MATLAB-app】csdn上第一套关于matlab appdesigner界面设计 系列“视频课”来啦~~

写作时间: 2020-12-10 标题: 01_为什么推荐你学习appdesigner? 目录: 1.什么是appdesigner? 2.appdesigner能干什么,有什么好处? 3.怎么学习?保证你一周内能够学会! 4.我的课程总目录 5.重磅来袭(如何获取学习资料代码+文档+视频) 正文: 1.什么是appdesigner? 2.appdesigner能干什么,有什么好处? 3.怎么学习?保证你一周内能够学会! 4.我的课程总目录 5.重磅来袭(如何获取学习资料代码+文档+视频) THE END

wind 2万+

152:vue+leaflet 判断一个点是否在一个电子围栏内

本文介绍了一个基于Vue+Leaflet的示例,演示如何判断点是否在电子围栏内。作者大剑师兰特(优快云知名博主)展示了使用polygon.getBounds().contains(latlng)方法检测点与多边形边界的关系。代码仅需80行,通过点击地图触发判断逻辑,结果显示提示信息。该技术可广泛应用于地理围栏、位置服务等场景,需要安装turf依赖。文章提供了完整源码和配置说明,适合GIS开发者学习参考。

大剑师兰特的GIS世界 758

linux 可执行文件格式分析

UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Executable and Linking Format 可执行和链接格式)。 可...

u014358841的博客 1568

matlab 异常值检测与处理——Robust Z-score法【2024最新版】

博客长期更新,本文最近一次更新时间为:2024年12月9日。

点云侠的博客 1516

linux可执行文件格式

可执行文件可以是具有不同格式的二进制文件,也可以是一个文本的脚本。可执行文件映像中包含了进程执行的代码和数据,同时也包含了操作系统用来将映像正确装入内存并执行的信息。在Linux中,当前的“本地”(系统默认的)可执行文件格式是ELF[15] (Executable and Linking Format)可执行链接格式。由于先前的a.out格式难于实现共享库,不能适用于动态链接,所以目前已经全部被E

dadalan的专栏 5272

基于深度学习的商品标签识别系统:UI界面 + YOLOv8/v7/v6/v5代码 + 训练数据集

基于YOLO系列模型的商品标签识别系统能够有效解决商品信息提取的自动化问题。通过合理的数据集准备、模型训练和UI设计,我们可以实现一个功能强大的商品标签识别系统。希望本文提供的内容能够为大家提供有价值的帮助。

YOLO 476

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

UNIX-LINUX平台可执行文件格式分析

UNIX-LINUX平台可执行文件格式分析 作者:施聪 本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Executable and Linking Format 可执行和链接格式...

weixin_30954607的博客 187

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

目标文件和可执行文件的存储格式

目标文件和可执行文件里面都有什么。编译器编译源代码(由于汇编比较简单,这里汇编包含在编译中)后生成的文件叫做目标文件(Object File),例如 Visual Studio 下的.obj,或者 GCC 下的.o。

草上爬的博客 3830

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

UNIX/LINUX 平台可执行文件格式分析(转)

<br />施聪 (memncmp@yahoo.com.cn ), 高级程序员、网络设计师<br />简介:  本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、COFF(Common Object File Format 通用对象文件格式)、ELF(Executable and Linking Format 可执行和链接格式)。首先是对可执行文件格式的一个综述,并通

阿弥陀佛 僧伽吒 846

Linux可执行文件的格式ELF

在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题。 示例程序 我们的示例程序如下: //hello.c #include<stdio.h> int main(int argc,char *argv[]) { printf("hello shouwangxiansheng\n"); return ...

我的博客 1552

Linux 下的可执行文件格式 ELF 全解析

可重定位文件(Relocatable File):包含代码和数据,可以与其他目标文件合并,创建可执行文件或共享目标文件。例如,在编译过程中生成的.o文件就是可重定位文件。可执行文件(Executable File):可以直接在系统上运行的文件,包含了程序执行的入口点以及运行所需的代码和数据。共享目标文件(Shared Object File):也称为共享库,在程序运行时可以被动态加载和链接,多个进程可以共享同一个共享库,节省内存空间。例如,常见的.so文件就是共享目标文件。

m0_57836225的博客 2241

a.ou、coff、elf三种文件格式

转自:http://blog.chinaunix.net/uid-11469366-id-1747286.html 补充:a.out早期并不是elf格式的,而是unix下另一种可执行格式,新的a.out是 本文讨论了 UNIX/LINUX 平台下三种主要的可执行文件格式:a.out(assembler and link editor output 汇编器和链接编辑器的输出)、C

Macross的专栏 4862
下一篇: ubuntu中获取命令的源代码
AstrayLinux
博客等级 码龄15年 55粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值