Skip to content

Commit

Permalink
auto merge of #8596 : vadimcn/rust/master, r=alexcrichton
Browse files Browse the repository at this point in the history
This resolves issue #908.  

Notable changes:
-  On Windows, LLVM integrated assembler emits bad stack unwind tables when segmented stacks are enabled.  However, unwind info directives in the assembly output are correct, so we generate assembly first and then run it through an external assembler, just like it is already done for Android builds.

- Linker is invoked  via "g++" command instead of "gcc": g++ passes the appropriate magic parameters to the linker, which ensure correct registration of stack unwind tables in dynamic libraries.
  • Loading branch information
bors committed Aug 23, 2013
2 parents 6f70377 + 651f382 commit 9e1e152
Show file tree
Hide file tree
Showing 46 changed files with 94 additions and 166 deletions.
18 changes: 9 additions & 9 deletions src/libextra/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ mod tests {
}
}

#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_arc_condvar_poison() {
unsafe {
let arc = ~MutexArc::new(1);
Expand All @@ -636,7 +636,7 @@ mod tests {
}
}
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_mutex_arc_poison() {
unsafe {
let arc = ~MutexArc::new(1);
Expand All @@ -651,7 +651,7 @@ mod tests {
}
}
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
pub fn test_mutex_arc_unwrap_poison() {
let arc = MutexArc::new(1);
let arc2 = ~(&arc).clone();
Expand All @@ -668,7 +668,7 @@ mod tests {
let one = arc.unwrap();
assert!(one == 1);
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_rw_arc_poison_wr() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand All @@ -681,7 +681,7 @@ mod tests {
assert_eq!(*one, 1);
}
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_rw_arc_poison_ww() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand All @@ -694,7 +694,7 @@ mod tests {
assert_eq!(*one, 1);
}
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_rw_arc_poison_dw() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand All @@ -709,7 +709,7 @@ mod tests {
assert_eq!(*one, 1);
}
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rw_arc_no_poison_rr() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand All @@ -722,7 +722,7 @@ mod tests {
assert_eq!(*one, 1);
}
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rw_arc_no_poison_rw() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand All @@ -735,7 +735,7 @@ mod tests {
assert_eq!(*one, 1);
}
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rw_arc_no_poison_dr() {
let arc = ~RWArc::new(1);
let arc2 = (*arc).clone();
Expand Down
1 change: 0 additions & 1 deletion src/libextra/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ fn test_arena_destructors() {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_arena_destructors_fail() {
let arena = Arena::new();
// Put some stuff in the arena.
Expand Down
2 changes: 0 additions & 2 deletions src/libextra/c_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_overrun_get() {
let cv = malloc(16u as size_t);

Expand All @@ -194,7 +193,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_overrun_set() {
let cv = malloc(16u as size_t);

Expand Down
2 changes: 0 additions & 2 deletions src/libextra/flatpipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -967,12 +967,10 @@ mod test {
}

#[test]
#[ignore(cfg(windows))]
fn test_try_recv_none4_reader() {
test_try_recv_none4(reader_port_loader);
}
#[test]
#[ignore(cfg(windows))]
fn test_try_recv_none4_pipe() {
test_try_recv_none4(pipe_port_loader);
}
Expand Down
1 change: 0 additions & 1 deletion src/libextra/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ mod test {

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_futurefail() {
let mut f = spawn(|| fail!());
let _x: ~str = f.get();
Expand Down
3 changes: 0 additions & 3 deletions src/libextra/priority_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_empty_pop() { let mut heap = PriorityQueue::new::<int>(); heap.pop(); }

#[test]
Expand All @@ -349,7 +348,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_empty_top() { let empty = PriorityQueue::new::<int>(); empty.top(); }

#[test]
Expand All @@ -360,7 +358,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); }

#[test]
Expand Down
24 changes: 12 additions & 12 deletions src/libextra/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ mod tests {
assert!(!cond.signal());
}
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_mutex_killed_simple() {
// Mutex must get automatically unlocked if failed/killed within.
let m = ~Mutex::new();
Expand All @@ -937,7 +937,7 @@ mod tests {
do m.lock { }
}
#[ignore(reason = "linked failure")]
#[test] #[ignore(cfg(windows))]
#[test]
fn test_mutex_killed_cond() {
// Getting killed during cond wait must not corrupt the mutex while
// unwinding (e.g. double unlock).
Expand All @@ -964,7 +964,7 @@ mod tests {
}
}
#[ignore(reason = "linked failure")]
#[test] #[ignore(cfg(windows))]
#[test]
fn test_mutex_killed_broadcast() {
use std::unstable::finally::Finally;

Expand Down Expand Up @@ -1024,7 +1024,7 @@ mod tests {
cond.wait();
}
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_mutex_different_conds() {
let result = do task::try {
let m = ~Mutex::new_with_condvars(2);
Expand All @@ -1045,7 +1045,7 @@ mod tests {
};
assert!(result.is_err());
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_mutex_no_condvars() {
let result = do task::try {
let m = ~Mutex::new_with_condvars(0);
Expand Down Expand Up @@ -1275,7 +1275,7 @@ mod tests {
test_rwlock_cond_broadcast_helper(12, false, true);
test_rwlock_cond_broadcast_helper(12, false, false);
}
#[cfg(test)] #[ignore(cfg(windows))]
#[cfg(test)]
fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
// Mutex must get automatically unlocked if failed/killed within.
let x = ~RWLock::new();
Expand All @@ -1290,23 +1290,23 @@ mod tests {
// child task must have finished by the time try returns
do lock_rwlock_in_mode(x, mode2) { }
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rwlock_reader_killed_writer() {
rwlock_kill_helper(Read, Write);
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rwlock_writer_killed_reader() {
rwlock_kill_helper(Write,Read );
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rwlock_reader_killed_reader() {
rwlock_kill_helper(Read, Read );
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rwlock_writer_killed_writer() {
rwlock_kill_helper(Write,Write);
}
#[test] #[ignore(cfg(windows))]
#[test]
fn test_rwlock_kill_downgrader() {
rwlock_kill_helper(Downgrade, Read);
rwlock_kill_helper(Read, Downgrade);
Expand All @@ -1321,7 +1321,7 @@ mod tests {
rwlock_kill_helper(Downgrade, DowngradeRead);
rwlock_kill_helper(Downgrade, DowngradeRead);
}
#[test] #[should_fail] #[ignore(cfg(windows))]
#[test] #[should_fail]
fn test_rwlock_downgrade_cant_swap() {
// Tests that you can't downgrade with a different rwlock's token.
let x = ~RWLock::new();
Expand Down
1 change: 0 additions & 1 deletion src/libextra/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,6 @@ mod tests {
}

#[test]
#[ignore(cfg(windows))]
fn test_should_fail() {
fn f() { fail!(); }
let desc = TestDescAndFn {
Expand Down
41 changes: 19 additions & 22 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,16 +419,8 @@ pub mod write {
}
}

pub fn run_ndk(sess: Session, assembly: &Path, object: &Path) {
let cc_prog: ~str = match &sess.opts.android_cross_path {
&Some(ref path) => {
fmt!("%s/bin/arm-linux-androideabi-gcc", *path)
}
&None => {
sess.fatal("need Android NDK path for building \
(--android-cross-path)")
}
};
pub fn run_assembler(sess: Session, assembly: &Path, object: &Path) {
let cc_prog = super::get_cc_prog(sess);

let cc_args = ~[
~"-c",
Expand Down Expand Up @@ -813,18 +805,14 @@ pub fn output_dll_filename(os: session::os, lm: LinkMeta) -> ~str {
fmt!("%s%s-%s-%s%s", dll_prefix, lm.name, lm.extras_hash, lm.vers, dll_suffix)
}

// If the user wants an exe generated we need to invoke
// cc to link the object file with some libs
pub fn link_binary(sess: Session,
obj_filename: &Path,
out_filename: &Path,
lm: LinkMeta) {
pub fn get_cc_prog(sess: Session) -> ~str {
// In the future, FreeBSD will use clang as default compiler.
// It would be flexible to use cc (system's default C compiler)
// instead of hard-coded gcc.
// For win32, there is no cc command,
// so we add a condition to make it use gcc.
let cc_prog: ~str = match sess.opts.linker {
// For win32, there is no cc command, so we add a condition to make it use g++.
// We use g++ rather than gcc because it automatically adds linker options required
// for generation of dll modules that correctly register stack unwind tables.
match sess.opts.linker {
Some(ref linker) => linker.to_str(),
None => match sess.targ_cfg.os {
session::os_android =>
Expand All @@ -837,12 +825,21 @@ pub fn link_binary(sess: Session,
(--android-cross-path)")
}
},
session::os_win32 => ~"gcc",
session::os_win32 => ~"g++",
_ => ~"cc"
}
};
// The invocations of cc share some flags across platforms
}
}

// If the user wants an exe generated we need to invoke
// cc to link the object file with some libs
pub fn link_binary(sess: Session,
obj_filename: &Path,
out_filename: &Path,
lm: LinkMeta) {

let cc_prog = get_cc_prog(sess);
// The invocations of cc share some flags across platforms

let output = if *sess.building_library {
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
Expand Down
20 changes: 15 additions & 5 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,31 @@ pub fn phase_5_run_llvm_passes(sess: Session,
trans: &CrateTranslation,
outputs: &OutputFilenames) {

// NB: Android hack
if sess.targ_cfg.os == session::os_android &&
// On Windows, LLVM integrated assembler emits bad stack unwind tables when
// segmented stacks are enabled. However, unwind info directives in assembly
// output are OK, so we generate assembly first and then run it through
// an external assembler.
// Same for Android.
if (sess.targ_cfg.os == session::os_android ||
sess.targ_cfg.os == session::os_win32) &&
(sess.opts.output_type == link::output_type_object ||
sess.opts.output_type == link::output_type_exe) {
let output_type = link::output_type_assembly;
let obj_filename = outputs.obj_filename.with_filetype("s");
let asm_filename = outputs.obj_filename.with_filetype("s");

time(sess.time_passes(), ~"LLVM passes", ||
link::write::run_passes(sess,
trans.context,
trans.module,
output_type,
&obj_filename));
&asm_filename));

link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
link::write::run_assembler(sess, &asm_filename, &outputs.obj_filename);

// Remove assembly source unless --save-temps was specified
if !sess.opts.save_temps {
os::remove_file(&asm_filename);
}
} else {
time(sess.time_passes(), ~"LLVM passes", ||
link::write::run_passes(sess,
Expand Down
2 changes: 0 additions & 2 deletions src/libstd/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_with_ref_empty_fail() {
let c_str = unsafe { CString::new(ptr::null(), false) };
c_str.with_ref(|_| ());
Expand All @@ -306,7 +305,6 @@ mod tests {
}

#[test]
#[ignore(cfg(windows))]
fn test_to_c_str_fail() {
use c_str::null_byte::cond;

Expand Down
2 changes: 0 additions & 2 deletions src/libstd/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,13 @@ fn test_basic() {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_take_empty() {
let value_cell = Cell::new_empty::<~int>();
value_cell.take();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_put_back_non_empty() {
let value_cell = Cell::new(~10);
value_cell.put_back(~20);
Expand Down
1 change: 0 additions & 1 deletion src/libstd/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,6 @@ mod tests {

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_read_buffer_too_small() {
let path = &Path("tmp/lib-io-test-read-buffer-too-small.tmp");
// ensure the file exists
Expand Down
Loading

0 comments on commit 9e1e152

Please sign in to comment.