Skip to content

Commit 20a10ff

Browse files
committed
Find the cratemap at runtime on windows.
1 parent 2d22c0c commit 20a10ff

File tree

3 files changed

+51
-5
lines changed

3 files changed

+51
-5
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2981,7 +2981,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
29812981
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
29822982
}
29832983
};
2984-
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
2984+
// On windows we'd like to export the toplevel cratemap
2985+
// such that we can find it from libstd.
2986+
if targ_cfg.os == session::OsWin32 && "toplevel" == mapname {
2987+
lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
2988+
} else {
2989+
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
2990+
}
2991+
29852992
return map;
29862993
}
29872994

@@ -3136,6 +3143,26 @@ pub fn trans_crate(sess: session::Session,
31363143

31373144
decl_gc_metadata(ccx, llmod_id);
31383145
fill_crate_map(ccx, ccx.crate_map);
3146+
3147+
// NOTE win32: wart with exporting crate_map symbol
3148+
// We set the crate map (_rust_crate_map_toplevel) to use dll_export
3149+
// linkage but that ends up causing the linker to look for a
3150+
// __rust_crate_map_toplevel symbol (extra underscore) which it will
3151+
// subsequently fail to find. So to mitigate that we just introduce
3152+
// an alias from the symbol it expects to the one that actually exists.
3153+
if ccx.sess.targ_cfg.os == session::OsWin32 &&
3154+
!*ccx.sess.building_library {
3155+
3156+
let maptype = val_ty(ccx.crate_map).to_ref();
3157+
3158+
do "__rust_crate_map_toplevel".with_c_str |buf| {
3159+
unsafe {
3160+
llvm::LLVMAddAlias(ccx.llmod, maptype,
3161+
ccx.crate_map, buf);
3162+
}
3163+
}
3164+
}
3165+
31393166
glue::emit_tydescs(ccx);
31403167
write_abi_version(ccx);
31413168
if ccx.sess.opts.debuginfo {

src/libstd/rt/crate_map.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use container::MutableSet;
2323
#[link_args = "-undefined dynamic_lookup"]
2424
extern {}
2525

26+
#[cfg(not(stage0), not(windows))]
2627
extern {
27-
#[cfg(not(stage0))]
2828
#[weak_linkage]
2929
#[link_name = "_rust_crate_map_toplevel"]
3030
static CRATE_MAP: CrateMap;
@@ -48,11 +48,30 @@ struct CrateMap {
4848
children: [*CrateMap, ..1]
4949
}
5050

51-
#[cfg(not(stage0))]
51+
#[cfg(not(stage0), not(windows))]
5252
pub fn get_crate_map() -> *CrateMap {
5353
&'static CRATE_MAP as *CrateMap
5454
}
5555

56+
#[cfg(not(stage0), windows)]
57+
#[fixed_stack_segment]
58+
#[inline(never)]
59+
pub fn get_crate_map() -> *CrateMap {
60+
use c_str::ToCStr;
61+
use unstable::dynamic_lib::dl;
62+
63+
let sym = unsafe {
64+
let module = dl::open_internal();
65+
let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
66+
dl::symbol(module, buf)
67+
};
68+
dl::close(module);
69+
sym
70+
};
71+
72+
sym as *CrateMap
73+
}
74+
5675
unsafe fn version(crate_map: *CrateMap) -> i32 {
5776
match (*crate_map).version {
5877
1 => return 1,

src/libstd/unstable/dynamic_lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ mod test {
138138
#[cfg(target_os = "android")]
139139
#[cfg(target_os = "macos")]
140140
#[cfg(target_os = "freebsd")]
141-
mod dl {
141+
pub mod dl {
142142
use c_str::ToCStr;
143143
use libc;
144144
use path;
@@ -207,7 +207,7 @@ mod dl {
207207
}
208208

209209
#[cfg(target_os = "win32")]
210-
mod dl {
210+
pub mod dl {
211211
use os;
212212
use libc;
213213
use path;

0 commit comments

Comments
 (0)