backtrace/symbolize/gimli/
libs_dl_iterate_phdr.rs1use super::mystd::borrow::ToOwned;
6use super::mystd::env;
7use super::mystd::ffi::{CStr, OsStr};
8use super::mystd::os::unix::prelude::*;
9use super::{Library, LibrarySegment, OsString, Vec};
10use core::slice;
11
12pub(super) fn native_libraries() -> Vec<Library> {
13 let mut ret = Vec::new();
14 unsafe {
15 libc::dl_iterate_phdr(Some(callback), core::ptr::addr_of_mut!(ret).cast());
16 }
17 return ret;
18}
19
20fn infer_current_exe(base_addr: usize) -> OsString {
21 cfg_if::cfg_if! {
22 if #[cfg(not(target_os = "hurd"))] {
23 if let Ok(entries) = super::parse_running_mmaps::parse_maps() {
24 let opt_path = entries
25 .iter()
26 .find(|e| e.ip_matches(base_addr) && e.pathname().len() > 0)
27 .map(|e| e.pathname())
28 .cloned();
29 if let Some(path) = opt_path {
30 return path;
31 }
32 }
33 }
34 }
35 env::current_exe().map(|e| e.into()).unwrap_or_default()
36}
37
38#[forbid(unsafe_op_in_unsafe_fn)]
42unsafe extern "C" fn callback(
43 info: *mut libc::dl_phdr_info,
44 _size: libc::size_t,
45 vec: *mut libc::c_void,
46) -> libc::c_int {
47 let dlpi_addr = unsafe { (*info).dlpi_addr };
49 let dlpi_name = unsafe { (*info).dlpi_name };
50 let dlpi_phdr = unsafe { (*info).dlpi_phdr };
51 let dlpi_phnum = unsafe { (*info).dlpi_phnum };
52 let libs = unsafe { &mut *vec.cast::<Vec<Library>>() };
54 let is_main = libs.is_empty();
56 let is_static = dlpi_addr == 0;
58 let no_given_name = dlpi_name.is_null()
60 || unsafe { *dlpi_name == 0 };
62 let name = if is_static {
63 env::current_exe().unwrap_or_default().into_os_string()
65 } else if is_main && no_given_name {
66 infer_current_exe(dlpi_addr as usize)
67 } else {
68 if dlpi_name.is_null() {
70 OsString::new()
71 } else {
72 OsStr::from_bytes(unsafe { CStr::from_ptr(dlpi_name) }.to_bytes()).to_owned()
74 }
75 };
76 let headers = if dlpi_phdr.is_null() || dlpi_phnum == 0 {
77 &[]
78 } else {
79 unsafe { slice::from_raw_parts(dlpi_phdr, dlpi_phnum as usize) }
81 };
82 libs.push(Library {
83 name,
84 segments: headers
85 .iter()
86 .map(|header| LibrarySegment {
87 len: (*header).p_memsz as usize,
88 stated_virtual_memory_address: (*header).p_vaddr as usize,
89 })
90 .collect(),
91 bias: dlpi_addr as usize,
92 });
93 0
94}