Skip to content

cadets/loom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loom: LLVM instrumentation library

Loom is a general-purpose library for adding instrumentation to software in the LLVM intermediate representation (IR) format. It is currently capable of generating static instrumentation points that expose values (e.g., function parameters and return values) to software-defined instrumentation functions.

Loom is part of the CADETS (Causal, Adaptive, Distributed, and Efficient Tracing System) project as part of DARPA's Transparent Computing program.

Get it

Loom itself is entirely contained within this GitHub repository, but it requires that you build LLVM from source. In order to run Loom's test suite, you must also build a matching version of Clang.

$ git clone https://github.com/cadets/llvm -b cadets llvm
$ git clone https://github.com/cadets/clang -b cadets llvm/tools/clang
$ git clone https://github.com/cadets/loom loom

Build it

Building Clang/LLVM

First, build LLVM using CMake and Ninja. The directions below assume a Release build, but a Debug build is also possible.

$ mkdir llvm/Release
$ cd llvm/Release
$ cmake -G Ninja -D CMAKE_BUILD_TYPE=Release ..
$ ninja
[go get some coffee]

Building LOOM

  1. Set your PATH to include the version of LLVM you just built:
$ export PATH=/path/to/LLVM/Release/bin:$PATH

or:

$ setenv PATH /path/to/LLVM/Release/bin:$PATH
  1. Configure Loom build:
$ cd /path/to/Loom
$ mkdir Release
$ cd Release
$ cmake -G Ninja -D CMAKE_BUILD_TYPE=Release ..
  1. Build Loom:
$ ninja
  1. (optional) run test suite:

    a. Install libxo, which is used by Loom to emit structured output:

$ pkg install libxo    # or whatever your package manager command is
b. Run the Loom test suite:
$ ninja check

Use it

opt pass

Loom is structured as a set of libraries for LLVM instrumentation, but can be run most straightforwardly as an LLVM opt pass. This requires creating an instrumentation policy file such as:

#
# There are two instrumentation strategies:
#  * callout:  call an instrumentation function like __loom_called_foo
#  * inline    inject instrumentation inline with instrumented events
#
strategy: callout

#
# When using callout instrumentation, the generated instrumentation functions
# are named __loom_{event-specific-name} by default. This configuration value
# allows the `__loom` prefix to be overridden.
#
hook_prefix: __test_hook

#
# Loom can automatically log events and their immediate values (e.g., when
# logging a call to foo(1, 2, 3.1415), emit "foo", 1, 2 and 3.1415) without
# any processing. Strategies include:
#
#  * none      do not use the simple logger
#  * printf    just print the event using printf()
#  * xo        use libxo to emit a structured representation (e.g., json)
#
logging: printf

#
# Loom can report events via FreeBSD's ktrace(1) mechanism, either from
# the kernel ("kernel") or from userspace via the utrace(2) system call.
#
ktrace: utrace

#
# Loom currently serializes event information for, e.g., ktrace reporting
# using libnv. Support for other serialization schemes can be added.
#
serialization: nv

#
# Specify how/when functions should be instrumented.
#
# Functions can be instrumented on the caller side (before/after the call)
# or the callee side (function prelude / return sites). This configuration
# value should be a list of entries, each specifying:
#
#  * `name`: the name of the function being instrumented (language-mangled)
#  * `caller`: (optional) list of directions to instrument calls (entry/exit)
#  * `callee`: (optional) list of directions to instrument functions
#
functions:
    - name: foo
      caller: [ entry, exit ]

    - name: bar
      caller: [ entry ]
      callee: [ exit ]

#
# Specify how/when structure fields should be instrumented.
#
# We can instrument both reads and writes to structure fields.
# These fields must currently be identified by number rather than name.
# The `structures` config value is a list of entries containing:
#
#  * `name`: the structure name
#  * `fields`: a list of structure field descriptions:
#    * `name`: field name
#    * `operations`: list of operations to instrument (`read` or `write`)
#
structures:
  - name: baz
    fields:
      - name: refcount
        operations: [ read, write ]

and then running opt:

$ opt -load /path/to/LLVMLoom.so -loom -loom-file /path/to/instr.policy

Loom's opt pass has options that can be seen in the help/usage output:

$ opt -load /path/to/LLVMLoom.so -help | grep loom

Instrumenting FreeBSD

To build FreeBSD with Loom, you need to clone our IR-augmented version of FreeBSD. Then, you can use our loom-fbsdmake script as a drop-in wrapper around make:

$ git clone https://github.com/cadets/freebsd -b cadets freebsd-cadets
$ cd freebsd-cadets
$ export LLVM_PREFIX=/path/to/LLVM/Release
$ export LOOM_LIB=/path/to/Loom/Release/lib/LLVMLoom.so
$ /path/to/Loom/scripts/loom-fbsdmake buildworld buildkernel
$ /path/to/Loom/scripts/loom-fbsdmake buildenv   # etc.