Skip to content

Commit

Permalink
Work around linkage bug cross-compiling from x86_64-apple-darwin to i…
Browse files Browse the repository at this point in the history
…686-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.
  • Loading branch information
brson committed Mar 13, 2013
1 parent b60c3bf commit 0ad3a11
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 37 deletions.
54 changes: 18 additions & 36 deletions src/libcore/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion src/libuv
Submodule libuv updated 1 files
+4 −1 src/unix/linux-syscalls.h
27 changes: 27 additions & 0 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,33 @@ rust_dec_kernel_live_count() {
task->kernel->dec_live_count();
}

#ifndef _WIN32
#include <sys/types.h>
#include <dirent.h>

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++
Expand Down
2 changes: 2 additions & 0 deletions src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 0ad3a11

Please sign in to comment.