@@ -97,6 +97,19 @@ fn new_global<'ll>(
9797 }
9898}
9999
100+ unsafe fn get_rva < ' ll > (
101+ llctx : & ' ll llvm:: Context ,
102+ llptr : & ' ll llvm:: Value ,
103+ llbase : & ' ll llvm:: Value ,
104+ ) -> & ' ll llvm:: Value {
105+ let llrva_ty = llvm:: LLVMInt32TypeInContext ( llctx) ;
106+
107+ let llbase_val = llvm:: LLVMConstPtrToInt ( llbase, llrva_ty) ;
108+ let llptr_val = llvm:: LLVMConstPtrToInt ( llptr, llrva_ty) ;
109+
110+ llvm:: LLVMConstSub ( llptr_val, llbase_val)
111+ }
112+
100113pub fn write_idata_sections < ' tcx > (
101114 _tcx : TyCtxt < ' tcx > ,
102115 raw_dylibs : & [ RawDylibImports ] ,
@@ -108,19 +121,29 @@ pub fn write_idata_sections<'tcx>(
108121
109122 // import directory table types
110123 let lldir_ty = unsafe {
111- let llint32 = llvm:: LLVMInt32TypeInContext ( idata_llctx) ;
112124 let lldir_ty_name = SmallCStr :: new ( ".win32.image_import_desc" ) ;
113125 let lldir_ty = llvm:: LLVMStructCreateNamed ( idata_llctx, lldir_ty_name. as_ptr ( ) ) ;
114126 llvm:: LLVMStructSetBody (
115127 lldir_ty,
116- [ llbyte_ptr , llint32, llint32, llbyte_ptr , llbyte_ptr ] . as_ptr ( ) ,
128+ [ llint32 , llint32, llint32, llint32 , llint32 ] . as_ptr ( ) ,
117129 5 ,
118130 0 ,
119131 ) ;
120132
121133 lldir_ty
122134 } ;
123135
136+ // image base constant for computing RVAs
137+ let image_base = unsafe {
138+ let llname = SmallCStr :: new ( "__ImageBase" ) ;
139+ let llty = llvm:: LLVMInt8TypeInContext ( idata_llctx) ;
140+
141+ let llglobal = llvm:: LLVMAddGlobal ( idata_llmod, llty, llname. as_ptr ( ) ) ;
142+ llvm:: LLVMRustSetLinkage ( llglobal, llvm:: Linkage :: ExternalLinkage ) ;
143+
144+ llglobal
145+ } ;
146+
124147 let mut dir_entries = vec ! [ ] ;
125148
126149 for raw_dylib in raw_dylibs {
@@ -204,11 +227,11 @@ pub fn write_idata_sections<'tcx>(
204227 let lldir_entry = llvm:: LLVMConstStructInContext (
205228 idata_llctx,
206229 [
207- llvm :: LLVMConstPointerCast ( ll_lookup_table, llbyte_ptr ) ,
230+ get_rva ( idata_llctx , ll_lookup_table, image_base ) ,
208231 llzero,
209232 llzero,
210- llvm :: LLVMConstPointerCast ( lldll_name, llbyte_ptr ) ,
211- llvm :: LLVMConstPointerCast ( ll_addr_table, llbyte_ptr ) ,
233+ get_rva ( idata_llctx , lldll_name, image_base ) ,
234+ get_rva ( idata_llctx , ll_addr_table, image_base ) ,
212235 ]
213236 . as_ptr ( ) ,
214237 5 ,
@@ -227,7 +250,7 @@ pub fn write_idata_sections<'tcx>(
227250 & [ ".dllimport" ] ,
228251 idata_llmod,
229252 lldir_table,
230- llvm:: Linkage :: AppendingLinkage ,
253+ llvm:: Linkage :: ExternalLinkage ,
231254 "idata$2" ,
232255 ) ;
233256 llvm:: LLVMSetGlobalConstant ( & lldir_table, 1 ) ;
0 commit comments