首页 Lib文件的结构

Lib文件的结构

举报
开通vip

Lib文件的结构COFF格式续篇—Lib文件的结构     上一篇文章介绍了COFF目标文件的结构。如果你试着做一个应用程序的连接器(Linker),就会发现,仅仅有目标文件是不够的。我们在连接程序时,不仅仅要用到目标文件,库文件也是必不可少的。     库文件是怎么样的结构呢?     其实,库文件的结构也很简单。它就是“一堆”目标文件的集合。把目标文件做成库以后,我们在使用目标文件中所实现的功能时,连接程序会自动在库文件里查找相应的目标文件,并使用它。这大大减少了我们对目标文件的管理工作,减轻了代码重用的负担。     Li...

Lib文件的结构
COFF格式续篇—Lib文件的结构     上一篇文章介绍了COFF目标文件的结构。如果你试着做一个应用程序的连接器(Linker),就会发现,仅仅有目标文件是不够的。我们在连接程序时,不仅仅要用到目标文件,库文件也是必不可少的。     库文件是怎么样的结构呢?     其实,库文件的结构也很简单。它就是“一堆”目标文件的集合。把目标文件做成库以后,我们在使用目标文件中所实现的功能时,连接程序会自动在库文件里查找相应的目标文件,并使用它。这大大减少了我们对目标文件的管理工作,减轻了代码重用的负担。     Lib文件中的节     COFF格式中所用到的“节”的概念再次出现在Lib格式中。不过,Lib文件的节要简单得多。先让我们来看看它的整体结构:     如右图所示:     Lib格式只有四种类型的节(Section),即First Sec,Second Sec,Longname Sec和Obj Sec;其中Second Sec与Longname Sec是可选节,很多Lib文件中都没有。而开头的Singature只是一个标识,它相当于COFF目标文件中的魔法数字。它是一个长度为8的字符串,值为“!\n”。     First Sec,顾名思义,就是第一个节。它包含了库中所有的符号名以及这些符号所在的目标文件在库中的位置(绝对偏移)。     Second Sec就是第二节。它的 内容 财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容 和First Sec是相同的。不同的是,Second Sec是一个有序表,通过它来查找库中的符号比通过First Sec来查找要快很多。 Signature First Sec Second Sec Longname Sec Obj Sec1 Obj Sec2 ……     Longname Sec是长名称节。这一节是一个字符串表。它包含了所有长目标文件名。如果后面的Obj Sec中没有给出相应的目标文件名,我们就要到这一节中来查找。     Obj Sec就是目标文件节。这些节中存储着不同的目标文件的原始数据。       在库文件中,每一节都有两个部分。一个部分是头,另一个部分才是该节的数据;数据紧跟在头的后面。头描述了该节数据的类型、长度等信息。这些头的格式都是相同的。其结构用C语言描述如下:     typedef struct {         char Name[16];      // 名称         char Time[12];      // 时间         char UserID[6];     // 用户ID         char GroupID[6];    // 组ID         char Mode[8];       // 模式         char Size[10];      // 长度         char EndOfHeader[2];// 结束符     } SectionHeader;     可以看到,头中的数据全都是字符串。用字符串的好处是可以提高格式的兼容性,因为在不同的机器上,数据的排列方式是不同的。有的机器是以Little-Endian方式工作,还有的是以Big-Endian方式工作,它们互不兼容(这两种方式的区别!?请看我的《COFF格式》一文,其中的文件头一节有说明)。用字符串就不会有这种问题(后面我们将会遇到)。但它也有不方便的地方,就是必须把字符串转换成数值,多了一个步骤。     在这个结构中,最常用的Name、Size以及EndOfHeader三个成员。Name就是节的名称啦!Size也很好理解,就是该节数据的长度。现在要注意的就是这个EndOfHeader成员了!这个成员标志着头的结束,其内容为“`\n”(注意,这里没有打错,是两个字符“`”和“\n”)。怎么样?有点奇怪吧?为什么要有这个结束符?每一节的头长度一定,每节中的数据长度也知道。按顺序向下读不行吗? 答案 八年级地理上册填图题岩土工程勘察试题省略号的作用及举例应急救援安全知识车间5s试题及答案 是:不行!因为每一节之间存在间隙!通常是一个字节或零个字节。如果是零个字节倒好,按顺序向下读是OK的。可是如果不为零的话,这样读就要错位了。要知道错位没有,只好用一个结束符来定位了。如果在读头的时候发现结束符不对,那就要一个字节一个字节地向下查找,直到找到结束符,才能算是对齐了。切记!切记!     当然,通过First Sec或Second Sec中给出的偏移来读数据就不存在这个问题。不会发生错位,放心读吧!     现在让我们来看看每一节中的数据是什么样子。       First Sec     第一节,通常就是Lib中的每一个小节。它的名称是“/”。其数据部分的结构如下:     typedef struct {         unsigned long SymbolNum;         // 库中符号的数量         unsigned long SymbolOffset[n];   // 符号所在目标节的偏移         char StrTable[m];                // 符号名称字符串表     }FirstSec;     第一个成员SymbolNum是符号的数量。注意!它是以Big-Endian方式储存的(x86平台上的数据是以Little-Endian方式储存的。这里应该注意转换。后面给出的convert函数可以在Little-Endian格式与Big-Endian格式之间进行相互转换)。     第二个成员SymbolOffset是一个数组,它的长度n就是符号的数量,也就是SymbolNum。这个数组储存了每一个符号所在的目标节的偏移。我们可以方便地通过它来查找符号所在的目标文件。注意!它也是以Big-Endian格式储存的。     第三个成员StrTable是一个字符串表,它的长度m就是SectionHeader.Size的值减去(SymbolNum+1)*4。其结构很简单,就是一堆以‘\0’结尾的字符串(和COFF文件中的字符串表结构相同)。在有的系统中,它还可能是以“/\n”这两个字符结尾的字符串的集合。     很简单的一个结构,不过有两个成员的长度是不定的。怎么才能方便地从Lib中读出这些数据,留给大家自己想吧!下面我只给出一个进行Little-Endian与Big-Endian互转的函数。     inline void convert(void * p          // 要转换的数据的指针                         ,size_t size = 4  // 数据的长度,long为4,short为2                         ) {         char * buf=(char*)p;         char temp;         for ( size_t i=0;i\n …… LongName Sec: This_Is_Long_Name0001\0 This_Is_Long_Name0002\0 …… Obj Sec1:  Name[16]:“shortname/”  …… Obj Sec2:  Name[16]:“/0”  // 这里使用了第一个长文件名This_Is_Long_Name0001  …… Obj Sec3:  Name[16]:“/22”  // 这里使用了第二个长文件名This_Is_Long_Name0002  ……       OK!现在已经介绍完了Lib文件的结构。大家的连接器可以加新功能了。不过这里只给出了最基本的Lib文件结构,动态连接库(DLL)的导出库有点特别,我将在PE文件格式中进行详细介绍。
本文档为【Lib文件的结构】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_959571
暂无简介~
格式:doc
大小:41KB
软件:Word
页数:5
分类:互联网
上传时间:2013-04-22
浏览量:53