From b1bd5dacc251fb395055b7357799a08c61b0e561 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Mar 2018 03:13:03 -0800 Subject: [PATCH 01/10] Parse reloc sections. --- src/elements/mod.rs | 1 + src/elements/module.rs | 38 ++++++ src/elements/reloc_section.rs | 244 ++++++++++++++++++++++++++++++++++ src/elements/section.rs | 12 +- 4 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 src/elements/reloc_section.rs diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 24c77d4..634889a 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -33,6 +33,7 @@ mod func; mod segment; mod index_map; mod name_section; +mod reloc_section; pub use self::module::{Module, peek_size, ImportCountType}; pub use self::section::{ diff --git a/src/elements/module.rs b/src/elements/module.rs index 5e47499..a824891 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -7,6 +7,7 @@ use super::section::{ GlobalSection, TableSection, ElementSection, DataSection, MemorySection }; use super::name_section::NameSection; +use super::reloc_section::RelocSection; const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; @@ -191,6 +192,43 @@ impl Module { } } + /// Try to parse reloc section in place + /// Corresponding custom section with proper header will convert to reloc sections + /// If some of them will fail to be decoded, Err variant is returned with the list of + /// (index, Error) tuples of failed sections. + pub fn parse_reloc(mut self) -> Result, Self)> { + let mut parse_errors = Vec::new(); + + for (i, section) in self.sections.iter_mut().enumerate() { + if let Some(relocation_section) = { + if let Section::Custom(ref custom) = *section { + if custom.name().starts_with("reloc.") { + let mut rdr = io::Cursor::new(custom.payload()); + let reloc_section = match RelocSection::deserialize(custom.name().to_owned(), &mut rdr) { + Ok(reloc_section) => reloc_section, + Err(e) => { parse_errors.push((i, e)); continue; } + }; + Some(Section::Reloc(reloc_section)) + } + else { + None + } + } + else { + None + } + } { + *section = relocation_section; + } + } + + if parse_errors.len() > 0 { + Err((parse_errors, self)) + } else { + Ok(self) + } + } + /// Count imports by provided type pub fn import_count(&self, count_type: ImportCountType) -> usize { self.import_section() diff --git a/src/elements/reloc_section.rs b/src/elements/reloc_section.rs new file mode 100644 index 0000000..971fa78 --- /dev/null +++ b/src/elements/reloc_section.rs @@ -0,0 +1,244 @@ +use std::io::{Read, Write}; + +use super::{CountedList, CountedListWriter, CountedWriter, Deserialize, Error, Serialize, VarInt32, VarUint32, VarUint7}; + +const R_WEBASSEMBLY_FUNCTION_INDEX_LEB: u8 = 0; +const R_WEBASSEMBLY_TABLE_INDEX_SLEB: u8 = 1; +const R_WEBASSEMBLY_TABLE_INDEX_I32: u8 = 2; +const R_WEBASSEMBLY_MEMORY_ADDR_LEB: u8 = 3; +const R_WEBASSEMBLY_MEMORY_ADDR_SLEB: u8 = 4; +const R_WEBASSEMBLY_MEMORY_ADDR_I32: u8 = 5; +const R_WEBASSEMBLY_TYPE_INDEX_LEB: u8 = 6; +const R_WEBASSEMBLY_GLOBAL_INDEX_LEB: u8 = 7; + +/// Relocation information. +#[derive(Clone, Debug)] +pub struct RelocSection { + // Name of this section. + name: String, + + // ID of the section containing the relocations described in this section. + section_id: u32, + + // Name of the section containing the relocations described in this section. Only set if section_id is 0. + relocation_section_name: Option, + + // Relocation entries. + entries: Vec, +} + +impl RelocSection { + pub fn deserialize( + name: String, + rdr: &mut R, + ) -> Result { + let section_id = VarUint32::deserialize(rdr)?.into(); + let relocation_section_name = + if section_id == 0 { + Some(String::deserialize(rdr)?) + } + else { + None + }; + + let entries = CountedList::deserialize(rdr)?.into_inner(); + + Ok(RelocSection { + name, + section_id, + relocation_section_name, + entries, + }) + } +} + +impl Serialize for RelocSection { + type Error = Error; + + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + let mut counted_writer = CountedWriter::new(wtr); + self.name.serialize(&mut counted_writer)?; + + VarUint32::from(self.section_id).serialize(&mut counted_writer)?; + + if let Some(relocation_section_name) = self.relocation_section_name { + relocation_section_name.serialize(&mut counted_writer)?; + } + + let counted_list = CountedListWriter(self.entries.len(), self.entries.into_iter()); + counted_list.serialize(&mut counted_writer)?; + + counted_writer.done()?; + + Ok(()) + } +} + +/// Relocation entry. +#[derive(Clone, Debug)] +pub enum RelocationEntry { + // Function index. + FunctionIndexLeb { + offset: u32, + index: u32, + }, + + // Function table index. + TableIndexSleb { + offset: u32, + index: u32, + }, + + // Function table index. + TableIndexI32 { + offset: u32, + index: u32, + }, + + // Linear memory index. + MemoryAddressLeb { + offset: u32, + index: u32, + addend: i32, + }, + + // Linear memory index. + MemoryAddressSleb { + offset: u32, + index: u32, + addend: i32, + }, + + // Linear memory index. + MemoryAddressI32 { + offset: u32, + index: u32, + addend: i32, + }, + + // Type table index. + TypeIndexLeb { + offset: u32, + index: u32, + }, + + // Global index. + GlobalIndexLeb { + offset: u32, + index: u32, + }, +} + +impl Deserialize for RelocationEntry { + type Error = Error; + + fn deserialize(rdr: &mut R) -> Result { + match VarUint7::deserialize(rdr)?.into() { + R_WEBASSEMBLY_FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_TABLE_INDEX_SLEB => Ok(RelocationEntry::TableIndexSleb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_TABLE_INDEX_I32 => Ok(RelocationEntry::TableIndexI32 { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_MEMORY_ADDR_LEB => Ok(RelocationEntry::MemoryAddressLeb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + addend: VarInt32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_MEMORY_ADDR_SLEB => Ok(RelocationEntry::MemoryAddressSleb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + addend: VarInt32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_MEMORY_ADDR_I32 => Ok(RelocationEntry::MemoryAddressI32 { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + addend: VarInt32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_TYPE_INDEX_LEB => Ok(RelocationEntry::TypeIndexLeb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + }), + + R_WEBASSEMBLY_GLOBAL_INDEX_LEB => Ok(RelocationEntry::GlobalIndexLeb { + offset: VarUint32::deserialize(rdr)?.into(), + index: VarUint32::deserialize(rdr)?.into(), + }), + + entry_type => Err(Error::UnknownValueType(entry_type as i8)), + } + } +} + +impl Serialize for RelocationEntry { + type Error = Error; + + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + match self { + RelocationEntry::FunctionIndexLeb { offset, index } => { + VarUint7::from(R_WEBASSEMBLY_FUNCTION_INDEX_LEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + }, + + RelocationEntry::TableIndexSleb { offset, index } => { + VarUint7::from(R_WEBASSEMBLY_TABLE_INDEX_SLEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + }, + + RelocationEntry::TableIndexI32 { offset, index } => { + VarUint7::from(R_WEBASSEMBLY_TABLE_INDEX_I32).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + }, + + RelocationEntry::MemoryAddressLeb { offset, index, addend } => { + VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_LEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + VarInt32::from(addend).serialize(wtr)?; + }, + + RelocationEntry::MemoryAddressSleb { offset, index, addend } => { + VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_SLEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + VarInt32::from(addend).serialize(wtr)?; + }, + + RelocationEntry::MemoryAddressI32 { offset, index, addend } => { + VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_I32).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + VarInt32::from(addend).serialize(wtr)?; + }, + + RelocationEntry::TypeIndexLeb { offset, index } => { + VarUint7::from(R_WEBASSEMBLY_TYPE_INDEX_LEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + }, + + RelocationEntry::GlobalIndexLeb { offset, index } => { + VarUint7::from(R_WEBASSEMBLY_GLOBAL_INDEX_LEB).serialize(wtr)?; + VarUint32::from(offset).serialize(wtr)?; + VarUint32::from(index).serialize(wtr)?; + }, + } + + Ok(()) + } +} diff --git a/src/elements/section.rs b/src/elements/section.rs index 98fa451..d3b36c3 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -23,6 +23,7 @@ use super::{ use super::types::Type; use super::name_section::NameSection; +use super::reloc_section::RelocSection; const ENTRIES_BUFFER_LENGTH: usize = 16384; @@ -64,6 +65,10 @@ pub enum Section { /// /// Note that initially it is not parsed until `parse_names` is called explicitly. Name(NameSection), + /// Relocation section. + /// + /// Note that initially it is not parsed until `parse_reloc` is called explicitly. + Reloc(RelocSection), } impl Deserialize for Section { @@ -191,7 +196,11 @@ impl Serialize for Section { payload: serialize(name_section)?, }; custom.serialize(writer)?; - } + }, + Section::Reloc(reloc_section) => { + VarUint7::from(0x00).serialize(writer)?; + reloc_section.serialize(writer)?; + }, } Ok(()) } @@ -214,6 +223,7 @@ impl Section { Section::Code(_) => 0x0a, Section::Data(_) => 0x0b, Section::Name(_) => 0x00, + Section::Reloc(_) => 0x00, } } } From dcb7770e242068032a1b20d248a78dceeb1d60fe Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 8 Mar 2018 06:01:26 +0300 Subject: [PATCH 02/10] bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2dc4d9a..c5fb95d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parity-wasm" -version = "0.27.1" +version = "0.27.2" authors = ["Nikolay Volf ", "Svyatoslav Nikolsky ", "Sergey Shulepov "] license = "MIT/Apache-2.0" readme = "README.md" From 0ab2aa15b2e5dbabb570651d0b2a62699ee31b38 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Mar 2018 21:23:05 -0800 Subject: [PATCH 03/10] Parse reloc sections in roundtrip example. --- examples/roundtrip.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/roundtrip.rs b/examples/roundtrip.rs index 4979b5b..b3b9519 100644 --- a/examples/roundtrip.rs +++ b/examples/roundtrip.rs @@ -12,6 +12,7 @@ fn main() { let module = match parity_wasm::deserialize_file(&args[1]) .expect("Failed to load module") .parse_names() + .and_then(|module| module.parse_reloc()) { Ok(m) => m, Err((errors, m)) => { From 653ba502007ac296dc22ff68eef3adbc41b4bcb7 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Mar 2018 21:23:39 -0800 Subject: [PATCH 04/10] Assert that reloc section completely uses up the custom section payload. --- src/elements/module.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/elements/module.rs b/src/elements/module.rs index a824891..5f3b257 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -208,6 +208,10 @@ impl Module { Ok(reloc_section) => reloc_section, Err(e) => { parse_errors.push((i, e)); continue; } }; + if rdr.position() != custom.payload().len() as u64 { + parse_errors.push((i, io::Error::from(io::ErrorKind::InvalidData).into())); + continue; + } Some(Section::Reloc(reloc_section)) } else { From bfe87d89df3c26852e98db7b30bc31d607172a5f Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Mar 2018 21:24:43 -0800 Subject: [PATCH 05/10] Fixed reloc section doc comments and removed prefix from entry type constants. --- src/elements/reloc_section.rs | 77 +++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/elements/reloc_section.rs b/src/elements/reloc_section.rs index 971fa78..1e9cce8 100644 --- a/src/elements/reloc_section.rs +++ b/src/elements/reloc_section.rs @@ -2,28 +2,28 @@ use std::io::{Read, Write}; use super::{CountedList, CountedListWriter, CountedWriter, Deserialize, Error, Serialize, VarInt32, VarUint32, VarUint7}; -const R_WEBASSEMBLY_FUNCTION_INDEX_LEB: u8 = 0; -const R_WEBASSEMBLY_TABLE_INDEX_SLEB: u8 = 1; -const R_WEBASSEMBLY_TABLE_INDEX_I32: u8 = 2; -const R_WEBASSEMBLY_MEMORY_ADDR_LEB: u8 = 3; -const R_WEBASSEMBLY_MEMORY_ADDR_SLEB: u8 = 4; -const R_WEBASSEMBLY_MEMORY_ADDR_I32: u8 = 5; -const R_WEBASSEMBLY_TYPE_INDEX_LEB: u8 = 6; -const R_WEBASSEMBLY_GLOBAL_INDEX_LEB: u8 = 7; +const FUNCTION_INDEX_LEB: u8 = 0; +const TABLE_INDEX_SLEB: u8 = 1; +const TABLE_INDEX_I32: u8 = 2; +const MEMORY_ADDR_LEB: u8 = 3; +const MEMORY_ADDR_SLEB: u8 = 4; +const MEMORY_ADDR_I32: u8 = 5; +const TYPE_INDEX_LEB: u8 = 6; +const GLOBAL_INDEX_LEB: u8 = 7; /// Relocation information. #[derive(Clone, Debug)] pub struct RelocSection { - // Name of this section. + /// Name of this section. name: String, - // ID of the section containing the relocations described in this section. + /// ID of the section containing the relocations described in this section. section_id: u32, - // Name of the section containing the relocations described in this section. Only set if section_id is 0. + /// Name of the section containing the relocations described in this section. Only set if section_id is 0. relocation_section_name: Option, - // Relocation entries. + /// Relocation entries. entries: Vec, } @@ -33,6 +33,7 @@ impl RelocSection { rdr: &mut R, ) -> Result { let section_id = VarUint32::deserialize(rdr)?.into(); + let relocation_section_name = if section_id == 0 { Some(String::deserialize(rdr)?) @@ -57,6 +58,7 @@ impl Serialize for RelocSection { fn serialize(self, wtr: &mut W) -> Result<(), Error> { let mut counted_writer = CountedWriter::new(wtr); + self.name.serialize(&mut counted_writer)?; VarUint32::from(self.section_id).serialize(&mut counted_writer)?; @@ -77,52 +79,55 @@ impl Serialize for RelocSection { /// Relocation entry. #[derive(Clone, Debug)] pub enum RelocationEntry { - // Function index. + /// Function index. FunctionIndexLeb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the function symbol in the symbol table. index: u32, }, - // Function table index. + /// Function table index. TableIndexSleb { offset: u32, index: u32, }, - // Function table index. + /// Function table index. TableIndexI32 { offset: u32, index: u32, }, - // Linear memory index. + /// Linear memory index. MemoryAddressLeb { offset: u32, index: u32, addend: i32, }, - // Linear memory index. + /// Linear memory index. MemoryAddressSleb { offset: u32, index: u32, addend: i32, }, - // Linear memory index. + /// Linear memory index. MemoryAddressI32 { offset: u32, index: u32, addend: i32, }, - // Type table index. + /// Type table index. TypeIndexLeb { offset: u32, index: u32, }, - // Global index. + /// Global index. GlobalIndexLeb { offset: u32, index: u32, @@ -134,45 +139,45 @@ impl Deserialize for RelocationEntry { fn deserialize(rdr: &mut R) -> Result { match VarUint7::deserialize(rdr)?.into() { - R_WEBASSEMBLY_FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb { + FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_TABLE_INDEX_SLEB => Ok(RelocationEntry::TableIndexSleb { + TABLE_INDEX_SLEB => Ok(RelocationEntry::TableIndexSleb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_TABLE_INDEX_I32 => Ok(RelocationEntry::TableIndexI32 { + TABLE_INDEX_I32 => Ok(RelocationEntry::TableIndexI32 { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_MEMORY_ADDR_LEB => Ok(RelocationEntry::MemoryAddressLeb { + MEMORY_ADDR_LEB => Ok(RelocationEntry::MemoryAddressLeb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), addend: VarInt32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_MEMORY_ADDR_SLEB => Ok(RelocationEntry::MemoryAddressSleb { + MEMORY_ADDR_SLEB => Ok(RelocationEntry::MemoryAddressSleb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), addend: VarInt32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_MEMORY_ADDR_I32 => Ok(RelocationEntry::MemoryAddressI32 { + MEMORY_ADDR_I32 => Ok(RelocationEntry::MemoryAddressI32 { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), addend: VarInt32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_TYPE_INDEX_LEB => Ok(RelocationEntry::TypeIndexLeb { + TYPE_INDEX_LEB => Ok(RelocationEntry::TypeIndexLeb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), }), - R_WEBASSEMBLY_GLOBAL_INDEX_LEB => Ok(RelocationEntry::GlobalIndexLeb { + GLOBAL_INDEX_LEB => Ok(RelocationEntry::GlobalIndexLeb { offset: VarUint32::deserialize(rdr)?.into(), index: VarUint32::deserialize(rdr)?.into(), }), @@ -188,52 +193,52 @@ impl Serialize for RelocationEntry { fn serialize(self, wtr: &mut W) -> Result<(), Error> { match self { RelocationEntry::FunctionIndexLeb { offset, index } => { - VarUint7::from(R_WEBASSEMBLY_FUNCTION_INDEX_LEB).serialize(wtr)?; + VarUint7::from(FUNCTION_INDEX_LEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; }, RelocationEntry::TableIndexSleb { offset, index } => { - VarUint7::from(R_WEBASSEMBLY_TABLE_INDEX_SLEB).serialize(wtr)?; + VarUint7::from(TABLE_INDEX_SLEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; }, RelocationEntry::TableIndexI32 { offset, index } => { - VarUint7::from(R_WEBASSEMBLY_TABLE_INDEX_I32).serialize(wtr)?; + VarUint7::from(TABLE_INDEX_I32).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; }, RelocationEntry::MemoryAddressLeb { offset, index, addend } => { - VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_LEB).serialize(wtr)?; + VarUint7::from(MEMORY_ADDR_LEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; VarInt32::from(addend).serialize(wtr)?; }, RelocationEntry::MemoryAddressSleb { offset, index, addend } => { - VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_SLEB).serialize(wtr)?; + VarUint7::from(MEMORY_ADDR_SLEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; VarInt32::from(addend).serialize(wtr)?; }, RelocationEntry::MemoryAddressI32 { offset, index, addend } => { - VarUint7::from(R_WEBASSEMBLY_MEMORY_ADDR_I32).serialize(wtr)?; + VarUint7::from(MEMORY_ADDR_I32).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; VarInt32::from(addend).serialize(wtr)?; }, RelocationEntry::TypeIndexLeb { offset, index } => { - VarUint7::from(R_WEBASSEMBLY_TYPE_INDEX_LEB).serialize(wtr)?; + VarUint7::from(TYPE_INDEX_LEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; }, RelocationEntry::GlobalIndexLeb { offset, index } => { - VarUint7::from(R_WEBASSEMBLY_GLOBAL_INDEX_LEB).serialize(wtr)?; + VarUint7::from(GLOBAL_INDEX_LEB).serialize(wtr)?; VarUint32::from(offset).serialize(wtr)?; VarUint32::from(index).serialize(wtr)?; }, From 040d6ef38835832c2ef24f15c419fcb4ae5bc94b Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Mar 2018 22:05:15 -0800 Subject: [PATCH 06/10] Added getters and setters for RelocSection, and tests. --- res/cases/v1/relocatable.wasm | Bin 0 -> 255 bytes src/elements/reloc_section.rs | 71 +++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 res/cases/v1/relocatable.wasm diff --git a/res/cases/v1/relocatable.wasm b/res/cases/v1/relocatable.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ec986f259263e22ae224f2fdde75711534d3f48e GIT binary patch literal 255 zcmZwB!D_-l5C-6XW|OE{3zq6t@FobM^bJDWa~~ltI%sgSE4#7aDSdQT>7j?tWtbo4 z=YxqI0iX$Qfh`XMc*RQGx88Xdy_LrL1L&R, } +impl RelocSection { + /// Name of this section. + pub fn name(&self) -> &str { + &self.name + } + + /// Name of this section (mutable). + pub fn name_mut(&mut self) -> &mut String { + &mut self.name + } + + /// ID of the section containing the relocations described in this section. + pub fn section_id(&self) -> u32 { + self.section_id + } + + /// ID of the section containing the relocations described in this section (mutable). + pub fn section_id_mut(&mut self) -> &mut u32 { + &mut self.section_id + } + + /// Name of the section containing the relocations described in this section. + pub fn relocation_section_name(&self) -> Option<&str> { + self.relocation_section_name.as_ref().map(String::as_str) + } + + /// Name of the section containing the relocations described in this section (mutable). + pub fn relocation_section_name_mut(&mut self) -> &mut Option { + &mut self.relocation_section_name + } + + /// List of relocation entries. + pub fn entries(&self) -> &[RelocationEntry] { + &self.entries + } + + /// List of relocation entries (mutable). + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.entries + } +} + impl RelocSection { pub fn deserialize( name: String, @@ -77,7 +119,7 @@ impl Serialize for RelocSection { } /// Relocation entry. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum RelocationEntry { /// Function index. FunctionIndexLeb { @@ -247,3 +289,30 @@ impl Serialize for RelocationEntry { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::super::{Section, deserialize_file}; + use super::RelocationEntry; + + #[test] + fn reloc_section() { + let module = + deserialize_file("./res/cases/v1/relocatable.wasm").expect("Module should be deserialized") + .parse_reloc().expect("Reloc section should be deserialized"); + let mut found = false; + for section in module.sections() { + match *section { + Section::Reloc(ref reloc_section) => { + assert_eq!(vec![ + RelocationEntry::MemoryAddressSleb { offset: 4, index: 0, addend: 0 }, + RelocationEntry::FunctionIndexLeb { offset: 12, index: 0 }, + ], reloc_section.entries()); + found = true + }, + _ => { } + } + } + assert!(found, "There should be a reloc section in relocatable.wasm"); + } +} From 6bf5f102738c434fc13c8d37a0028fb0cd49dee2 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Thu, 8 Mar 2018 12:47:43 -0800 Subject: [PATCH 07/10] Added more missing doc comments. --- src/elements/reloc_section.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/elements/reloc_section.rs b/src/elements/reloc_section.rs index f791d72..7271ca1 100644 --- a/src/elements/reloc_section.rs +++ b/src/elements/reloc_section.rs @@ -132,46 +132,73 @@ pub enum RelocationEntry { /// Function table index. TableIndexSleb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the function symbol in the symbol table. index: u32, }, /// Function table index. TableIndexI32 { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the function symbol in the symbol table. index: u32, }, /// Linear memory index. MemoryAddressLeb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the data symbol in the symbol table. index: u32, + + /// Addend to add to the address. addend: i32, }, /// Linear memory index. MemoryAddressSleb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the data symbol in the symbol table. index: u32, + + /// Addend to add to the address. addend: i32, }, /// Linear memory index. MemoryAddressI32 { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the data symbol in the symbol table. index: u32, + + /// Addend to add to the address. addend: i32, }, /// Type table index. TypeIndexLeb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the type used. index: u32, }, /// Global index. GlobalIndexLeb { + /// Offset of the value to rewrite. offset: u32, + + /// Index of the global symbol in the symbol table. index: u32, }, } From 3c65f63973c7292086a7f04c78403171b2ae4d7b Mon Sep 17 00:00:00 2001 From: Arnavion Date: Thu, 8 Mar 2018 12:49:46 -0800 Subject: [PATCH 08/10] Make relocation section types visible to crate users. --- src/elements/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 634889a..1f8b818 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -57,6 +57,9 @@ pub use self::name_section::{ NameMap, NameSection, ModuleNameSection, FunctionNameSection, LocalNameSection, }; +pub use self::reloc_section::{ + RelocSection, RelocationEntry, +}; /// Deserialization from serial i/o pub trait Deserialize : Sized { From 5cf1ae0a084ee4d74fb6c76f87b6d02c3fe61b12 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Thu, 8 Mar 2018 12:51:09 -0800 Subject: [PATCH 09/10] One last missing doc comment warning. --- src/elements/reloc_section.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/elements/reloc_section.rs b/src/elements/reloc_section.rs index 7271ca1..c3bdf48 100644 --- a/src/elements/reloc_section.rs +++ b/src/elements/reloc_section.rs @@ -70,6 +70,7 @@ impl RelocSection { } impl RelocSection { + /// Deserialize a reloc section. pub fn deserialize( name: String, rdr: &mut R, From 1896f609c3cd176d9127ea151c102af972c3ddb3 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 13 Mar 2018 20:00:19 +0300 Subject: [PATCH 10/10] Update section.rs --- src/elements/section.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/elements/section.rs b/src/elements/section.rs index d3b36c3..4853bec 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -68,6 +68,9 @@ pub enum Section { /// Relocation section. /// /// Note that initially it is not parsed until `parse_reloc` is called explicitly. + /// Also note that currently there are serialization (but not de-serialization) + /// issues with this section + /// (see https://github.com/paritytech/parity-wasm/issues/198) Reloc(RelocSection), }