|
1 | 1 | #![allow(dead_code)] |
2 | 2 | use crate::Error; |
3 | | -use core::{ |
4 | | - mem::MaybeUninit, |
5 | | - num::NonZeroU32, |
6 | | - ptr::NonNull, |
7 | | - sync::atomic::{fence, AtomicPtr, Ordering}, |
8 | | -}; |
9 | | -use libc::c_void; |
| 3 | +use core::{mem::MaybeUninit, num::NonZeroU32}; |
10 | 4 |
|
11 | 5 | cfg_if! { |
12 | 6 | if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] { |
@@ -76,62 +70,6 @@ pub fn sys_fill_exact( |
76 | 70 | Ok(()) |
77 | 71 | } |
78 | 72 |
|
79 | | -// A "weak" binding to a C function that may or may not be present at runtime. |
80 | | -// Used for supporting newer OS features while still building on older systems. |
81 | | -// Based off of the DlsymWeak struct in libstd: |
82 | | -// https://github.com/rust-lang/rust/blob/1.61.0/library/std/src/sys/unix/weak.rs#L84 |
83 | | -// except that the caller must manually cast self.ptr() to a function pointer. |
84 | | -pub struct Weak { |
85 | | - name: &'static str, |
86 | | - addr: AtomicPtr<c_void>, |
87 | | -} |
88 | | - |
89 | | -impl Weak { |
90 | | - // A non-null pointer value which indicates we are uninitialized. This |
91 | | - // constant should ideally not be a valid address of a function pointer. |
92 | | - // However, if by chance libc::dlsym does return UNINIT, there will not |
93 | | - // be undefined behavior. libc::dlsym will just be called each time ptr() |
94 | | - // is called. This would be inefficient, but correct. |
95 | | - // TODO: Replace with core::ptr::invalid_mut(1) when that is stable. |
96 | | - const UNINIT: *mut c_void = 1 as *mut c_void; |
97 | | - |
98 | | - // Construct a binding to a C function with a given name. This function is |
99 | | - // unsafe because `name` _must_ be null terminated. |
100 | | - pub const unsafe fn new(name: &'static str) -> Self { |
101 | | - Self { |
102 | | - name, |
103 | | - addr: AtomicPtr::new(Self::UNINIT), |
104 | | - } |
105 | | - } |
106 | | - |
107 | | - // Return the address of a function if present at runtime. Otherwise, |
108 | | - // return None. Multiple callers can call ptr() concurrently. It will |
109 | | - // always return _some_ value returned by libc::dlsym. However, the |
110 | | - // dlsym function may be called multiple times. |
111 | | - pub fn ptr(&self) -> Option<NonNull<c_void>> { |
112 | | - // Despite having only a single atomic variable (self.addr), we still |
113 | | - // cannot always use Ordering::Relaxed, as we need to make sure a |
114 | | - // successful call to dlsym() is "ordered before" any data read through |
115 | | - // the returned pointer (which occurs when the function is called). |
116 | | - // Our implementation mirrors that of the one in libstd, meaning that |
117 | | - // the use of non-Relaxed operations is probably unnecessary. |
118 | | - match self.addr.load(Ordering::Relaxed) { |
119 | | - Self::UNINIT => { |
120 | | - let symbol = self.name.as_ptr() as *const _; |
121 | | - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, symbol) }; |
122 | | - // Synchronizes with the Acquire fence below |
123 | | - self.addr.store(addr, Ordering::Release); |
124 | | - NonNull::new(addr) |
125 | | - } |
126 | | - addr => { |
127 | | - let func = NonNull::new(addr)?; |
128 | | - fence(Ordering::Acquire); |
129 | | - Some(func) |
130 | | - } |
131 | | - } |
132 | | - } |
133 | | -} |
134 | | - |
135 | 73 | // SAFETY: path must be null terminated, FD must be manually closed. |
136 | 74 | pub unsafe fn open_readonly(path: &str) -> Result<libc::c_int, Error> { |
137 | 75 | debug_assert_eq!(path.as_bytes().last(), Some(&0)); |
|
0 commit comments