use metrowrap::assembler;
use metrowrap::workspace::{TempMode, Workspace};
use object::{self, Object, ObjectSection, SectionKind};
fn workspace() -> Workspace {
Workspace::new(TempMode::Normal).expect("workspace")
}
#[test]
fn test_assembler() {
let assembler = assembler::Assembler {
as_path: "mipsel-linux-gnu-as".into(),
as_march: "allegrex".into(),
as_mabi: "32".into(),
as_flags: vec!["-G0".into()],
macro_inc_path: Some("tests/data/macro.inc".into()),
};
let ws = workspace();
let asm_bytes = assembler
.assemble_file("tests/data/Add.s", ws.path())
.expect("asm");
assert!(asm_bytes.len() > 0);
let obj = object::File::parse(&*asm_bytes).expect("object");
let mut sections = obj.sections();
let null_section = sections.next().expect("NULL section");
assert!(
matches!(null_section.kind(), SectionKind::Metadata),
"NULL Section Kind: {null_section:?}"
);
assert_eq!(0, null_section.size());
assert_eq!(0, null_section.file_range().unwrap().0);
let text_section = sections.next().expect("PROGBITS section");
assert!(
matches!(text_section.kind(), SectionKind::Text),
"Text Section Kind: {text_section:?}"
);
assert_eq!(16, text_section.size());
assert_eq!(0x40, text_section.file_range().unwrap().0);
let data_section = sections.next().expect("PROGBITS section");
assert!(
matches!(data_section.kind(), SectionKind::Data),
"Data Section Kind: {text_section:?}"
);
assert_eq!(0, data_section.size());
assert_eq!(0x50, data_section.file_range().unwrap().0);
let bss_section = sections.next().expect("NOBITS section");
assert!(
matches!(bss_section.kind(), SectionKind::UninitializedData),
"BSS Section Kind: {text_section:?}"
);
assert_eq!(0, bss_section.size());
assert!(matches!(bss_section.file_range(), None));
let _reginfo_section = sections.next().expect("MIPS_REGINFO section");
let _mips_abiflags_section = sections.next().expect("MIPS_ABIFLAGS section");
let _pdr_section = sections.next().expect("PROGBITS section");
let _gnu_attributes_section = sections.next().expect("GNU_ATTRIBUTES section");
let _symtab_section = sections.next().expect("SYMTAB section");
let _strtab_section = sections.next().expect("STRTAB section");
let _shstrtab_section = sections.next().expect("STRTAB section");
let no_section = sections.next();
assert!(
matches!(no_section, None),
"expected none, got: {no_section:?}"
);
}
#[test]
fn test_assembler_macro_inc_no_parent_dir() {
let assembler = assembler::Assembler {
as_path: "mipsel-linux-gnu-as".into(),
as_march: "allegrex".into(),
as_mabi: "32".into(),
as_flags: vec!["-G0".into()],
macro_inc_path: Some("macro.inc".into()), };
let ws = workspace();
let result = assembler.assemble_data(
std::fs::File::open("tests/data/NoMacros.s").expect("NoMacros.s"),
ws.path(),
);
assert!(result.is_ok(), "unexpected error: {result:?}");
}
#[test]
fn test_assembler_failure() {
let assembler = assembler::Assembler {
as_path: "mipsel-linux-gnu-as".into(),
as_march: "allegrex".into(),
as_mabi: "32".into(),
as_flags: vec!["-G0".into()],
macro_inc_path: None,
};
let ws = workspace();
let bad_asm = b"this is not valid assembly\n".as_ref();
let result = assembler.assemble_data(bad_asm, ws.path());
assert!(
matches!(result, Err(metrowrap::error::MWError::Assembler(_))),
"expected Assembler error, got: {result:?}"
);
}