diff --git a/testfiles b/testfiles index 0bd0f083..86bf162a 160000 --- a/testfiles +++ b/testfiles @@ -1 +1 @@ -Subproject commit 0bd0f08374ad21385687ce244c218f53733de77c +Subproject commit 86bf162a75f9234313ae58ea30ca61901d0cce58 diff --git a/tests/read/coff.rs b/tests/read/coff.rs index dcf3b3c6..fe27201b 100644 --- a/tests/read/coff.rs +++ b/tests/read/coff.rs @@ -1,4 +1,6 @@ -use object::{pe, read, Object, ObjectSection}; +use object::coff::{self, ImportType}; +use object::read::{self, archive::ArchiveFile}; +use object::{pe, Architecture, Import, Object, ObjectSection}; use std::fs; use std::path::PathBuf; @@ -21,3 +23,110 @@ fn coff_extended_relocations() { let relocations = code_section.relocations().collect::>(); assert_eq!(relocations.len(), 65536); } + +#[test] +fn coff_imports() { + // for pretty assert messages. + #[derive(Debug, PartialEq, Eq)] + enum ImportName<'a> { + Name(&'a str), + Ordinal(u16), + } + fn import_name(from: coff::ImportName<'_>) -> ImportName<'_> { + match from { + coff::ImportName::Name(name) => ImportName::Name(std::str::from_utf8(name).unwrap()), + coff::ImportName::Ordinal(n) => ImportName::Ordinal(n), + } + } + + #[track_caller] + fn expect( + found: &coff::CoffImportFile<'_>, + expected: (Architecture, &str, &str, ImportName, ImportType), + ) { + let dll = std::str::from_utf8(found.dll()).unwrap(); + let symbol = std::str::from_utf8(found.symbol()).unwrap(); + let import = import_name(found.import()); + + assert_eq!(found.architecture(), expected.0); + assert_eq!(dll, expected.1, "Coff import dll name mismatch"); + assert_eq!(symbol, expected.2, "Coff import symbol name mismatch"); + assert_eq!(import, expected.3, "Coff import name mismatch"); + assert_eq!(found.import_type(), expected.4, "Coff import type mismatch"); + } + + let path_to_lib: PathBuf = ["testfiles", "coff", "import_msvc.lib"].iter().collect(); + + let mut imports = Vec::new(); + let contents = fs::read(&path_to_lib).expect("Could not read import_msvc.lib"); + let archive = ArchiveFile::parse(&contents[..]).expect("Could not parse import_msvc.lib"); + for member in archive.members() { + let member = member.expect("Could not read members from import_msvc.lib"); + if let Ok(data) = member.data(&contents[..]) { + if object::FileKind::parse(data) == Ok(object::FileKind::CoffImportFile) { + imports.push(coff::CoffImportFile::parse(data).unwrap()) + } + } + } + + expect( + &imports[0], + ( + Architecture::X86_64, + "test_x64.dll", + "foo_x64", + ImportName::Name("foo_x64"), + ImportType::Code, + ), + ); + expect( + &imports[1], + ( + Architecture::X86_64, + "test_x64.dll", + "bar_x64", + ImportName::Ordinal(1), + ImportType::Code, + ), + ); + expect( + &imports[2], + ( + Architecture::X86_64, + "test_x64.dll", + "FOO_x64", + ImportName::Name("FOO_x64"), + ImportType::Data, + ), + ); + expect( + &imports[3], + ( + Architecture::X86_64, + "test_x64.dll", + "BAR_x64", + ImportName::Name("BAR_x64"), + ImportType::Const, + ), + ); + expect( + &imports[4], + ( + Architecture::I386, + "test_x86.dll", + "_foo_x86", + ImportName::Name("foo_x86"), + ImportType::Code, + ), + ); + expect( + &imports[5], + ( + Architecture::Unknown, + "test_arm64ec.dll", + "#foo_arm64ec", + ImportName::Name("foo_arm64ec"), + ImportType::Code, + ), + ); +}