| 
 | 1 | +//! Smoke test to check that that symbols of `extern "C"` functions and `#[no_mangle]` rust  | 
 | 2 | +//! functions:  | 
 | 3 | +//!  | 
 | 4 | +//! 1. Are externally visible in the dylib produced.  | 
 | 5 | +//! 2. That the symbol visibility is orthogonal to the Rust nameres visibility of the functions  | 
 | 6 | +//!    involved.  | 
 | 7 | +
  | 
 | 8 | +//@ ignore-cross-compile  | 
 | 9 | + | 
 | 10 | +use run_make_support::object::{self, Object, ObjectSection, ObjectSymbol};  | 
 | 11 | +use run_make_support::{dynamic_lib_name, is_darwin, is_msvc, path, rfs, rustc};  | 
 | 12 | + | 
 | 13 | +fn main() {  | 
 | 14 | +    let dylib = dynamic_lib_name("dylib");  | 
 | 15 | +    rustc().input("dylib.rs").output(&dylib).arg("-Cprefer-dynamic").run();  | 
 | 16 | +    let mut fun1_count = 0; // #[no_mangle] pub extern "C" fn fun1() {}  | 
 | 17 | +    let mut fun2_count = 0; // #[no_mangle] extern "C" fn fun2() {}  | 
 | 18 | +    let mut fun3_count = 0; // mod foo { #[no_mangle] pub extern "C" fn fun3() {} }  | 
 | 19 | +    let mut fun4_count = 0; // pub mod bar { #[no_mangle] pub extern "C" fn fun4() {} }  | 
 | 20 | +    let mut fun5_count = 0; // #[no_mangle] pub fn fun5() {}  | 
 | 21 | +    let mut fun6_count = 0; // #[no_mangle] fn fun6() {}  | 
 | 22 | + | 
 | 23 | +    let p = if is_msvc() { path(dylib) } else { path(dylib) };  | 
 | 24 | +    let blob = rfs::read(&p);  | 
 | 25 | +    let file = object::File::parse(&*blob).unwrap();  | 
 | 26 | + | 
 | 27 | +    for export in file.exports().unwrap() {  | 
 | 28 | +        let sym_name = export.name();  | 
 | 29 | +        let sym_name = String::from_utf8_lossy(sym_name);  | 
 | 30 | +        match sym_name.as_ref() {  | 
 | 31 | +            "fun1" => fun1_count += 1,  | 
 | 32 | +            "fun2" => fun2_count += 1,  | 
 | 33 | +            "fun3" => fun3_count += 1,  | 
 | 34 | +            "fun4" => fun4_count += 1,  | 
 | 35 | +            "fun5" => fun5_count += 1,  | 
 | 36 | +            "fun6" => fun6_count += 1,  | 
 | 37 | +            // Mach-O states that all exported symbols should have an underscore as prefix. At the  | 
 | 38 | +            // same time dlsym will implicitly add it, so outside of compilers, linkers and people  | 
 | 39 | +            // writing assembly, nobody needs to be aware of this.  | 
 | 40 | +            "_fun1" if is_darwin() => fun1_count += 1,  | 
 | 41 | +            "_fun2" if is_darwin() => fun2_count += 1,  | 
 | 42 | +            "_fun3" if is_darwin() => fun3_count += 1,  | 
 | 43 | +            "_fun4" if is_darwin() => fun4_count += 1,  | 
 | 44 | +            "_fun5" if is_darwin() => fun5_count += 1,  | 
 | 45 | +            "_fun6" if is_darwin() => fun6_count += 1,  | 
 | 46 | +            _ => {}  | 
 | 47 | +        }  | 
 | 48 | +    }  | 
 | 49 | +    assert_eq!(fun1_count, 1);  | 
 | 50 | +    assert_eq!(fun2_count, 1);  | 
 | 51 | +    assert_eq!(fun3_count, 1);  | 
 | 52 | +    assert_eq!(fun4_count, 1);  | 
 | 53 | +    assert_eq!(fun5_count, 1);  | 
 | 54 | +    assert_eq!(fun6_count, 1);  | 
 | 55 | +}  | 
0 commit comments