parity-wasm/src/elements/reloc_section.rs

250 lines
6.3 KiB
Rust
Raw Normal View History

2018-03-07 03:13:03 -08:00
use std::io::{Read, Write};
use super::{CountedList, CountedListWriter, CountedWriter, Deserialize, Error, Serialize, VarInt32, VarUint32, VarUint7};
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;
2018-03-07 03:13:03 -08:00
/// Relocation information.
#[derive(Clone, Debug)]
pub struct RelocSection {
/// Name of this section.
2018-03-07 03:13:03 -08:00
name: String,
/// ID of the section containing the relocations described in this section.
2018-03-07 03:13:03 -08:00
section_id: u32,
/// Name of the section containing the relocations described in this section. Only set if section_id is 0.
2018-03-07 03:13:03 -08:00
relocation_section_name: Option<String>,
/// Relocation entries.
2018-03-07 03:13:03 -08:00
entries: Vec<RelocationEntry>,
}
impl RelocSection {
pub fn deserialize<R: Read>(
name: String,
rdr: &mut R,
) -> Result<Self, Error> {
let section_id = VarUint32::deserialize(rdr)?.into();
2018-03-07 03:13:03 -08:00
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<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
let mut counted_writer = CountedWriter::new(wtr);
2018-03-07 03:13:03 -08:00
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.
2018-03-07 03:13:03 -08:00
FunctionIndexLeb {
/// Offset of the value to rewrite.
2018-03-07 03:13:03 -08:00
offset: u32,
/// Index of the function symbol in the symbol table.
2018-03-07 03:13:03 -08:00
index: u32,
},
/// Function table index.
2018-03-07 03:13:03 -08:00
TableIndexSleb {
offset: u32,
index: u32,
},
/// Function table index.
2018-03-07 03:13:03 -08:00
TableIndexI32 {
offset: u32,
index: u32,
},
/// Linear memory index.
2018-03-07 03:13:03 -08:00
MemoryAddressLeb {
offset: u32,
index: u32,
addend: i32,
},
/// Linear memory index.
2018-03-07 03:13:03 -08:00
MemoryAddressSleb {
offset: u32,
index: u32,
addend: i32,
},
/// Linear memory index.
2018-03-07 03:13:03 -08:00
MemoryAddressI32 {
offset: u32,
index: u32,
addend: i32,
},
/// Type table index.
2018-03-07 03:13:03 -08:00
TypeIndexLeb {
offset: u32,
index: u32,
},
/// Global index.
2018-03-07 03:13:03 -08:00
GlobalIndexLeb {
offset: u32,
index: u32,
},
}
impl Deserialize for RelocationEntry {
type Error = Error;
fn deserialize<R: Read>(rdr: &mut R) -> Result<Self, Self::Error> {
match VarUint7::deserialize(rdr)?.into() {
FUNCTION_INDEX_LEB => Ok(RelocationEntry::FunctionIndexLeb {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
}),
TABLE_INDEX_SLEB => Ok(RelocationEntry::TableIndexSleb {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
}),
TABLE_INDEX_I32 => Ok(RelocationEntry::TableIndexI32 {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
}),
MEMORY_ADDR_LEB => Ok(RelocationEntry::MemoryAddressLeb {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
addend: VarInt32::deserialize(rdr)?.into(),
}),
MEMORY_ADDR_SLEB => Ok(RelocationEntry::MemoryAddressSleb {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
addend: VarInt32::deserialize(rdr)?.into(),
}),
MEMORY_ADDR_I32 => Ok(RelocationEntry::MemoryAddressI32 {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
addend: VarInt32::deserialize(rdr)?.into(),
}),
TYPE_INDEX_LEB => Ok(RelocationEntry::TypeIndexLeb {
2018-03-07 03:13:03 -08:00
offset: VarUint32::deserialize(rdr)?.into(),
index: VarUint32::deserialize(rdr)?.into(),
}),
GLOBAL_INDEX_LEB => Ok(RelocationEntry::GlobalIndexLeb {
2018-03-07 03:13:03 -08:00
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<W: Write>(self, wtr: &mut W) -> Result<(), Error> {
match self {
RelocationEntry::FunctionIndexLeb { offset, index } => {
VarUint7::from(FUNCTION_INDEX_LEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
},
RelocationEntry::TableIndexSleb { offset, index } => {
VarUint7::from(TABLE_INDEX_SLEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
},
RelocationEntry::TableIndexI32 { offset, index } => {
VarUint7::from(TABLE_INDEX_I32).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
},
RelocationEntry::MemoryAddressLeb { offset, index, addend } => {
VarUint7::from(MEMORY_ADDR_LEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
VarInt32::from(addend).serialize(wtr)?;
},
RelocationEntry::MemoryAddressSleb { offset, index, addend } => {
VarUint7::from(MEMORY_ADDR_SLEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
VarInt32::from(addend).serialize(wtr)?;
},
RelocationEntry::MemoryAddressI32 { offset, index, addend } => {
VarUint7::from(MEMORY_ADDR_I32).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
VarInt32::from(addend).serialize(wtr)?;
},
RelocationEntry::TypeIndexLeb { offset, index } => {
VarUint7::from(TYPE_INDEX_LEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
},
RelocationEntry::GlobalIndexLeb { offset, index } => {
VarUint7::from(GLOBAL_INDEX_LEB).serialize(wtr)?;
2018-03-07 03:13:03 -08:00
VarUint32::from(offset).serialize(wtr)?;
VarUint32::from(index).serialize(wtr)?;
},
}
Ok(())
}
}