豹哥嵌入式讲堂:ARM Cortex-M开发的文件详解(6)- 可执行文件(.out/.elf)

2.1.1 GNU工具集(binutils)

  GNU是“GNU’s Not
Unix”的递归缩写,又称为GNU计划,很多有名的开源软件和工具都是GNU开发之(比如有名的C语言编译器GCC)。binutils是GNU一系列binary小器的会师,大家从下边的链接里找到官方binutils包。

主页:http://www.gnu.org/software/binutils/
仓库:git://sourceware.org/git/binutils-gdb.git
下载:http://ftp.gnu.org/gnu/binutils/
文档:https://sourceware.org/binutils/docs-2.29/binutils/index.html

  但是用上述包里之readelf会有一个题材,上述工具是当Linux系统下采取的,而大家平常做ARM
Cortex-M开发多还是于windows平台下,那么怎么在windows下行使readelf工具也?别急,cygwin给了俺们帮忙。

当下底图服务器架设(分布式文件系统+CDN)

当构建当前底图片服务器架设之前,可以优先彻底废除web服务器,直接配置单独的图形服务器/域名。但面临如下的题材:

  1. 原来图数怎么收拾?能否继续配合旧图路径访问规则?
  2. 独立的图片服务器上待提供单身的上传写入的接口(服务API对外公布),安全问题怎么保证?
  3. 同理,假如有多光独立图片服务器,是使可扩大的共享存储方案,还是用实时同步机制?

 

以至应用级别之(非系统级) DFS(例如FastDFS HDFS MogileFs
MooseFS、TFS)的盛行,简化了是题材:执行冗余备份、支持电动同步、支持线性扩展、支持主流语言的客户端api上传/下载/删除等操作,部分支持文件目录,部分支持提供Web的道来走访。

