Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ jobs:
run: cargo fmt --all -- --check
- name: Unit Tests
run: cargo test --verbose
- name: Serde Tests
run: cargo test --verbose --features serde --tests serde
- name: Coverage Report
run: |
rustup component add llvm-tools-preview
PATH=$(rustup show home | xargs -I '{}' find {} -name 'llvm-profdata' | xargs -I '{}' dirname {}):$PATH
RUSTFLAGS="-C instrument-coverage" cargo test --lib
RUSTFLAGS="-C instrument-coverage" cargo test --lib --features serde
find . -name '*.profraw' > profraw-files.txt
llvm-profdata merge -sparse -f profraw-files.txt -o merged.profdata
llvm-cov report \
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

### Added

* Support for serializing `libsla` structures using `serde`

### Fixed

* `AddressSpace` from another Sleigh instance is now properly recognized.
Expand Down
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ repository = "https://github.com/mnemonikr/libsla"

[features]
fuzzing = ["libsla-sys/fuzzing"]
serde = ["dep:serde"]

[dependencies]
thiserror = "2.0"
libsla-sys = { version = "0.1.4" }
serde = { version = "1", features = ["derive"], optional = true }

[dev-dependencies]
flate2 = "1.1"
sleigh-config = { version = "1", features = ["x86"] }
serde_json = { version = "1.0.145" }
7 changes: 7 additions & 0 deletions src/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use libsla_sys::sys;

/// A representation of opcodes for p-code instructions.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum OpCode {
/// Copy a sequence of bytes from one fixed location to another.
Copy,
Expand Down Expand Up @@ -69,6 +70,7 @@ pub enum OpCode {

/// Operations for boolean, single-bit inputs.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum BoolOp {
/// Negate a single bit: `!x`.
Negate,
Expand All @@ -87,6 +89,7 @@ pub enum BoolOp {
/// operation does not include `IntSign` as an argument, then distinguishing between signed and
/// unsigned is not applicable for the operation.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum IntSign {
/// An integer where the most significant bit (msb) indicates the sign of the integer. The integer is
/// positive if the msb is `0` and negative if the msb is `1`. Signed integers are represented
Expand All @@ -99,6 +102,7 @@ pub enum IntSign {

/// Operations on integers.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum IntOp {
/// Add two integers: `x + y`.
Add,
Expand Down Expand Up @@ -155,6 +159,7 @@ pub enum IntOp {

/// Operations on floating-point numbers.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum FloatOp {
/// Check if two numbers are equal: `x == y`.
Equal,
Expand Down Expand Up @@ -213,6 +218,7 @@ pub enum FloatOp {

/// Operations which represent black-box placeholders for some sequence of changes to the machine state.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum PseudoOp {
/// A call that cannot be semantically represented in p-code. For example, a syscall.
CallOther,
Expand All @@ -229,6 +235,7 @@ pub enum PseudoOp {
/// for use in processor specifications and therefore will never be emitted when directly
/// translating machine instructions.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AnalysisOp {
/// Copies a sequence of bytes to a fixed location. There are multiple origins possible for the
/// bytes. The selected origin depends on the execution path leading to this operation.
Expand Down
13 changes: 11 additions & 2 deletions src/sleigh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub trait Sleigh {

/// An address is represented by an offset into an address space
#[derive(Ord, PartialOrd, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Address {
/// The standard interpretation of the offset is an index into the associated address space.
/// However, when used in conjunction with the constant address space, the offset is the actual
Expand Down Expand Up @@ -132,6 +133,7 @@ impl From<&sys::Address> for Address {

/// A VarnodeData represents the address and size of data.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VarnodeData {
pub address: Address,
pub size: usize,
Expand Down Expand Up @@ -193,6 +195,7 @@ impl From<&sys::VarnodeData> for VarnodeData {
/// guaranteed to be deterministically constructed. This means different instances of Sleigh may
/// identify the same address space with _different_ identifiers.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AddressSpaceId(usize);

impl std::fmt::Debug for AddressSpaceId {
Expand Down Expand Up @@ -234,6 +237,7 @@ impl AddressSpaceId {

/// Information about an address space
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AddressSpace {
pub id: AddressSpaceId,
pub name: Cow<'static, str>,
Expand Down Expand Up @@ -285,6 +289,7 @@ impl From<&sys::AddrSpace> for AddressSpaceId {

/// Types for an [AddressSpace].
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AddressSpaceType {
/// Special space to represent constants
Constant,
Expand Down Expand Up @@ -321,6 +326,7 @@ impl From<sys::spacetype> for AddressSpaceType {
/// cases. For example, the [OpCode::Load] operation encodes the [AddressSpace] using the
/// [AddressSpaceId]. This identifier in particular may differ across Sleigh instances.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PcodeInstruction {
/// The originating address for this instruction. This information is necessary to include for
/// the [OpCode::BranchIndirect] operation, which determines the destination address space from
Expand Down Expand Up @@ -360,7 +366,8 @@ impl std::fmt::Display for PcodeInstruction {
}

/// A disassembled native assembly instruction
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AssemblyInstruction {
/// The origin of the assembly instruction
pub address: Address,
Expand All @@ -387,6 +394,7 @@ impl std::fmt::Display for AssemblyInstruction {

/// Disassembly of an instruction into pcode
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PcodeDisassembly {
/// The disassembled instructions
pub instructions: Vec<PcodeInstruction>,
Expand All @@ -396,7 +404,8 @@ pub struct PcodeDisassembly {
}

/// Disassembly of an instruction into its native assembly
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NativeDisassembly {
/// The disassembled instruction
pub instruction: AssemblyInstruction,
Expand Down
3 changes: 3 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod opcodes;
mod sleigh;

#[cfg(feature = "serde")]
mod serde;
Loading