Skip to content
Closed
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
37 changes: 36 additions & 1 deletion analysis/runtime/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::{
collections::HashMap,
fmt::{self, Debug, Formatter},
io::Cursor,
iter,
};

use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::mir_loc::{DefPathHash, Func, MirLoc, MirLocId};

Expand All @@ -17,6 +19,39 @@ impl Metadata {
pub fn get(&self, index: MirLocId) -> &MirLoc {
&self.locs[index as usize]
}

pub fn read(bytes: &[u8]) -> bincode::Result<Self> {
bincode_deserialize_many(bytes)
}
}

fn bincode_deserialize_many<T, C>(bytes: &[u8]) -> bincode::Result<C>
where
T: DeserializeOwned,
C: FromIterator<T>,
{
let len = bytes.len();
let mut cursor = Cursor::new(bytes);
iter::from_fn(|| {
// No good alternatives: <https://github.com/rust-lang/rust/issues/86369>.
if cursor.position() == len.try_into().unwrap() {
return None;
}
Some(bincode::deserialize_from(&mut cursor))
})
.collect::<Result<_, _>>()
}

impl FromIterator<Metadata> for Metadata {
fn from_iter<I: IntoIterator<Item = Metadata>>(iter: I) -> Self {
let mut locs = Vec::new();
let mut functions = HashMap::new();
for metadata in iter {
locs.extend(metadata.locs);
functions.extend(metadata.functions);
}
Self { locs, functions }
}
}

impl Debug for MirLoc {
Expand Down
2 changes: 1 addition & 1 deletion analysis/runtime/src/runtime/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl DetectBackend for DebugBackend {
// TODO may want to deduplicate this with [`pdg::builder::read_metadata`] in [`Metadata::read`],
// but that may require adding `color-eyre`/`eyre` as a dependency
let bytes = fs_err::read(path)?;
let metadata = bincode::deserialize(&bytes)?;
let metadata = Metadata::read(&bytes)?;
Ok(Self { metadata })
}
}
Expand Down
14 changes: 11 additions & 3 deletions dynamic_instrumentation/src/instrument.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use anyhow::Context;
use anyhow::{ensure, Context};
use c2rust_analysis_rt::metadata::Metadata;
use c2rust_analysis_rt::mir_loc::{self, EventMetadata, Func, MirLoc, MirLocId, TransferKind};
use c2rust_analysis_rt::HOOK_FUNCTIONS;
use fs_err::OpenOptions;
use indexmap::IndexSet;
use log::debug;
use rustc_index::vec::Idx;
Expand All @@ -14,6 +15,7 @@ use rustc_middle::ty::{self, TyCtxt, TyS};
use rustc_span::def_id::{DefId, DefPathHash};
use rustc_span::DUMMY_SP;
use std::collections::HashMap;
use std::io::Write;
use std::path::Path;
use std::sync::Mutex;

Expand Down Expand Up @@ -62,14 +64,20 @@ impl Instrumenter {
}

/// Finish instrumentation and write out metadata to `metadata_file_path`.
pub fn finalize(&self, metadata_file_path: &Path) -> anyhow::Result<()> {
pub fn finalize(&self, metadata_path: &Path) -> anyhow::Result<()> {
let mut locs = self.mir_locs.lock().unwrap();
let mut functions = self.functions.lock().unwrap();
let locs = locs.drain(..).collect::<Vec<_>>();
let functions = functions.drain().collect::<HashMap<_, _>>();
let metadata = Metadata { locs, functions };
let bytes = bincode::serialize(&metadata).context("Location serialization failed")?;
fs_err::write(metadata_file_path, &bytes).context("Could not open metadata file")?;
let mut file = OpenOptions::new()
.append(true)
.write(true)
.open(metadata_path)
.context("Could not open metadata file")?;
let bytes_written = file.write(&bytes)?;
ensure!(bytes_written == bytes.len());
Ok(())
}

Expand Down
8 changes: 8 additions & 0 deletions dynamic_instrumentation/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use std::{
process::{self, Command, ExitStatus},
};

use fs_err::OpenOptions;
use rustc_driver::{RunCompiler, TimePassesCallbacks};
use rustc_session::config::CrateType;

Expand Down Expand Up @@ -311,6 +312,13 @@ fn cargo_wrapper(rustc_wrapper: &Path) -> anyhow::Result<()> {
cmd.args(&["clean", "--package", root_package.name.as_str()]);
})?;

// Create and truncate the metadata file for the [`rustc_wrapper`]s to append to.
OpenOptions::new()
.create(true)
.write(true) // need write for truncate
.truncate(true)
.open(&metadata)?;

cargo.run(|cmd| {
// Enable the runtime dependency.
add_feature(&mut cargo_args, &["c2rust-analysis-rt"]);
Expand Down
3 changes: 1 addition & 2 deletions pdg/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ pub fn read_event_log(path: &Path) -> io::Result<Vec<Event>> {

pub fn read_metadata(path: &Path) -> eyre::Result<Metadata> {
let bytes = fs_err::read(path)?;
let metadata = bincode::deserialize(&bytes)?;
Ok(metadata)
Ok(Metadata::read(&bytes)?)
}

pub trait EventKindExt {
Expand Down