Skip to content

Commit 611a766

Browse files
authored
Remove memmap dependency (#311)
Try to slim down the dependencies of `gimli-symbolize`
1 parent c8067c6 commit 611a766

File tree

5 files changed

+139
-8
lines changed

5 files changed

+139
-8
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ cpp_demangle = { default-features = false, version = "0.2.3", optional = true }
3636
# Optional dependencies enabled through the `gimli-symbolize` feature
3737
addr2line = { version = "0.11.0", optional = true, default-features = false, features = ['std'] }
3838
findshlibs = { version = "0.5.0", optional = true }
39-
memmap = { version = "0.7.0", optional = true }
4039
goblin = { version = "0.2", optional = true, default-features = false, features = ['elf32', 'elf64', 'mach32', 'mach64', 'pe32', 'pe64', 'std'] }
4140

4241
[target.'cfg(windows)'.dependencies]
@@ -97,7 +96,7 @@ kernel32 = []
9796
libbacktrace = ["backtrace-sys/backtrace-sys"]
9897
dladdr = []
9998
coresymbolication = []
100-
gimli-symbolize = ["addr2line", "findshlibs", "memmap", "goblin"]
99+
gimli-symbolize = ["addr2line", "findshlibs", "goblin"]
101100

102101
#=======================================
103102
# Methods of serialization
@@ -112,6 +111,7 @@ verify-winapi = [
112111
'winapi/dbghelp',
113112
'winapi/handleapi',
114113
'winapi/libloaderapi',
114+
'winapi/memoryapi',
115115
'winapi/minwindef',
116116
'winapi/processthreadsapi',
117117
'winapi/synchapi',

src/symbolize/gimli.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
use self::gimli::read::EndianSlice;
88
use self::gimli::LittleEndian as Endian;
9+
use self::mmap::Mmap;
910
use crate::symbolize::dladdr;
1011
use crate::symbolize::ResolveWhat;
1112
use crate::types::BytesOrWideString;
@@ -15,13 +16,20 @@ use core::mem;
1516
use core::u32;
1617
use findshlibs::{self, Segment, SharedLibrary};
1718
use libc::c_void;
18-
use memmap::Mmap;
19+
use std::convert::TryInto;
1920
use std::env;
2021
use std::ffi::OsString;
2122
use std::fs::File;
2223
use std::path::Path;
2324
use std::prelude::v1::*;
2425

26+
#[cfg(windows)]
27+
#[path = "gimli/mmap_windows.rs"]
28+
mod mmap;
29+
#[cfg(unix)]
30+
#[path = "gimli/mmap_unix.rs"]
31+
mod mmap;
32+
2533
const MAPPINGS_CACHE_SIZE: usize = 4;
2634

2735
struct Context<'a> {
@@ -76,8 +84,8 @@ macro_rules! mk {
7684

7785
fn mmap(path: &Path) -> Option<Mmap> {
7886
let file = File::open(path).ok()?;
79-
// TODO: not completely safe, see https://github.com/danburkert/memmap-rs/issues/25
80-
unsafe { Mmap::map(&file).ok() }
87+
let len = file.metadata().ok()?.len().try_into().ok()?;
88+
unsafe { Mmap::map(&file, len) }
8189
}
8290

8391
cfg_if::cfg_if! {

src/symbolize/gimli/mmap_unix.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use std::fs::File;
2+
use std::ops::Deref;
3+
use std::os::unix::prelude::*;
4+
use std::ptr;
5+
use std::slice;
6+
7+
pub struct Mmap {
8+
ptr: *mut libc::c_void,
9+
len: usize,
10+
}
11+
12+
impl Mmap {
13+
pub unsafe fn map(file: &File, len: usize) -> Option<Mmap> {
14+
let ptr = libc::mmap(
15+
ptr::null_mut(),
16+
len,
17+
libc::PROT_READ,
18+
libc::MAP_PRIVATE,
19+
file.as_raw_fd(),
20+
0,
21+
);
22+
if ptr == libc::MAP_FAILED {
23+
return None;
24+
}
25+
Some(Mmap { ptr, len })
26+
}
27+
}
28+
29+
impl Deref for Mmap {
30+
type Target = [u8];
31+
32+
fn deref(&self) -> &[u8] {
33+
unsafe { slice::from_raw_parts(self.ptr as *const u8, self.len) }
34+
}
35+
}
36+
37+
impl Drop for Mmap {
38+
fn drop(&mut self) {
39+
unsafe {
40+
let r = libc::munmap(self.ptr, self.len);
41+
debug_assert_eq!(r, 0);
42+
}
43+
}
44+
}

src/symbolize/gimli/mmap_windows.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use crate::windows::*;
2+
use std::fs::File;
3+
use std::ops::Deref;
4+
use std::os::windows::prelude::*;
5+
use std::ptr;
6+
use std::slice;
7+
8+
pub struct Mmap {
9+
// keep the file alive to prevent it from ebeing deleted which would cause
10+
// us to read bad data.
11+
_file: File,
12+
ptr: *mut c_void,
13+
len: usize,
14+
}
15+
16+
impl Mmap {
17+
pub unsafe fn map(file: &File, len: usize) -> Option<Mmap> {
18+
let file = file.try_clone().ok()?;
19+
let mapping = CreateFileMappingA(
20+
file.as_raw_handle() as *mut _,
21+
ptr::null_mut(),
22+
PAGE_READONLY,
23+
0,
24+
0,
25+
ptr::null(),
26+
);
27+
if mapping.is_null() {
28+
return None;
29+
}
30+
let ptr = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, len);
31+
CloseHandle(mapping);
32+
if ptr.is_null() {
33+
return None;
34+
}
35+
Some(Mmap {
36+
_file: file,
37+
ptr,
38+
len,
39+
})
40+
}
41+
}
42+
impl Deref for Mmap {
43+
type Target = [u8];
44+
45+
fn deref(&self) -> &[u8] {
46+
unsafe { slice::from_raw_parts(self.ptr as *const u8, self.len) }
47+
}
48+
}
49+
50+
impl Drop for Mmap {
51+
fn drop(&mut self) {
52+
unsafe {
53+
let r = UnmapViewOfFile(self.ptr);
54+
debug_assert!(r != 0);
55+
}
56+
}
57+
}

src/windows.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ cfg_if::cfg_if! {
2525
pub use winapi::shared::basetsd::*;
2626
pub use winapi::shared::minwindef::*;
2727
pub use winapi::um::dbghelp::*;
28+
pub use winapi::um::fileapi::*;
2829
pub use winapi::um::handleapi::*;
2930
pub use winapi::um::libloaderapi::*;
31+
pub use winapi::um::memoryapi::*;
32+
pub use winapi::um::minwinbase::*;
3033
pub use winapi::um::processthreadsapi::*;
34+
pub use winapi::um::synchapi::*;
3135
pub use winapi::um::winbase::*;
3236
pub use winapi::um::winnt::*;
33-
pub use winapi::um::fileapi::*;
34-
pub use winapi::um::minwinbase::*;
35-
pub use winapi::um::synchapi::*;
3637
}
3738
} else {
3839
pub use core::ffi::c_void;
@@ -324,6 +325,8 @@ ffi! {
324325
pub const OPEN_EXISTING: DWORD = 0x3;
325326
pub const GENERIC_READ: DWORD = 0x80000000;
326327
pub const INFINITE: DWORD = !0;
328+
pub const PAGE_READONLY: DWORD = 2;
329+
pub const FILE_MAP_READ: DWORD = 4;
327330

328331
pub type DWORD = u32;
329332
pub type PDWORD = *mut u32;
@@ -344,6 +347,9 @@ ffi! {
344347
pub type LPDWORD = *mut DWORD;
345348
pub type DWORDLONG = u64;
346349
pub type HMODULE = HINSTANCE;
350+
pub type SIZE_T = usize;
351+
pub type LPVOID = *mut c_void;
352+
pub type LPCVOID = *const c_void;
347353

348354
extern "system" {
349355
pub fn GetCurrentProcess() -> HANDLE;
@@ -379,6 +385,22 @@ ffi! {
379385
dwMilliseconds: DWORD,
380386
bAlertable: BOOL,
381387
) -> DWORD;
388+
pub fn CreateFileMappingA(
389+
hFile: HANDLE,
390+
lpFileMappingAttributes: LPSECURITY_ATTRIBUTES,
391+
flProtect: DWORD,
392+
dwMaximumSizeHigh: DWORD,
393+
dwMaximumSizeLow: DWORD,
394+
lpName: LPCSTR,
395+
) -> HANDLE;
396+
pub fn MapViewOfFile(
397+
hFileMappingObject: HANDLE,
398+
dwDesiredAccess: DWORD,
399+
dwFileOffsetHigh: DWORD,
400+
dwFileOffsetLow: DWORD,
401+
dwNumberOfBytesToMap: SIZE_T,
402+
) -> LPVOID;
403+
pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
382404
}
383405
}
384406

0 commit comments

Comments
 (0)