Skip to content

Commit

Permalink
October 2019 release.
Browse files Browse the repository at this point in the history
  • Loading branch information
james-ben committed Oct 30, 2019
1 parent e55841d commit b7c373d
Show file tree
Hide file tree
Showing 67 changed files with 4,344 additions and 595 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Welcome to the COAST Repository

Welcome to the repository for COAST (COmpiler-Assisted Software fault Tolerance), BYU's tool for automated software mitigation! To get started, please refer to our [documentation pages](https://coast-compiler.readthedocs.io/en/stable/).
# Welcome to the COAST Repository

Welcome to the repository for COAST (COmpiler-Assisted Software fault Tolerance), BYU's tool for automated software mitigation! To get started, please refer to our [documentation pages](https://coast-compiler.readthedocs.io/en/latest/).
6 changes: 6 additions & 0 deletions docs/source/cfcss.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ To implement the control flow checking, we inserted a set of instructions at the
One of the optimizations we used was to only insert the extra XOR operation when :math:`D_n−1` was :math:`\neq 0`. This is one reason why the buffer block fix worked.


Notes
=============

This pass was created for the purposes of studying LLVM IR and the LLVM C++ framework. It is not actively being maintained.


.. rubric:: Footnotes

.. [#f1] N. Oh, P. P. Shirvani, and E. J. McCluskey, "Control-flow checking by software signatures," *IEEE Transactions on Reliability*\ , vol. 51, no. 1, pp. 111–122, Mar. 2002.
24 changes: 24 additions & 0 deletions docs/source/eclipse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,27 @@ Building the projects
2. Call the target name ``all`` and click OK.
3. To build your pass, right click on the build folder and click "Make Targets -> Build -> Build" (with the target ``all`` selected).
4. After the first time that you’ve done this, you can rebuild all your passes by pressing ``F9``.


Fixing the CDT settings
========================

The default settings of the project are not sufficient to allow the Eclipse CDT indexer to work correctly. While not necessary to fix the CDT settings, it allows you to use the auotcomplete functionality of Eclipse.

1. Right-click on the project and select "Properties"
#. Under "C/C++ General" select "Paths and Symbols"
#. Add a new Include Directory using the "Add" button
#. Select "File System"
#. Navigate to the repository root, then select ``llvm/include``
#. Check the box "Add to all languages," then click "OK"
#. On the left pane, select "Preprocessor Include Paths, Macros, etc"
#. On the "Providers" select "CDT GCC Built-in Compiler Settings"
#. Edit the "Command to get compiler specs" by putting ``std=c++11`` right before ``${INPUTS}``
#. Move the entry "CDT GCC Built-in Compiler Settings" to the top of the list using the "Move Up" button
#. Select "Apply and Close"

1. Select "Window" -> "Preferences"
#. Select "C/C++" -> "Build" -> "Settings"
#. Under the "Discovery" tab select "CDT GCC Built-in Compiler Settings"
#. Edit the "Command to get compiler specs" the same as before
#. Select "Apply and Close"
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ COAST
passes
troubleshooting
cfcss
release_notes

Folder guide
==============
Expand Down
111 changes: 107 additions & 4 deletions docs/source/passes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ These options are only applicable to the ``-DWC`` and ``-TMR`` passes.
+---------------------------+-----------------------------------------------------+
| ``-noStoreAddrSync`` | Don’t synchronize the address on data stores (C5). |
+---------------------------+-----------------------------------------------------+
| ``-storeDataSync`` | Force synchronizing data on data stores (C4). |
+---------------------------+-----------------------------------------------------+

.. table::
:widths: 25 40
Expand Down Expand Up @@ -129,6 +131,47 @@ In-code Directives
| | instead of modifying the function body. |
+----------------------+-------------------------------------------------------+

.. versionadded:: Oct2019

.. table::
:widths: 25 40

+----------------------------------+----------------------------------------------------+
| | Used to mark global variables as ones that the |
| ``__COAST_VOLATILE`` | pass should not remove, even if it does not appear |
| | to be used. |
+----------------------------------+----------------------------------------------------+
| | Ignore checks for global variable replication in |
| ``__COAST_IGNORE_GLOBAL(name)`` | function following this directive. |
| | |
| | See section `Replication Scope`_. |
+----------------------------------+----------------------------------------------------+

.. table::
:widths: 25 40

+------------------------------------+-------------------------------------------------+
| | Give the name of a ``malloc()``-like function |
| ``MALLOC_WRAPPER_REGISTER(fname)`` | that will be replicated. Should be treated the |
| | same as a function prototype. |
+------------------------------------+-------------------------------------------------+
| | Make a call to the function registered using |
| ``MALLOC_WRAPPER_CALL(fname, x)`` | the above macro. This will be replicated by |
| | COAST, using the clones of the arguments. |
+------------------------------------+-------------------------------------------------+
| | Give the name of a ``printf()``-like function |
| ``PRINTF_WRAPPER_REGISTER(fname)`` | that will be replicated. Should be treated the |
| | same as a function prototype. |
+------------------------------------+-------------------------------------------------+
| ``PRINTF_WRAPPER_CALL | Make a call to the function registered using |
| (fname, fmt, ...)`` | the above macro. This will be replicated by |
| | COAST, using the clones of the arguments. |
+------------------------------------+-------------------------------------------------+
| | Make your own wrapper function for COAST to |
| ``GENERIC_COAST_WRAPPER(fname)`` | replicate calls to. Used in both declaring and |
| | calling the function. |
+------------------------------------+-------------------------------------------------+


See the file COAST.h_

Expand All @@ -147,6 +190,8 @@ The `default file`_ contains functions we have identified as commonly treated di
.. _default file: https://github.com/byuccl/coast/blob/master/projects/dataflowProtection/functions.config


.. _when_repl_cmds:

When to use replication command line options
----------------------------------------------

Expand Down Expand Up @@ -197,27 +242,85 @@ The first option, ``-noMemReplication``, should be used whenever memory has a se

The option ``-noStoreAddrSync`` corresponds to C5. In EDDI, memory was simply duplicated and each duplicate was offset from the original value by a constant. However, COAST runs before the linker, and thus has no notion of an address space. We implement rules C3 and C5, checking addresses before stores and loads, for data structures such as arrays and structs that have an offset from a base address. These offsets, instead of the base addresses, are compared in the synchronization logic.

.. versionchanged:: Oct2019

As of the October 2019 release, COAST no longer syncs before storing data. Test data indicated that, in many cases, the number of synchronization points generated by this rule limited the effective protection that the replication of variables afforded. This behavior can be overridden using the ``-storeDataSync`` flag.

.. _repl_scope:

Replication Scope
--------------------

The user can specify any functions and global variables that should not be protected using ``-ignoreFns`` and ``-ignoreGlbls``. At minimum, these options should be used to exclude code that interacts with hard- ware devices (GPIO, UART) from the SoR. Replicating this code is likely to lead to errors. The option ``-replicateFnCalls`` causes user functions to be called in a coarse grained way, meaning the call is replicated instead of fine-grained instruction replication within the function body. Library function calls can also be excluded from replication via the flag ``-skipLibCalls``, which causes those calls to only be executed once. These two options should be used when multiple independent copies of a return value should be generated, instead of a single return value propagating through all replicated instructions. Changing the scope of replication can cause problems across function calls.
The user can specify any functions and global variables that should not be protected using ``-ignoreFns`` and ``-ignoreGlbls``. At minimum, these options should be used to exclude code that interacts with hardware devices (GPIO, UART) from the SoR. Replicating this code is likely to lead to errors. The option ``-replicateFnCalls`` causes user functions to be called in a coarse grained way, meaning the call is replicated instead of fine-grained instruction replication within the function body. Library function calls can also be excluded from replication via the flag ``-skipLibCalls``, which causes those calls to only be executed once. These two options should be used when multiple independent copies of a return value should be generated, instead of a single return value propagating through all replicated instructions. Changing the scope of replication can cause problems across function calls.

.. versionadded:: Oct2019

Before processing the IR code, COAST begins by checking to make sure the replication scope rules it was given are consistent. It checks to make sure all cloned globals are only used in functions that are also protected. If they are not, the compilation will fail, with an error message informating the user which global is used in which function. The user has the option to ignore these checks if they feel that it is safe. This is done using the ``__COAST_IGNORE_GLOBAL`` macro mentioned above.

Other Options
----------------

**Error Logging**\ : This option was developed for tests in a radiation beam, where upsets are stochastically distributed, unlike fault injection tests where one upset is guaranteed for each run. COAST can be instructed to keep track of the number of corrected faults via the flag ``-countErrors``. This flag allows the program to detect corrected upsets, which yields more precise results on the number of radiation-induced SEUs. This option is only applicable to TMR because DWC halts on the first error. A global variable, ``TMR_ERROR_CNT``, is incremented each time that all three copies of the datum do not agree. If this global is not present in the source code then the pass creates it. The user can print this value at the end of program execution, or read it using a debugging tool.

**Error Handlers**\ : The user has the choice of how to handle DWC and CFCSS errors because these are uncorrectable. The default behavior is to create ``abort()`` function calls if errors are detected. However, user functions can be called in place of ``abort()``. In order to do so, the source code needs a definition for the function ``void FAULT_DETECTED_DWC()`` or ``void FAULT_DETECTED_CFCSS`` for DWC and CFCSS, respectively.
**Error Handlers**\ : The user has the choice of how to handle DWC and CFCSS errors because these are uncorrectable. The default behavior is to create ``abort()`` function calls if errors are detected. However, user functions can be called in place of ``abort()``. In order to do so, the source code needs a definition for the function ``void FAULT_DETECTED_DWC()`` or ``void FAULT_DETECTED_CFCSS()`` for DWC and CFCSS, respectively.

**Input Initialization**\ : Global variables with initial values provide an interesting problem for testing. By default, these initial values are assigned to each replicate at compile time. This models the scenario where the SoR expands into the source of the data. However, this does not accurately model the case when code inputs need to be replicated at runtime. This could happen, for instance, if a UART was feeding data into a program and storing the result in a global variable. When global variables are listed using ``-runtimeInitGlbls`` the pass inserts ``memcpy()`` calls to copy global variable data into the replicates at runtime. This supports scalar values as well as aggregate data types, such as arrays and structures.

**Interleaving**\ : In previous work replicated instructions have all been placed immediately after the original instructions. Interleaving instructions in this manner effectively reduces the number of available registers because each load statement executes repeatedly, causing each original value to occupy more registers. For TMR, this means that a single load instruction in the initial code uses three registers in the protected program. As a result, the processor may start using the stack as extra storage. This introduces additional memory accesses, increasing both the code size and execution time. Placing each set of replicated instructions immediately before the next synchronization point lessens the pressure on the register file by eliminating the need for multiple copies of data to be live simultaneously.

By default, COAST groups copies of instructions before synchronization points, effectively partitioning regions of code into segments where each copy of the program runs uninterrupted. Alternately, the user can specify that instructions should be interleaved using ``-i``.

**Printing Status Messages**\ : Using the ``-verbose`` flag will print more information about what the pass is doing. This includes removing unused functions and unused global strings. These are mainly helpful for examining when your code is not behaving exactly as expected.
**Printing Status Messages**\ : Using the ``-verbose`` flag will print more information about what the pass is doing. This includes removing unused functions and unused global strings.

If you are developing passes, then on occasion you might need to include more printing statements. Using the ``-dumpModule`` flag causes the pass to print out the entirety of the LLVM module to the command line in LLVM IR format.


.. _dbg_tools:

Debugging Tools
=================

COAST verbose output
--------------------

If you are developing passes, then on occasion you might need to include more printing statements. Using ``-dumpModule`` causes the pass to print out the entirety of the LLVM module to the command line in a format that can be tested using ``lli``. This is mainly helpful if the pass is not cleaning up after itself properly. The function ``dumpModule()`` can also be placed in different places in the code for additional debugging capabilities.
As mentioned above, COAST supports the ``-verbose`` and ``-dumpModule`` flags. The ``-verbose`` output lists alls of the in-code directives processed, which functions are having their signatures changed, as well as any unused globals or functions being removed. COAST will also print warnings or errors about unsupported language constructs being used.

Using the ``-dumpModule`` flag is useful to get an idea of what COAST is doing if it's failing to finish compilation. The function ``dumpModule()`` can also be placed in different places in the code for additional debugging capabilities. Since the module will be output to the ``stderr`` stream, and it can be quite a lot of data, it is important to redirect the output properly.

Example: ``opt -TMR -dumpModule input.bc -o output.bc > dump.ll 2>&1``


Debug Statements
-----------------

By default, the Debug Statements pass will add code to the beginning of every basic block that prints out the function name followed by the name of the basic block. For example, you would expect the first message to be ``main->entry``. This can produce 100s of MegaBytes of data, so it is important to redirect this output to a file, as shown in the example above. This verbose output represents a complete call graph of the execution, although trawling through all of this data can be quite difficult.

.. versionadded:: Oct2019

There is an option to only add print statements to certain functions. Pass ``-fnPrintList=`` with a comma-separated list of function names that will be instrumented with the print statements. This will allow examining smaller parts of the execution at a time.


Small Profiler
-----------------

.. versionadded:: Oct2019

The Small Profiler is a pass which simply counts the number of calls to each function in the module. It creates global variables that correspond to each function in the module. Each time a function is called, the corresponding global variable is incremented. The pass adds a call to a function named ``PRINT_PROFILE_STATS`` immediately before the ``main`` function exits. If the program does not terminate, calls to this function may be inserted manually by the programmer.

This pass also has two command line parameters:

.. table::
:widths: 25 40

+---------------------------+-----------------------------------------------------+
| Command line option | Effect |
+===========================+=====================================================+
| | The name of the function that is used to print |
| ``printFnName`` | the stats. The default is ``printf``. This flag |
| | is for if the platform does not support ``printf``. |
+---------------------------+-----------------------------------------------------+
| ``noPrint`` | Do not insert the call to ``PRINT_PROFILE_STATS``. |
+---------------------------+-----------------------------------------------------+


.. rubric:: Footnotes
Expand Down
61 changes: 61 additions & 0 deletions docs/source/release_notes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.. This document explains the changes in the releases
Release Notes
**************

October 2019
==============


Features
---------

- Support for ``invoke`` instructions.

- Replication rules, does NOT sync on stores by default, added flag to enable turning that on (``-storeDataSync``).

- Support for compiling multiple files in the same project at different times (using the ``-noMain`` flag).

- Before running the pass, validates that the replication rules given to COAST are consistent with themselves.

- Can sync on vector types.

- Added more unit tests, along with a test driver.


Directives
------------

- Added directive ``__SKIP_FN_CALL`` that has the same behavior as ``-skipFnCalls=`` command line parameter.

- Can add option to not check globals crossing Sphere of Replication (``__COAST_IGNORE_GLOBAL(name)``).

- Added directive macro for marking variables as volatile.

- Treats any globals or functions marked with ``__attribute__((used))`` as volatile and will not remove them. Also true for globals used in functions marked as "used".

- Added wrapper macros for calling a function with the clones of the arguments. Useful for ``printf()`` and ``malloc()``, etc, when you only want specific calls to be replicated.


Bug Fixes
-------------

Thanks to Christos Gentsos for pointing out some errors in the code base.

- Allow more usage of function pointers by printing warning message instead of crashing.

- Added various missing ``nullptr`` checks.

- Fixed crashing on some ``void`` return type functions.

- Better cleanup of stale pointers.


Debugging Tools
-----------------

- Added an option to the ``DebugStatements`` pass that only adds print statements to specified functions.

- Created a simplistic profiling pass called ``SmallProfile`` that can collect function call counts.

- Support for preserving debug info when source is compiled with debug flags.
Loading

0 comments on commit b7c373d

Please sign in to comment.