From 0ad3a110be9070b87ecd7e1c71d20a02660d8959 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 12 Mar 2013 20:06:20 -0700 Subject: [PATCH] Work around linkage bug cross-compiling from x86_64-apple-darwin to i686-apple-darwin The correct opendir/readdir to use appear to be the 64-bit versions called opendir$INODE64, etc. but for some reason I can't get them to link properly on i686. Putting them in librustrt and making gcc figure it out works. This mystery will have to wait for another day. --- src/libcore/libc.rs | 54 ++++++++++++++--------------------------- src/libuv | 2 +- src/rt/rust_builtin.cpp | 27 +++++++++++++++++++++ src/rt/rustrt.def.in | 2 ++ 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index a25beb9132f..e3646ef60f5 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -1385,48 +1385,30 @@ pub mod funcs { use libc::types::common::posix88::{DIR, dirent_t}; use libc::types::os::arch::c95::{c_char, c_int, c_long}; - pub extern { - // default bindings for opendir and readdir in - // non-macos unix - #[cfg(target_os = "linux")] - #[cfg(target_os = "android")] - #[cfg(target_os = "freebsd")] - unsafe fn opendir(dirname: *c_char) -> *DIR; - #[cfg(target_os = "linux")] - #[cfg(target_os = "android")] - #[cfg(target_os = "freebsd")] - unsafe fn readdir(dirp: *DIR) -> *dirent_t; + // NOTE: On OS X opendir and readdir have two versions, + // one for 32-bit kernelspace and one for 64. + // We should be linking to the 64-bit ones, called + // opendir$INODE64, etc. but for some reason rustc + // doesn't link it correctly on i686, so we're going + // through a C function that mysteriously does work. + pub unsafe fn opendir(dirname: *c_char) -> *DIR { + rust_opendir(dirname) + } + pub unsafe fn readdir(dirp: *DIR) -> *dirent_t { + rust_readdir(dirp) + } + extern { + unsafe fn rust_opendir(dirname: *c_char) -> *DIR; + unsafe fn rust_readdir(dirp: *DIR) -> *dirent_t; + } + + pub extern { unsafe fn closedir(dirp: *DIR) -> c_int; unsafe fn rewinddir(dirp: *DIR); unsafe fn seekdir(dirp: *DIR, loc: c_long); unsafe fn telldir(dirp: *DIR) -> c_long; } - - #[cfg(target_word_size = "64")] - pub extern { - // on OSX (particularly when running with a - // 64bit kernel), we have an issue where there - // are separate bindings for opendir and readdir, - // which we have to explicitly link, as below. - #[cfg(target_os = "macos")] - #[link_name = "opendir$INODE64"] - unsafe fn opendir(dirname: *c_char) -> *DIR; - #[cfg(target_os = "macos")] - #[link_name = "readdir$INODE64"] - unsafe fn readdir(dirp: *DIR) -> *dirent_t; - } - #[cfg(target_word_size = "32")] - pub extern { - // on OSX (particularly when running with a - // 64bit kernel), we have an issue where there - // are separate bindings for opendir and readdir, - // which we have to explicitly link, as below. - #[cfg(target_os = "macos")] - unsafe fn opendir(dirname: *c_char) -> *DIR; - #[cfg(target_os = "macos")] - unsafe fn readdir(dirp: *DIR) -> *dirent_t; - } } #[nolink] diff --git a/src/libuv b/src/libuv index 218ab86721e..576ab1db8ea 160000 --- a/src/libuv +++ b/src/libuv @@ -1 +1 @@ -Subproject commit 218ab86721eefd7b7e97fa6d9f95a80a1fa8686c +Subproject commit 576ab1db8ea03889eb7b2274654afe7c5c867230 diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 248f851e5b9..8d83e2036b9 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -818,6 +818,33 @@ rust_dec_kernel_live_count() { task->kernel->dec_live_count(); } +#ifndef _WIN32 +#include +#include + +extern "C" DIR* +rust_opendir(char *dirname) { + return opendir(dirname); +} + +extern "C" dirent* +rust_readdir(DIR *dirp) { + return readdir(dirp); +} + +#else + +extern "C" void +rust_opendir() { +} + +extern "C" void +rust_readdir() { +} + +#endif + + // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index e27e0d52405..886d945b144 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -194,3 +194,5 @@ rust_dec_kernel_live_count rust_get_exchange_count_ptr rust_get_sched_tls_key swap_registers +rust_readdir +rust_opendir \ No newline at end of file