-
Notifications
You must be signed in to change notification settings - Fork 555
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
1,322 additions
and
1,042 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,7 @@ | ||
mod analyzed; | ||
mod jump_map; | ||
mod raw; | ||
|
||
pub use analyzed::LegacyAnalyzedBytecode; | ||
pub use jump_map::JumpTable; | ||
|
||
use bitvec::{bitvec, order::Lsb0}; | ||
use primitives::Bytes; | ||
use std::sync::Arc; | ||
|
||
/// Legacy analyzed | ||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct LegacyAnalyzedBytecode { | ||
/// Bytecode with 32 zero bytes padding. | ||
bytecode: Bytes, | ||
/// Original bytes length. | ||
original_len: usize, | ||
/// Jump table. | ||
jump_table: JumpTable, | ||
} | ||
|
||
impl Default for LegacyAnalyzedBytecode { | ||
#[inline] | ||
fn default() -> Self { | ||
Self { | ||
bytecode: Bytes::from_static(&[0]), | ||
original_len: 0, | ||
jump_table: JumpTable(Arc::new(bitvec![u8, Lsb0; 0])), | ||
} | ||
} | ||
} | ||
|
||
impl LegacyAnalyzedBytecode { | ||
/// Create new analyzed bytecode. | ||
pub fn new(bytecode: Bytes, original_len: usize, jump_table: JumpTable) -> Self { | ||
Self { | ||
bytecode, | ||
original_len, | ||
jump_table, | ||
} | ||
} | ||
|
||
/// Returns a reference to the bytecode. | ||
/// | ||
/// The bytecode is padded with 32 zero bytes. | ||
pub fn bytecode(&self) -> &Bytes { | ||
&self.bytecode | ||
} | ||
|
||
/// Original bytes length. | ||
pub fn original_len(&self) -> usize { | ||
self.original_len | ||
} | ||
|
||
/// Original bytes without padding. | ||
pub fn original_bytes(&self) -> Bytes { | ||
self.bytecode.slice(..self.original_len) | ||
} | ||
|
||
/// Original bytes without padding. | ||
pub fn original_byte_slice(&self) -> &[u8] { | ||
&self.bytecode[..self.original_len] | ||
} | ||
|
||
/// Jumptable of analyzed bytes. | ||
pub fn jump_table(&self) -> &JumpTable { | ||
&self.jump_table | ||
} | ||
} | ||
pub use raw::LegacyRawBytecode; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use super::JumpTable; | ||
use bitvec::{bitvec, order::Lsb0}; | ||
use primitives::Bytes; | ||
use std::sync::Arc; | ||
|
||
// Legacy analyzed | ||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct LegacyAnalyzedBytecode { | ||
/// Bytecode with 32 zero bytes padding. | ||
bytecode: Bytes, | ||
/// Original bytes length. | ||
original_len: usize, | ||
/// Jump table. | ||
jump_table: JumpTable, | ||
} | ||
|
||
impl Default for LegacyAnalyzedBytecode { | ||
#[inline] | ||
fn default() -> Self { | ||
Self { | ||
bytecode: Bytes::from_static(&[0]), | ||
original_len: 0, | ||
jump_table: JumpTable(Arc::new(bitvec![u8, Lsb0; 0])), | ||
} | ||
} | ||
} | ||
|
||
impl LegacyAnalyzedBytecode { | ||
/// Create new analyzed bytecode. | ||
pub fn new(bytecode: Bytes, original_len: usize, jump_table: JumpTable) -> Self { | ||
Self { | ||
bytecode, | ||
original_len, | ||
jump_table, | ||
} | ||
} | ||
|
||
/// Returns a reference to the bytecode. | ||
/// | ||
/// The bytecode is padded with 32 zero bytes. | ||
pub fn bytecode(&self) -> &Bytes { | ||
&self.bytecode | ||
} | ||
|
||
/// Original bytes length. | ||
pub fn original_len(&self) -> usize { | ||
self.original_len | ||
} | ||
|
||
/// Original bytes without padding. | ||
pub fn original_bytes(&self) -> Bytes { | ||
self.bytecode.slice(..self.original_len) | ||
} | ||
|
||
/// Original bytes without padding. | ||
pub fn original_byte_slice(&self) -> &[u8] { | ||
&self.bytecode[..self.original_len] | ||
} | ||
|
||
/// Jumptable of analyzed bytes. | ||
pub fn jump_table(&self) -> &JumpTable { | ||
&self.jump_table | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use super::{JumpTable, LegacyAnalyzedBytecode}; | ||
use crate::opcode; | ||
use bitvec::{bitvec, order::Lsb0, vec::BitVec}; | ||
use core::ops::Deref; | ||
use primitives::Bytes; | ||
use std::{sync::Arc, vec::Vec}; | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct LegacyRawBytecode(pub Bytes); | ||
|
||
impl LegacyRawBytecode { | ||
pub fn analysis(&self) -> JumpTable { | ||
let mut jumps: BitVec<u8> = bitvec![u8, Lsb0; 0; self.0.len()]; | ||
|
||
let range = self.0.as_ptr_range(); | ||
let start = range.start; | ||
let mut iterator = start; | ||
let end = range.end; | ||
while iterator < end { | ||
let opcode = unsafe { *iterator }; | ||
if opcode::JUMPDEST == opcode { | ||
// SAFETY: jumps are max length of the code | ||
unsafe { jumps.set_unchecked(iterator.offset_from(start) as usize, true) } | ||
iterator = unsafe { iterator.offset(1) }; | ||
} else { | ||
let push_offset = opcode.wrapping_sub(opcode::PUSH1); | ||
if push_offset < 32 { | ||
// SAFETY: iterator access range is checked in the while loop | ||
iterator = unsafe { iterator.offset((push_offset + 2) as isize) }; | ||
} else { | ||
// SAFETY: iterator access range is checked in the while loop | ||
iterator = unsafe { iterator.offset(1) }; | ||
} | ||
} | ||
} | ||
|
||
JumpTable(Arc::new(jumps)) | ||
} | ||
|
||
pub fn into_analyzed(self) -> LegacyAnalyzedBytecode { | ||
let jump_table = self.analysis(); | ||
let len = self.0.len(); | ||
let mut padded_bytecode = Vec::with_capacity(len + 33); | ||
padded_bytecode.extend_from_slice(&self.0); | ||
padded_bytecode.resize(len + 33, 0); | ||
LegacyAnalyzedBytecode::new(padded_bytecode.into(), len, jump_table) | ||
} | ||
} | ||
|
||
impl From<Bytes> for LegacyRawBytecode { | ||
fn from(bytes: Bytes) -> Self { | ||
Self(bytes) | ||
} | ||
} | ||
|
||
impl<const N: usize> From<[u8; N]> for LegacyRawBytecode { | ||
fn from(bytes: [u8; N]) -> Self { | ||
Self(bytes.into()) | ||
} | ||
} | ||
|
||
impl Deref for LegacyRawBytecode { | ||
type Target = Bytes; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} |
Oops, something went wrong.