数学建模社区-数学中国

标题: [转载]LIB文件的结构(1) [打印本页]

作者: Blackbird    时间: 2005-9-17 14:48
标题: [转载]LIB文件的结构(1)
<><STRONG>重要声明:本文乃转载自其他社区,由于在下无法获得任何有关作者和出处的信息,所以不能在此登出,恳请作者原谅,并希望知情者能告知在下。本着资源的共享的精神,在下深信作者不会拒绝在下的转载行为。同时强烈BS数学中国的下载系统,它不但不能及时给予他人需要的帮助,还浪费了他人大量的时间,仅仅是为了获得无聊的点数,而且遗憾的是,那些点数并不能保证你真能获得帮助!</STRONG></P>
5 Z& f7 V* x' [: K1 h) C& D4 u<>下面让我们来仔细看看每一小节的内容:</P>
4 d' J/ G, w! H8 W* t  I6 g<><STRONG>First Sec<BR></STRONG>    第一节,通常就是Lib中的每一个小节。它的名称是“/”。其数据部分的结构如下:<BR>    typedef struct {<BR>        unsigned long SymbolNum;         // 库中符号的数量<BR>        unsigned long SymbolOffset[n];   // 符号所在目标节的偏移<BR>        char StrTable[m];                // 符号名称字符串表<BR>    }FirstSec;<BR>    第一个成员SymbolNum是符号的数量。注意!它是以Big-Endian方式储存的(x86平台上的数据是以Little-Endian方式储存的。这里应该注意转换。后面给出的convert函数可以在Little-Endian格式与Big-Endian格式之间进行相互转换)。<BR>    第二个成员SymbolOffset是一个数组,它的长度n就是符号的数量,也就是SymbolNum。这个数组储存了每一个符号所在的目标节的偏移。我们可以方便地通过它来查找符号所在的目标文件。注意!它也是以Big-Endian格式储存的。<BR>    第三个成员StrTable是一个字符串表,它的长度m就是SectionHeader.Size的值减去(SymbolNum+1)*4。其结构很简单,就是一堆以‘\0’结尾的字符串(和COFF文件中的字符串表结构相同)。在有的系统中,它还可能是以“/\n”这两个字符结尾的字符串的集合。<BR>    很简单的一个结构,不过有两个成员的长度是不定的。怎么才能方便地从Lib中读出这些数据,留给大家自己想吧!下面我只给出一个进行Little-Endian与Big-Endian互转的函数。<BR>    inline void convert(void * p          // 要转换的数据的指针<BR>                        ,size_t size = 4  // 数据的长度,long为4,short为2<BR>                        ) {<BR>        char * buf=(char*)p;<BR>        char temp;<BR>        for ( size_t i=0;i&lt;size/2;i++ ) {<BR>            temp=buf;<BR>            buf=buf[size-i-1];<BR>            buf[size-i-1]=temp;<BR>        }<BR>    } </P>
' |# c8 C  N8 ^/ x3 L' n# q. k<DIV> </DIV>) K3 v9 ~) T9 d* i
<DIV><STRONG>Second Sec<BR></STRONG>    现在看看第二节。<BR>    这一节与第一节很相似!它通常也就是Lib文件的第二个节。它的名字也是“/”(注意:文件中第一个叫“/”的节是第一节,第二个就是第二节)。不过它的结构与第一节有些不同,如下:<BR>    typedef struct {<BR>        unsigned long ObjNum;        // Obj Sec的数量<BR>        unsigned long ObjOffset[x];  // 每一个Obj Sec的偏移<BR>        unsigned long SymbolNum;     // 库中符号的数量<BR>        unsigned short SymbolIdx[n]; // 符号在ObjOffset表中的索引<BR>        char StrTable[m];            // 符号名称字符串表<BR>    }SecondSec;<BR>    第一个成员ObjNum是库中Obj Sec的数量。<BR>    第二个成员ObjOffset是一个偏移表,它记录了库中所有Obj Sec的偏移。这个表的记录数x就是ObjNum。<BR>    第三个成员SymbolNum与First Sec中的SymbolNum意义相同。<BR>    第四个成员SymbolIdx变成了一个索引,它记录了相应名称字符串在ObjOffset这个表中的位置,我们要通过两次索引才能找到我们所要符号的Obj Sec位置。它的项目数n为SymbolNum。但请注意,这个索引是unsigned short型,不再是unsigned long型。<BR>    第五个成员StrTable结构与First Sec中的一样。不过,它的长度m为SectionHeader.Size的值减去((ObjNum+1)*4+(SymbolNum+2)*2)。<BR>    值得注意的是,这里的所有数据都是Little-Endian格式的。千万不要弄错了!<BR><BR><STRONG>Longname Sec</STRONG><BR>    这个小节就是一个字符串表,它的名称为“//”,其结构同FirstSec.StrTable。这里就不多说了。<BR><STRONG><BR>Obj Sec</STRONG><BR>    这一节中的数据就是COFF文件的原始数据,把它读出来存成文件,就是一个COFF文件。它的格式请参考《COFF格式》一文。<BR>    要指出的是它的命名方式有些特殊。如果Obj文件的名称少于16个字符,它就会被保存在SectionHeader的Name成员中,以‘/’字符结尾。如果无法保存在Name成员中,则Name成员的第一个字符就为‘/’,之后再跟上这个名称在Longname Sec中的偏移。<BR><STRONG><BR>例如</STRONG>:<BR>!&lt;arch&gt;\n<BR>……<BR>LongName Sec:<BR>This_Is_Long_Name0001\0<BR>This_Is_Long_Name0002\0<BR>……<BR>Obj Sec1:<BR> Name[16]:“shortname/”<BR> ……<BR>Obj Sec2:<BR> Name[16]:“/0”  // 这里使用了第一个长文件名This_Is_Long_Name0001<BR> ……<BR>Obj Sec3:<BR> Name[16]:“/22”  // 这里使用了第二个长文件名This_Is_Long_Name0002<BR> ……</DIV>
$ h( h* s# a4 }+ J<DIV> </DIV>
, A- x( R4 W: D" J* r, _+ ?<DIV>    OK!现在已经介绍完了Lib文件的结构。大家的连接器可以加新功能了。不过这里只给出了最基本的Lib文件结构,动态连接库(DLL)的导出库有点特别,我将在PE文件格式中进行详细介绍。</DIV>
作者: cupidvenus    时间: 2005-9-23 13:42
学习




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5