《程序员自我修养》读书笔记 第三章 目标文件里面有什么

 这是关于《程序员的自我修养——装载,链接和库》一书的读书笔记,从第三章开始。第一章和第二章主要介绍操作系统和编译器的内容,不加赘述。
 
目标代码英语object code)指计算机科学编译器汇编器处理源代码后所生成的代码,它一般由机器代码或接近于机器语言的代码组成。目标文件英语object file)即存放目标代码计算机文件,它常被称作二进制文件binaries)。(From WIKI)
 


3.1 目标文件的格式

目标文件,例如,windows下的PE文件,Linux下的ELF文件等等。“从广义上看,目标文件和可执行文件的格式几乎一样,我们将两者看成一种文件”。除了可执行文件,静态链接库(dll,so)文件和动态链接库(lib,a)文件也按照这种格式存储。
在linux下,可以用file命令来查看文件类型。
 


3.2 目标文件是什么样的
 
 
这一节大致描述了目标文件的格式,以ELF为例,包括.text段,.data段,.bss段等等。做过操作系统实习JOS,或者编译实习什么的,对这个肯定比较熟悉了。
 
以及,书中提问,为什么要把code和data分开?首先从OS的角度讲,在内存空间中data和code的区域的权限不同,code一般不会被写。其次,data和code的分离对cache的设计和运行效率有帮助。最后,code这片实际的物理内存,也许会被许多进程的虚拟内存同时映射,code可以重用。
 

3.3 挖掘SimpleSection.o
 
好吧,我们也编译一下这个SimpleSection.c.电脑是64位的,linux也是64位的,只好用32位的虚拟机来尝试。
 
 
 
 
Size指的是这个段的大小,text段的大小是50,是从地址0x00000034开始的。
 
利用objdump -s -d 命令查看16进制及反汇编。
 
 
 
text段的内容就是代码(汇编指令)
 
data段中存放的是已经初始化了的全局静态变量和局部静态变量,有两个,global_init_varabal 和 static_var 共8字节
 
rodata段(貌似是 read only data )存放的是字符串常量 和 只读变量 %d
 
comment段,版本信息
 
 
以及,书中提到一个问题,如何将一个图片image.jpeg作为目标文件的一个段?
利用objcopy工具。
有介绍
 

 
3.4 ELF文件结构描述
 
 
 
ELF文件描述
这个链接有ELF文件的详细介绍:
 
查看ELF文件的内容用readelf命令,关于readelf命令可以参考这个文章:
总结一下:
 
读取ELF文件头        readelf -h 文件名
读取ELF程序头表     readelf -l 文件名
ELF节头表               readelf -S 文件名
符号表                    readelf -s 文件名
 
 
段类型
w:可写
A:需要分配空间
S:可执行
 
字符串表
把ELF文件中的各种字符串(比如段名,变量名)统一管理的表。
 
.strtab 和 .shstrtab
 
重定位表
存放重定位的信息
 


3.5 链接的接口——符号
 
链接的过程的本质是把不同的目标文件之间相互“粘”到一起
“粘”到一起的方式就是通过符号
对“粘”可能有帮助的符号包括,本目标文件中的全局符号,外部符号(比如例子中的printf)。而局部符号,段名等,对于别的目标文件是不可见的。
 
ELF符号表,.symtab
 

 

 
特殊符号
我们使用ld链接器的时候,ld链接器会自动生成一些特殊的符号,比如:
__executable_start
__etext
_edata
_end等等。
我们在程序中 用 extern char etext[]; 声明了之后,可以直接使用。
 
 
符号修饰和函数签名
这一节,主要讲了如何处理符号名冲突的问题
最简单的,加一个下划线
C++中,对符号进行修饰,函数进行签名之类的,其实就是把一个名字加上一些修饰,使得不仅仅通过符号的“名字”作为区别符,而是把“名字”加上一些信息作为区别符。
 
 
 
 
 





posted @ 2013-07-05 18:21  二哥拉手网  阅读(253)  评论(0编辑  收藏  举报