diff --git a/cargo-auditable/src/object_file.rs b/cargo-auditable/src/object_file.rs index d4997a9..e8b2e09 100644 --- a/cargo-auditable/src/object_file.rs +++ b/cargo-auditable/src/object_file.rs @@ -322,6 +322,28 @@ windows assert_eq!(result.architecture(), Architecture::X86_64); } + #[test] + fn test_create_object_file_windows_msvc_i686() { + let rustc_output = br#"debug_assertions +target_arch="x86" +target_endian="little" +target_env="msvc" +target_family="windows" +target_feature="fxsr" +target_feature="sse" +target_feature="sse2" +target_os="windows" +target_pointer_width="32" +target_vendor="pc" +windows +"#; + let target_triple = "i686-pc-windows-msvc"; + let target_info = parse_rustc_target_info(rustc_output); + let result = create_object_file(&target_info, target_triple).unwrap(); + assert_eq!(result.format(), BinaryFormat::Coff); + assert_eq!(result.architecture(), Architecture::I386); + } + #[test] fn test_create_object_file_windows_gnu() { let rustc_output = br#"debug_assertions diff --git a/cargo-auditable/src/platform_detection.rs b/cargo-auditable/src/platform_detection.rs index 26d7a72..ccbef38 100644 --- a/cargo-auditable/src/platform_detection.rs +++ b/cargo-auditable/src/platform_detection.rs @@ -22,6 +22,10 @@ pub fn is_32bit(target_info: &RustcTargetInfo) -> bool { key_equals(target_info, "target_pointer_width", "32") } +pub fn is_32bit_x86(target_info: &RustcTargetInfo) -> bool { + key_equals(target_info, "target_arch", "x86") +} + fn key_equals(target_info: &RustcTargetInfo, key: &str, value: &str) -> bool { target_info.get(key).map(|s| s.as_str()) == Some(value) } diff --git a/cargo-auditable/src/rustc_wrapper.rs b/cargo-auditable/src/rustc_wrapper.rs index 51ffba4..0ba4755 100644 --- a/cargo-auditable/src/rustc_wrapper.rs +++ b/cargo-auditable/src/rustc_wrapper.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ binary_file, collect_audit_data, - platform_detection::{is_apple, is_msvc, is_wasm}, + platform_detection::{is_32bit_x86, is_apple, is_msvc, is_wasm}, rustc_arguments::{self, should_embed_audit_data}, target_info, }; @@ -134,7 +134,14 @@ fn rustc_command_with_audit_data(rustc_path: &OsStr) -> Option { command.arg("-Clink-arg=-Wl,-u,_AUDITABLE_VERSION_INFO"); } } else if is_msvc(&target_info) { - command.arg("-Clink-arg=/INCLUDE:AUDITABLE_VERSION_INFO"); + // On x86 MSVC, the `object` crate's CoffI386 mangling adds a `_` + // prefix to global symbols, so the linker must reference the + // decorated name. + if is_32bit_x86(&target_info) { + command.arg("-Clink-arg=/INCLUDE:_AUDITABLE_VERSION_INFO"); + } else { + command.arg("-Clink-arg=/INCLUDE:AUDITABLE_VERSION_INFO"); + } } else if is_wasm(&target_info) { // We don't emit the symbol name in WASM, so nothing to do } else {