@@ -84,7 +84,14 @@ fn current_dll_path() -> Result<PathBuf, String> {
84
84
85
85
#[ cfg( target_os = "aix" ) ]
86
86
unsafe {
87
- let addr = current_dll_path as u64 ;
87
+ // On AIX, the symbol `current_dll_path` references a function descriptor.
88
+ // A function descriptor is consisted of (See https://reviews.llvm.org/D62532)
89
+ // * The address of the entry point of the function.
90
+ // * The TOC base address for the function.
91
+ // * The environment pointer.
92
+ // Deref `current_dll_path` directly so that we can get the address of `current_dll_path`'s
93
+ // entry point in text section.
94
+ let addr = * ( current_dll_path as * const u64 ) ;
88
95
let mut buffer = vec ! [ std:: mem:: zeroed:: <libc:: ld_info>( ) ; 64 ] ;
89
96
loop {
90
97
if libc:: loadquery (
@@ -103,19 +110,18 @@ fn current_dll_path() -> Result<PathBuf, String> {
103
110
}
104
111
let mut current = buffer. as_mut_ptr ( ) as * mut libc:: ld_info ;
105
112
loop {
106
- let data_base = ( * current) . ldinfo_dataorg as u64 ;
107
- let data_end = data_base + ( * current) . ldinfo_datasize ;
108
113
let text_base = ( * current) . ldinfo_textorg as u64 ;
109
114
let text_end = text_base + ( * current) . ldinfo_textsize ;
110
- if ( data_base <= addr && addr < data_end ) || ( text_base <= addr && addr < text_end ) {
115
+ if ( text_base..text_end ) . contains ( & addr) {
111
116
let bytes = CStr :: from_ptr ( & ( * current) . ldinfo_filename [ 0 ] ) . to_bytes ( ) ;
112
117
let os = OsStr :: from_bytes ( bytes) ;
113
118
return Ok ( PathBuf :: from ( os) ) ;
114
119
}
115
120
if ( * current) . ldinfo_next == 0 {
116
121
break ;
117
122
}
118
- current = ( ( current as u64 ) + ( ( * current) . ldinfo_next ) as u64 ) as * mut libc:: ld_info ;
123
+ current =
124
+ ( current as * mut i8 ) . offset ( ( * current) . ldinfo_next as isize ) as * mut libc:: ld_info ;
119
125
}
120
126
return Err ( format ! ( "current dll's address {} is not in the load map" , addr) ) ;
121
127
}
0 commit comments