C and C++ Binaries

Writing C Plug-Ins For CodeSonar

This section describes how to write and install C plug-ins for CodeSonar.

CodeSonar SaaS Note: If you want to use your own custom plug-ins with CodeSonar SaaS, contact CodeSecure support for assistance. The installation instructions provided in this page are not sufficient to make plug-ins available to SaaS analyses.



Overview

To create and use a CodeSonar C plug-in, do the following:

  1. Create C source file(s) for the plug-in.
  2. Compile the plug-in into a library: .dll, .so, or .bundle as appropriate for your platform.
  3. Save the plug-in in directory $CSONAR/codesonar/plugins, where $CSONAR is the CodeSonar installation directory.

Create Source File(s)

Suppose you want to define a plug-in called pname_plugin.

File content requirements The source file(s) for the plug-in must include the following elements.
#include "csonar_plugin.h"
// #include any other C API headers used
// ...
static void cs_plug_main(void){// all visitors must be added in this function
   } 
CS_DEFINE_PLUGIN(pname_plugin)  // must be final line; built plug-in library must have corresponding name
File name requirements Source file: none
Built library: must correspond to the name registered with CS_DEFINE_PLUGIN(pname_plugin) in the source file:
Windows: pname_plugin.dll
All other systems: pname_plugin.so
Add visitors In cs_plug_main().
Define new warning classes;
define new metric classes
In a setup visitor, which in turn must be added in cs_plug_main().
Key API Functions CodeSonar Plug-In API: C Functions and Types for Visitors, Warnings, and Metrics (csonar_plugin.h)
Annotated Examples Classes Plug-in Tutorial: C, AST Tutorial: C

(Further implementation notes are provided below.)

Compile the Plug-In

Once the plug-in source files are created, compile the plug-in into a library. The library name must meet the file name requirements listed above.

Preliminaries

There are two important requirements for building a C plug-in.

Performing the Compilation

Compilation instructions vary slightly depending on your operating system.

  Compiler Command Line Notes
Windows
  cl
cl /LD /MD "/I%CSONAR%\codesonar\include"
"/I%CSONAR%\csurf\include" pname_plugin.c
"%CSONAR%\codesonar\lib\codesonar.lib"
Cygwin gcc Note: Cygwin gcc is only suitable for building 32-bit CodeSonar plug-ins. Cygwin gcc only builds Cygwin binaries, so is not suitable for building 64-bit CodeSonar plug-ins. If you do not have an alternative gcc, you will need to download and install one. One option is mingw-w64.
  • Cygwin 1.7 Use the gcc-3 executable (not gcc / gcc4, which does not support -mno-cygwin). If you do not have a gcc-3 binary, use Cygwin's setup.exe tool to install the mingw-gcc component.
    gcc-3 -shared -mno-cygwin "-I$CSONAR/codesonar/include"
    "-I$CSONAR/csurf/include" pname_plugin.c -o pname_plugin.dll
    "-L$CSONAR/codesonar/lib" -lcodesonar
  • Cygwin 1.5
    gcc -shared -mno-cygwin "-I$CSONAR/codesonar/include"
    "-I$CSONAR/csurf/include" pname_plugin.c -o pname_plugin.dll
    "-L$CSONAR/codesonar/lib" -lcodesonar
  • Link against $CSONAR/codesonar/lib/libcodesonar.a
  • Use the -mno-cygwin flag.
  • If you are using 32-bit CodeSonar on a 64-bit platform, add the -m32 flag to the command line (unless your compiler version will not accept it).
MinGW gcc
gcc -shared "-I$CSONAR/codesonar/include"
"-I$CSONAR/csurf/include" pname_plugin.c -o pname_plugin.dll
"-L$CSONAR/codesonar/lib" -lcodesonar
  • Link against $CSONAR/codesonar/lib/libcodesonar.a
  • If you are using 64-bit CodeSonar, use 64-bit MinGW gcc. Note that, depending on your system configuration, this may not be the version invoked by the 'gcc' command - in this case you will need to either adjust your environment or use a different name to invoke the correct compiler.
  • If you are using 32-bit CodeSonar on a 64-bit platform, add the -m32 flag to the command line (unless your gcc version will not accept it).
otherwise
  • Refer to your compiler documentation to see how to create an import library from
    $CSONAR/codesonar/lib/codesonar.def
    (or have your plug-in obtain the necessary function pointers with GetProcAddress).
  • Build pname_plugin.dll from pname_plugin.c, linking against this import library and including $CSONAR/codesonar/include and $CSONAR/csurf/include.
  • [64-bit CodeSonar only] A useful starting place for Visual Studio users is How to: Configure Visual C++ Projects to Target 64-Bit Platforms.
  gcc
