Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Use elsa for debuggable_module::loader
Browse files Browse the repository at this point in the history
  • Loading branch information
Porges committed Dec 16, 2022
1 parent ff923d2 commit 98b558b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 85 deletions.
45 changes: 23 additions & 22 deletions src/agent/Cargo.lock

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

1 change: 1 addition & 0 deletions src/agent/debuggable-module/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ license = "MIT"

[dependencies]
anyhow = "1.0"
elsa = "1.7.0"
gimli = "0.26.2"
goblin = "0.6.0"
iced-x86 = "1.17"
Expand Down
68 changes: 5 additions & 63 deletions src/agent/debuggable-module/src/loader.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use std::collections::HashMap;
use std::sync::Mutex;

use anyhow::Result;
use thiserror::Error;

use crate::path::FilePath;

#[derive(Clone, Copy)]
struct Leaked(&'static [u8]);

impl Leaked {
pub fn into_raw(self) -> *mut [u8] {
self.0 as *const _ as *mut _
}
}

impl From<Vec<u8>> for Leaked {
fn from(data: Vec<u8>) -> Self {
let data = Box::leak(data.into_boxed_slice());
Leaked(data)
}
}

#[derive(Default)]
pub struct Loader {
loaded: Mutex<HashMap<FilePath, Leaked>>,
loaded: elsa::FrozenMap<FilePath, Box<[u8]>>,
}

impl Loader {
Expand All @@ -36,49 +16,11 @@ impl Loader {
}

pub fn load(&self, path: &FilePath) -> Result<&[u8]> {
if let Some(data) = self.get(path)? {
Ok(data)
} else {
self.load_new(path)
if let Some(data) = self.loaded.get(path) {
return Ok(data);
}
}

fn load_new(&self, path: &FilePath) -> Result<&[u8]> {
let mut loaded = self.loaded.lock().map_err(|_| LoaderError::PoisonedMutex)?;
let data = std::fs::read(path)?;
let leaked = Leaked::from(data);
loaded.insert(path.clone(), leaked);

Ok(leaked.0)
let data: Box<[u8]> = std::fs::read(path)?.into();
Ok(self.loaded.insert(path.clone(), data))
}

pub fn get(&self, path: &FilePath) -> Result<Option<&[u8]>> {
let loaded = self.loaded.lock().map_err(|_| LoaderError::PoisonedMutex)?;

let data = loaded.get(path).map(|l| l.0);

Ok(data)
}
}

impl Drop for Loader {
fn drop(&mut self) {
if let Ok(mut loaded) = self.loaded.lock() {
for (_, leaked) in loaded.drain() {
unsafe {
let raw = leaked.into_raw();
let owned = Box::from_raw(raw);
drop(owned);
}
}

debug_assert!(loaded.is_empty());
}
}
}

#[derive(Error, Debug)]
pub enum LoaderError {
#[error("internal mutex poisoned")]
PoisonedMutex,
}

0 comments on commit 98b558b

Please sign in to comment.