diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs index 8c7051d4..060f7d3d 100644 --- a/src/symbolize/gimli.rs +++ b/src/symbolize/gimli.rs @@ -4,18 +4,15 @@ use self::gimli::read::EndianSlice; use self::gimli::NativeEndian as Endian; -use self::mmap::Mmap; use self::stash::Stash; use super::BytesOrWideString; use super::ResolveWhat; use super::SymbolName; use addr2line::gimli; -use core::convert::TryInto; use core::mem; use core::u32; use libc::c_void; use mystd::ffi::OsString; -use mystd::fs::File; use mystd::path::Path; use mystd::prelude::v1::*; @@ -26,33 +23,6 @@ mod mystd { #[cfg(not(backtrace_in_libstd))] extern crate std as mystd; -cfg_if::cfg_if! { - if #[cfg(windows)] { - #[path = "gimli/mmap_windows.rs"] - mod mmap; - } else if #[cfg(target_vendor = "apple")] { - #[path = "gimli/mmap_unix.rs"] - mod mmap; - } else if #[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "linux", - target_os = "openbsd", - target_os = "solaris", - target_os = "illumos", - target_os = "aix", - ))] { - #[path = "gimli/mmap_unix.rs"] - mod mmap; - } else { - #[path = "gimli/mmap_fake.rs"] - mod mmap; - } -} - mod stash; const MAPPINGS_CACHE_SIZE: usize = 4; @@ -60,7 +30,7 @@ const MAPPINGS_CACHE_SIZE: usize = 4; struct Mapping { // 'static lifetime is a lie to hack around lack of support for self-referential structs. cx: Context<'static>, - _map: Mmap, + _map: Vec, stash: Stash, } @@ -74,7 +44,7 @@ impl Mapping { /// Creates a `Mapping` by ensuring that the `data` specified is used to /// create a `Context` and it can only borrow from that or the `Stash` of /// decompressed sections or auxiliary data. - fn mk(data: Mmap, mk: F) -> Option + fn mk(data: Vec, mk: F) -> Option where F: for<'a> FnOnce(&'a [u8], &'a Stash) -> Option>, { @@ -86,7 +56,7 @@ impl Mapping { /// Creates a `Mapping` from `data`, or if the closure decides to, returns a /// different mapping. - fn mk_or_other(data: Mmap, mk: F) -> Option + fn mk_or_other(data: Vec, mk: F) -> Option where F: for<'a> FnOnce(&'a [u8], &'a Stash) -> Option>>, { @@ -184,12 +154,6 @@ impl<'data> Context<'data> { } } -fn mmap(path: &Path) -> Option { - let file = File::open(path).ok()?; - let len = file.metadata().ok()?.len().try_into().ok()?; - unsafe { Mmap::map(&file, len) } -} - cfg_if::cfg_if! { if #[cfg(windows)] { mod coff; diff --git a/src/symbolize/gimli/coff.rs b/src/symbolize/gimli/coff.rs index 018cb494..ef75ecc3 100644 --- a/src/symbolize/gimli/coff.rs +++ b/src/symbolize/gimli/coff.rs @@ -1,3 +1,4 @@ +use super::mystd::fs; use super::{gimli, Context, Endian, EndianSlice, Mapping, Path, Stash, Vec}; use alloc::sync::Arc; use core::convert::TryFrom; @@ -14,7 +15,7 @@ type Pe = object::pe::ImageNtHeaders64; impl Mapping { pub fn new(path: &Path) -> Option { - let map = super::mmap(path)?; + let map = fs::read(path).ok()?; Mapping::mk(map, |data, stash| { Context::new(stash, Object::parse(data)?, None, None) }) diff --git a/src/symbolize/gimli/elf.rs b/src/symbolize/gimli/elf.rs index 906a3005..5fa9bd09 100644 --- a/src/symbolize/gimli/elf.rs +++ b/src/symbolize/gimli/elf.rs @@ -19,7 +19,7 @@ type Elf = object::elf::FileHeader64; impl Mapping { pub fn new(path: &Path) -> Option { - let map = super::mmap(path)?; + let map = fs::read(path).ok()?; Mapping::mk_or_other(map, |map, stash| { let object = Object::parse(&map)?; @@ -45,7 +45,7 @@ impl Mapping { /// Load debuginfo from an external debug file. fn new_debug(original_path: &Path, path: PathBuf, crc: Option) -> Option { - let map = super::mmap(&path)?; + let map = fs::read(&path).ok()?; Mapping::mk(map, |map, stash| { let object = Object::parse(&map)?; @@ -56,7 +56,7 @@ impl Mapping { // Try to locate a supplementary object file. let mut sup = None; if let Some((path_sup, build_id_sup)) = object.gnu_debugaltlink_path(&path) { - if let Some(map_sup) = super::mmap(&path_sup) { + if let Ok(map_sup) = fs::read(&path_sup) { let map_sup = stash.cache_mmap(map_sup); if let Some(sup_) = Object::parse(map_sup) { if sup_.build_id() == Some(build_id_sup) { @@ -84,7 +84,7 @@ impl Mapping { }) .unwrap_or_else(|| "dwp".into()); path_dwp.set_extension(dwp_extension); - if let Some(map_dwp) = super::mmap(&path_dwp) { + if let Ok(map_dwp) = fs::read(&path_dwp) { let map_dwp = stash.cache_mmap(map_dwp); if let Some(dwp_) = Object::parse(map_dwp) { return Some(dwp_); @@ -473,7 +473,7 @@ pub(super) fn handle_split_dwarf<'data>( path.push(convert_path(load.path.as_ref()?).ok()?); - if let Some(map_dwo) = super::mmap(&path) { + if let Ok(map_dwo) = fs::read(&path) { let map_dwo = stash.cache_mmap(map_dwo); if let Some(dwo) = Object::parse(map_dwo) { return gimli::Dwarf::load(|id| -> Result<_, ()> { diff --git a/src/symbolize/gimli/libs_windows.rs b/src/symbolize/gimli/libs_windows.rs index 9afeaf91..3b8462cc 100644 --- a/src/symbolize/gimli/libs_windows.rs +++ b/src/symbolize/gimli/libs_windows.rs @@ -1,6 +1,7 @@ use super::super::super::windows_sys::*; +use super::mystd::fs; use super::mystd::os::windows::prelude::*; -use super::{coff, mmap, Library, LibrarySegment, OsString}; +use super::{coff, Library, LibrarySegment, OsString}; use alloc::vec; use alloc::vec::Vec; use core::mem; @@ -75,7 +76,7 @@ unsafe fn load_library(me: &MODULEENTRY32W) -> Option { // // For now it appears that unlike ELF/MachO we can make do with one // segment per library, using `modBaseSize` as the whole size. - let mmap = mmap(name.as_ref())?; + let mmap = fs::read(&name).ok()?; let image_base = coff::get_image_base(&mmap)?; let base_addr = me.modBaseAddr as usize; Some(Library { diff --git a/src/symbolize/gimli/macho.rs b/src/symbolize/gimli/macho.rs index ef51f148..f21da531 100644 --- a/src/symbolize/gimli/macho.rs +++ b/src/symbolize/gimli/macho.rs @@ -1,3 +1,4 @@ +use super::mystd::fs; use super::{gimli, Box, Context, Endian, EndianSlice, Mapping, Path, Stash, Vec}; use alloc::sync::Arc; use core::convert::TryInto; @@ -20,7 +21,7 @@ impl Mapping { pub fn new(path: &Path) -> Option { // First up we need to load the unique UUID which is stored in the macho // header of the file we're reading, specified at `path`. - let map = super::mmap(path)?; + let map = fs::read(path).ok()?; let (macho, data) = find_header(&map)?; let endian = macho.endian().ok()?; let uuid = macho.uuid(endian, data, 0).ok()?; @@ -74,7 +75,7 @@ impl Mapping { // information. for entry in dir.read_dir().ok()? { let entry = entry.ok()?; - let map = super::mmap(&entry.path())?; + let map = fs::read(&entry.path()).ok()?; let candidate = Mapping::mk(map, |data, stash| { let (macho, data) = find_header(data)?; let endian = macho.endian().ok()?; @@ -285,7 +286,7 @@ fn object_mapping(file: &object::read::ObjectMapFile<'_>) -> Option { use super::mystd::ffi::OsStr; use super::mystd::os::unix::prelude::*; - let map = super::mmap(Path::new(OsStr::from_bytes(file.path())))?; + let map = fs::read(Path::new(OsStr::from_bytes(file.path()))).ok()?; let member_name = file.member(); Mapping::mk(map, |data, stash| { let data = match member_name { diff --git a/src/symbolize/gimli/mmap_fake.rs b/src/symbolize/gimli/mmap_fake.rs deleted file mode 100644 index ce509641..00000000 --- a/src/symbolize/gimli/mmap_fake.rs +++ /dev/null @@ -1,25 +0,0 @@ -use super::{mystd::io::Read, File}; -use alloc::vec::Vec; -use core::ops::Deref; - -pub struct Mmap { - vec: Vec, -} - -impl Mmap { - pub unsafe fn map(mut file: &File, len: usize) -> Option { - let mut mmap = Mmap { - vec: Vec::with_capacity(len), - }; - file.read_to_end(&mut mmap.vec).ok()?; - Some(mmap) - } -} - -impl Deref for Mmap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.vec[..] - } -} diff --git a/src/symbolize/gimli/mmap_unix.rs b/src/symbolize/gimli/mmap_unix.rs deleted file mode 100644 index 261ffc1d..00000000 --- a/src/symbolize/gimli/mmap_unix.rs +++ /dev/null @@ -1,49 +0,0 @@ -use super::mystd::fs::File; -use super::mystd::os::unix::prelude::*; -use core::ops::Deref; -use core::ptr; -use core::slice; - -#[cfg(not(all(target_os = "linux", target_env = "gnu")))] -use libc::mmap as mmap64; -#[cfg(all(target_os = "linux", target_env = "gnu"))] -use libc::mmap64; - -pub struct Mmap { - ptr: *mut libc::c_void, - len: usize, -} - -impl Mmap { - pub unsafe fn map(file: &File, len: usize) -> Option { - let ptr = mmap64( - ptr::null_mut(), - len, - libc::PROT_READ, - libc::MAP_PRIVATE, - file.as_raw_fd(), - 0, - ); - if ptr == libc::MAP_FAILED { - return None; - } - Some(Mmap { ptr, len }) - } -} - -impl Deref for Mmap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.ptr as *const u8, self.len) } - } -} - -impl Drop for Mmap { - fn drop(&mut self) { - unsafe { - let r = libc::munmap(self.ptr, self.len); - debug_assert_eq!(r, 0); - } - } -} diff --git a/src/symbolize/gimli/mmap_windows.rs b/src/symbolize/gimli/mmap_windows.rs deleted file mode 100644 index 787eccf9..00000000 --- a/src/symbolize/gimli/mmap_windows.rs +++ /dev/null @@ -1,59 +0,0 @@ -use super::super::super::windows_sys::*; - -use super::mystd::fs::File; -use super::mystd::os::windows::prelude::*; -use core::ffi::c_void; -use core::ops::Deref; -use core::ptr; -use core::slice; - -pub struct Mmap { - // keep the file alive to prevent it from being deleted which would cause - // us to read bad data. - _file: File, - ptr: *mut c_void, - len: usize, -} - -impl Mmap { - pub unsafe fn map(file: &File, len: usize) -> Option { - let file = file.try_clone().ok()?; - let mapping = CreateFileMappingA( - file.as_raw_handle(), - ptr::null_mut(), - PAGE_READONLY, - 0, - 0, - ptr::null(), - ); - if mapping.is_null() { - return None; - } - let ptr = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, len); - CloseHandle(mapping); - if ptr.Value.is_null() { - return None; - } - Some(Mmap { - _file: file, - ptr: ptr.Value, - len, - }) - } -} -impl Deref for Mmap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.ptr.cast_const().cast::(), self.len) } - } -} - -impl Drop for Mmap { - fn drop(&mut self) { - unsafe { - let r = UnmapViewOfFile(MEMORY_MAPPED_VIEW_ADDRESS { Value: self.ptr }); - debug_assert!(r != 0); - } - } -} diff --git a/src/symbolize/gimli/stash.rs b/src/symbolize/gimli/stash.rs index 5ec06e24..66b1c5cf 100644 --- a/src/symbolize/gimli/stash.rs +++ b/src/symbolize/gimli/stash.rs @@ -2,7 +2,6 @@ // only used on Linux right now, so allow dead code elsewhere #![cfg_attr(not(target_os = "linux"), allow(dead_code))] -use super::Mmap; use alloc::vec; use alloc::vec::Vec; use core::cell::UnsafeCell; @@ -10,7 +9,7 @@ use core::cell::UnsafeCell; /// A simple arena allocator for byte buffers. pub struct Stash { buffers: UnsafeCell>>, - mmaps: UnsafeCell>, + mmaps: UnsafeCell>>, } impl Stash { @@ -34,9 +33,9 @@ impl Stash { &mut buffers[i] } - /// Stores a `Mmap` for the lifetime of this `Stash`, returning a pointer + /// Stores a `Vec` for the lifetime of this `Stash`, returning a pointer /// which is scoped to just this lifetime. - pub fn cache_mmap(&self, map: Mmap) -> &[u8] { + pub fn cache_mmap(&self, map: Vec) -> &[u8] { // SAFETY: this is the only location for a mutable pointer to // `mmaps`, and this structure isn't threadsafe to shared across // threads either. We also never remove elements from `self.mmaps`, diff --git a/src/symbolize/gimli/xcoff.rs b/src/symbolize/gimli/xcoff.rs index dd308840..10c0e0dd 100644 --- a/src/symbolize/gimli/xcoff.rs +++ b/src/symbolize/gimli/xcoff.rs @@ -1,4 +1,5 @@ use super::mystd::ffi::{OsStr, OsString}; +use super::mystd::fs; use super::mystd::os::unix::ffi::OsStrExt; use super::mystd::str; use super::{gimli, Context, Endian, EndianSlice, Mapping, Path, Stash, Vec}; @@ -18,7 +19,7 @@ type Xcoff = object::xcoff::FileHeader64; impl Mapping { pub fn new(path: &Path, member_name: &OsString) -> Option { - let map = super::mmap(path)?; + let map = fs::read(path).ok()?; Mapping::mk(map, |data, stash| { if member_name.is_empty() { Context::new(stash, Object::parse(data)?, None, None) @@ -80,7 +81,7 @@ pub fn parse_xcoff(data: &[u8]) -> Option { } pub fn parse_image(path: &Path, member_name: &OsString) -> Option { - let map = super::mmap(path)?; + let map = fs::read(path).ok()?; let data = map.deref(); if member_name.is_empty() { return parse_xcoff(data);