青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 71,  comments - 41,  trackbacks - 0
上一篇文章介紹了COFF目標文件的結構。如果你試著做一個應用程序的連接器(Linker),就會發現,僅僅有目標文件是不夠的。我們在連接程序時,不僅僅要用到目標文件,庫文件也是必不可少的。
    庫文件是怎么樣的結構呢?
    其實,庫文件的結構也很簡單。它就是“一堆”目標文件的集合。把目標文件做成庫以后,我們在使用目標文件中所實現的功能時,連接程序會自動在庫文件里查找相應的目標文件,并使用它。這大大減少了我們對目標文件的管理工作,減輕了代碼重用的負擔。
    Lib文件中的節
    COFF格式中所用到的“節”的概念再次出現在Lib格式中。不過,Lib文件的節要簡單得多。先讓我們來看看它的整體結構:
    如右圖所示:
    Lib格式只有四種類型的節(Section),即First Sec,Second Sec,Longname Sec和Obj Sec;其中Second Sec與Longname Sec是可選節,很多Lib文件中都沒有。而開頭的Singature只是一個標識,它相當于COFF目標文件中的魔法數字。它是一個長度為8的字符串,值為“!<arch>\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”)。怎么樣?有點奇怪吧?為什么要有這個結束符?每一節的頭長度一定,每節中的數據長度也知道。按順序向下讀不行嗎?答案是:不行!因為每一節之間存在間隙!通常是一個字節或零個字節。如果是零個字節倒好,按順序向下讀是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<size/2;i++ ) {
            temp=buf[i];
            buf[i]=buf[size-i-1];
            buf[size-i-1]=temp;
        }
    }
 
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中的偏移。

例如

!<arch>\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文件格式中進行詳細介紹。
posted on 2007-07-19 16:54 Charles 閱讀(2290) 評論(1)  編輯 收藏 引用 所屬分類: 拿來主義

FeedBack:
# re: COFF格式續篇—Lib文件的結構zz[未登錄]
2007-07-20 01:07 | Corner Zhang
好文!
期待關于dll的  回復  更多評論
  
<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

決定開始寫工作日記,記錄一下自己的軌跡...

常用鏈接

留言簿(4)

隨筆分類(70)

隨筆檔案(71)

charles推薦訪問

搜索

  •  