设想到各DFS的性状,客户端API语言支持情况(需要支持C#),文档和案例,以及社区的支持度,我们最终摘取了FastDFS来配置。

唯的题材是:可能会见不般配旧本子的拜访规则。如果拿老图一次性导入FastDFS,但出于原图看路径分布存储在不同工作数据库的一一表中,整体创新起来为十分困难,所以要得相当旧本子的访问规则。架构升级往往比较做全新架构更发出难度,就是以还要配合之前版本的题目。(给飞机在空中换引擎可正如造架飞机难以得多)

2.1.2 cygwin(windows下使用GNU)

  Cygwin是一个在windows平台上运行的类UNIX模拟条件,是cygnus
solutions公司(已被Redhat收购)开发的自由软件。它对学UNIX/Linux操作环境,或者打UNIX到Windows的应用程序移植,尤其是用GNU工具集在Windows上进展嵌入式系统开发,非常实用。

// 下载链接
Installer:http://cygwin.com/install.html
Package:  https://cygwin.com/packages/package_list.html
// 相关包(根据平台选择)
binutils                - GNU assembler, linker, and similar utilities
cygwin32-binutils       - Binutils for Cygwin 32bit toolchain
mingw64-x86_64-binutils - Binutils for MinGW-w64 Win64 toolchain 
mingw64-i686-binutils   - Binutils for MinGW-w64 Win32 toolchain

  下载安装好cygwin包后,便可每当装目录下\cygwin64\bin\找到x86_64-w64-mingw32-readelf.exe工具(豹哥选择的是mingw64-x86_64-binutils包)。

正文将以一个诚实垂直门户网站的提高过程,向大家不断道来。

  • project文件 +
    relocatable文件 ->
    executable文件

集群时代的图样服务器架设(实时同步)

于website站点下面,新建一个名叫吧upload的虚拟目录,由于虚拟目录的油滑,能于自然水准上代表物理目录,并配合原有的图形上传和走访方式。用户之访方式还是:

http://www.yourdomain.com/upload/qa/test.jpg

亮点:配置更加灵活,也能配合老版的上传和做客方式。

为虚拟目录,可以本着本地任意盘符下的任性目录。这样一来,还足以经过交接外置存储,来开展单机的容量扩展。

短:部署变为是因为多台Web服务器组成的集群,各个Web服务器(集群节点)之间(虚拟目录下之)需要实时的错过联合文件,由于并效率以及实时性的范围,很为难保证有同随时各节点上文件是完全一致的。

着力架构使下图所示:

图片 1

自达图可看出,整个Web服务器架设已颇具“可扩大、高可用”了,主要问题以及瓶颈都汇集在多雅服务器间的公文共上。

上述架构中仅能够当当时几乎令Web服务器上相互“增量同步”,这样一来,就不支持文件之“删除、更新”操作的一起了。

首的想法是,在应用程序层面做决定,当用户请求于web1服务器进行上传写入的而,也同去调动用另外web服务器上之上传接口,这眼看是得不偿失的。所以我们选择使用Rsync类的软件来做定时文件并的,从而省去了“重复过去轮子”的基金,也下滑了风险性。

同步操作里面,一般发生比较经典的星星种模型,即推拉模型:所谓“拉”,就是依轮询地失去赢得更新,所谓推,就是产生转移后积极的“推”给任何机器。当然,也堪运用加高级的风波通报机制来成功此类动作。

每当强并作写副的观被,同步都见面冒出频率以及实时性问题,而且大量文件同步啊是蛮耗费系统及牵动富资源的(跨网段则重复显)。

二、解析elf文件

  所谓工欲善其事,必先利其器,在起解析elf文件前,我们亟须事先找到同样磨蹭合适的分析工具,readelf就是GNU/Linux官方推出的专用解析工具。有矣是分析工具,我们便可慢慢分析elf文件。

独自图片服务器/独立域名之利

  1. 图表看是甚耗费服务器资源的(因为见面提到到操作系统的上下文切换和磁盘I/O操作)。分离出来后,Web/App服务器可以还小心发挥动态处理的力。
  2. 单身存储,更有利做扩容、容灾和数量迁移。
  3. 浏览器(相同域名下的)并发策略限制,性能损失。
  4. 看图片时,请求信息遭受总带cookie信息,也会见招致性能损失。
  5. 好做图片看请求的载重均衡,方便用各种缓存策略(HTTP
    Header、Proxy Cache等),也愈来愈惠及迁移到CDN。

……

 

俺们好采取Lighttpd或者Nginx等轻量级的web服务器来架构独立图片服务器。

2.2.4 获得symbol list
c:cygwin64\bin>x86_64-w64-mingw32-readelf.exe -s demo.elf

Symbol table '.symtab' contains 198 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
    74: 10002018    16 OBJECT  LOCAL  DEFAULT    7 s_array
    75: 10002014     4 OBJECT  LOCAL  DEFAULT    7 s_variable0
    76: 10002010     4 OBJECT  LOCAL  DEFAULT    7 s_variable2
   135: 00000000     0 OBJECT  GLOBAL DEFAULT    4 __vector_table
   140: 00000041     0 FUNC    GLOBAL DEFAULT    5 Reset_Handler
   141: 00000098     4 OBJECT  GLOBAL DEFAULT    5 s_constant
   142: 000000ad    32 FUNC    GLOBAL DEFAULT    5 main
   143: 000000cd    14 FUNC    GLOBAL DEFAULT    5 normal_task
   144: 000000db    60 FUNC    GLOBAL DEFAULT    5 heap_task
   155: 0000034d    84 FUNC    GLOBAL DEFAULT    5 init_data_bss
   156: 000003a1    18 FUNC    GLOBAL DEFAULT    5 init_interrupts
   157: 000003dd    12 FUNC    GLOBAL DEFAULT    5 SystemInit
   186: 10002001    16 FUNC    GLOBAL DEFAULT    7 ram_task
   191: 10002034     4 OBJECT  GLOBAL DEFAULT    7 n_variable1

  通过readelf -s命令可以拿走symbol
list解析后的音信。可以看出许多个symbol,豹哥在此地仅排有利用工程里从定义之函数和变量,从symbol表里我们可以查出函数/变量在存储器中实际分配地址与长,这对咱们更为分析及调试应用是发生帮的。

以主流的Web站点中,图片数是少不了的页面元素,尤其在巨型网站中,几乎都拿面临“海量图片资源”的蕴藏、访问等相关技术问题。在对图片服务器的架扩展中,也会见历经重重曲折甚至是血泪教训(尤其是前期规划不足,造成后期架构上挺不便兼容和扩张)。

2.2 逐步分析elf文件

  万事俱备了,开始分析elf文件,以第三节课project文件里demo工程也例。编译链接该工程而在D:\myProject\bsp\builds\demo\Release\Exe路径下得demo.elf文件。该公文大小32612
bytes,显然这样简单的一个粗工程image
size不可能这样好,说明elf文件里的笔录信息数据占比较生酷。

不少小卖部之所以选择Windows(.NET)平台来构建网站以及图表服务器,很大部分由于创始团队的技能背景决定的,早期的技术人员可能更熟悉.NET,或者组织的领导人员觉得Windows/.NET的易用性、“短平快”的开支模式、人才基金等地方还较吻合创业初期的社,自然就选了Windows。后期工作发展至一定规模,也生不便轻易用圆架构迁移至其它开源平台上了。当然,对于构建大互联网,更建议首选开源架构,因为发很多熟之案例与开源生态的支持(也会见发不少坑,就看是若协调初去踩坑,还是以人家踩了修复之后你再就此),避免再次过去轮子和付出高额授权费。对于迁移难度比较充分的施用,个人于推荐Linux、Mono、Jexus、Mysql、Memcahed、Redis……混搭的架,同样会支撑具有高并发访问与天数据量等特色的互联网使用。

工具2:IAR工具ielftool.exe

位置:\IAR Systems\Embedded Workbench xxx\arm\bin\ielftool.exe
用法:
      ielftool.exe --bin  demo.elf demo.bin
      ielftool.exe --ihex demo.elf demo.hex
      ielftool.exe --srec demo.elf demo.s19

  至此,嵌入式开发里之executable文件(elf)文件豹哥就是介绍完了,掌声以哪~~~

釜底抽薪方案如下:

首先,关闭旧本子及污染入口(避免后续利用导致数据不一致)。将原有图数通过rsync工具一次性迁移到独门的图服务器上(即下图被讲述的Old
Image
Server)。在无比前端(七层代理,如Haproxy、Nginx)用ACL(访问规则控制),将本来图对诺URL规则的恳求(正则)匹配到,然后将请求直接倒车指定的web
服务器列表,在拖欠列表中的服务器上安排好提供图片(以Web方式)访问的站点,并加入缓存策略。这样实现原图服务器的离别和缓存,兼容了原始图的走访规则并提升原有图看效率,也避免了实时同步所带的题目。

 

一体化架构使图:

图片 2

基于FastDFS的独图片服务器集群架构,虽然曾死之秋,但是出于国内“南北互联”和IDC带富成本等问题(图片是十分耗流量的),我们最终还是择了商用的CDN技术,实现起来也非常容易,原理其实呢深简单,我这里就做个简易的介绍:

将img域名cname到CDN厂商指定的域名及,用户要访问图片时,则由CDN厂商提供智能DNS解析,将新近底(当然也说不定发其他更复杂的政策,例如负载情况、健康状态相当)服务节点地址返回给用户,用户要到达指定的服务器节点上,该节点上提供了看似Squid/Vanish的代办缓存服务,如果是率先涂鸦呼吁该路线,则会由源站获取图片资源归客户端浏览器,如果缓存中留存,则一直打缓存中获取并回到给客户端浏览器,完成请求/响应过程。

由用了商用CDN服务,所以我们连从未设想用Squid/Vanish来自实践构建前置代理缓存。

上面的满集群架构,可以挺便宜的举行横向扩张,能满足一般垂直领域中大型网站的图纸服务需(当然,像taobao这样超大规模的或者另当别论)。经测试,提供图片看的单台Nginx服务器(至强E5季核对CPU、16G内存、SSD),对小静态页面(压缩后大约只有发生10kb左右之)可以扛住几千独连发且毫无压力。当然,由于图片本身体积比纯粹文本的静态页面大过多,提供图片看的服务器的抗并发能力,往往会受限于磁盘的I/O处理能力跟IDC提供的带来富。Nginx的抗并发能力还是不行大之,而且对准资源占用很没有,尤其是处理静态资源,似乎还无待发了多操心了。可以依据实际访问量的急需,通过调整Nginx的参数,对Linux内核做调优,加入分级缓存策略等手段能够开重新特别程度之优化,也得经过多服务器或者升级服务器配置来做扩展,最直接的凡透过市又尖端的存储设备和重复老的带动富,以满足再怪访问量的需。

值得一提的凡,在“云计算”流行的就,也援引高速发展内的网站,使用“云存储”这样的方案,既能够协助您解决各项存储、扩展、备灾的问题,又能够搞活CDN加速。最重点的凡,价格为非贵。

总结,有关图片服务器架设扩展,大致围绕这些问题展开:

  1. 容量规划以及扩大问题。
  2. 数量的一块、冗余同容灾。
  3. 硬件装备的资产及可靠性(是平常机械硬盘,还是SSD,或者又高端的存储设备和方案)。
  4. 文件系统的挑。根据文件特性(例如文件大小、读写比例相当)选择是用ext3/4或NFS/GFS/TFS这些开源的(分布式)文件系统。
  5. 图表的加快访问。采用商用CDN或者自建的代理缓存、web静态缓存架构。
  6. 原有图路径和访问规则的兼容性,应用程序层面的而扩大,上传和做客的性质和安全性等。
2.2.1 获得file header
C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -h demo.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x41
  Start of program headers:          31740 (bytes into file)
  Start of section headers:          31772 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         21
  Section header string table index: 1

  第一步首先分析file header,前面介绍里说罢file
header是位于文件最前面的。通过readelf -h命令可以获file
header解析后的消息。让咱们来对比一下,使用HexEditor直接打开demo.elf可抱如下数据,仅获前52bytes(0x34)数据,因为Elf32_Ehdr大小就是52bytes:

offset(h)
00000000: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
00000010: 02 00 28 00 01 00 00 00 41 00 00 00 FC 7B 00 00
00000020: 1C 7C 00 00 00 00 00 05 34 00 20 00 01 00 28 00
00000030: 15 00 01 00 -- -- -- -- -- -- -- -- -- -- -- --

  可以见到前16byte是e_ident[16],与分析后的Magic是一样的;再来说明prgram
header偏移e_phoff=0x00007BFC,数量e_phnum=0x0001,大小e_phentsize=0x0020,也是暨析后的消息匹配的;余下可自行对照。

集群时代的图样服务器架设改进(共享存储)

套用虚拟目录的计,通过UNC(网络路径)的措施实现共享存储(将upload虚拟目录指向UNC)

用户的拜会方式1:

http://www.yourdomain.com/upload/qa/test.jpg

用户之走访方式2(可以配备独立域名):

http://img.yourdomain.com/upload/qa/test.jpg

支持UNC所在server上配置独立域名对,并配备轻量级的web服务器,来促成独立图片服务器。

可取:
通过UNC(网络路径)的道来拓展读写操作,可以避多服务器之间同步相关的问题。相对来讲很利索,也支持扩容/扩展。支持配置成单身图片服务器和域名访问,也圆兼容旧本子的造访规则。

缺点
:但是UNC配置有些麻烦,而且会造成一定的(读写及安全)性能损失。可能会见现出“单点故障”。如果存储级别没有raid或者重新尖端的灾备措施,还见面造成数丢失。

主导架构使下图所示:

图片 3

于初期的众多基于Linux开源架构的网站被,如果非思一起图片,可能会见用NFS来促成。事实证明,NFS在青出于蓝并发读写及海量存储方面,效率达在一定问题,并非最佳的选项,所以大部分互联网公司都未会见采取NFS来实现此类应用。当然,也可经过Windows自带的DFS来兑现,缺点是“配置复杂,效率未知,而且少资料大量之实在案例”。另外,也起局部柜使用FTP或Samba来实现。

 

上面提到的几乎种植架构,在上传/下载操作时,都通过了Web服务器(虽然共享存储的这种架构,也可以配备独立域名和站点来供图片看,但达到传写入仍然得经过Web服务器上之应用程序来处理),这对准Web服务器来讲确实是导致巨大的压力。所以,更建议利用独立的图形服务器和独立的域名,来提供用户图片的上传和看。

工具1:GNU工具objcopy

位置:C:\cygwin64\bin>x86_64-w64-mingw32-objcopy.exe
用法:
      objcopy.exe -O binary -S demo.elf demo.bin
      objcopy.exe -O srec   -S demo.elf demo.s19

备注:一说需用arm-linux-objcopy,待验证

构建以Windows平台之上的网站,往往会为正式多术看甚“保守”,甚至会发生接触。很大部分由,是出于微软技术体系之查封及组成部分技术人员的急功近利造成的(当然,主要还是食指之问题)。由于天长日久短缺开源支持,所以重重人口只能“闭门造车”,这样不行容易形成思维局限性和短板。以图片服务器也例,如果早期没有容量规划及而扩大的统筹,那么就图片文件的不断增加及访问量的上升,由于在性、容错/容灾、扩展性等方面的计划不足,后续将会晤吃支付、运维工作牵动很多问题,严重时还是会影响到网站工作正常运转与互联网商家之迈入(这绝不是在震惊)。

如出一辙、elf文件基础

  ELF全称Executable and Linkable
Format,可实行连接格式,ELF格式的文件最早用于存储Linux程序,后演变到ARM系统上存储ARM程序。ELF文件(目标文件)格式主要三种:

  • 可重定向文件:用来和其余的靶子文件并来创造一个可执行文件或者共享目标文件(也如object文件或者静态库文件,通常后缀为.o和.a的公文)。这个文件是用于编译和链接阶段。
  • 可执行文件:用于转移应用image,载入存储器执行(后缀通常为.out或者.elf)。这个文件是用以加载执行阶段。
  • 共享目标文件:用于与其余共享目标文件或者object文件并变可执行文件,或者跟可执行文件一起创造以image。(也称一起享库文件,后缀为.so的文书)。这个文件既而用以编译和链接阶段,也可用于加载执行等级。

  我们于ARM开发中另行多点的凡前方少种格式,第一种格式前面系列文章relocatable文件一度介绍过,本文的中坚是亚栽格式-可执行文件。不管是啊种格式的ELF文件,其都可能含如下三栽基本索引表:

  • file header:一般以文件的开始,描述了ELF文件之完好组织状况。
  • program
    header
    :告诉系统如何创造image,可执行文件必须有program
    header,而而重定向文件则非需。
  • section
    header
    :包含了叙文件section的音信,每个section都产生一个header,每一个header给闹诸如section名称、section大小相当于消息。可重定向文件要包含section
    header。

  既然知道了存在三种植索引表,那么表底布局定义在乌吧?github上的linux仓库里来具体定义,在elf.h头文件里。

Linux仓库:https://github.com/torvalds/linux.git
elf.h路径:\linux\include\uapi\linux\elf.h

  打开elf.h文件就只是找到三单说明底原型定义,鉴于目前之ARM
Cortex-M都是32bit,所以这里就列有32bit下蛋之发明底原型:Elf32_Ehdr、Elf32_Phdr、Elf32_Shdr。

// file header
#define EI_NIDENT    16
typedef struct elf32_hdr{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */  
  Elf32_Half    e_machine;              /* Architecture */  
  Elf32_Word    e_version;              /* Object file version */  
  Elf32_Addr    e_entry;                /* Entry point virtual address */  
  Elf32_Off     e_phoff;                /* Program header table file offset */  
  Elf32_Off     e_shoff;                /* Section header table file offset */  
  Elf32_Word    e_flags;                /* Processor-specific flags */  
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */  
  Elf32_Half    e_phentsize;            /* Program header table entry size */  
  Elf32_Half    e_phnum;                /* Program header table entry count */  
  Elf32_Half    e_shentsize;            /* Section header table entry size */  
  Elf32_Half    e_shnum;                /* Section header table entry count */  
  Elf32_Half    e_shstrndx;             /* Section header string table index */ 
} Elf32_Ehdr;

// program header
typedef struct elf32_phdr{
  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, file & memory */
} Elf32_Phdr;

// section header
typedef struct elf32_shdr {
  Elf32_Word    sh_name;          /* Section name, index in string tbl */
  Elf32_Word    sh_type;          /* Type of section */
  Elf32_Word    sh_flags;         /* Miscellaneous section attributes */
  Elf32_Addr    sh_addr;          /* Section virtual addr at execution */
  Elf32_Off     sh_offset;        /* Section file offset */
  Elf32_Word    sh_size;          /* Size of section in bytes */
  Elf32_Word    sh_link;          /* Index of 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;

单机时代之图形服务器架设(集中式)

初创时代由于时间紧迫,开发人员水平为大单薄等因。所以便就直以website文件所在的目录下,建立1只upload子目录,用于保存用户上传的图文件。如果按工作更分开,可以以upload目录下再立不同的子目录来区别。例如:upload\QA,upload\Face等。

每当数据库表中保存的啊是”upload/qa/test.jpg”这仿佛相对路径。

用户的走访方式如下:

http://www.yourdomain.com/upload/qa/test.jpg

程序及污染和描写副道:

程序员A通过以web.config中安排物理目录D:\Web\yourdomain\upload 
然后经过stream的法子写副文件;

程序员B通过Server.MapPath等艺术,根据相对路径获取物理目录 
然后为通过stream的法门写副文件。

瑜:实现起来最简易,无需任何扑朔迷离技术,就能得逞将用户上传的文本写副指定目录。保存数据库记录以及看起来却也死有利。

缺陷:上传方式混乱,严重不便民网站的扩展。

对上述极端老的架,主要面临着如下问题:

  1. 趁着upload目录中文件越来越多,所于划分区(例如D盘)如果起容量不足,则好麻烦扩容。只能停机后变又怪容量的存储设备,再以老数据导入。
  2. 当配置新本子(部署新本子前经过需要备份)和平凡备份website文件的时候,需要同时操作upload目录中之公文,如果考虑到访问量上升,后止部署由多台Web服务器组成的负载均衡集群,集群节点内要做好文件实时同步将是个难题。

 

  文件涉及:linker文件

  仔细看过豹哥之前课程的恋人肯定晓得,豹哥在第四节课relocatable文件里介绍的object文件在格式上其实和本文要提的elf文件是看似的,它们都属于ELF文件分支。只不是relocatable文件只是中等过渡文件,而本文要出口的elf却是标准的output文件,这个文件几乎涵盖了工的有着消息,有了此文件我们既可在线调试工程,也可拿elf文件转换成为image文件,直接下载image文件数据上芯片中脱机运行。今天豹哥就是也大家细心分析elf文件。

番外一、几个elf转换image工具

  于今底西外篇里,豹哥被大家顺便介绍几迟迟专业的elf文件转换成image文件的工具。

2.3 elf文件layout

  经过上亦然节省对demo.elf里相继header的辨析,此时咱们就算可以简单地画出elf文件layout。

File offset Data content Data size in bytes
0x00000000 ELF file header 52
0x00000034 Image binary (Section4-A0 rw, .intvec中断向量表) 0x40
0x00000074 Image binary (Section5-P1 ro, readonly section(.text, .rodata…)) 0x484
0x000004F8 Section8-20 (包含各种辅助调试和系统段.debug_xx, .iar.xx) 0x5E3E
0x00006336 NULL 0x2
0x00006338 Section1-.shstrtab字符串表 0xE6
0x00006420 Section2-.strtab字符串信息 0xB7C
0x00006F9C Section3-.symtab符号信息 0xC60
0x00007BFC ELF Program header 0x20
0x00007C1C ELF Section headers (0 – 20) 21 * 40

  大家吓,我是豹哥,猎豹的金钱豹,犀利哥的哥哥。今天豹哥为大家提的凡嵌入式开发里之executable文件(elf)

2.2.3 获得section header
c:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -S demo.elf
There are 21 section headers, starting at offset 0x7c1c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 006338 000000 00      0   0  4
  [ 1] .shstrtab         STRTAB          00000000 006338 0000e6 00      0   0  4
  [ 2] .strtab           STRTAB          00000000 006420 000b7c 00      0   0  4
  [ 3] .symtab           SYMTAB          00000000 006f9c 000c60 10      2 135  4
  [ 4] A0 rw             PROGBITS        00000000 000034 000040 01  AX  0   0 256
  [ 5] P1 ro             PROGBITS        00000040 000074 000484 01  AX  0   0  4
  [ 6] P3 ui             NOBITS          10000000 0004f8 002000 01  WA  0   0  8
  [ 7] P2 rw             NOBITS          10002000 0004f8 000438 01  WA  0   0  8
  [ 8] .debug_abbrev     PROGBITS        00000000 0004f8 0002c6 01      0   0  0
  [ 9] .debug_aranges    PROGBITS        00000000 0007c0 00016c 01      0   0  0
  [10] .debug_frame      PROGBITS        00000000 00092c 00057c 01      0   0  0
  [11] .debug_info       PROGBITS        00000000 000ea8 000e2e 01      0   0  0
  [12] .debug_line       PROGBITS        00000000 001cd8 000dcb 01      0   0  0
  [13] .debug_loc        PROGBITS        00000000 002aa4 00024c 01      0   0  0
  [14] .debug_macinfo    PROGBITS        00000000 002cf0 00011e 01      0   0  0
  [15] .debug_pubnames   PROGBITS        00000000 002e10 00012a 01      0   0  0
  [16] .iar.debug_frame  PROGBITS        00000000 002f3c 00007e 01      0   0  0
  [17] .iar.debug_line   PROGBITS        00000000 002fbc 000367 01      0   0  0
  [18] .comment          PROGBITS        00000000 003324 002fa2 01      0   0  0
  [19] .iar.rtmodel      PROGBITS        00000000 0062c8 000047 01      0   0  0
  [20] .ARM.attributes   ARM_ATTRIBUTES  00000000 006310 000026 01      0   0  0
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),
  y (purecode), p (processor specific)

  再来分析section header,通过readelf -S命令可以取section
header解析后的信。可以看来出诸多只section,其中最关键的4独section是A0(readonly
vector), P1(readonly code,data), P2(readwrite data, heap),
P3(STACK)。具体分析,各位朋友自己尝试看。

2.2.2 获得program header
C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -l demo.elf

Elf file type is EXEC (Executable file)
Entry point 0x41
There are 1 program headers, starting at offset 31740

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000034 0x00000000 0x00000000 0x004c4 0x004c4 R E 0x100

 Section to Segment mapping:
  Segment Sections...
   00     A0 rw P1 ro

  再来分析program header,通过readelf -l命令可以获得program
header解析后的音信。从地方可以摸清header起始位置于demo.elf的31740
byte处(与file header里的e_phoff信息是呼应的),header信息提示program
data从offset 0x34开,大小共0x4c4
bytes,Reset_Handler入口是0x41。继续以HexEditor查看31740地处始的32byte数据,因为Elf32_Phdr大小就32bytes:

offset(h)
00007BF0: -- -- -- -- -- -- -- -- -- -- -- -- 01 00 00 00
00007C00: 34 00 00 00 00 00 00 00 00 00 00 00 C4 04 00 00
00007C10: C4 04 00 00 05 00 00 00 00 01 00 00 -- -- -- --

  可以见到p_offset=0x00000034,p_memsz=0x000004c4,
与地方解析后的消息是同一的;余下可自行对照。
这里的信就是比主要了,因为及时指示了一切image
binary数据所在(知道了是信息,我们虽好一直写脚论根据elf文件生成image
binary),继续于HexEditor里看下去(仅截取部分显得):

offset(h)
00000030: -- -- -- -- 00 20 00 10 41 00 00 00 03 04 00 00
00000040: 3F 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060: 61 04 00 00 00 00 00 00 00 00 00 00 63 04 00 00
00000070: 65 04 00 00 72 B6 0E 48 0E 49 88 60 00 22 00 23
00000080: 00 24 00 25 00 26 00 27 B8 46 B9 46 BA 46 BB 46

  ARM系统的image前16单指针都是系中断向量,我们可以看SP=0x10002000,
PC=0x00000041,这跟方解析的Reset_Handler入口是0x41凡配合的。

  第四、五节课里,豹哥已经让大家介绍了2栽output文件,本文继续为大家称project生成的另一样种植output文件-executable文件,也是专门要之output文件。

2.1.3 readelf.exe用法

  readelf.exe以标准的windows命令行用法,使用–help可以列出所有命令option及其简介,下面就排有比较常用之option。

C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe --help
Usage: readelf <option(s)> elf-file(s)
 Display information about the contents of ELF format files
 Options are:
  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I
  -h --file-header       Display the ELF file header
  -l --program-headers   Display the program headers
     --segments          An alias for --program-headers
  -S --section-headers   Display the sections' header
     --sections          An alias for --section-headers
  -t --section-details   Display the section details
  -e --headers           Equivalent to: -h -l -S
  -s --syms              Display the symbol table
     --symbols           An alias for --syms
  --dyn-syms             Display the dynamic symbol table
  -r --relocs            Display the relocations (if present)
  -d --dynamic           Display the dynamic section (if present)
  -V --version-info      Display the version sections (if present)
  -A --arch-specific     Display architecture specific information (if any)
  -I --histogram         Display histogram of bucket list lengths
  @<file>                Read options from <file>

2.1 解析工具readelf

  既然elf文件是Linux系统下常用之可执行文件格式,那么Linux社区一定会生配套的工具去分析其,是的,这个家伙就为readelf,在GNU工具集binutils里。