Skip to content

Commit 7bba437

Browse files
committed
inital directory / addr tables layout
1 parent ee39aee commit 7bba437

File tree

1 file changed

+136
-37
lines changed

1 file changed

+136
-37
lines changed

src/librustc_codegen_llvm/base.rs

+136-37
Original file line numberDiff line numberDiff line change
@@ -76,63 +76,162 @@ pub fn write_compressed_metadata<'tcx>(
7676
}
7777
}
7878

79+
fn new_global<'ll>(
80+
name: &[&str],
81+
llmod: &'ll llvm::Module,
82+
llvalue: &'ll llvm::Value,
83+
linkage: llvm::Linkage,
84+
section: &str,
85+
) -> &'ll llvm::Value {
86+
let name = CString::new(name.join(".")).unwrap();
87+
let section = SmallCStr::new(section);
88+
89+
unsafe {
90+
let llglobal = llvm::LLVMAddGlobal(llmod, common::val_ty(llvalue), name.as_ptr());
91+
92+
llvm::LLVMSetInitializer(llglobal, llvalue);
93+
llvm::LLVMRustSetLinkage(llglobal, linkage);
94+
llvm::LLVMSetSection(llglobal, section.as_ptr());
95+
96+
llglobal
97+
}
98+
}
99+
79100
pub fn write_idata_sections<'tcx>(
80101
_tcx: TyCtxt<'tcx>,
81102
raw_dylibs: &[RawDylibImports],
82103
llvm_module: &mut ModuleLlvm,
83104
) {
84105
let (idata_llctx, idata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
106+
let llint32 = unsafe { llvm::LLVMInt32TypeInContext(idata_llctx) };
107+
let llbyte_ptr = unsafe { llvm::LLVMPointerType(llvm::LLVMInt8TypeInContext(idata_llctx), 0) };
108+
109+
// import directory table types
110+
let lldir_ty = unsafe {
111+
let llint32 = llvm::LLVMInt32TypeInContext(idata_llctx);
112+
let lldir_ty_name = SmallCStr::new(".win32.image_import_desc");
113+
let lldir_ty = llvm::LLVMStructCreateNamed(idata_llctx, lldir_ty_name.as_ptr());
114+
llvm::LLVMStructSetBody(
115+
lldir_ty,
116+
[llbyte_ptr, llint32, llint32, llbyte_ptr, llbyte_ptr].as_ptr(),
117+
5,
118+
0,
119+
);
120+
121+
lldir_ty
122+
};
85123

86-
let idata_7 = SmallCStr::new(".idata$7");
87-
let idata_6 = SmallCStr::new(".idata$6");
124+
let mut dir_entries = vec![];
88125

89126
for raw_dylib in raw_dylibs {
90127
debug!("creating raw dylib idata secions - {:?}", raw_dylib);
91128

92129
let name = CString::new(&*raw_dylib.name.as_str()).unwrap();
93130
let llname = common::bytes_in_context(idata_llctx, name.as_bytes());
94131

95-
let buf = format!("import.{}.dll_name", raw_dylib.name);
96-
let buf = CString::new(buf).unwrap();
97-
unsafe {
98-
let llglobal = llvm::LLVMAddGlobal(idata_llmod, common::val_ty(llname), buf.as_ptr());
99-
100-
llvm::LLVMSetInitializer(llglobal, llname);
101-
llvm::LLVMSetGlobalConstant(&llglobal, 1);
102-
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
103-
llvm::LLVMSetSection(llglobal, idata_7.as_ptr());
132+
let lldll_name = new_global(
133+
&["import", &*raw_dylib.name.as_str(), "dll_name"],
134+
idata_llmod,
135+
llname,
136+
llvm::Linkage::PrivateLinkage,
137+
"idata$7",
138+
);
104139

105-
for item in &raw_dylib.items {
106-
match item {
107-
RawDylibImportName::Name(s) => {
108-
let mut buf = vec![0, 0];
109-
buf.extend(s.as_str().as_bytes());
110-
111-
if buf.len() % 2 == 1 {
112-
buf.push(0);
140+
unsafe {
141+
llvm::LLVMSetGlobalConstant(&lldll_name, 1);
142+
143+
let mut lookup_table = raw_dylib
144+
.items
145+
.iter()
146+
.map(|item| {
147+
match item {
148+
RawDylibImportName::Name(s) => {
149+
let mut buf = vec![0, 0];
150+
buf.extend(s.as_str().as_bytes());
151+
152+
if buf.len() % 2 == 1 {
153+
buf.push(0);
154+
}
155+
156+
let llname = common::bytes_in_context(idata_llctx, &buf);
157+
158+
let llglobal = new_global(
159+
&["import", &*raw_dylib.name.as_str(), "fn", &*s.as_str()],
160+
idata_llmod,
161+
llname,
162+
llvm::Linkage::PrivateLinkage,
163+
"idata$6",
164+
);
165+
166+
llvm::LLVMSetGlobalConstant(&llglobal, 1);
167+
llvm::LLVMConstPointerCast(llglobal, llbyte_ptr)
113168
}
169+
RawDylibImportName::Ordinal(o) => {
170+
//FIXME: support 32-bit targets
171+
let o = *o as u64 | 0x8000_0000_0000_0000;
172+
let llint64 = llvm::LLVMInt64TypeInContext(idata_llctx);
173+
let llordinal = llvm::LLVMConstInt(llint64, o, 0);
114174

115-
let llname = common::bytes_in_context(idata_llctx, &buf);
116-
117-
let global_name = format!("import.{}.fn.{}", raw_dylib.name, s);
118-
let global_name = CString::new(global_name).unwrap();
119-
120-
let llglobal = llvm::LLVMAddGlobal(
121-
idata_llmod,
122-
common::val_ty(llname),
123-
global_name.as_ptr(),
124-
);
125-
126-
llvm::LLVMSetInitializer(llglobal, llname);
127-
llvm::LLVMSetGlobalConstant(&llglobal, 1);
128-
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
129-
llvm::LLVMSetSection(llglobal, idata_6.as_ptr());
175+
llvm::LLVMConstIntToPtr(llordinal, llbyte_ptr)
176+
}
130177
}
131-
_ => {}
132-
}
133-
}
178+
})
179+
.collect::<Vec<_>>();
180+
181+
lookup_table.push(llvm::LLVMConstNull(llbyte_ptr));
182+
let lltable =
183+
llvm::LLVMConstArray(llbyte_ptr, lookup_table.as_ptr(), lookup_table.len() as u32);
184+
185+
//import lookup table
186+
let ll_lookup_table = new_global(
187+
&["import", &*raw_dylib.name.as_str(), "desc"],
188+
idata_llmod,
189+
lltable,
190+
llvm::Linkage::PrivateLinkage,
191+
"idata$4",
192+
);
193+
194+
//import address table - filled in at runtime
195+
let ll_addr_table = new_global(
196+
&["import", &*raw_dylib.name.as_str(), "ptr"],
197+
idata_llmod,
198+
lltable,
199+
llvm::Linkage::PrivateLinkage,
200+
"idata$3",
201+
);
202+
203+
let llzero = llvm::LLVMConstInt(llint32, 0, 0);
204+
let lldir_entry = llvm::LLVMConstStructInContext(
205+
idata_llctx,
206+
[
207+
llvm::LLVMConstPointerCast(ll_lookup_table, llbyte_ptr),
208+
llzero,
209+
llzero,
210+
llvm::LLVMConstPointerCast(lldll_name, llbyte_ptr),
211+
llvm::LLVMConstPointerCast(ll_addr_table, llbyte_ptr),
212+
]
213+
.as_ptr(),
214+
5,
215+
0,
216+
);
217+
218+
dir_entries.push(lldir_entry);
134219
}
135220
}
221+
unsafe {
222+
dir_entries.push(llvm::LLVMConstNull(lldir_ty));
223+
let lldir_table =
224+
llvm::LLVMConstArray(lldir_ty, dir_entries.as_ptr(), dir_entries.len() as u32);
225+
226+
let lldir_table = new_global(
227+
&[".dllimport"],
228+
idata_llmod,
229+
lldir_table,
230+
llvm::Linkage::AppendingLinkage,
231+
"idata$2",
232+
);
233+
llvm::LLVMSetGlobalConstant(&lldir_table, 1);
234+
}
136235
}
137236

138237
pub struct ValueIter<'ll> {

0 commit comments

Comments
 (0)