1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 //! Common support for resolving with `dladdr`, often used as a fallback if
12 //! other strategies don't work.
13 
14 #![allow(dead_code)]
15 
16 cfg_if::cfg_if! {
17     if #[cfg(all(unix, not(target_os = "emscripten"), feature = "dladdr"))] {
18         use core::{mem, slice};
19         use crate::types::BytesOrWideString;
20         use core::ffi::c_void;
21         use libc::{self, Dl_info};
22 
23         use crate::SymbolName;
24 
25         pub struct Symbol {
26             inner: Dl_info,
27         }
28 
29         impl Symbol {
30             pub fn name(&self) -> Option<SymbolName> {
31                 if self.inner.dli_sname.is_null() {
32                     None
33                 } else {
34                     let ptr = self.inner.dli_sname as *const u8;
35                     unsafe {
36                         let len = libc::strlen(self.inner.dli_sname);
37                         Some(SymbolName::new(slice::from_raw_parts(ptr, len)))
38                     }
39                 }
40             }
41 
42             pub fn addr(&self) -> Option<*mut c_void> {
43                 Some(self.inner.dli_saddr as *mut _)
44             }
45 
46             pub fn filename_raw(&self) -> Option<BytesOrWideString> {
47                 None
48             }
49 
50             #[cfg(feature = "std")]
51             pub fn filename(&self) -> Option<&::std::path::Path> {
52                 None
53             }
54 
55             pub fn lineno(&self) -> Option<u32> {
56                 None
57             }
58         }
59 
60         pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol)) {
61             let mut info = Symbol {
62                 inner: mem::zeroed(),
63             };
64             if libc::dladdr(addr as *mut _, &mut info.inner) != 0 {
65                 cb(info)
66             }
67         }
68     } else {
69         use core::ffi::c_void;
70         use crate::types::BytesOrWideString;
71         use crate::symbolize::SymbolName;
72 
73         pub enum Symbol {}
74 
75         impl Symbol {
76             pub fn name(&self) -> Option<SymbolName> {
77                 match *self {}
78             }
79 
80             pub fn addr(&self) -> Option<*mut c_void> {
81                 match *self {}
82             }
83 
84             pub fn filename_raw(&self) -> Option<BytesOrWideString> {
85                 match *self {}
86             }
87 
88             #[cfg(feature = "std")]
89             pub fn filename(&self) -> Option<&::std::path::Path> {
90                 match *self {}
91             }
92 
93             pub fn lineno(&self) -> Option<u32> {
94                 match *self {}
95             }
96         }
97 
98         pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol)) {
99             drop((addr, cb));
100         }
101     }
102 }
103