From 92ad7b44cb194a90d353a7f2d05ec5b8faad1365 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Mon, 8 May 2023 16:42:42 +1000 Subject: [PATCH] read/wasm: add support for wasm64 Also add test files for globals. --- .../testfiles/wasm/global-wasm32.objdump | 38 ++++++++++++++++++ .../wasm/global-wasm64-import.objdump | 38 ++++++++++++++++++ .../testfiles/wasm/global-wasm64.objdump | 39 +++++++++++++++++++ src/common.rs | 2 + src/read/wasm.rs | 22 ++++++++--- testfiles | 2 +- 6 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 crates/examples/testfiles/wasm/global-wasm32.objdump create mode 100644 crates/examples/testfiles/wasm/global-wasm64-import.objdump create mode 100644 crates/examples/testfiles/wasm/global-wasm64.objdump diff --git a/crates/examples/testfiles/wasm/global-wasm32.objdump b/crates/examples/testfiles/wasm/global-wasm32.objdump new file mode 100644 index 00000000..6523af27 --- /dev/null +++ b/crates/examples/testfiles/wasm/global-wasm32.objdump @@ -0,0 +1,38 @@ +Format: Wasm Little-endian 32-bit +Kind: Unknown +Architecture: Wasm32 +Flags: None +Relative Address Base: 0 +Entry Address: 0 +1: Section { name: "", address: 0, size: 8, align: 1, kind: Metadata, flags: None } +2: Section { name: "", address: 0, size: 13, align: 1, kind: Linker, flags: None } +3: Section { name: "", address: 0, size: 3, align: 1, kind: Metadata, flags: None } +5: Section { name: "", address: 0, size: 3, align: 1, kind: UninitializedData, flags: None } +6: Section { name: "", address: 0, size: 4b, align: 1, kind: Data, flags: None } +7: Section { name: "", address: 0, size: bd, align: 1, kind: Linker, flags: None } +10: Section { name: "", address: 0, size: 38, align: 1, kind: Text, flags: None } +11: Section { name: "", address: 0, size: f, align: 1, kind: Data, flags: None } +0: Section { name: "name", address: 0, size: 48, align: 1, kind: Other, flags: None } +0: Section { name: "producers", address: 0, size: 5c, align: 1, kind: Other, flags: None } +0: Section { name: "target_features", address: 0, size: 1c, align: 1, kind: Other, flags: None } + +Symbols +0: Symbol { name: "env", address: 0, size: 0, kind: File, section: None, scope: Dynamic, weak: false, flags: None } +1: Symbol { name: "console_log", address: 0, size: 0, kind: Text, section: Undefined, scope: Dynamic, weak: false, flags: None } +2: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +3: Symbol { name: "memory", address: 0, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +4: Symbol { name: "__wasm_call_ctors", address: 2, size: 2, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +5: Symbol { name: "print", address: 5, size: 33, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +6: Symbol { name: "global1", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +7: Symbol { name: "global2", address: 404, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +8: Symbol { name: "__dso_handle", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +9: Symbol { name: "__data_end", address: 408, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +10: Symbol { name: "__stack_low", address: 410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +11: Symbol { name: "__stack_high", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +12: Symbol { name: "__global_base", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +13: Symbol { name: "__heap_base", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +14: Symbol { name: "__heap_end", address: 20000, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +15: Symbol { name: "__memory_base", address: 0, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +16: Symbol { name: "__table_base", address: 1, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } + +Dynamic symbols diff --git a/crates/examples/testfiles/wasm/global-wasm64-import.objdump b/crates/examples/testfiles/wasm/global-wasm64-import.objdump new file mode 100644 index 00000000..efbf85bd --- /dev/null +++ b/crates/examples/testfiles/wasm/global-wasm64-import.objdump @@ -0,0 +1,38 @@ +Format: Wasm Little-endian 64-bit +Kind: Unknown +Architecture: Wasm64 +Flags: None +Relative Address Base: 0 +Entry Address: 0 +1: Section { name: "", address: 0, size: 8, align: 1, kind: Metadata, flags: None } +2: Section { name: "", address: 0, size: 21, align: 1, kind: Linker, flags: None } +3: Section { name: "", address: 0, size: 3, align: 1, kind: Metadata, flags: None } +6: Section { name: "", address: 0, size: 50, align: 1, kind: Data, flags: None } +7: Section { name: "", address: 0, size: c5, align: 1, kind: Linker, flags: None } +10: Section { name: "", address: 0, size: 48, align: 1, kind: Text, flags: None } +11: Section { name: "", address: 0, size: f, align: 1, kind: Data, flags: None } +0: Section { name: "name", address: 0, size: 48, align: 1, kind: Other, flags: None } +0: Section { name: "producers", address: 0, size: 5c, align: 1, kind: Other, flags: None } +0: Section { name: "target_features", address: 0, size: 26, align: 1, kind: Other, flags: None } + +Symbols +0: Symbol { name: "env", address: 0, size: 0, kind: File, section: None, scope: Dynamic, weak: false, flags: None } +1: Symbol { name: "memory", address: 0, size: 0, kind: Data, section: Undefined, scope: Dynamic, weak: false, flags: None } +2: Symbol { name: "console_log", address: 0, size: 0, kind: Text, section: Undefined, scope: Dynamic, weak: false, flags: None } +3: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +4: Symbol { name: "__wasm_call_ctors", address: 2, size: 2, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +5: Symbol { name: "print", address: 5, size: 43, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +6: Symbol { name: "global1", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +7: Symbol { name: "global2", address: 404, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +8: Symbol { name: "__dso_handle", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +9: Symbol { name: "__data_end", address: 408, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +10: Symbol { name: "__stack_low", address: 410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +11: Symbol { name: "__stack_high", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +12: Symbol { name: "__global_base", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +13: Symbol { name: "__heap_base", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +14: Symbol { name: "__heap_end", address: 20000, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +15: Symbol { name: "__memory_base", address: 0, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +16: Symbol { name: "__table_base", address: 1, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +17: Symbol { name: "__table_base32", address: 1, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } + +Dynamic symbols diff --git a/crates/examples/testfiles/wasm/global-wasm64.objdump b/crates/examples/testfiles/wasm/global-wasm64.objdump new file mode 100644 index 00000000..067da2e4 --- /dev/null +++ b/crates/examples/testfiles/wasm/global-wasm64.objdump @@ -0,0 +1,39 @@ +Format: Wasm Little-endian 64-bit +Kind: Unknown +Architecture: Wasm64 +Flags: None +Relative Address Base: 0 +Entry Address: 0 +1: Section { name: "", address: 0, size: 8, align: 1, kind: Metadata, flags: None } +2: Section { name: "", address: 0, size: 13, align: 1, kind: Linker, flags: None } +3: Section { name: "", address: 0, size: 3, align: 1, kind: Metadata, flags: None } +5: Section { name: "", address: 0, size: 3, align: 1, kind: UninitializedData, flags: None } +6: Section { name: "", address: 0, size: 50, align: 1, kind: Data, flags: None } +7: Section { name: "", address: 0, size: ce, align: 1, kind: Linker, flags: None } +10: Section { name: "", address: 0, size: 48, align: 1, kind: Text, flags: None } +11: Section { name: "", address: 0, size: f, align: 1, kind: Data, flags: None } +0: Section { name: "name", address: 0, size: 48, align: 1, kind: Other, flags: None } +0: Section { name: "producers", address: 0, size: 5c, align: 1, kind: Other, flags: None } +0: Section { name: "target_features", address: 0, size: 26, align: 1, kind: Other, flags: None } + +Symbols +0: Symbol { name: "env", address: 0, size: 0, kind: File, section: None, scope: Dynamic, weak: false, flags: None } +1: Symbol { name: "console_log", address: 0, size: 0, kind: Text, section: Undefined, scope: Dynamic, weak: false, flags: None } +2: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +3: Symbol { name: "memory", address: 0, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +4: Symbol { name: "__wasm_call_ctors", address: 2, size: 2, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +5: Symbol { name: "print", address: 5, size: 43, kind: Text, section: Section(SectionIndex(a)), scope: Dynamic, weak: false, flags: None } +6: Symbol { name: "global1", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +7: Symbol { name: "global2", address: 404, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +8: Symbol { name: "__dso_handle", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +9: Symbol { name: "__data_end", address: 408, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +10: Symbol { name: "__stack_low", address: 410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +11: Symbol { name: "__stack_high", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +12: Symbol { name: "__global_base", address: 400, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +13: Symbol { name: "__heap_base", address: 10410, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +14: Symbol { name: "__heap_end", address: 20000, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +15: Symbol { name: "__memory_base", address: 0, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +16: Symbol { name: "__table_base", address: 1, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } +17: Symbol { name: "__table_base32", address: 1, size: 0, kind: Data, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: None } + +Dynamic symbols diff --git a/src/common.rs b/src/common.rs index 9d946185..7d789a71 100644 --- a/src/common.rs +++ b/src/common.rs @@ -27,6 +27,7 @@ pub enum Architecture { Sbf, Sparc64, Wasm32, + Wasm64, Xtensa, } @@ -58,6 +59,7 @@ impl Architecture { Architecture::Sbf => Some(AddressSize::U64), Architecture::Sparc64 => Some(AddressSize::U64), Architecture::Wasm32 => Some(AddressSize::U32), + Architecture::Wasm64 => Some(AddressSize::U64), Architecture::Xtensa => Some(AddressSize::U32), } } diff --git a/src/read/wasm.rs b/src/read/wasm.rs index 4cad57af..b950ef2b 100644 --- a/src/read/wasm.rs +++ b/src/read/wasm.rs @@ -42,6 +42,7 @@ const MAX_SECTION_ID: usize = SectionId::DataCount as usize; #[derive(Debug)] pub struct WasmFile<'data, R = &'data [u8]> { data: &'data [u8], + has_memory64: bool, // All sections, including custom sections. sections: Vec>, // Indices into `sections` of sections with a non-zero id. @@ -84,6 +85,7 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { let mut file = WasmFile { data, + has_memory64: false, sections: Vec::new(), id_sections: Default::default(), has_debug_symbols: false, @@ -141,9 +143,11 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { imported_funcs_count += 1; SymbolKind::Text } - wp::TypeRef::Table(_) - | wp::TypeRef::Memory(_) - | wp::TypeRef::Global(_) => SymbolKind::Data, + wp::TypeRef::Memory(memory) => { + file.has_memory64 |= memory.memory64; + SymbolKind::Data + } + wp::TypeRef::Table(_) | wp::TypeRef::Global(_) => SymbolKind::Data, wp::TypeRef::Tag(_) => SymbolKind::Unknown, }; @@ -167,6 +171,10 @@ impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { } wp::Payload::MemorySection(section) => { file.add_section(SectionId::Memory, section.range(), ""); + for memory in section { + let memory = memory.read_error("Couldn't read a memory item")?; + file.has_memory64 |= memory.memory64; + } } wp::Payload::GlobalSection(section) => { file.add_section(SectionId::Global, section.range(), ""); @@ -372,7 +380,11 @@ where #[inline] fn architecture(&self) -> Architecture { - Architecture::Wasm32 + if self.has_memory64 { + Architecture::Wasm64 + } else { + Architecture::Wasm32 + } } #[inline] @@ -382,7 +394,7 @@ where #[inline] fn is_64(&self) -> bool { - false + self.has_memory64 } fn kind(&self) -> ObjectKind { diff --git a/testfiles b/testfiles index 7794059d..0bd0f083 160000 --- a/testfiles +++ b/testfiles @@ -1 +1 @@ -Subproject commit 7794059d3ae288e4cebc658cea39a41c0d6aa405 +Subproject commit 0bd0f08374ad21385687ce244c218f53733de77c