diff options
| author | Kai Luo <lkail@cn.ibm.com> | 2023-03-23 16:50:49 +0800 |
|---|---|---|
| committer | Kai Luo <lkail@cn.ibm.com> | 2023-03-23 16:50:49 +0800 |
| commit | 6e8a8282b8c131adb7f39909b9148687ea6c3b7b (patch) | |
| tree | f3f8e8cc7059a84ca73e4533852536f4fa121b07 /compiler/rustc_session | |
| parent | 1c771fec3329ef1d8c66697daf9517501d0c129a (diff) | |
| download | rust-6e8a8282b8c131adb7f39909b9148687ea6c3b7b.tar.gz rust-6e8a8282b8c131adb7f39909b9148687ea6c3b7b.zip | |
Implement current_dll_path for AIX
Diffstat (limited to 'compiler/rustc_session')
| -rw-r--r-- | compiler/rustc_session/src/filesearch.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index e734599cbfc..2c804f0f0a4 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -67,6 +67,7 @@ fn current_dll_path() -> Result<PathBuf, String> { use std::ffi::{CStr, OsStr}; use std::os::unix::prelude::*; + #[cfg(not(target_os = "aix"))] unsafe { let addr = current_dll_path as usize as *mut _; let mut info = std::mem::zeroed(); @@ -80,6 +81,39 @@ fn current_dll_path() -> Result<PathBuf, String> { let os = OsStr::from_bytes(bytes); Ok(PathBuf::from(os)) } + + #[cfg(target_os = "aix")] + unsafe { + let addr = current_dll_path as u64; + let mut buffer = vec![0i8; 4096]; + loop { + if libc::loadquery(libc::L_GETINFO, buffer.as_mut_ptr(), buffer.len() as u32) >= 0 { + break; + } else { + if std::io::Error::last_os_error().raw_os_error().unwrap() != libc::ENOMEM { + return Err("loadquery failed".into()); + } + buffer.resize(buffer.len() * 2, 0i8); + } + } + let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; + loop { + let data_base = (*current).ldinfo_dataorg as u64; + let data_end = data_base + (*current).ldinfo_datasize; + let text_base = (*current).ldinfo_textorg as u64; + let text_end = text_base + (*current).ldinfo_textsize; + if (data_base <= addr && addr < data_end) || (text_base <= addr && addr < text_end) { + let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); + let os = OsStr::from_bytes(bytes); + return Ok(PathBuf::from(os)); + } + if (*current).ldinfo_next == 0 { + break; + } + current = ((current as u64) + ((*current).ldinfo_next) as u64) as *mut libc::ld_info; + } + return Err(format!("current dll's address {} is not in the load map", addr)); + } } #[cfg(windows)] |
