文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>《返璞归真--UNIX技术内幕》-- 第11章 UNIX可执行文件

《返璞归真--UNIX技术内幕》-- 第11章 UNIX可执行文件

时间:2010-08-06  来源:qingfenghao

11.1  .out文件

本版UNIX的可执行文件是.out格式,如果你在UNIX下用gcc编译程序,它默认会生成一个名为“a.out”的可执行文件。尽管现在的UNIX/Linux基本上用ELF(EXECUTABLE AND LINKABLE FORMAT)代替了.out做为可执行(以及目标和库)文件的标准格式,而且ELF对于动态链接、扩展库和面向对象语言(比如C++)有着更好的支持,但作为一个时代的标记,.out文件曾经扮演过重要的角色,而且ELF也由它发展而来,因此了解.out的格式是很有意义的。

.out文件最多可包含七个部分:可执行头(exec header)、程序段(Text segment)、数据段(data segment)、程序重定向表(text relocation)、数据重定向表(data relocation)、符号表(symbol table)和字符串表(string table)如图11-1所示。


图11-1  .out文件格式



其中只有可执行头是必须的,其他段都是可选的。

11.1.1  可执行头

其结构定义如下:

struct exec {

                   unsigned long   a_midmag;

                        unsigned long   a_text;

                   unsigned long   a_data;

                   unsigned long   a_bss;

                   unsigned long   a_syms;

                   unsigned long   a_entry;

                   unsigned long   a_trsize;

                   unsigned long   a_drsize;

};

对于16位CPU,它占用16字节,对于32位CPU,占用32字节。

—     a_midmag

a_midmag是魔术数,它标识了可执行文件的格式,取值如下:

#define OMAGIC          0407    /* old impure format */

#define NMAGIC          0410    /* read-only text */

#define ZMAGIC          0411    /* demand load format */

#define QMAGIC          0314    /* "compact" demand load    format */

OMAGIC表示程序段是可写的,在空间上和数据段连续。

NMAGIC表示程序段是只读的,并且空间上和数据段不连续,它和数据段的起始地址都是8K边界。

ZMAGIC表示程序段和数据段是通过两套活动页寄存器映射的,程序段是只读的。

QMAGIC目前还不支持。

—     a_text

程序段(text segment)大小,字节数。

—     a_data

已初始化的数据段大小。

—     a_bss

未初始化的数据段大小(bss = block started by symbol)。

—     a_syms

符号表(symbol table)大小,字节数。

—     a_entry

程序入口地址。

—     a_trsize

程序重定向表(text relocation)大小。

—     a_drsize

数据重定向表(data relocation)大小。

11.1.2  程序段

编译后的机器代码,它从0地址开始,只读。

11.1.3  数据段

它包含了已初始化的全局变量值。未初始化的全局变量并不在可执行文件中记录,而会在创建对应进程时分配空间,而因为没有初值,所以不需要记录。

11.1.4  程序和数据重定向表

它记录了程序段中哪些符号(全局变量和函数)需要重定向,链接器(link editor)会根据该表和符号表来设定它们的绝对地址,因为这在编译阶段是不可能知道的。

比如,有一段代码在main.c中:

int xx, yy;

void main()

{

   xx = 1;

   yy = 2;

}

在编译(还未链接)后,其汇编代码如下:

.globl _main

_main:

   mov &xx, R0

   mov 1,  (R0)

   mov &yy, R1

   mov 2,  (R1)

   rts PC

由于还未链接,xx、yy的空间还未被分配,所以&xx、&yy用其他值比如0代替,并把它们记录到程序重定向表中,它们会在链接阶段被替换为真正的地址。

所以对应的机器码如图11-2所示:

图11-2  程序对应机器指令

目标文件main.o中的代码(数据)重定向记录结构如下:

struct relocation_info

{

                   int                    r_address;

                   unsigned int          r_symbolnum : 24,

                                           r_pcrel : 1,

                                           r_length : 2,

                                           r_extern : 1,

                                           r_baserel : 1,

                                           r_jmptable : 1,

                                           r_relative : 1,

                                           r_copy : 1;

};

(1)r_address

它表示需要重定向的符号相对于代码段(或数据段)的偏移量,字节数。上例中&xx对应值就是2,而&yy是10。


上一章 进程交换过程                      目录       

                       


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载