Skip to content

Commit e71e296

Browse files
committed
Convert path to posix
1 parent 24a9104 commit e71e296

File tree

2 files changed

+53
-29
lines changed

2 files changed

+53
-29
lines changed

src/symbolize/gimli.rs

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ cfg_if::cfg_if! {
4343
target_os = "solaris",
4444
target_os = "illumos",
4545
target_os = "aix",
46+
target_os = "cygwin",
4647
))] {
4748
#[path = "gimli/mmap_unix.rs"]
4849
mod mmap;

src/symbolize/gimli/libs_windows.rs

+52-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::super::super::windows_sys::*;
22
use super::mystd::ffi::OsString;
3+
#[cfg(windows)]
4+
use super::mystd::os::windows::prelude::*;
35
use super::{coff, mmap, Library, LibrarySegment};
46
use alloc::vec;
57
use alloc::vec::Vec;
@@ -42,43 +44,64 @@ unsafe fn add_loaded_images(ret: &mut Vec<Library>) {
4244
}
4345
}
4446

45-
unsafe fn load_library(me: &MODULEENTRY32W) -> Option<Library> {
46-
let pos = me
47-
.szExePath
48-
.iter()
49-
.position(|i| *i == 0)
50-
.unwrap_or(me.szExePath.len());
47+
// Safety: long_path should be null-terminated
48+
#[cfg(target_os = "cygwin")]
49+
unsafe fn get_posix_path(long_path: &[u16]) -> Option<OsString> {
50+
use std::os::unix::ffi::OsStringExt;
51+
52+
unsafe extern "C" {
53+
fn cygwin_conv_path(
54+
what: libc::c_uint,
55+
from: *const libc::c_void,
56+
to: *mut libc::c_void,
57+
size: libc::size_t,
58+
) -> libc::ssize_t;
59+
}
60+
const CCP_WIN_W_TO_POSIX: libc::c_uint = 3;
61+
5162
let name_len = unsafe {
52-
WideCharToMultiByte(
53-
CP_UTF8,
54-
0,
55-
me.szExePath.as_ptr(),
56-
pos as i32,
63+
cygwin_conv_path(
64+
CCP_WIN_W_TO_POSIX,
65+
long_path.as_ptr().cast(),
5766
core::ptr::null_mut(),
5867
0,
59-
core::ptr::null_mut(),
60-
core::ptr::null_mut(),
61-
) as usize
68+
)
6269
};
70+
// Expect at least 1 for null terminator.
71+
if name_len < 1 {
72+
return None;
73+
}
74+
let name_len = name_len as usize;
6375
let mut name_buffer = vec![0_u8; name_len];
64-
let name_len = unsafe {
65-
WideCharToMultiByte(
66-
CP_UTF8,
67-
0,
68-
me.szExePath.as_ptr(),
69-
pos as i32,
70-
name_buffer.as_mut_ptr(),
71-
name_buffer.len() as i32,
72-
core::ptr::null_mut(),
73-
core::ptr::null_mut(),
74-
) as usize
76+
let res = unsafe {
77+
cygwin_conv_path(
78+
CCP_WIN_W_TO_POSIX,
79+
long_path.as_ptr().cast(),
80+
name_buffer.as_mut_ptr().cast(),
81+
name_buffer.len(),
82+
)
7583
};
76-
if name_len == 0 || name_len > name_buffer.len() {
77-
// This can't happen.
84+
if res != 0 {
7885
return None;
7986
}
80-
unsafe { name_buffer.set_len(name_len) };
81-
let name = unsafe { OsString::from_encoded_bytes_unchecked(name_buffer) };
87+
// Ignore null terminator.
88+
unsafe { name_buffer.set_len(name_len - 1) };
89+
let name = OsString::from_vec(name_buffer);
90+
Some(name)
91+
}
92+
93+
unsafe fn load_library(me: &MODULEENTRY32W) -> Option<Library> {
94+
let pos = me
95+
.szExePath
96+
.iter()
97+
.position(|i| *i == 0)
98+
.unwrap_or(me.szExePath.len());
99+
#[cfg(windows)]
100+
let name = OsString::from_wide(&me.szExePath[..pos]);
101+
#[cfg(target_os = "cygwin")]
102+
// Safety: the path with max length MAX_PATH always contains a null
103+
// terminator
104+
let name = unsafe { get_posix_path(&me.szExePath[..pos])? };
82105

83106
// MinGW libraries currently don't support ASLR
84107
// (rust-lang/rust#16514), but DLLs can still be relocated around in

0 commit comments

Comments
 (0)