gcc -Wl,-search_paths_first -bundle -bundle_loader $CSONAR/codesonar/bin/codesonar -fPIC
-o pname_plugin.bundle pname_plugin.c
-I$CSONAR/codesonar/include
-I$CSONAR/csurf/include
  • Use the -fPIC flag.
  • If you are using 32-bit CodeSonar on a 64-bit platform, add the -m32 flag to the command line (unless it causes problems).
All Other Systems
We provide a full example for gcc. For other compilers, build pname_plugin.so from pname_plugin.c, including $CSONAR/codesonar/include and $CSONAR/csurf/include.
  gcc
gcc -fPIC -shared -o pname_plugin.so pname_plugin.c
-I$CSONAR/codesonar/include
-I$CSONAR/csurf/include
  • Use the -fPIC flag.
  • If you are using 32-bit CodeSonar on a 64-bit platform, add the -m32 flag to the command line (unless it causes problems).

Troubleshooting

If the build fails and reports errors in cs_basic_types.h, this generally indicates that your build has a different pointer width than that of the CodeSonar installation. If this happens:

  1. Double-check the "Host Platform" line in $CSONAR/SIGNATURE.txt to make sure you know the pointer width for your CodeSonar installation
  2. Make sure your build command has the same pointer width.
    In particular, make sure you have applied any build flags or other adjustments indicated in Performing the Compilation (above). Depending on your compiler, you may need to perform additional steps: consult your compiler documentation for details.

Install

Save the plug-in in directory $CSONAR/codesonar/plugins, where $CSONAR is the CodeSonar installation directory. The plug-in will be automatically loaded and run when CodeSonar runs.

If you want to save the plug-in in a different location, use the PLUGINS configuration file option to specify its file path so that CodeSonar can load and run it.

Windows Note: you will not be able to modify plug-in .dll files in $CSONAR/codesonar/plugins, or .dll files specified by the PLUGINS option, while a CodeSonar process is running. If you encounter this problem while trying to update an existing plug-in, use the Windows Task Manager (or a similar tool) to end all codesonar.exe processes.

Implementation Notes

Adding Visitors

Add visitors in cs_plug_main().
Adding: all visitors except step visitors
  1. Define a visitor function.
  2. Pass the function to the appropriate csonar_add_*_visitor() method.
Adding: step visitors
  1. Define a cs_step_visitor_dispatch_t that characterizes your step visitor.
  2. Pass it to analysis.add_step_bottom_up_visitor().

The following table lists the available functions for adding visitors.

Build/Analysis Phase Add visitors with
drop traversal csonar_add_program_drop_visitor()
csonar_add_uid_drop_visitor()
csonar_add_pdg_drop_visitor()
csonar_add_global_abs_loc_drop_visitor()
csonar_add_program_drop_finish_visitor()
after drop traversal, before anything else csonar_add_setup_visitor()
after setup visitors, before serial depth-first analysis phase csonar_add_program_visitor()
serial depth-first analysis phase csonar_add_uid_visitor()
csonar_add_sf_visitor()
csonar_add_sfi_visitor()
csonar_add_sfi_finish_visitor()
csonar_add_sf_finish_visitor()
csonar_add_pdg_visitor()
csonar_add_pdg_vertex_visitor()
csonar_add_abs_loc_visitor()
csonar_add_pdg_finish_visitor()
csonar_add_uid_finish_visitor()
after serial depth-first analysis phase, before any program parallel visitors csonar_add_program_finish_visitor()
after program finish visitors, before parallel depth-first analysis phase csonar_add_program_parallel visitor()
parallel depth-first analysis phase csonar_add_uid_parallel_visitor()
csonar_add_sf_parallel_visitor()
csonar_add_sfi_parallel_visitor()
csonar_add_sfi_parallel_finish_visitor()
csonar_add_sf_parallel_finish_visitor()
csonar_add_pdg_parallel_visitor()
csonar_add_pdg_vertex_parallel_visitor()
csonar_add_abs_loc_parallel_visitor()
csonar_add_pdg_parallel_finish_visitor()
csonar_add_uid_parallel_finish_visitor()
after parallel depth-first analysis phase, before any program bottom-up visitors csonar_add_program_parallel_finish_visitor()
after pointer analysis phase, before bottom up analysis phase csonar_add_program_bottom_up_visitor()
bottom-up analysis phase csonar_add_pdg_bottom_up_visitor()
csonar_add_pdg_vertex_bottom_up_visitor()
csonar_add_step_bottom_up_visitor()
csonar_add_pdg_bottom_up_finish_visitor()
after bottom-up phase (all traversal is finished) csonar_add_program_bottom_up_finish_visitor()
(periodically, as analysis progresses) csonar_add_cache_cleanup_visitor()

