Expand description
§Decoder and tracer for RISC-V E-Traces
This library provides a packet decoder and encoder a tracer as well as a payload generator for the instruction tracing defined in the Efficient Trace for RISC-V specification. Given trace packets previously retrieved from an encoder and the traced program, the tracer allows reconstructing the execution path. The generator, on the other hand, serves as a software implementation for a trace encoder.
This library also features a limited instruction database with decoding functionality. Currently, only decoding of RV32IC and RV64IC instructions are supported. However, tracing is not impacted by other instructions that do not influence the control flow (“control transfer instructions”).
§Tracing flow
Raw trace data needs to be decoded via packet::decoder::Decoders, which
are constructed via a packet::Builder. A builder is usually configured
for a trace Unit implementation with specific
config::Parameters.
A decoded packet or Payload payload needs to
be dispatched to the Tracer for that RISC-V hart. It is
the responsibility of the library user to do so.
A Tracer processes packets and generates a series of
tracing Items. It is constructed via a
tracer::Builder, which is configured for the specific program
being traced (in the form of a Binary) and the same
config::Parameters that the decoder was configured with.
Binary is a trait abstracting access to
Instructions. This library provides a number
of implementations and utilities for constructing one, including limited
instruction decoding capabilities.
§E-Trace options
The following E-Trace options are supported:
- delta/full address mode
- sequentially inferred jumps
- implicit return (tracer only, known to be broken by specification)
§Crate features
Some functionality if controlled via crate features:
alloc: enables some features that require allocationeither: enables impls of various traits foreither::Eitherelf: enables thebinary::elfmodule providing aBinaryfor static ELF files using theelfcrateriscv-isa: enables support for decoding and tracingriscv_isa::Instructions instead ofinstruction::Kind.serde: enables (de)serialization of configuration viaserde
§no_std
This crate does not dependent on std and is thus suitable for no_std
environments.
§Example
The following example demonstrates basic instruction tracing, with default
config::Parameters, a simple Binary and tracing
packets conforming to the Unformatted Trace & Diagnostic Data Packet
Encapsulation for RISC-V specification placed in a single buffer.
use riscv_etrace::binary::{self, Adaptable};
use riscv_etrace::packet;
use riscv_etrace::instruction::{base, Instruction};
use riscv_etrace::tracer::{self, Tracer};
let binary = binary::from_segment(binary_data, base::Set::Rv32I)
.with_offset(binary_offset);
let parameters = Default::default();
let mut decoder = packet::builder()
.with_params(¶meters)
.decoder(trace_data);
let mut tracer: Tracer<_> = tracer::builder()
.with_binary(binary)
.with_params(¶meters)
.build()
.unwrap();
while decoder.bytes_left() > 0 {
let packet = decoder.decode_encap_packet().unwrap().into_normal();
if let Some(packet) = packet.filter(|p| p.src_id() == hart_to_trace) {
let payload = packet.decode_payload().unwrap();
eprintln!("{payload:?}");
tracer.process_payload(&payload).unwrap();
tracer.by_ref().for_each(|i| {
let item = i.unwrap();
if let Some(info) = item.trap() {
println!("Trap! EPC={:0x}, interrupt={}", item.pc(), info.is_interrupt());
} else {
println!("PC: {:0x}", item.pc());
}
});
}
}Modules§
- binary
- Binaries containing
Instructions - config
- Configuration and utilities
- generator
- Payload generation utilities
- instruction
- Instruction disassembly/decoding and information
- packet
- Packet decoder and entities it can decode (packets and payloads)
- tracer
- Tracing logic
- types
- Types not specific to packets or tracer