]> git.lizzy.rs Git - rust.git/commitdiff
Find the cratemap at runtime on windows.
authorLuqman Aden <me@luqman.ca>
Sun, 22 Sep 2013 02:48:12 +0000 (19:48 -0700)
committerLuqman Aden <laden@csclub.uwaterloo.ca>
Mon, 23 Sep 2013 22:26:16 +0000 (18:26 -0400)
src/librustc/middle/trans/base.rs
src/libstd/rt/crate_map.rs
src/libstd/unstable/dynamic_lib.rs

index 762c658ea6ebfc0684556ed4b6519aae6f8338f7..4034d1ef8dd94370e514b9e4ff25e48052f1d7dc 100644 (file)
@@ -2981,7 +2981,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
             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;
 }
 
@@ -3136,6 +3143,26 @@ pub fn trans_crate(sess: session::Session,
 
     decl_gc_metadata(ccx, llmod_id);
     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);
     write_abi_version(ccx);
     if ccx.sess.opts.debuginfo {
index e4c3763be96aef2008c557507bd24f378d8ea267..f73aa1fad67dce05b1792edfa133a3fc3a88398b 100644 (file)
@@ -23,8 +23,8 @@
 #[link_args = "-undefined dynamic_lookup"]
 extern {}
 
+#[cfg(not(stage0), not(windows))]
 extern {
-    #[cfg(not(stage0))]
     #[weak_linkage]
     #[link_name = "_rust_crate_map_toplevel"]
     static CRATE_MAP: CrateMap;
@@ -48,11 +48,30 @@ struct CrateMap {
     children: [*CrateMap, ..1]
 }
 
-#[cfg(not(stage0))]
+#[cfg(not(stage0), not(windows))]
 pub fn get_crate_map() -> *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 {
     match (*crate_map).version {
         1 => return 1,
index 4c92d9c2e362c5272edbaf4e3e2bb399db614140..41ff79bc8845815db4eda5382c676bb04473eb62 100644 (file)
@@ -138,7 +138,7 @@ fn test_errors_do_not_crash() {
 #[cfg(target_os = "android")]
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
-mod dl {
+pub mod dl {
     use c_str::ToCStr;
     use libc;
     use path;
@@ -207,7 +207,7 @@ pub enum RTLD {
 }
 
 #[cfg(target_os = "win32")]
-mod dl {
+pub mod dl {
     use os;
     use libc;
     use path;