Skip to content

Commit

Permalink
Merge pull request #193 from knurling-rs/check-version-first
Browse files Browse the repository at this point in the history
check defmt version before demangling symbols
  • Loading branch information
japaric authored Oct 19, 2020
2 parents f745993 + 6805111 commit 9e6a9a2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
29 changes: 19 additions & 10 deletions decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,26 @@ pub struct Table {
entries: BTreeMap<usize, TableEntry>,
}

impl Table {
pub fn new(entries: BTreeMap<usize, TableEntry>, version: &str) -> Result<Self, String> {
if version != DEFMT_VERSION {
return Err(format!(
"defmt version mismatch (firmware is using {}, host is using {}); \
are you using the same git version of defmt and related tools?",
version, DEFMT_VERSION,
));
}
/// Checks if the version encoded in the symbol table is compatible with this version of the
/// `decoder` crate
pub fn check_version(version: &str) -> Result<(), String> {
if version != DEFMT_VERSION {
return Err(format!(
"defmt version mismatch (firmware is using {}, host is using {}); \
are you using the same git version of defmt and related tools?
Try `cargo install`-ing the latest git version of `probe-run` AND updating your project's `Cargo.lock` with `cargo update`",
version, DEFMT_VERSION,
));
}

Ok(Self { entries })
Ok(())
}

impl Table {
/// NOTE caller must verify that defmt symbols are compatible with this version of the `decoder`
/// crate using the `check_version` function
pub fn new(entries: BTreeMap<usize, TableEntry>) -> Self {
Self { entries }
}

fn _get(&self, index: usize) -> Result<(Option<Level>, &str), ()> {
Expand Down
35 changes: 22 additions & 13 deletions elf2table/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,7 @@ use object::{Object, ObjectSection};
/// This function returns `None` if the ELF file contains no `.defmt` section
pub fn parse(elf: &[u8]) -> Result<Option<Table>, anyhow::Error> {
let elf = object::File::parse(elf)?;
// find the index of the `.defmt` section
let defmt_shndx = if let Some(section) = elf.section_by_name(".defmt") {
section.index()
} else {
return Ok(None);
};

let mut map = BTreeMap::new();
// first pass to extract the `_defmt_version`
let mut version = None;
for (_, entry) in elf.symbols() {
let name = match entry.name() {
Expand All @@ -52,6 +45,26 @@ pub fn parse(elf: &[u8]) -> Result<Option<Table>, anyhow::Error> {
}
version = Some(new_version);
}
}

let version = version.ok_or_else(|| anyhow!("defmt version symbol not found"))?;

defmt_decoder::check_version(version).map_err(anyhow::Error::msg)?;

// find the index of the `.defmt` section
let defmt_shndx = if let Some(section) = elf.section_by_name(".defmt") {
section.index()
} else {
return Ok(None);
};

// second pass to demangle symbols
let mut map = BTreeMap::new();
for (_, entry) in elf.symbols() {
let name = match entry.name() {
Some(name) => name,
None => continue,
};

if entry.section_index() == Some(defmt_shndx) {
let sym = symbol::Symbol::demangle(name)?;
Expand All @@ -67,11 +80,7 @@ pub fn parse(elf: &[u8]) -> Result<Option<Table>, anyhow::Error> {
}
}

let version = version.ok_or_else(|| anyhow!("defmt version symbol not found"))?;

Table::new(map, version)
.map_err(anyhow::Error::msg)
.map(Some)
Ok(Some(Table::new(map)))
}

#[derive(Clone)]
Expand Down

0 comments on commit 9e6a9a2

Please sign in to comment.