Second Sec
现在看看第二节。
这一节与第一节很相似!它通常也就是Lib文件的第二个节。它的名字也是“/”(注意:文件中第一个叫“/”的节是第一节,第二个就是第二节)。不过它的结构与第一节有些不同,如下:
typedef struct {
unsigned long ObjNum; // Obj Sec的数量
unsigned long ObjOffset[x]; // 每一个Obj Sec的偏移
unsigned long SymbolNum; // 库中符号的数量
unsigned short SymbolIdx[n]; // 符号在ObjOffset表中的
索引 char StrTable[m]; // 符号名称字符串表
}SecondSec;
第一个成员ObjNum是库中Obj Sec的数量。
第二个成员ObjOffset是一个偏移表,它记录了库中所有Obj Sec的偏移。这个表的记录数x就是ObjNum。
第三个成员SymbolNum与First Sec中的SymbolNum意义相同。
第四个成员SymbolIdx变成了一个索引,它记录了相应名称字符串在ObjOffset这个表中的位置,我们要通过两次索引才能找到我们所要符号的Obj Sec位置。它的项目数n为SymbolNum。但请注意,这个索引是unsigned short型,不再是unsigned long型。
第五个成员StrTable结构与First Sec中的一样。不过,它的长度m为SectionHeader.Size的值减去((ObjNum+1)*4+(SymbolNum+2)*2)。
值得注意的是,这里的所有数据都是Little-Endian格式的。千万不要弄错了!
Longname Sec 这个小节就是一个字符串表,它的名称为“//”,其结构同FirstSec.StrTable。这里就不多说了。
Obj Sec 这一节中的数据就是COFF文件的原始数据,把它读出来存成文件,就是一个COFF文件。它的格式请参考《COFF格式》一文。
要指出的是它的命名方式有些特殊。如果Obj文件的名称少于16个字符,它就会被保存在SectionHeader的Name成员中,以‘/’字符结尾。如果无法保存在Name成员中,则Name成员的第一个字符就为‘/’,之后再跟上这个名称在Longname Sec中的偏移。
例如:
!
……
LongName Sec:
This_Is_Long_Name0001
This_Is_Long_Name0002
……
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文件格式中进行详细介绍。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10752019/viewspace-962536/
,如需转载,请注明出处,否则将追究法律责任。