@@ -67,6 +67,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
67
67
use std:: ffi:: { CStr , OsStr } ;
68
68
use std:: os:: unix:: prelude:: * ;
69
69
70
+ #[ cfg( not( target_os = "aix" ) ) ]
70
71
unsafe {
71
72
let addr = current_dll_path as usize as * mut _ ;
72
73
let mut info = std:: mem:: zeroed ( ) ;
@@ -80,6 +81,39 @@ fn current_dll_path() -> Result<PathBuf, String> {
80
81
let os = OsStr :: from_bytes ( bytes) ;
81
82
Ok ( PathBuf :: from ( os) )
82
83
}
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
+ }
83
117
}
84
118
85
119
#[ cfg( windows) ]
0 commit comments