• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      基于Clang的AST提取結(jié)構(gòu)體數(shù)據(jù)庫(kù)插件的實(shí)現(xiàn)

      2017-04-26 07:27張紅
      電腦知識(shí)與技術(shù) 2017年6期
      關(guān)鍵詞:信息提取

      張紅

      摘要:在嵌入式系統(tǒng)調(diào)試環(huán)境下,需將大量的結(jié)構(gòu)體變量輸出到診斷軟件,進(jìn)行解析與呈現(xiàn),而結(jié)構(gòu)體數(shù)量龐大,且容易變化。在軟件快速迭代開(kāi)發(fā)階段,迫切需要使結(jié)構(gòu)體解析過(guò)程自動(dòng)化。最關(guān)鍵的一步,是實(shí)現(xiàn)結(jié)構(gòu)體定義數(shù)據(jù)庫(kù)的提取。此文主要研究基于Clang編譯器,實(shí)現(xiàn)從前端編譯結(jié)構(gòu)體定義文件生成的抽象語(yǔ)法樹(shù)中提取結(jié)構(gòu)體定義信息。實(shí)驗(yàn)結(jié)果表明,該方法能準(zhǔn)確的實(shí)現(xiàn)從結(jié)構(gòu)體定義文件提取結(jié)構(gòu)體定義XML數(shù)據(jù)庫(kù)。

      關(guān)鍵詞: Clang編譯器;抽象語(yǔ)法樹(shù);信息提取;結(jié)構(gòu)體定義

      中圖分類(lèi)號(hào):TP393 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2017)06-0019-03

      Abstract: In the debugging environment of the embedded system, the structure variables which are very large in quantity and mutable, should be output to the diagnostic software to be parsed and presented. In the rapidly iteration development phase, it is an urgent need to make the structure parsing process automation. It is the most crucial step to realize the extraction of structure definition database. This paper mainly studies how to extract structure definition information from the abstract syntax tree generated by the fronted compiler Clang. The experimental results show that this method can realize the structure XML database form the definition files accurately.

      Key words:Clang compiler; abstract syntax tree (AST); information extraction; structure definition

      1 概述

      在嵌入式軟件開(kāi)發(fā)過(guò)程中,為了快速分析軟件運(yùn)行過(guò)程,定位問(wèn)題,將系統(tǒng)運(yùn)行中的各類(lèi)診斷信息輸出到診斷軟件解析,而大量的診斷信息是基于結(jié)構(gòu)體類(lèi)型,在嵌入式系統(tǒng)開(kāi)發(fā)前期,采用手工編寫(xiě)解析結(jié)構(gòu)體的函數(shù)來(lái)實(shí)現(xiàn)。但結(jié)構(gòu)體定義在開(kāi)發(fā)調(diào)試過(guò)程中會(huì)經(jīng)常發(fā)生變更,結(jié)構(gòu)體解析庫(kù)就需要同步更新維護(hù),隨著系統(tǒng)工程模塊化程度提高,規(guī)模也越來(lái)越大,涉及的人員越來(lái)越多,結(jié)構(gòu)體定義與解析庫(kù)之間更新不同步的問(wèn)題越來(lái)越頻繁,維護(hù)成本越來(lái)越高,嚴(yán)重影響了軟件開(kāi)發(fā)迭代進(jìn)度。

      本文在開(kāi)源編譯框架LLVM的前端編譯器Clang的基礎(chǔ)上,通過(guò)開(kāi)發(fā)一個(gè)Clang前端插件,實(shí)現(xiàn)從抽象語(yǔ)法樹(shù)AST(Abstract Syntax Tree)中進(jìn)行結(jié)構(gòu)體數(shù)據(jù)庫(kù)提取。相比于手工編寫(xiě)解析函數(shù),將繁重的開(kāi)發(fā)和維護(hù)工作量降到0,大大提高了工作效率。

      本文第二節(jié)介紹Clang 前端插件的編寫(xiě)、編譯與執(zhí)行方法;給出結(jié)構(gòu)體數(shù)據(jù)庫(kù)提取插件的實(shí)現(xiàn)方法;第三節(jié)對(duì)本文進(jìn)行總結(jié)。

      2 相關(guān)工作

      2.1 Clang 前端插件開(kāi)發(fā)介紹

      Clang作為L(zhǎng)LVM開(kāi)源編譯框架的一種前端編譯器,實(shí)現(xiàn)編譯過(guò)程中的詞法分析,語(yǔ)法分析,類(lèi)型檢查,中間代碼生成。Clang對(duì)用戶(hù)進(jìn)行前端插件的開(kāi)發(fā)提供了很好的支持,前端操作的切入點(diǎn)是抽象類(lèi)FrontendAction,此接口支持在前端編譯過(guò)程中執(zhí)行插件定制的操作。AST消費(fèi)者的切入點(diǎn)是抽象類(lèi)ASTConsumer,此接口支持對(duì)抽象語(yǔ)法樹(shù)的訪問(wèn)。

      本文是研究在編譯過(guò)程中從抽象語(yǔ)法樹(shù)提取結(jié)構(gòu)體定義相關(guān)的信息,面向AST消費(fèi)者前端操作的抽象接口類(lèi)為FrontendAction的子類(lèi)ASTFrontendAction,插件中前端操作基類(lèi)選擇ASTFrontendAction的子類(lèi)PluginASTAction。自定義的AST消費(fèi)者基類(lèi)選擇ASTConsumer。

      2.1.1 編寫(xiě)Clang插件

      1) 定義繼承自PluginASTAction的自定義類(lèi)StructFrontendAction。重載三個(gè)成員函數(shù):

      ①用于創(chuàng)建抽象語(yǔ)法樹(shù)的Consumer類(lèi)。

      ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef);

      ②用于分析此插件執(zhí)行命令傳入的參數(shù)。

      bool ParseArgs(const CompilerInstance &CI,const std::vector& args);

      ③用于打印輸出此插件執(zhí)行的help信息。

      void PrintHelp(llvm::raw_ostream& ros);

      2) 定義繼承自ASTConsumer的抽象語(yǔ)法樹(shù)ASTStructConsumer類(lèi)。

      重載virtual bool HandleTopLevelDecl(DeclGroupRef DG),實(shí)現(xiàn)從抽象語(yǔ)法樹(shù)節(jié)點(diǎn)中提取所需信息。為了將分析AST過(guò)程中得到的信息組織成XML文件,可在此類(lèi)的構(gòu)造函數(shù)中創(chuàng)建XML文件,并構(gòu)造初始的節(jié)點(diǎn)框架,在析構(gòu)函數(shù)中完成文件的保存與關(guān)閉。

      3) 注冊(cè)插件

      static FrontendPluginRegistry::Add X("plugin-name", "plugin description");

      2.1.2 編譯Clang插件

      參考開(kāi)源代碼Clang/Examples下的插件示例將編譯環(huán)境配置好后,進(jìn)入build目錄執(zhí)行:make clang,編譯完成后,進(jìn)入build/tools/clang/example下的插件編譯目錄,執(zhí)行make,即可對(duì)插件進(jìn)行編譯。

      2.1.3 執(zhí)行clang插件

      $clang –cc1 –load StructFrontendAction.so –plugin my-plugin-name compileFile

      Clang –cc1為編譯器,-load將加載所有注冊(cè)的插件,-plugin指定加載特定的插件,若要將參數(shù)傳遞到插件里,可以使用-plugin-arg-。另外,可通過(guò)-fpack-struct=n指定編譯過(guò)程中的字節(jié)對(duì)齊策略,通過(guò)-triple 指定編譯目標(biāo)三元組信息,實(shí)現(xiàn)交叉編譯。

      2.2 結(jié)構(gòu)體信息提取的實(shí)現(xiàn)

      結(jié)構(gòu)體定義信息包括結(jié)構(gòu)體名稱(chēng)、大小和成員個(gè)數(shù),結(jié)構(gòu)體成員變量名稱(chēng)、類(lèi)型名稱(chēng),成員變量類(lèi)型的基礎(chǔ)類(lèi)型,成員變量在結(jié)構(gòu)體中的偏移值,成員變量的大小。

      結(jié)構(gòu)體的成員的類(lèi)型分以下六類(lèi):1)基本的系統(tǒng)內(nèi)置(builtin)數(shù)據(jù)類(lèi)型,如unsigned char,unsigned short,int等;2)重定義(typedef)數(shù)據(jù)類(lèi)型,如對(duì)內(nèi)置數(shù)據(jù)類(lèi)型、結(jié)構(gòu)體類(lèi)型、枚舉類(lèi)型的重定義;3)指針;4)數(shù)組;5)聯(lián)合體;6)位域。

      以ASTConsumer的接口函數(shù)HandleTopLevelDecl(DeclGroupRef DG)為入口點(diǎn),從AST的頂層節(jié)點(diǎn)TranslationUnitDecl開(kāi)始, 該節(jié)點(diǎn)下的子節(jié)點(diǎn)類(lèi)型有TypedefDecl,EnumDecl,RecordDecl,F(xiàn)unctionDec。結(jié)構(gòu)體定義屬于RecordDecl,自定義的成員類(lèi)型定義信息來(lái)自于TypedefDecl,而枚舉類(lèi)型信息在EnumDecl節(jié)點(diǎn)。因此需要分析AST中的TranslationUnitDecl頂級(jí)節(jié)點(diǎn)下的所有TypedefDecl,EnumDecl和RecordDecl節(jié)點(diǎn)。每種節(jié)點(diǎn)類(lèi)型的都是繼承自NamedDecl。

      首先獲取Decl的名稱(chēng),可以通過(guò)NamedDecl的getNameAsString()實(shí)現(xiàn)。有些可能是匿名,獲取Decl名字為空,如“typedef { …}TypeA;”,這時(shí)可以通過(guò)getTypedefNameForAnonDecl()獲取匿名Decl的TypedefNameDecl,若該匿名對(duì)象的TypedefNameDecl為空,該Decl將不可能作為結(jié)構(gòu)體成員類(lèi)型,可以忽略。

      下面依次介紹TypedefDecl、EnumDecl,和RecordDecl節(jié)點(diǎn)信息的提取。

      1)TypedefDecl節(jié)點(diǎn)

      如“typedef A B;”,獲取到的Decl的名稱(chēng)是B,此時(shí)需要分析出B的原始類(lèi)型名稱(chēng),原始類(lèi)型可以是內(nèi)置數(shù)據(jù)類(lèi)型,或自定義結(jié)構(gòu)體類(lèi)型或枚舉類(lèi)型等,提取出新類(lèi)型與基礎(chǔ)類(lèi)型的對(duì)應(yīng)關(guān)系。當(dāng)A不屬于基礎(chǔ)類(lèi)型,將繼續(xù)分析A的基礎(chǔ)類(lèi)型,直至找到基礎(chǔ)類(lèi)型C作為B的基礎(chǔ)類(lèi)型。

      將提取到的新類(lèi)型名稱(chēng)與基礎(chǔ)類(lèi)型名稱(chēng)的信息作為typedefs的子節(jié)點(diǎn)存入XML文件:

      2)EnumDecl 節(jié)點(diǎn)

      分析出枚舉類(lèi)型名字后,通過(guò)遍歷EnumDecl的枚舉向量來(lái)提取枚舉成員字符串與數(shù)值,將信息作為enums的子節(jié)點(diǎn)寫(xiě)入XML文件:

      < item name=”Item2” value=”1”/>

      3)RecordDecl節(jié)點(diǎn)

      RecordDecl下除了struct類(lèi)型還有其它類(lèi)型,本文只關(guān)注RecordDecl下的struct類(lèi)型,可以通過(guò)下isStruct()判斷。在結(jié)構(gòu)體成員不為空,即field_empty()為FALSE時(shí),通過(guò)訪問(wèn)ASTRecordLayout對(duì)象,getFieldCount()可以獲取結(jié)構(gòu)體成員個(gè)數(shù)FiledCount,getSize()可以獲取結(jié)構(gòu)體的大小。將信息作為structs的子節(jié)點(diǎn)存入XML文件:

      ,其中size值為字節(jié)數(shù)。

      通過(guò)遍歷RecordDecl::field_iterator來(lái)獲取結(jié)構(gòu)體成員變量信息,getFieldIndex()可以獲取成員變量索引值,getFieldOffset(fieldIndex)可以獲取索引值為fieldIndex的成員在結(jié)構(gòu)體中的偏移值,getName()可以獲取該成員的變量名,getType()可以獲取該成員的類(lèi)型,成員變量的大小需要通過(guò)getASTContext()獲取ASTContext對(duì)象,進(jìn)而由getTypeSize(fieldType)獲取。將信息作為該struct節(jié)點(diǎn)的子節(jié)點(diǎn)存入XML文件:

      ,其中size值表示二進(jìn)制位數(shù),baseType為對(duì)成員變量類(lèi)型的原始類(lèi)型的分類(lèi)碼,內(nèi)嵌類(lèi)型為0,結(jié)構(gòu)體類(lèi)型為1,數(shù)組類(lèi)型為2,聯(lián)合體類(lèi)型為3,位域類(lèi)型為4,指針類(lèi)型為5,枚舉類(lèi)型為6。

      分析成員變量類(lèi)型時(shí),需對(duì)聯(lián)合體、指針、數(shù)組、位域類(lèi)型信息作進(jìn)一步提取。

      ①對(duì)聯(lián)合體類(lèi)型,可以通過(guò)isUnionType()來(lái)判斷,union節(jié)點(diǎn)對(duì)象為RecordDecl類(lèi)型,通過(guò)ASTRecordLayout可以獲取union下的成員信息。

      ②對(duì)位域類(lèi)型,可以通過(guò)isBitField()來(lái)判斷,需進(jìn)一步提取位寬信息,通過(guò) (*iter)->getBitWidthValue((*iter)->getASTContext() );來(lái)實(shí)現(xiàn),其中iter 為RecordDecl::field_iterator 。將位寬信息作為該成員變量field節(jié)點(diǎn)的子節(jié)點(diǎn)存入XML文件:

      ③對(duì)指針類(lèi)型,可以通過(guò)isPointerType()來(lái)判斷,提取指針?biāo)割?lèi)型的名稱(chēng)和原始類(lèi)型信息。將信息作為field節(jié)點(diǎn)的子節(jié)點(diǎn)存入XML文件:

      ④對(duì)數(shù)組類(lèi)型,可通過(guò)isArrayType()來(lái)判斷,需要獲取數(shù)組對(duì)象類(lèi)型信息與數(shù)組的大小。通過(guò)getElementType()獲取數(shù)組成員類(lèi)型,然后進(jìn)一步分析該類(lèi)型的原始類(lèi)型。結(jié)構(gòu)體成員中的數(shù)組均是定長(zhǎng)數(shù)組,即使作為變長(zhǎng)使用的零數(shù)組,在編譯階段也是作為定長(zhǎng)數(shù)組處理。 對(duì)于定長(zhǎng)數(shù)組ConstantArrayType可以通過(guò)getSize()獲取數(shù)組的大小。將數(shù)組類(lèi)型成員信息存入XML文件:

      對(duì)于多維數(shù)組,可以對(duì)數(shù)組成員進(jìn)行數(shù)組類(lèi)型的遞歸分析。

      3 總結(jié)

      本文針對(duì)嵌入式系統(tǒng)中,對(duì)結(jié)構(gòu)體類(lèi)型診斷信息解析維護(hù)工作量大的問(wèn)題,提出了采用基于clang編譯器的前端插件在編譯過(guò)程中,通過(guò)訪問(wèn)抽象語(yǔ)法樹(shù)節(jié)點(diǎn),提取結(jié)構(gòu)體定義信息數(shù)據(jù)庫(kù)的方法,按一定策略組織成結(jié)構(gòu)體定義的XML數(shù)據(jù)庫(kù)。本方法已應(yīng)用于嵌入式系統(tǒng)調(diào)試中,為結(jié)構(gòu)體自動(dòng)解析提供了基礎(chǔ),大大提高了軟件迭代開(kāi)發(fā)效率。

      參考文獻(xiàn):

      [1] LLVM[EB/OL]. http://www.llvm.org .

      [2] Clang[EB/OL]. http://clang.llvm.org .

      [3] 周睿. 基于Clang編譯器的程序結(jié)構(gòu)分析器設(shè)計(jì)[J]. 計(jì)算機(jī)時(shí)代,2016(10):54-56.

      [4] 高傳平,談利群,宮云戰(zhàn). 基于抽象語(yǔ)法樹(shù)的代碼靜態(tài)自動(dòng)測(cè)試方法研究[J]. 北京化工大學(xué)學(xué)報(bào):自然科學(xué)版,2007(S1):25-29.

      [5] 章磊. Clang上的C/C++過(guò)程間分析和漏洞發(fā)掘[D].合肥:中國(guó)科學(xué)技術(shù)大學(xué),2009.

      [6] 陳火旺.程序設(shè)計(jì)語(yǔ)言編譯原理[M]. 北京: 國(guó)防工業(yè)出版社, 2000.

      [7] Kenneth C Louden.編譯原理及實(shí)踐[M]. 馮博琴,譯.北京: 機(jī)械工業(yè)出版社, 2000.

      [8] 高艷玲. 編譯原理——C教學(xué)編譯器設(shè)計(jì)[J]. 電腦知識(shí)與技術(shù),2009(18):4932-4933.

      猜你喜歡
      信息提取
      基于信號(hào)處理技術(shù)的正念腦電信息提取方法
      建筑電氣設(shè)計(jì)中BIM技術(shù)的應(yīng)用研究
      霍林郭勒市| 健康| 隆子县| 贵港市| 舟曲县| 盐边县| 新龙县| 勃利县| 黑山县| 潞城市| 关岭| 广平县| 德江县| 新郑市| 深州市| 资阳市| 凤阳县| 皮山县| 宁津县| 三都| 利川市| 广灵县| 颍上县| 武汉市| 阳原县| 万载县| 牡丹江市| 韶关市| 屏东市| 泗洪县| 蓬溪县| 靖边县| 普兰店市| 平罗县| 灯塔市| 龙海市| 百色市| 汕头市| 勐海县| 泸州市| 灵璧县|