xcalcc / labrador

C/C++ standard compliance analyzer
Other
4 stars 0 forks source link
autosar cert-c clang compiler misra misra-c program-analysis security static-analysis

Xcalibyte Standard Compliance Analyzer (XSCA)

License

1. How to build

1.1 Get CLANG prebuilt libraryes

 # ubuntu
 $ sudo apt install clang

 # mac
 $ brew install llvm

 # download prebuilt clang libraries
 $ wget https://github.com/xcalcc/labrador/releases/download/v0.1/clang-11.0.0.tar.xz
 $ mkdir clang-prebuilt && cd clang-prebuilt
 $ tar Jxf clang-11.0.0.tar.xz

 # set CLANG_HOME
 $ export CLANG_HOME=/path/to/clang/libraries

1.2 Get XSCA source

 $ git clone https://github.com/xcalcc/labrador.git

1.3 Build XSCA

xsca will be built in build directory, and its components will be installed to $XSCA_HOME

 # set XSCA_HOME
 $ export XSCA_HOME=/directory/which/contains/components

 $ cd labrador
 $ mkdir build && cd build

 $ cmake -G Ninja ../src
 $ ninja
 $ ninja install

1.4 Simple run

 $ ./xsca -cc1 -emit-llvm test.c

2. How to add new ruleset

2.1 Create subdirectory in rules for the new rule

Copy the whole example in src/rules directory to new ruleset name:

 $ cd src/rules
 $ cp -r example <NEW-RULESET-NAME>

rename files in .

2.2 Update CMakeLists.txt in new subdirectory

Modify /CMakeLists.txt with correct library and source file name to build the library for new rule

2.3 Update rules's CMakeLists.txt

Modify src/rules/CMakeLists.txt to include this new ruleset subdirectory

2.4 Update src's CMakeLists.txt

Modify src/CMakeLists.txt to add the new library to XSCA_LIBS

2.5 Make sure new library is linked correctly

Modify src/xsca_link.cpp to add new extern and static variable to make sure the library is correct linked and static objects are initialized correctly. Define the new variable in example_checker.cpp. In xsca_link.cpp

extern int __NEW_RULESET_NAME__;   // defined in rules/example/example_checker.cpp
static ATTRIBUTE_UNUSED int New_Ruleset_Name = __NEW_RULESET_NAME__;

In example_checker.cpp

int __NEW_RULESET_NAME__;          // used in xsca_link.cpp

3. How to add new rule

3.1 Identify the type of the new rule. Possible type can be:

3.2 Implement the rule in seperated .inc file

3.3 Add new rule to rule list file

3.4 Modify example_checker.cpp

4. XSCA internal

4.1 virtual function v.s. template

XSCA oonly uses virtual functions in the interface with clang, include ASTConsumer and PPCallbacks. Inside XSCA, all checkers are composed by template without virtual function for performance consideration.

4.2 Checker, CheckerManager, CheckerFactory and CheckerFactooryRegister

Each ruleset is implemented as a checker. The checker base class provides 2 virtual functions to return callbacks (ASTConsumer and PPCallbacks) to be invoked by clang Lexer and Sema. CheckerManager is a singleton to manage all Checker instances and CheckerFactory instances. In XcalCheckerManager::Initialize(), all checker are created by CheckerFactory and added to clang's preprocess callbacks or AST consumers. CheckerFactory provides interface to create the Checker instance. It's created and added to CheckerManager by CheckerFactoryRegister.CheckerFactoryRegister is a static object to create CheckerFactory instance and add to CheckerManager.

XcalChecker is defined in include/xsca_checker.h. XcalCheckerManager, XcalCheckerFactory and XcalCheckerFactoryRegister is defined in include/xsca_checker_manager.h.

4.3 PPCallback, PPNullHandler and PPListHandler

PPCallback derives from clang::PPCallbacks which will be invoked by clang Lexer. When interfaces in PPCallbacks is called, the corresponding handler API will be invoked. PPNullHandler implements all clang::PPCallbacks API but do nothing. This can be the default base class for all PP handlers. PPListHandler composes multiple PP handles as a list so that they can be invoked by PPCallbacks one by one.

XcalPPCallback is defined in include/pp_callback.h. PPNullHandler is defined in pp_null_handler.h. PPListHandler is defined in pp_list_handler.h

4.4 TypeVisitor, TypeNullHandler and TypeListHandler

TypeVisitor implements a general Visit(clang::Type *type) method, which checks the type class and call individual Visit method on given Type class. In iindividual Visit method, corresponding handler method is called. TypeNullHandler implements all Visit* method for types but do nothing. This can be the default base class for all Type checkers. TypeListHandler composes multiple Type handlers as a list so that they can be invoked one by one.

XcalTypeVisitor is defined in include/type_visiotor.h. TypeNullHandler is defined in type_null_handler.h. TypeListHandler is defined in type_list_handler.h

4.5 StmtVisitor, StmtNullHandler and StmtListHandler.

Similar to TypeVisitor, TypeNullHandler, TypeListHandler. StmtVisitor will visit the Stmt node ans all it's children.

XcalStmtVisitor is defined in include/stmt_visiotor.h. StmtNullHandler is defined in stmt_null_handler.h. StmtListHandler is defined in stmt_list_handler.h

4.6 DeclVisitor, DeclNullHandler and DeclListHandler.

Similar to TypeVisitor, TypeNullHandler, TypeListHandler. DeclVisitor will visit the Decl node ans call TypeVisitor for TypeDecl and StmtVisitor for FunctionDecl.

XcalDeclVisitor is defined in include/decl_visiotor.h. DeclNullHandler is defined in decl_null_handler.h. DeclListHandler is defined in decl_list_handler.h

4.7 ASTConsumer

Interfaces in ASTConsumer is called by clang Sema and corresponding method in DeclVisitor is called so that all Handlers can be called.

4.8 Calling sequence:

For preprocess:

  Clang Lex --> PPCallbacks --> PPHandler --> individual PP check

For AST:

  Clang Sema --> ASTConsumer --> DeclVisitor --> DeclHandler --> individual Decl check
                                             --> (FunctionDecl) StmtVisitor --> StmtHandler --> individual Stmt check
                                             --> (TypeDecl) TypeVisitor --> TypeHandler --> individual Type check