@@ -112,7 +112,7 @@ pub fn trace_enabled() -> bool {
112112
113113/// The address of `name` in the running process, if the dynamic linker
114114/// knows it.
115- #[ cfg( not( target_arch = "wasm32" ) ) ]
115+ #[ cfg( all ( unix , not( target_arch = "wasm32" ) ) ) ]
116116fn process_symbol ( name : & str ) -> Option < * const u8 > {
117117 let c = std:: ffi:: CString :: new ( name) . ok ( ) ?;
118118 // SAFETY: `dlsym` with the default handle reads the process's own
@@ -121,7 +121,42 @@ fn process_symbol(name: &str) -> Option<*const u8> {
121121 ( !p. is_null ( ) ) . then_some ( p as * const u8 )
122122}
123123
124- #[ cfg( target_arch = "wasm32" ) ]
124+ /// Windows has no default handle: every loaded module is asked in turn.
125+ #[ cfg( windows) ]
126+ fn process_symbol ( name : & str ) -> Option < * const u8 > {
127+ use std:: ffi:: { c_char, c_void} ;
128+ #[ link( name = "kernel32" ) ]
129+ unsafe extern "system" {
130+ fn GetCurrentProcess ( ) -> * mut c_void ;
131+ fn K32EnumProcessModules (
132+ process : * mut c_void ,
133+ modules : * mut * mut c_void ,
134+ size : u32 ,
135+ needed : * mut u32 ,
136+ ) -> i32 ;
137+ fn GetProcAddress ( module : * mut c_void , name : * const c_char ) -> * const c_void ;
138+ }
139+ let c = std:: ffi:: CString :: new ( name) . ok ( ) ?;
140+ let mut modules = [ std:: ptr:: null_mut :: < c_void > ( ) ; 512 ] ;
141+ let mut needed = 0u32 ;
142+ // SAFETY: the buffer is passed with its own byte size, and only the
143+ // handles written into it are read; `c` outlives the lookups.
144+ unsafe {
145+ let size = size_of_val ( & modules) as u32 ;
146+ if K32EnumProcessModules ( GetCurrentProcess ( ) , modules. as_mut_ptr ( ) , size, & mut needed) == 0
147+ {
148+ return None ;
149+ }
150+ let n = ( needed as usize / size_of :: < * mut c_void > ( ) ) . min ( modules. len ( ) ) ;
151+ modules[ ..n]
152+ . iter ( )
153+ . map ( |& m| GetProcAddress ( m, c. as_ptr ( ) ) )
154+ . find ( |p| !p. is_null ( ) )
155+ . map ( |p| p as * const u8 )
156+ }
157+ }
158+
159+ #[ cfg( not( any( all( unix, not( target_arch = "wasm32" ) ) , windows) ) ) ]
125160fn process_symbol ( _name : & str ) -> Option < * const u8 > {
126161 None
127162}
0 commit comments