@@ -84,7 +84,14 @@ fn current_dll_path() -> Result<PathBuf, String> {
8484
8585 #[ cfg( target_os = "aix" ) ]
8686 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 ) ;
8895 let mut buffer = vec ! [ std:: mem:: zeroed:: <libc:: ld_info>( ) ; 64 ] ;
8996 loop {
9097 if libc:: loadquery (
@@ -103,19 +110,18 @@ fn current_dll_path() -> Result<PathBuf, String> {
103110 }
104111 let mut current = buffer. as_mut_ptr ( ) as * mut libc:: ld_info ;
105112 loop {
106- let data_base = ( * current) . ldinfo_dataorg as u64 ;
107- let data_end = data_base + ( * current) . ldinfo_datasize ;
108113 let text_base = ( * current) . ldinfo_textorg as u64 ;
109114 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) {
111116 let bytes = CStr :: from_ptr ( & ( * current) . ldinfo_filename [ 0 ] ) . to_bytes ( ) ;
112117 let os = OsStr :: from_bytes ( bytes) ;
113118 return Ok ( PathBuf :: from ( os) ) ;
114119 }
115120 if ( * current) . ldinfo_next == 0 {
116121 break ;
117122 }
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 ;
119125 }
120126 return Err ( format ! ( "current dll's address {} is not in the load map" , addr) ) ;
121127 }
0 commit comments