@@ -67,6 +67,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
6767 use std:: ffi:: { CStr , OsStr } ;
6868 use std:: os:: unix:: prelude:: * ;
6969
70+ #[ cfg( not( target_os = "aix" ) ) ]
7071 unsafe {
7172 let addr = current_dll_path as usize as * mut _ ;
7273 let mut info = std:: mem:: zeroed ( ) ;
@@ -80,6 +81,39 @@ fn current_dll_path() -> Result<PathBuf, String> {
8081 let os = OsStr :: from_bytes ( bytes) ;
8182 Ok ( PathBuf :: from ( os) )
8283 }
84+
85+ #[ cfg( target_os = "aix" ) ]
86+ unsafe {
87+ let addr = current_dll_path as u64 ;
88+ let mut buffer = vec ! [ 0i8 ; 4096 ] ;
89+ loop {
90+ if libc:: loadquery ( libc:: L_GETINFO , buffer. as_mut_ptr ( ) , buffer. len ( ) as u32 ) >= 0 {
91+ break ;
92+ } else {
93+ if std:: io:: Error :: last_os_error ( ) . raw_os_error ( ) . unwrap ( ) != libc:: ENOMEM {
94+ return Err ( "loadquery failed" . into ( ) ) ;
95+ }
96+ buffer. resize ( buffer. len ( ) * 2 , 0i8 ) ;
97+ }
98+ }
99+ let mut current = buffer. as_mut_ptr ( ) as * mut libc:: ld_info ;
100+ loop {
101+ let data_base = ( * current) . ldinfo_dataorg as u64 ;
102+ let data_end = data_base + ( * current) . ldinfo_datasize ;
103+ let text_base = ( * current) . ldinfo_textorg as u64 ;
104+ let text_end = text_base + ( * current) . ldinfo_textsize ;
105+ if ( data_base <= addr && addr < data_end) || ( text_base <= addr && addr < text_end) {
106+ let bytes = CStr :: from_ptr ( & ( * current) . ldinfo_filename [ 0 ] ) . to_bytes ( ) ;
107+ let os = OsStr :: from_bytes ( bytes) ;
108+ return Ok ( PathBuf :: from ( os) ) ;
109+ }
110+ if ( * current) . ldinfo_next == 0 {
111+ break ;
112+ }
113+ current = ( ( current as u64 ) + ( ( * current) . ldinfo_next ) as u64 ) as * mut libc:: ld_info ;
114+ }
115+ return Err ( format ! ( "current dll's address {} is not in the load map" , addr) ) ;
116+ }
83117}
84118
85119#[ cfg( windows) ]
0 commit comments