diff options
author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/object/src/read/wasm.rs | |
parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip |
Deleted vendor folder
Diffstat (limited to 'vendor/object/src/read/wasm.rs')
-rw-r--r-- | vendor/object/src/read/wasm.rs | 966 |
1 files changed, 0 insertions, 966 deletions
diff --git a/vendor/object/src/read/wasm.rs b/vendor/object/src/read/wasm.rs deleted file mode 100644 index 4d034bc..0000000 --- a/vendor/object/src/read/wasm.rs +++ /dev/null @@ -1,966 +0,0 @@ -//! Support for reading Wasm files. -//! -//! [`WasmFile`] implements the [`Object`] trait for Wasm files. -use alloc::boxed::Box; -use alloc::vec::Vec; -use core::marker::PhantomData; -use core::ops::Range; -use core::{slice, str}; -use wasmparser as wp; - -use crate::read::{ - self, Architecture, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, - Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ObjectSection, - ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result, - SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, - SymbolScope, SymbolSection, -}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(usize)] -enum SectionId { - Custom = 0, - Type = 1, - Import = 2, - Function = 3, - Table = 4, - Memory = 5, - Global = 6, - Export = 7, - Start = 8, - Element = 9, - Code = 10, - Data = 11, - DataCount = 12, -} -// Update this constant when adding new section id: -const MAX_SECTION_ID: usize = SectionId::DataCount as usize; - -/// A WebAssembly object file. -#[derive(Debug)] -pub struct WasmFile<'data, R = &'data [u8]> { - data: &'data [u8], - has_memory64: bool, - // All sections, including custom sections. - sections: Vec<SectionHeader<'data>>, - // Indices into `sections` of sections with a non-zero id. - id_sections: Box<[Option<usize>; MAX_SECTION_ID + 1]>, - // Whether the file has DWARF information. - has_debug_symbols: bool, - // Symbols collected from imports, exports, code and name sections. - symbols: Vec<WasmSymbolInternal<'data>>, - // Address of the function body for the entry point. - entry: u64, - marker: PhantomData<R>, -} - -#[derive(Debug)] -struct SectionHeader<'data> { - id: SectionId, - range: Range<usize>, - name: &'data str, -} - -#[derive(Clone)] -enum LocalFunctionKind { - Unknown, - Exported { symbol_ids: Vec<u32> }, - Local { symbol_id: u32 }, -} - -impl<T> ReadError<T> for wasmparser::Result<T> { - fn read_error(self, error: &'static str) -> Result<T> { - self.map_err(|_| Error(error)) - } -} - -impl<'data, R: ReadRef<'data>> WasmFile<'data, R> { - /// Parse the raw wasm data. - pub fn parse(data: R) -> Result<Self> { - let len = data.len().read_error("Unknown Wasm file size")?; - let data = data.read_bytes_at(0, len).read_error("Wasm read failed")?; - let parser = wp::Parser::new(0).parse_all(data); - - let mut file = WasmFile { - data, - has_memory64: false, - sections: Vec::new(), - id_sections: Default::default(), - has_debug_symbols: false, - symbols: Vec::new(), - entry: 0, - marker: PhantomData, - }; - - let mut main_file_symbol = Some(WasmSymbolInternal { - name: "", - address: 0, - size: 0, - kind: SymbolKind::File, - section: SymbolSection::None, - scope: SymbolScope::Compilation, - }); - - let mut imported_funcs_count = 0; - let mut local_func_kinds = Vec::new(); - let mut entry_func_id = None; - let mut code_range_start = 0; - let mut code_func_index = 0; - // One-to-one mapping of globals to their value (if the global is a constant integer). - let mut global_values = Vec::new(); - - for payload in parser { - let payload = payload.read_error("Invalid Wasm section header")?; - - match payload { - wp::Payload::TypeSection(section) => { - file.add_section(SectionId::Type, section.range(), ""); - } - wp::Payload::ImportSection(section) => { - file.add_section(SectionId::Import, section.range(), ""); - let mut last_module_name = None; - - for import in section { - let import = import.read_error("Couldn't read an import item")?; - let module_name = import.module; - - if last_module_name != Some(module_name) { - file.symbols.push(WasmSymbolInternal { - name: module_name, - address: 0, - size: 0, - kind: SymbolKind::File, - section: SymbolSection::None, - scope: SymbolScope::Dynamic, - }); - last_module_name = Some(module_name); - } - - let kind = match import.ty { - wp::TypeRef::Func(_) => { - imported_funcs_count += 1; - SymbolKind::Text - } - wp::TypeRef::Memory(memory) => { - file.has_memory64 |= memory.memory64; - SymbolKind::Data - } - wp::TypeRef::Table(_) | wp::TypeRef::Global(_) => SymbolKind::Data, - wp::TypeRef::Tag(_) => SymbolKind::Unknown, - }; - - file.symbols.push(WasmSymbolInternal { - name: import.name, - address: 0, - size: 0, - kind, - section: SymbolSection::Undefined, - scope: SymbolScope::Dynamic, - }); - } - } - wp::Payload::FunctionSection(section) => { - file.add_section(SectionId::Function, section.range(), ""); - local_func_kinds = - vec![LocalFunctionKind::Unknown; section.into_iter().count()]; - } - wp::Payload::TableSection(section) => { - file.add_section(SectionId::Table, section.range(), ""); - } - 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(), ""); - for global in section { - let global = global.read_error("Couldn't read a global item")?; - let mut address = None; - if !global.ty.mutable { - // There should be exactly one instruction. - let init = global.init_expr.get_operators_reader().read(); - address = match init.read_error("Couldn't read a global init expr")? { - wp::Operator::I32Const { value } => Some(value as u64), - wp::Operator::I64Const { value } => Some(value as u64), - _ => None, - }; - } - global_values.push(address); - } - } - wp::Payload::ExportSection(section) => { - file.add_section(SectionId::Export, section.range(), ""); - if let Some(main_file_symbol) = main_file_symbol.take() { - file.symbols.push(main_file_symbol); - } - - for export in section { - let export = export.read_error("Couldn't read an export item")?; - - let (kind, section_idx) = match export.kind { - wp::ExternalKind::Func => { - if let Some(local_func_id) = - export.index.checked_sub(imported_funcs_count) - { - let local_func_kind = - &mut local_func_kinds[local_func_id as usize]; - if let LocalFunctionKind::Unknown = local_func_kind { - *local_func_kind = LocalFunctionKind::Exported { - symbol_ids: Vec::new(), - }; - } - let symbol_ids = match local_func_kind { - LocalFunctionKind::Exported { symbol_ids } => symbol_ids, - _ => unreachable!(), - }; - symbol_ids.push(file.symbols.len() as u32); - } - (SymbolKind::Text, SectionId::Code) - } - wp::ExternalKind::Table - | wp::ExternalKind::Memory - | wp::ExternalKind::Global => (SymbolKind::Data, SectionId::Data), - // TODO - wp::ExternalKind::Tag => continue, - }; - - // Try to guess the symbol address. Rust and C export a global containing - // the address in linear memory of the symbol. - let mut address = 0; - if export.kind == wp::ExternalKind::Global { - if let Some(&Some(x)) = global_values.get(export.index as usize) { - address = x; - } - } - - file.symbols.push(WasmSymbolInternal { - name: export.name, - address, - size: 0, - kind, - section: SymbolSection::Section(SectionIndex(section_idx as usize)), - scope: SymbolScope::Dynamic, - }); - } - } - wp::Payload::StartSection { func, range, .. } => { - file.add_section(SectionId::Start, range, ""); - entry_func_id = Some(func); - } - wp::Payload::ElementSection(section) => { - file.add_section(SectionId::Element, section.range(), ""); - } - wp::Payload::CodeSectionStart { range, .. } => { - code_range_start = range.start; - file.add_section(SectionId::Code, range, ""); - if let Some(main_file_symbol) = main_file_symbol.take() { - file.symbols.push(main_file_symbol); - } - } - wp::Payload::CodeSectionEntry(body) => { - let i = code_func_index; - code_func_index += 1; - - let range = body.range(); - - let address = range.start as u64 - code_range_start as u64; - let size = (range.end - range.start) as u64; - - if entry_func_id == Some(i as u32) { - file.entry = address; - } - - let local_func_kind = &mut local_func_kinds[i]; - match local_func_kind { - LocalFunctionKind::Unknown => { - *local_func_kind = LocalFunctionKind::Local { - symbol_id: file.symbols.len() as u32, - }; - file.symbols.push(WasmSymbolInternal { - name: "", - address, - size, - kind: SymbolKind::Text, - section: SymbolSection::Section(SectionIndex( - SectionId::Code as usize, - )), - scope: SymbolScope::Compilation, - }); - } - LocalFunctionKind::Exported { symbol_ids } => { - for symbol_id in core::mem::take(symbol_ids) { - let export_symbol = &mut file.symbols[symbol_id as usize]; - export_symbol.address = address; - export_symbol.size = size; - } - } - _ => unreachable!(), - } - } - wp::Payload::DataSection(section) => { - file.add_section(SectionId::Data, section.range(), ""); - } - wp::Payload::DataCountSection { range, .. } => { - file.add_section(SectionId::DataCount, range, ""); - } - wp::Payload::CustomSection(section) => { - let name = section.name(); - let size = section.data().len(); - let mut range = section.range(); - range.start = range.end - size; - file.add_section(SectionId::Custom, range, name); - if name == "name" { - for name in - wp::NameSectionReader::new(section.data(), section.data_offset()) - { - // TODO: Right now, ill-formed name subsections - // are silently ignored in order to maintain - // compatibility with extended name sections, which - // are not yet supported by the version of - // `wasmparser` currently used. - // A better fix would be to update `wasmparser` to - // the newest version, but this requires - // a major rewrite of this file. - if let Ok(wp::Name::Function(name_map)) = name { - for naming in name_map { - let naming = - naming.read_error("Couldn't read a function name")?; - if let Some(local_index) = - naming.index.checked_sub(imported_funcs_count) - { - if let LocalFunctionKind::Local { symbol_id } = - local_func_kinds[local_index as usize] - { - file.symbols[symbol_id as usize].name = naming.name; - } - } - } - } - } - } else if name.starts_with(".debug_") { - file.has_debug_symbols = true; - } - } - _ => {} - } - } - - Ok(file) - } - - fn add_section(&mut self, id: SectionId, range: Range<usize>, name: &'data str) { - let section = SectionHeader { id, range, name }; - self.id_sections[id as usize] = Some(self.sections.len()); - self.sections.push(section); - } -} - -impl<'data, R> read::private::Sealed for WasmFile<'data, R> {} - -impl<'data, 'file, R: ReadRef<'data>> Object<'data, 'file> for WasmFile<'data, R> -where - 'data: 'file, - R: 'file, -{ - type Segment = WasmSegment<'data, 'file, R>; - type SegmentIterator = WasmSegmentIterator<'data, 'file, R>; - type Section = WasmSection<'data, 'file, R>; - type SectionIterator = WasmSectionIterator<'data, 'file, R>; - type Comdat = WasmComdat<'data, 'file, R>; - type ComdatIterator = WasmComdatIterator<'data, 'file, R>; - type Symbol = WasmSymbol<'data, 'file>; - type SymbolIterator = WasmSymbolIterator<'data, 'file>; - type SymbolTable = WasmSymbolTable<'data, 'file>; - type DynamicRelocationIterator = NoDynamicRelocationIterator; - - #[inline] - fn architecture(&self) -> Architecture { - if self.has_memory64 { - Architecture::Wasm64 - } else { - Architecture::Wasm32 - } - } - - #[inline] - fn is_little_endian(&self) -> bool { - true - } - - #[inline] - fn is_64(&self) -> bool { - self.has_memory64 - } - - fn kind(&self) -> ObjectKind { - // TODO: check for `linking` custom section - ObjectKind::Unknown - } - - fn segments(&'file self) -> Self::SegmentIterator { - WasmSegmentIterator { file: self } - } - - fn section_by_name_bytes( - &'file self, - section_name: &[u8], - ) -> Option<WasmSection<'data, 'file, R>> { - self.sections() - .find(|section| section.name_bytes() == Ok(section_name)) - } - - fn section_by_index(&'file self, index: SectionIndex) -> Result<WasmSection<'data, 'file, R>> { - // TODO: Missing sections should return an empty section. - let id_section = self - .id_sections - .get(index.0) - .and_then(|x| *x) - .read_error("Invalid Wasm section index")?; - let section = self.sections.get(id_section).unwrap(); - Ok(WasmSection { - file: self, - section, - }) - } - - fn sections(&'file self) -> Self::SectionIterator { - WasmSectionIterator { - file: self, - sections: self.sections.iter(), - } - } - - fn comdats(&'file self) -> Self::ComdatIterator { - WasmComdatIterator { file: self } - } - - #[inline] - fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<WasmSymbol<'data, 'file>> { - let symbol = self - .symbols - .get(index.0) - .read_error("Invalid Wasm symbol index")?; - Ok(WasmSymbol { index, symbol }) - } - - fn symbols(&'file self) -> Self::SymbolIterator { - WasmSymbolIterator { - symbols: self.symbols.iter().enumerate(), - } - } - - fn symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> { - Some(WasmSymbolTable { - symbols: &self.symbols, - }) - } - - fn dynamic_symbols(&'file self) -> Self::SymbolIterator { - WasmSymbolIterator { - symbols: [].iter().enumerate(), - } - } - - #[inline] - fn dynamic_symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> { - None - } - - #[inline] - fn dynamic_relocations(&self) -> Option<NoDynamicRelocationIterator> { - None - } - - fn imports(&self) -> Result<Vec<Import<'data>>> { - // TODO: return entries in the import section - Ok(Vec::new()) - } - - fn exports(&self) -> Result<Vec<Export<'data>>> { - // TODO: return entries in the export section - Ok(Vec::new()) - } - - fn has_debug_symbols(&self) -> bool { - self.has_debug_symbols - } - - fn relative_address_base(&self) -> u64 { - 0 - } - - #[inline] - fn entry(&'file self) -> u64 { - self.entry - } - - #[inline] - fn flags(&self) -> FileFlags { - FileFlags::None - } -} - -/// An iterator for the segments in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmSegmentIterator<'data, 'file, R = &'data [u8]> { - #[allow(unused)] - file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmSegmentIterator<'data, 'file, R> { - type Item = WasmSegment<'data, 'file, R>; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - None - } -} - -/// A segment in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmSegment<'data, 'file, R = &'data [u8]> { - #[allow(unused)] - file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmSegment<'data, 'file, R> {} - -impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> { - #[inline] - fn address(&self) -> u64 { - unreachable!() - } - - #[inline] - fn size(&self) -> u64 { - unreachable!() - } - - #[inline] - fn align(&self) -> u64 { - unreachable!() - } - - #[inline] - fn file_range(&self) -> (u64, u64) { - unreachable!() - } - - fn data(&self) -> Result<&'data [u8]> { - unreachable!() - } - - fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> { - unreachable!() - } - - #[inline] - fn name_bytes(&self) -> Result<Option<&[u8]>> { - unreachable!() - } - - #[inline] - fn name(&self) -> Result<Option<&str>> { - unreachable!() - } - - #[inline] - fn flags(&self) -> SegmentFlags { - unreachable!() - } -} - -/// An iterator for the sections in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSectionIterator<'data, 'file, R = &'data [u8]> { - file: &'file WasmFile<'data, R>, - sections: slice::Iter<'file, SectionHeader<'data>>, -} - -impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { - type Item = WasmSection<'data, 'file, R>; - - fn next(&mut self) -> Option<Self::Item> { - let section = self.sections.next()?; - Some(WasmSection { - file: self.file, - section, - }) - } -} - -/// A section in a [`WasmFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct WasmSection<'data, 'file, R = &'data [u8]> { - file: &'file WasmFile<'data, R>, - section: &'file SectionHeader<'data>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmSection<'data, 'file, R> {} - -impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for WasmSection<'data, 'file, R> { - type RelocationIterator = WasmRelocationIterator<'data, 'file, R>; - - #[inline] - fn index(&self) -> SectionIndex { - // Note that we treat all custom sections as index 0. - // This is ok because they are never looked up by index. - SectionIndex(self.section.id as usize) - } - - #[inline] - fn address(&self) -> u64 { - 0 - } - - #[inline] - fn size(&self) -> u64 { - let range = &self.section.range; - (range.end - range.start) as u64 - } - - #[inline] - fn align(&self) -> u64 { - 1 - } - - #[inline] - fn file_range(&self) -> Option<(u64, u64)> { - let range = &self.section.range; - Some((range.start as _, range.end as _)) - } - - #[inline] - fn data(&self) -> Result<&'data [u8]> { - let range = &self.section.range; - self.file - .data - .read_bytes_at(range.start as u64, range.end as u64 - range.start as u64) - .read_error("Invalid Wasm section size or offset") - } - - fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> { - unimplemented!() - } - - #[inline] - fn compressed_file_range(&self) -> Result<CompressedFileRange> { - Ok(CompressedFileRange::none(self.file_range())) - } - - #[inline] - fn compressed_data(&self) -> Result<CompressedData<'data>> { - self.data().map(CompressedData::none) - } - - #[inline] - fn name_bytes(&self) -> Result<&[u8]> { - self.name().map(str::as_bytes) - } - - #[inline] - fn name(&self) -> Result<&str> { - Ok(match self.section.id { - SectionId::Custom => self.section.name, - SectionId::Type => "<type>", - SectionId::Import => "<import>", - SectionId::Function => "<function>", - SectionId::Table => "<table>", - SectionId::Memory => "<memory>", - SectionId::Global => "<global>", - SectionId::Export => "<export>", - SectionId::Start => "<start>", - SectionId::Element => "<element>", - SectionId::Code => "<code>", - SectionId::Data => "<data>", - SectionId::DataCount => "<data_count>", - }) - } - - #[inline] - fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { - Ok(None) - } - - #[inline] - fn segment_name(&self) -> Result<Option<&str>> { - Ok(None) - } - - #[inline] - fn kind(&self) -> SectionKind { - match self.section.id { - SectionId::Custom => match self.section.name { - "reloc." | "linking" => SectionKind::Linker, - _ => SectionKind::Other, - }, - SectionId::Type => SectionKind::Metadata, - SectionId::Import => SectionKind::Linker, - SectionId::Function => SectionKind::Metadata, - SectionId::Table => SectionKind::UninitializedData, - SectionId::Memory => SectionKind::UninitializedData, - SectionId::Global => SectionKind::Data, - SectionId::Export => SectionKind::Linker, - SectionId::Start => SectionKind::Linker, - SectionId::Element => SectionKind::Data, - SectionId::Code => SectionKind::Text, - SectionId::Data => SectionKind::Data, - SectionId::DataCount => SectionKind::UninitializedData, - } - } - - #[inline] - fn relocations(&self) -> WasmRelocationIterator<'data, 'file, R> { - WasmRelocationIterator(PhantomData) - } - - #[inline] - fn flags(&self) -> SectionFlags { - SectionFlags::None - } -} - -/// An iterator for the COMDAT section groups in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdatIterator<'data, 'file, R = &'data [u8]> { - #[allow(unused)] - file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmComdatIterator<'data, 'file, R> { - type Item = WasmComdat<'data, 'file, R>; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - None - } -} - -/// A COMDAT section group in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdat<'data, 'file, R = &'data [u8]> { - #[allow(unused)] - file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> read::private::Sealed for WasmComdat<'data, 'file, R> {} - -impl<'data, 'file, R> ObjectComdat<'data> for WasmComdat<'data, 'file, R> { - type SectionIterator = WasmComdatSectionIterator<'data, 'file, R>; - - #[inline] - fn kind(&self) -> ComdatKind { - unreachable!(); - } - - #[inline] - fn symbol(&self) -> SymbolIndex { - unreachable!(); - } - - #[inline] - fn name_bytes(&self) -> Result<&[u8]> { - unreachable!(); - } - - #[inline] - fn name(&self) -> Result<&str> { - unreachable!(); - } - - #[inline] - fn sections(&self) -> Self::SectionIterator { - unreachable!(); - } -} - -/// An iterator for the sections in a COMDAT section group in a [`WasmFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> { - #[allow(unused)] - file: &'file WasmFile<'data, R>, -} - -impl<'data, 'file, R> Iterator for WasmComdatSectionIterator<'data, 'file, R> { - type Item = SectionIndex; - - fn next(&mut self) -> Option<Self::Item> { - None - } -} - -/// A symbol table in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSymbolTable<'data, 'file> { - symbols: &'file [WasmSymbolInternal<'data>], -} - -impl<'data, 'file> read::private::Sealed for WasmSymbolTable<'data, 'file> {} - -impl<'data, 'file> ObjectSymbolTable<'data> for WasmSymbolTable<'data, 'file> { - type Symbol = WasmSymbol<'data, 'file>; - type SymbolIterator = WasmSymbolIterator<'data, 'file>; - - fn symbols(&self) -> Self::SymbolIterator { - WasmSymbolIterator { - symbols: self.symbols.iter().enumerate(), - } - } - - fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> { - let symbol = self - .symbols - .get(index.0) - .read_error("Invalid Wasm symbol index")?; - Ok(WasmSymbol { index, symbol }) - } -} - -/// An iterator for the symbols in a [`WasmFile`]. -#[derive(Debug)] -pub struct WasmSymbolIterator<'data, 'file> { - symbols: core::iter::Enumerate<slice::Iter<'file, WasmSymbolInternal<'data>>>, -} - -impl<'data, 'file> Iterator for WasmSymbolIterator<'data, 'file> { - type Item = WasmSymbol<'data, 'file>; - - fn next(&mut self) -> Option<Self::Item> { - let (index, symbol) = self.symbols.next()?; - Some(WasmSymbol { - index: SymbolIndex(index), - symbol, - }) - } -} - -/// A symbol in a [`WasmFile`]. -/// -/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. -#[derive(Clone, Copy, Debug)] -pub struct WasmSymbol<'data, 'file> { - index: SymbolIndex, - symbol: &'file WasmSymbolInternal<'data>, -} - -#[derive(Clone, Debug)] -struct WasmSymbolInternal<'data> { - name: &'data str, - address: u64, - size: u64, - kind: SymbolKind, - section: SymbolSection, - scope: SymbolScope, -} - -impl<'data, 'file> read::private::Sealed for WasmSymbol<'data, 'file> {} - -impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> { - #[inline] - fn index(&self) -> SymbolIndex { - self.index - } - - #[inline] - fn name_bytes(&self) -> read::Result<&'data [u8]> { - Ok(self.symbol.name.as_bytes()) - } - - #[inline] - fn name(&self) -> read::Result<&'data str> { - Ok(self.symbol.name) - } - - #[inline] - fn address(&self) -> u64 { - self.symbol.address - } - - #[inline] - fn size(&self) -> u64 { - self.symbol.size - } - - #[inline] - fn kind(&self) -> SymbolKind { - self.symbol.kind - } - - #[inline] - fn section(&self) -> SymbolSection { - self.symbol.section - } - - #[inline] - fn is_undefined(&self) -> bool { - self.symbol.section == SymbolSection::Undefined - } - - #[inline] - fn is_definition(&self) -> bool { - (self.symbol.kind == SymbolKind::Text || self.symbol.kind == SymbolKind::Data) - && self.symbol.section != SymbolSection::Undefined - } - - #[inline] - fn is_common(&self) -> bool { - self.symbol.section == SymbolSection::Common - } - - #[inline] - fn is_weak(&self) -> bool { - false - } - - #[inline] - fn scope(&self) -> SymbolScope { - self.symbol.scope - } - - #[inline] - fn is_global(&self) -> bool { - self.symbol.scope != SymbolScope::Compilation - } - - #[inline] - fn is_local(&self) -> bool { - self.symbol.scope == SymbolScope::Compilation - } - - #[inline] - fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> { - SymbolFlags::None - } -} - -/// An iterator for the relocations for a [`WasmSection`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct WasmRelocationIterator<'data, 'file, R = &'data [u8]>( - PhantomData<(&'data (), &'file (), R)>, -); - -impl<'data, 'file, R> Iterator for WasmRelocationIterator<'data, 'file, R> { - type Item = (u64, Relocation); - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - None - } -} |