Skip to content

Commit

Permalink
Merge #750
Browse files Browse the repository at this point in the history
750: Add support for decoding wire format version 3 r=Urhengulas a=jannic

As suggested in #749 (comment), it would be nice if defmt-decoder could handle older wire format versions transparently.

This patch implements support for version 3. A version of `probe-run` compiled against this was verified to work with defmt versions 0.3.2, 0.3.3 and 0.3.4.

Co-authored-by: Jan Niehusmann <jan@gondor.com>
Co-authored-by: Johann Hemmann <johann.hemmann@code.berlin>
  • Loading branch information
3 people authored May 3, 2023
2 parents 87e16dd + a98b5b5 commit d58633f
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

- [#750]: Add support for decoding wire format version 3

[#750]: https://github.com/knurling-rs/defmt/pull/750

## [v0.3.4] - 2023-04-05

- [#748]: Release `defmt-v0.3.4`, `defmt-decoder-v0.3.6`, `defmt-print-v0.3.4` and yank previous
Expand Down
8 changes: 4 additions & 4 deletions decoder/src/elf2table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{
path::{Path, PathBuf},
};

use crate::{BitflagsKey, StringEntry, Table, TableEntry, Tag, DEFMT_VERSION};
use crate::{BitflagsKey, StringEntry, Table, TableEntry, Tag, DEFMT_VERSIONS};
use anyhow::{anyhow, bail, ensure};
use object::{Object, ObjectSection, ObjectSymbol};

Expand Down Expand Up @@ -169,7 +169,7 @@ pub fn parse_impl(elf: &[u8], check_version: bool) -> Result<Option<Table>, anyh
ident: bitflags_name.into(),
package: sym.package().into(),
disambig: sym.disambiguator().into(),
crate_name: sym.crate_name().into(),
crate_name: sym.crate_name().map(|s| s.into()),
};

bitflags_map.entry(key).or_insert_with(Vec::new).push((
Expand Down Expand Up @@ -218,10 +218,10 @@ pub fn parse_impl(elf: &[u8], check_version: bool) -> Result<Option<Table>, anyh

/// Checks if the version encoded in the symbol table is compatible with this version of the `decoder` crate
fn check_version(version: &str) -> Result<(), String> {
if version != DEFMT_VERSION {
if !DEFMT_VERSIONS.contains(&version) {
let msg = format!(
"defmt wire format version mismatch: firmware is using {}, `probe-run` supports {}\nsuggestion: use a newer version of `defmt` or `cargo install` a different version of `probe-run` that supports defmt {}",
version, DEFMT_VERSION, version
version, DEFMT_VERSIONS.join(", "), version
);

return Err(msg);
Expand Down
6 changes: 3 additions & 3 deletions decoder/src/elf2table/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct Symbol {
data: String,

/// Crate name obtained via CARGO_CRATE_NAME (added since a Cargo package can contain many crates).
crate_name: String,
crate_name: Option<String>,
}

pub enum SymbolTag<'a> {
Expand Down Expand Up @@ -72,7 +72,7 @@ impl Symbol {
&self.disambiguator
}

pub fn crate_name(&self) -> &str {
&self.crate_name
pub fn crate_name(&self) -> Option<&str> {
self.crate_name.as_deref()
}
}
7 changes: 5 additions & 2 deletions decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
#![cfg_attr(docsrs, doc(cfg(unstable)))]
#![doc(html_logo_url = "https://knurling.ferrous-systems.com/knurling_logo_light_text.svg")]

pub const DEFMT_VERSION: &str = "4";
pub const DEFMT_VERSIONS: &[&str] = &["3", "4"];
// To avoid a breaking change, still provide `DEFMT_VERSION`.
#[deprecated = "Please use DEFMT_VERSIONS instead"]
pub const DEFMT_VERSION: &str = DEFMT_VERSIONS[1];

mod decoder;
mod elf2table;
Expand Down Expand Up @@ -116,7 +119,7 @@ struct BitflagsKey {
ident: String,
package: String,
disambig: String,
crate_name: String,
crate_name: Option<String>,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand Down
23 changes: 11 additions & 12 deletions parser/src/display_hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub enum DisplayHint {
name: String,
package: String,
disambiguator: String,
crate_name: String,
crate_name: Option<String>,
},
/// Display hints currently not supported / understood
Unknown(String),
Expand Down Expand Up @@ -61,17 +61,16 @@ impl DisplayHint {

if let Some(stripped) = s.strip_prefix(BITFLAGS_HINT_START) {
let parts = stripped.split('@').collect::<Vec<_>>();
match *parts {
[bitflags_name, package, disambiguator, crate_name] => {
return Some(DisplayHint::Bitflags {
name: bitflags_name.into(),
package: package.into(),
disambiguator: disambiguator.into(),
crate_name: crate_name.into(),
});
}
_ => return Some(DisplayHint::Unknown(s.into())),
if parts.len() < 3 || parts.len() > 4 {
return Some(DisplayHint::Unknown(s.into()));
}
return Some(DisplayHint::Bitflags {
name: parts[0].into(),
package: parts[1].into(),
disambiguator: parts[2].into(),
// crate_name was added in wire format version 4
crate_name: parts.get(3).map(|&s| s.to_string()),
});
}

Some(match s {
Expand Down Expand Up @@ -111,7 +110,7 @@ pub enum TimePrecision {
///
/// Returns the integer and remaining text, if `s` started with an integer. Any errors parsing the
/// number (which we already know only contains digits) are silently ignored.
fn parse_integer<T: FromStr>(s: &str) -> Option<(&str, usize)> {
fn parse_integer<T: FromStr>(s: &str) -> Option<(&str, T)> {
let start_digits = s
.as_bytes()
.iter()
Expand Down
8 changes: 6 additions & 2 deletions print/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{

use anyhow::anyhow;
use clap::Parser;
use defmt_decoder::{DecodeError, Frame, Locations, Table};
use defmt_decoder::{DecodeError, Frame, Locations, Table, DEFMT_VERSIONS};

/// Prints defmt-encoded logs to stdout
#[derive(Parser)]
Expand Down Expand Up @@ -129,6 +129,10 @@ fn location_info(locs: &Option<Locations>, frame: &Frame, current_dir: &Path) ->
#[allow(clippy::unnecessary_wraps)]
fn print_version() -> anyhow::Result<()> {
println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
println!("supported defmt version: {}", defmt_decoder::DEFMT_VERSION);
println!(
"supported defmt version{}: {}",
if DEFMT_VERSIONS.len() > 1 { "s" } else { "" },
DEFMT_VERSIONS.join(", ")
);
Ok(())
}

0 comments on commit d58633f

Please sign in to comment.