Skip to main content

Crate riscv_etrace

Crate riscv_etrace 

Source
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:

§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(&parameters)
    .decoder(trace_data);
let mut tracer: Tracer<_> = tracer::builder()
    .with_binary(binary)
    .with_params(&parameters)
    .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