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

简介: 11.1  .out文件 本版UNIX的可执行文件是.out格式,如果你在UNIX下用gcc编译程序,它默认会生成一个名为“a.out”的可执行文件。

11.1  .out文件

本版UNIX的可执行文件是.out格式,如果你在UNIX下用gcc编译程序,它默认会生成一个名为“a.out”的可执行文件。尽管现在的UNIX/Linux基本上用ELFEXECUTABLE 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所示。

100806131726.jpg

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;

};

对于16CPU,它占用16字节,对于32CPU,占用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

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

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

100806131836.jpg

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;

};

1r_address

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


上一章 进程交换过程                      目录                            下一章 系统调用    

                       


目录
相关文章
|
11月前
|
Unix 程序员 Linux
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
254 0
|
5月前
|
Unix Linux Shell
在Unix/Linux系统中,文件和目录的权限管理
在Unix/Linux系统中,文件和目录的权限管理
75 3
|
移动开发 Unix Linux
一文搞清UNIX/Linux与Windows文件换行符格式差异
一文搞清UNIX/Linux与Windows文件换行符格式差异
410 0
一文搞清UNIX/Linux与Windows文件换行符格式差异
|
Unix Shell Linux
Unix 设置用户ID和文件访问权限
Unix 设置用户ID和文件访问权限
282 0