Find the cratemap at runtime on windows.

This commit is contained in:
Luqman Aden
2013-09-21 19:48:12 -07:00
committed by Luqman Aden
parent 2d22c0c8e4
commit 20a10ff9c9
3 changed files with 51 additions and 5 deletions

View File

@@ -2981,7 +2981,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf) llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
} }
}; };
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage); // On windows we'd like to export the toplevel cratemap
// such that we can find it from libstd.
if targ_cfg.os == session::OsWin32 && "toplevel" == mapname {
lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
} else {
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
}
return map; return map;
} }
@@ -3136,6 +3143,26 @@ pub fn trans_crate(sess: session::Session,
decl_gc_metadata(ccx, llmod_id); decl_gc_metadata(ccx, llmod_id);
fill_crate_map(ccx, ccx.crate_map); fill_crate_map(ccx, ccx.crate_map);
// NOTE win32: wart with exporting crate_map symbol
// We set the crate map (_rust_crate_map_toplevel) to use dll_export
// linkage but that ends up causing the linker to look for a
// __rust_crate_map_toplevel symbol (extra underscore) which it will
// subsequently fail to find. So to mitigate that we just introduce
// an alias from the symbol it expects to the one that actually exists.
if ccx.sess.targ_cfg.os == session::OsWin32 &&
!*ccx.sess.building_library {
let maptype = val_ty(ccx.crate_map).to_ref();
do "__rust_crate_map_toplevel".with_c_str |buf| {
unsafe {
llvm::LLVMAddAlias(ccx.llmod, maptype,
ccx.crate_map, buf);
}
}
}
glue::emit_tydescs(ccx); glue::emit_tydescs(ccx);
write_abi_version(ccx); write_abi_version(ccx);
if ccx.sess.opts.debuginfo { if ccx.sess.opts.debuginfo {

View File

@@ -23,8 +23,8 @@ use container::MutableSet;
#[link_args = "-undefined dynamic_lookup"] #[link_args = "-undefined dynamic_lookup"]
extern {} extern {}
#[cfg(not(stage0), not(windows))]
extern { extern {
#[cfg(not(stage0))]
#[weak_linkage] #[weak_linkage]
#[link_name = "_rust_crate_map_toplevel"] #[link_name = "_rust_crate_map_toplevel"]
static CRATE_MAP: CrateMap; static CRATE_MAP: CrateMap;
@@ -48,11 +48,30 @@ struct CrateMap {
children: [*CrateMap, ..1] children: [*CrateMap, ..1]
} }
#[cfg(not(stage0))] #[cfg(not(stage0), not(windows))]
pub fn get_crate_map() -> *CrateMap { pub fn get_crate_map() -> *CrateMap {
&'static CRATE_MAP as *CrateMap &'static CRATE_MAP as *CrateMap
} }
#[cfg(not(stage0), windows)]
#[fixed_stack_segment]
#[inline(never)]
pub fn get_crate_map() -> *CrateMap {
use c_str::ToCStr;
use unstable::dynamic_lib::dl;
let sym = unsafe {
let module = dl::open_internal();
let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
dl::symbol(module, buf)
};
dl::close(module);
sym
};
sym as *CrateMap
}
unsafe fn version(crate_map: *CrateMap) -> i32 { unsafe fn version(crate_map: *CrateMap) -> i32 {
match (*crate_map).version { match (*crate_map).version {
1 => return 1, 1 => return 1,

View File

@@ -138,7 +138,7 @@ mod test {
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
mod dl { pub mod dl {
use c_str::ToCStr; use c_str::ToCStr;
use libc; use libc;
use path; use path;
@@ -207,7 +207,7 @@ mod dl {
} }
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
mod dl { pub mod dl {
use os; use os;
use libc; use libc;
use path; use path;