Annotation Framework
Lotus provides annotation frameworks for specifying and analyzing program behavior. The annotation system is organized into several components for tracking argument positions, modification/reference effects, pointer effects, and taint analysis.
Dedicated module pages:
ModRef Function Effect Specifications for external mod/ref summaries
Pointer Effect Specifications for pointer-side-effect specifications
Taint Configuration Format and API for taint source, sink, and propagation specs
Position Tracking
The position tracking system provides abstractions for identifying function arguments and return values in annotations.
Location: include/Annotation/ArgPosition.h
Components:
ArgPosition – Represents a specific function argument position
RetPosition – Represents the return value position
APosition – Union type that can represent either an argument or return position
Usage: .. code-block:: cpp
#include <Annotation/ArgPosition.h> using namespace annotation;
// Create argument positions APosition arg0 = APosition::getArgPosition(0); APosition arg1 = APosition::getAfterArgPosition(1); // After argument 1 APosition ret = APosition::getReturnPosition();
// Query position type if (ret.isReturnPosition()) {
// Handle return position
} if (arg0.isArgPosition()) {
const ArgPosition& pos = arg0.getAsArgPosition(); uint8_t idx = pos.getArgIndex(); bool after = pos.isAfterArgPosition();
}
ModRef Annotations
Modification and reference behavior annotations track how functions access memory through their arguments and return values.
Location: include/Annotation/ModRef/
Components:
ModRefType – Enumeration:
Mod(modification) orRef(reference/read)ModRefClass – Enumeration:
DirectMemoryorReachableMemoryModRefEffect – Represents a single mod/ref effect with type, class, and position
ModRefEffectSummary – Collection of mod/ref effects for a function
ExternalModRefTable – Table mapping function names to their mod/ref summaries
ExternalModRefTablePrinter – Utility for printing mod/ref tables
Usage: .. code-block:: cpp
#include <Annotation/ModRef/ExternalModRefTable.h> #include <Annotation/ModRef/ModRefEffect.h> using namespace annotation;
// Load mod/ref table from file ExternalModRefTable table = ExternalModRefTable::loadFromFile(“modref.spec”);
// Lookup function effects llvm::StringRef funcName = “strcpy”; const ModRefEffectSummary* summary = table.lookup(funcName);
- if (summary) {
- for (const auto& effect*summary) {
ModRefType type = effect.getType(); ModRefClass mClass = effect.getClass(); APosition pos = effect.getPosition();
- if (effect.isModEffect() && effect.onDirectMemory()) {
// Function modifies direct memory
}
}
}
// Print table ExternalModRefTablePrinter printer(llvm::errs()); printer.printTable(table);
Pointer Annotations
Pointer annotations specify how functions allocate, copy, or exit with pointers.
Location: include/Annotation/Pointer/
Components:
PointerEffectType – Enumeration:
Alloc,Copy, orExitPointerAllocEffect – Represents pointer allocation with optional size position
CopySource – Source of a copy operation (Value, DirectMemory, ReachableMemory, Null, Universal, Static)
CopyDest – Destination of a copy operation (Value, DirectMemory, ReachableMemory)
PointerCopyEffect – Represents a copy operation from source to destination
PointerExitEffect – Represents program exit
PointerEffect – Union type representing any pointer effect
PointerEffectSummary – Collection of pointer effects for a function
ExternalPointerTable – Table mapping function names to their pointer effect summaries
ExternalPointerTablePrinter – Utility for printing pointer tables
Usage: .. code-block:: cpp
#include <Annotation/Pointer/ExternalPointerTable.h> #include <Annotation/Pointer/PointerEffect.h> using namespace annotation;
// Load pointer table from file ExternalPointerTable table = ExternalPointerTable::loadFromFile(“ptr.spec”);
// Lookup function effects llvm::StringRef funcName = “malloc”; const PointerEffectSummary* summary = table.lookup(funcName);
- if (summary) {
- for (const auto& effect*summary) {
- switch (effect.getType()) {
- case PointerEffectType::Alloc: {
const PointerAllocEffect& alloc = effect.getAsAllocEffect(); if (alloc.hasSizePosition()) {
APosition sizePos = alloc.getSizePosition();
} break;
} case PointerEffectType::Copy: {
const PointerCopyEffect& copy = effect.getAsCopyEffect(); const CopyDest& dest = copy.getDest(); const CopySource& src = copy.getSource(); break;
} case PointerEffectType::Exit:
// Function exits program break;
}
}
}
// Print table ExternalPointerTablePrinter printer(llvm::errs()); printer.printTable(table);
Taint Analysis Annotations
Taint analysis annotations specify information flow and taint propagation through functions.
Location: include/Annotation/Taint/
Components:
TaintSpec – Specification for taint location (ARG, AFTER_ARG, RET), access mode (VALUE, DEREF), and taint type (TAINTED, UNINITIALIZED)
PipeSpec – Specification for taint propagation from source to destination
FunctionTaintConfig – Complete taint configuration for a single function (sources, sinks, pipes)
TaintConfig – Complete taint configuration containing all function specs
TaintConfigParser – Parser for taint specification files (.spec format)
TaintConfigManager – Singleton manager for taint configurations with function name normalization
Usage: .. code-block:: cpp
#include <Annotation/Taint/TaintConfigManager.h> using namespace taint_config;
// Load configuration (singleton pattern) TaintConfigManager& manager = TaintConfigManager::getInstance(); manager.load_config(“config/taint.spec”); // Or use convenience namespace functions load_config(“config/taint.spec”); load_default_config(); // Tries multiple standard paths
// Check if function is a source or sink bool isSrc = is_source(“read”); bool isSink = is_sink(“printf”); bool isIgnored = is_ignored(“memcpy”);
// Check LLVM call instructions llvm::CallInst* call = …; if (is_source(call)) {
// Function call is a taint source
}
// Get detailed function configuration const FunctionTaintConfig* funcConfig = get_function_config(“strcpy”); if (funcConfig) {
// Access source_specs, sink_specs, pipe_specs
}
// Normalize function names (handles platform prefixes) std::string normalized = normalize_name(“__strcpy_chk”); // Returns “strcpy”
// Dump configuration dump_config(llvm::errs());
// Get statistics size_t numSources = get_source_count(); size_t numSinks = get_sink_count();