積分與排名

  • 積分 - 51915
  • 排名 - 448

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩精品| 亚洲精品日本| 国产精品你懂的| 欧美精品激情blacked18| 欧美99久久| 欧美精品91| 欧美黄色影院| 欧美性猛交视频| 国产婷婷精品| 亚洲精品美女久久7777777| 欧美一级在线视频| 亚洲欧美日韩国产成人| 久久久.com| 欧美国产一区二区| 欧美午夜免费| 激情综合色丁香一区二区| 亚洲青色在线| 亚洲欧美日韩天堂| 麻豆精品在线视频| 亚洲欧洲一区| 欧美一区二区日韩| 欧美激情精品久久久六区热门| 欧美特黄视频| 在线免费观看成人网| 一区二区三区 在线观看视| 亚洲在线成人| 欧美激情第8页| 亚洲欧美视频| 欧美精品观看| 久久视频这里只有精品| 国产精品一区久久久久| 在线国产日韩| 久久激五月天综合精品| 亚洲人成毛片在线播放女女| 午夜精品久久久久久久久久久| 另类欧美日韩国产在线| 国产精品日韩欧美一区二区三区| 亚洲黄一区二区| 欧美亚洲一区在线| 亚洲人成人一区二区在线观看| 亚洲资源av| 欧美日韩亚洲高清一区二区| 在线日韩av永久免费观看| 午夜免费日韩视频| 亚洲日本理论电影| 老牛影视一区二区三区| 国产性天天综合网| 亚洲一区二区在线| 亚洲精品美女免费| 欧美国产亚洲精品久久久8v| 永久555www成人免费| 欧美一区精品| 亚洲天堂网站在线观看视频| 欧美激情一区二区在线| 亚洲国产一区在线| 欧美成人精品高清在线播放| 午夜久久资源| 国产欧美日韩高清| 欧美一级欧美一级在线播放| 一道本一区二区| 欧美午夜激情在线| 亚洲女人av| 亚洲一区二区三区777| 欧美午夜一区二区| 亚洲欧美另类综合偷拍| 99在线观看免费视频精品观看| 欧美精品激情在线| 欧美一区二区高清在线观看| 久久精品视频免费观看| 国产欧美日韩三区| 久久久99国产精品免费| 欧美一区二区三区视频在线观看| 国产视频在线观看一区| 欧美在线日韩精品| 欧美亚洲免费在线| 禁久久精品乱码| 欧美多人爱爱视频网站| 欧美成人午夜激情| 亚洲视频导航| 亚洲欧美电影院| 激情婷婷欧美| 亚洲国产欧美精品| 欧美日韩美女| 久久精品国产一区二区三| 久久精品亚洲一区二区三区浴池| 伊人久久噜噜噜躁狠狠躁 | 91久久精品一区二区别| 欧美黄色一区二区| 欧美日韩国产小视频| 亚洲天堂网在线观看| 亚洲欧美日韩在线| 亚洲国产精品一区二区久| 亚洲精品日韩欧美| 国产一区观看| 亚洲国产精品www| 国产精品久久亚洲7777| 久久夜色精品国产欧美乱极品 | 欧美高清成人| 国产精品国产自产拍高清av| 久久久一区二区| 欧美日韩成人激情| 久久精品国产第一区二区三区最新章节| 久久精品在线观看| 中文亚洲欧美| 久久看片网站| 亚洲欧美资源在线| 欧美福利一区二区| 久久久久免费视频| 欧美调教vk| 女同性一区二区三区人了人一 | 亚洲高清激情| 中文一区二区在线观看| 久久精品国产亚洲aⅴ| 亚洲最新在线视频| 久久久噜噜噜久久狠狠50岁| 日韩视频免费| 久久本道综合色狠狠五月| 中日韩午夜理伦电影免费| 久久人人看视频| 欧美在线视频不卡| 欧美视频在线观看视频极品| 久久久爽爽爽美女图片| 国产精品女主播一区二区三区| 亚洲大黄网站| 久久福利资源站| 欧美www视频在线观看| 国产精品久久久久久久久久ktv| 乱码第一页成人| 国产精品久久久久久av福利软件 | 狠狠色丁香久久婷婷综合丁香| 亚洲久久一区二区| 亚洲欧洲日产国产网站| 久久久成人精品| 久久久久99| 国产午夜亚洲精品羞羞网站| 亚洲专区一区| 欧美在线视频一区二区三区| 国产精品美女久久福利网站| aa日韩免费精品视频一| 制服丝袜激情欧洲亚洲| 欧美日韩在线精品| 一本色道久久综合| 亚洲免费婷婷| 国产精品你懂的在线| 亚洲在线观看视频| 欧美一区二区三区电影在线观看| 国产精品高潮呻吟视频| 亚洲视频图片小说| 性欧美xxxx大乳国产app| 国产精品日韩专区| 欧美一区二区三区精品电影| 久久一二三区| 亚洲欧洲另类国产综合| 欧美日韩免费观看一区二区三区| 国产欧美日韩视频| 91久久黄色| 欧美精品在线观看一区二区| 亚洲三级电影全部在线观看高清| 99在线热播精品免费99热| 欧美日韩视频| 亚洲欧美一区二区三区极速播放| 久久精品一区二区三区中文字幕 | 日韩视频一区二区在线观看 | 免费在线播放第一区高清av| 亚洲国产精品v| 欧美理论视频| 亚洲综合成人在线| 蜜桃久久精品乱码一区二区| 亚洲人成亚洲人成在线观看图片| 欧美日韩国产大片| 亚洲一区在线观看免费观看电影高清| 午夜精品亚洲| 亚洲国产cao| 国产精品成人午夜| 欧美在线观看一区二区| 亚洲电影免费| 欧美一级片久久久久久久| 亚洲国产片色| 国产精品久久久久久久久久尿| 欧美成人亚洲成人| 一区二区三区视频在线| 免费在线日韩av| 欧美另类在线播放| 亚洲国产欧美另类丝袜| 亚洲电影在线看| 久久精品在线播放| 欲色影视综合吧| 日韩一二在线观看| 猫咪成人在线观看| 亚洲天堂成人在线观看| 91久久精品一区| 国外成人在线视频网站| 亚洲国产精品激情在线观看| 欧美特黄一级| 欧美.www| 国产欧美 在线欧美| 亚洲免费小视频| 欧美一区二区三区免费观看视频 | 欧美成人伊人久久综合网| 久久日韩粉嫩一区二区三区|