1. 程式人生 > >vxworks之符號表

vxworks之符號表

符號表初始化

          符號表用於建立符號名稱、型別和值之間的關係。其中,名稱為null結尾的任意字串;型別為標識各種符號的整數;值為一個字元指標。符號表主要用來作為目標模組載入的基礎,但在需要名稱和值關聯的任何時候都看使用。           執行系統中一般存在兩個符號表結構sysSymTbl和statSymTbl。sysSymTbl為目標機的系統符號表,通過程式或tShell動態載入的目標模組的符號模組的符號都新增到該符號表中,sysSymTbl和statSymTbl兩個標識本身頁包含在該系統符號表中。statSymTbl中包含errno的資訊,若相在tShell中使用printErrno命令,就必須包含該符號表。          主機的Target Server只使用一個符號表,看通過全域性變數tgtSymTbl訪問。          vxWorks中符號表函式庫symLib,提供用於符號表操作的相關函式。系統符號表允許同名衝突,同名符號回加入符號表而不報錯,當引用符號時,系統預設使用symFindByName查詢,所以最新加入的符號總會先找到,代替老符號完成引用。同名符號的存在還帶來另一個問題,不能確保查詢到的符號是自己載入模組的,即不能保證group號。主機symlib庫中函式用於維護主機符號表tgtSymTbl。           vxWorks的符號表與編譯器的符號表吧同,vxWorks的符號表時動態存在系統中的,由symLib提供的函式進行維護,在執行過程中可以增加和刪除符號,主要用於目標模組的動態載入,與目標模組的格式無關。而編譯器中的符號表時靜態的,由編譯器和聯結器在建立程式映像時生成並使用,主要用於符號的靜態解析,幫助建立映像,它們的格式和目標型別有關。交叉偵錯程式中原始碼除錯,頁時由靜態符號表支援的,這種符號表佔用很大的程式映像空間,當程式釋出時,可以去掉(不使用 -g 選項)。         vxWorks需要主機工具在映像生成時完成一些準備工作來建立系統符號表,sysSymTbl和statSymTbl對應兩個主機工具makeSymTbl.exe和makeStatTbl.exe,用於生成符號陣列以編譯進入程式映像。工具makeSymTbl.exe用於建立包含SYMBOL型別陣列的symTbl.c檔案,包含目標模組中所有全域性符號的名稱、地址和型別,該全域性陣列名稱為standTbl,其大小為standTblSize,存放在程式映像的data段中。工具makeStatTbl.exe用於建立狀態程式碼SYMBOL陣列,包含一些標頭檔案中定義的所有狀態程式碼的名稱和值,所有狀態程式碼以“S-”開頭,一般庫標頭檔案中都有這樣的定義。,該全域性陣列名成為statTbl,其大小為statTblSize,statSymTbl主要由printErrno函式使用,也可以由應用程式使用,輸出確定意義的狀態資訊,存放在程式映像的data段中。          符號表初始方式有build-in和downloaded兩種方式,使用內建符號表時,符號時Vxworks程式映像的一部分;下載符號表則和VxWorks映像分離,由目標機單獨下載Sym檔案獲得符號。若使用下載符號表,使用主機工具xsym,生成符號模組檔案VxWorks.sym,該檔案和普通目標模組一樣,只是沒有data和bss段,下載到目標機後,和普通目標模組一樣動態載入,模組中的符號會新增到系統符號表。          目標機符號表時完成動態載入、連線,以及除錯的輔助機制,映像有沒有符號表都不影響程式正常執行,除錯時,只要不從目標機上動態載入目標模組,程式映像符號都靜態連線解析,目標機上也可以沒有符號,主機開發工具都使用主機符號表tgtSymTbl來完成交叉除錯。       符號表同步
         主機和目標機使用不同的符號表,在主機上使用的各種工具並不能訪問目標機上所有的內容,工具都是通過主機上Target Server和目標機上Target Agent進行通訊的,主機和目標機都不能直接訪問對方的符號資訊。主機和目標機都維護著自己的符號表,當新增符號時,將符號加入到其中一個表中,在wShell上新增的符號到了主機符號表,而tShell上新增的符號就到了目標機符號表中,預設時兩個表互不共享,可以通過新增符號表同步元件------INCLUDE_SYM_TBL_SYNC,這樣符號會在主機和目標機之間福祉,兩符號表會同步更新。           主機和目標機使用不同的符號表,系統啟動時兩個符號表的內容是一樣的,當動態載入目標模組後,兩個符號表就不一致了,從wShell中載入目標模組後,卻想從tShell引用該模組符號,或者從tShell載入後,想用主機工具除錯該模組,因為wShell或tShell都看不見對方載入的模組,可能出現下面錯誤:            Error:module contains undefined symbol            Unresolved symbol            Fatal Error: unresolvable symbol          要解決此問題就需要使用符號表同步機制,Vxworks提供了symSyncLib庫來完成符號表同步,系統執行中,從主機或目標機新增的符號都可以被對方看見,symSyncLib會在目標機建立同步任務tSymSyc,該任務被當作WTX工具與主機的Target Server相連,任務啟動時,會立即同步符號表。如果不再需要同步符號表,可以手動將tSymSync懸掛起來,以提高目標機效能。        錯誤狀態
          若VxWorks庫函式執行出現問題,函式會返回ERROR值,並設定錯誤狀態表示具體的原因和位置。           錯誤狀態庫errnoLib用於獲取和設定任務和中斷的錯誤狀態值errno,VxWorks每個任務和中斷都有自己的errno,任務的errno存放在TCB中,為任務私有,中斷的errno存放在中斷棧中,只要字啊中斷處理函式中errno都有效。          VxWorks的errno值由4byte構成,高字表明發生錯誤的庫,各庫對應的值在“taget/h/vwModNum.h”中定義,低字表示該庫發生的具體錯誤,在相應庫的標頭檔案中定義。約定VxWorks系統模組使用高字值,範圍為1~500,其他值可以由應用模組使用,對低字值沒有規定。          usrLib提供printErrno函式來顯示具體錯誤資訊,printErrno根據輸入的errno值,在statSymTbl中查詢到對應的錯誤資訊,並顯示在標準輸出上。          ----> printErrno 0xd0003          0xd0003 = S_iosLib_INVALID_FILE_DESCRIPTOR          "S_"表示狀態,iosLib為發生錯誤的庫名稱,INVALID_FILE_DESCRIPTOR表示該庫具體的錯誤。          若想在tShell或程式中呼叫printErrno來顯示錯誤資訊,程式映像中需包含錯誤程式碼元件---INCLUDE_STAT_SYM_TBL
,
以在目標機建立statSymTbl。‘          如果不能使用printErrno,也可以手動查詢標頭檔案得到錯誤資訊,比如“d0003”,先在vwModNum.h查詢“d”對應的庫,“d”換算成十進位制“13”,查到M_iosLib:              #define M_iosLib        (13 << 16)          再到iosLib庫自己的標頭檔案iosLib.h中查詢具體錯誤,其中“0003”對應的巨集定義為:            # define S_iosLib_INVALID_FILE_DESCRIPTOR     (M_iosLIb | 3)           這個巨集定義名就是使用者要知道的錯誤資訊。