1#![deny(missing_docs)]
2mod error;
5
6pub mod ext {
8 pub use crate::model::ext::MachoExt;
9}
10pub mod format;
12mod mapped;
13pub mod model;
15
16pub use crate::error::{ContextFrame, OffsetSpan, ParseError, ParseErrorKind, ParseResult};
17pub use crate::format::{
18 ParseLimits, ParseMode, ParseOptions, ParseOutcome, parse, parse_with_options,
19};
20
21pub use format::load_commands::parse_load_commands;
22pub use mapped::{
23 FileRvaMapping, MappedImageReader, MaterializationLimits, MaterializedImage,
24 materialize_mapped_image,
25};
26pub use model::load_command::{LoadCommand, format_uuid};
27pub use model::macho_file::MachoFile;
28pub use model::section::Section;
29pub use model::symbol::{Symbol, SymbolTable};
30pub use model::{SelectedImage, SelectionKey};
31
32pub fn probe(data: &[u8]) -> bool {
37 let Some(magic) = data.get(..4) else {
38 return false;
39 };
40 matches!(
41 magic,
42 [0xfe, 0xed, 0xfa, 0xce]
43 | [0xce, 0xfa, 0xed, 0xfe]
44 | [0xfe, 0xed, 0xfa, 0xcf]
45 | [0xcf, 0xfa, 0xed, 0xfe]
46 | [0xca, 0xfe, 0xba, 0xbe]
47 | [0xbe, 0xba, 0xfe, 0xca]
48 | [0xca, 0xfe, 0xba, 0xbf]
49 | [0xbf, 0xba, 0xfe, 0xca]
50 )
51}
52
53#[cfg(test)]
54mod probe_tests {
55 #[test]
56 fn probe_recognizes_truncated_thin_and_fat_headers() {
57 assert!(super::probe(&0xfeed_facfu32.to_be_bytes()));
58 assert!(super::probe(&0xcafe_babeu32.to_be_bytes()));
59 assert!(!super::probe(b"ELF!"));
60 assert!(!super::probe(&[0xfe, 0xed, 0xfa]));
61 }
62}