New Warning Classes

Warning class type cs_warningclass_t
Warning class flag type csonar_warningclass_flags
Must be defined in a setup visitor.
Defined with csonar_create_warningclass()
csonar_create_warningclass_ex()

Issuing Warnings

Issue a warning associated with... API Function
... no particular file, procedure, or code location. csonar_report_analysis_warning()
... a specific source file instance. csonar_report_file_warning()
... a code span. csonar_report_location_span_warning()
... a code span in a specified procedure. csonar_report_location_span_warning_in_pdg()
... a source line. csonar_report_location_warning()
... a source line in a specified procedure. csonar_report_location_warning_in_pdg()
... a list of code locations. csonar_report_locations_warning()
... a list of code locations in a specified procedure. csonar_report_locations_warning_in_pdg()
... a program path. csonar_report_path_warning()
... a program point. csonar_report_warning()
... a step path. csonar_report_step_path_warning()

Retracting Warnings

Retraction info parameter type (when warning reported) cs_warning_retraction_info_t
Manually retract with csonar_retract_warning()

Warning Class Information

Warning Class Information Function
ID (a numeric identifier) csonar_warningclass_id()
Name csonar_warningclass_name()
Are WARNING_FILTER settings such that instances of this warning class will always be ignored? csonar_warningclass_always_discarded()
Retrieve class by ID csonar_warningclass_lookup()
Retrieve class by name csonar_warningclass_lookup_by_name()

New Metric Classes

Metric class type cs_metricclass_t
Metric class flag type cs_metricclass_flags
Must be defined in a setup visitor.
Defined with Granularity-specific creation functions:
csonar_metric_create_class_analysis()
csonar_metric_create_class_compunit()
csonar_metric_create_class_file()
csonar_metric_create_class_procedure()

Reporting and Retracting Metric Values

Automatically-reported metrics are computed and reported automatically by the CodeSonar analysis. Manually-reported metrics must be reported explicitly by the plug-in, using the appropriate granularity-specific function.

Both automatic and manual retraction can take place.

Manually report with csonar_report_metric_analysis()
csonar_report_metric_compunit()
csonar_report_metric_file()
csonar_report_metric_procedure()
Manually retract with csonar_metric_retract_compunit()
csonar_metric_retract_file()
csonar_metric_retract_procedure()
(All analysis-granularity metrics are automatically retracted.)

Other Metric Functionality

Functionality Function
Get the granularity of a metric class. csonar_metric_get_granularity()
Get the tag (short identifier) of a metric class. csonar_metric_tag()
Get the description (longer, human readable description) of a metric class. csonar_metric_description()
Get the flags associated with a metric class. csonar_metric_flags()
Look up a metric class. csonar_metric_get_class()
Get the value of a specified metric for a specified program element. csonar_metric_getvalue_analysis()
csonar_metric_getvalue_compunit()
csonar_metric_getvalue_file()
csonar_metric_getvalue_procedure()
Iterate over all metric classes with a specified granularity. csonar_metric_class_iter_first()
csonar_metric_class_iter_next()
csonar_metric_class_iter_close()

More on Plug-Ins

General Information:

Visitors Plug-ins are based on visitors, which specify actions to be carried out on elements of the CodeSonar internal representation (IR) at various stages of the analysis.
Writing Plug-Ins General information about creating plug-ins to attach custom functionality to the CodeSonar analysis.
Custom Checks: Accounting for Incrementality Ensuring that custom checks implemented in plug-ins generate appropriate results in incremental analyses.
Plug-In Tutorial Two annotated example plug-ins (each provided in all API languages), with building and installation instructions.
AST API Tutorial The AST API tutorial (provided in all API languages) also uses plug-ins.

Specific API Language:

  Plug-In Guidelines Key API References
C++ Writing C++ Plug-Ins classes analysis, visitor, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass.
Python Writing Python Plug-Ins Visitor decorators, Metric decorators; classes analysis, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass.
C Writing C Plug-Ins
(this page)
CodeSonar Plug-In API: C Functions and Types for Visitors, Warnings, and Metrics