Kaynağa Gözat

use shared Instruction class in disassembler

bidhan-a 1 ay önce
ebeveyn
işleme
33c38d5ebf

+ 2 - 0
crates/common/Cargo.toml

@@ -18,6 +18,8 @@ num-traits = { workspace = true }
 thiserror = { workspace = true }
 phf = "0.13.1"
 phf_macros = "0.13.1"
+serde = { version = "1.0.228", features = ["derive"] }
+
 
 [dev-dependencies]
 hex-literal = "1.0.0"

+ 64 - 15
crates/common/src/instruction.rs

@@ -4,8 +4,9 @@ use crate::syscall::SYSCALLS;
 
 use core::fmt;
 use core::ops::Range;
+use serde::{Deserialize, Serialize};
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct Register {
     pub n: u8,
 }
@@ -16,7 +17,7 @@ impl fmt::Display for Register {
     }
 }
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum Number {
     Int(i64),
     Addr(i64),
@@ -31,7 +32,7 @@ impl fmt::Display for Number {
     }
 }
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct Instruction {
     pub opcode: Opcode,
     pub dst: Option<Register>,
@@ -491,7 +492,11 @@ impl Instruction {
             Opcode::Lddw => {
                 match (&self.dst, &self.imm) {
                     (Some(dst), Some(imm)) => format!("{} r{}, {}", self.opcode, dst.n, imm),
-                    _ => format!("{} r0, 0", self.opcode),
+                    _ => return Err(SBPFError::BytecodeError {
+                        error: "Lddw instruction missing destination register or immediate value".to_string(),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // ldx - (load x) store a 8/16/32/64 bit (byte/half/word/double word)
@@ -502,7 +507,11 @@ impl Instruction {
             Opcode::Ldxdw => {
                 match &self.dst {
                     Some(dst) => format!("{} r{}, {}", self.opcode, dst.n, self.src_off()),
-                    None => format!("{} r0, {}", self.opcode, self.src_off()),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // stb - these instructions are deprecated
@@ -512,7 +521,11 @@ impl Instruction {
             Opcode::Stdw => {
                 match &self.imm {
                     Some(imm) => format!("{} {}, {}", self.opcode, self.dst_off(), imm),
-                    None => format!("{} {}, 0", self.opcode, self.dst_off()),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing immediate value", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // stx - store a 8/16/32/64 bit value from a source register into the offset
@@ -523,7 +536,11 @@ impl Instruction {
             Opcode::Stxdw => {
                 match &self.src {
                     Some(src) => format!("{} {}, r{}", self.opcode, self.dst_off(), src.n),
-                    None => format!("{} {}, r0", self.opcode, self.dst_off()),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing source register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // Math
@@ -531,7 +548,11 @@ impl Instruction {
             Opcode::Neg64 => {
                 match &self.dst {
                     Some(dst) => format!("{} r{}", self.opcode, dst.n),
-                    None => format!("{} r0", self.opcode),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // LE and BE OpCodes act a little differently to others. In assembly form, they are
@@ -542,7 +563,11 @@ impl Instruction {
             Opcode::Be => {
                 match &self.dst {
                     Some(dst) => format!("{}{}", self.op_imm_bits()?, dst.n),
-                    None => format!("{}0", self.op_imm_bits()?),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             }, // Docs for this seem wrong //DC01000010000000 DC01000020000000 DC01000040000000
             // Immedate
@@ -585,7 +610,11 @@ impl Instruction {
             Opcode::Srem64Imm => {
                 match (&self.dst, &self.imm) {
                     (Some(dst), Some(imm)) => format!("{} r{}, {}", self.opcode, dst.n, imm),
-                    _ => format!("{} r0, 0", self.opcode),
+                    _ => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination register or immediate value", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // Register
@@ -627,7 +656,11 @@ impl Instruction {
             Opcode::Srem64Reg => {
                 match (&self.dst, &self.src) {
                     (Some(dst), Some(src)) => format!("{} r{}, r{}", self.opcode, dst.n, src.n),
-                    _ => format!("{} r0, r0", self.opcode),
+                    _ => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination or source register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
 
@@ -648,7 +681,11 @@ impl Instruction {
             Opcode::JsleImm => {
                 match (&self.dst, &self.imm) {
                     (Some(dst), Some(imm)) => format!("{} r{}, {}, {}", self.opcode, dst.n, imm, self.off_str()),
-                    _ => format!("{} r0, 0, {}", self.opcode, self.off_str()),
+                    _ => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination register or immediate value", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             // Registers
@@ -665,7 +702,11 @@ impl Instruction {
             Opcode::JsleReg => {
                 match (&self.dst, &self.src) {
                     (Some(dst), Some(src)) => format!("{} r{}, r{}, {}", self.opcode, dst.n, src.n, self.off_str()),
-                    _ => format!("{} r0, r0, {}", self.opcode, self.off_str()),
+                    _ => return Err(SBPFError::BytecodeError {
+                        error: format!("{} instruction missing destination or source register", self.opcode),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
 
@@ -674,13 +715,21 @@ impl Instruction {
             Opcode::Call => {
                 match &self.imm {
                     Some(imm) => format!("call {}", imm),
-                    None => "call 0".to_string(),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: "Call instruction missing immediate value".to_string(),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             Opcode::Callx => {
                 match &self.src {
                     Some(src) => format!("call r{}", src.n),
-                    None => "call r0".to_string(),
+                    None => return Err(SBPFError::BytecodeError {
+                        error: "Callx instruction missing source register".to_string(),
+                        span: self.span.clone(),
+                        custom_label: None,
+                    }),
                 }
             },
             Opcode::Exit => format!("{}", self.opcode),

+ 2 - 1
crates/common/src/opcode.rs

@@ -2,8 +2,9 @@ use core::fmt;
 use core::str::FromStr;
 
 use num_derive::FromPrimitive;
+use serde::{Deserialize, Serialize};
 
-#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive)]
+#[derive(Debug, Clone, Copy, PartialEq, FromPrimitive, Serialize, Deserialize)]
 #[repr(u8)]
 pub enum Opcode {
     Lddw,

+ 1 - 0
crates/disassembler/Cargo.toml

@@ -16,6 +16,7 @@ name = "sbpf_disassembler"
 anyhow = { workspace = true }
 hex = "0.4.3"
 object = { workspace = true }
+sbpf-common = { workspace = true }
 thiserror = "2.0.17"
 serde = { version = "1.0.228", features = ["derive"] }
 serde_json = "1.0.145"

+ 11 - 0
crates/disassembler/src/errors.rs

@@ -1,3 +1,4 @@
+use sbpf_common::errors::SBPFError;
 use thiserror::Error;
 
 #[derive(Debug, Error)]
@@ -16,4 +17,14 @@ pub enum DisassemblerError {
     InvalidDataLength,
     #[error("Invalid string")]
     InvalidString,
+    #[error("Bytecode error: {0}")]
+    BytecodeError(String),
+}
+
+impl From<SBPFError> for DisassemblerError {
+    fn from(err: SBPFError) -> Self {
+        match err {
+            SBPFError::BytecodeError { error, .. } => DisassemblerError::BytecodeError(error),
+        }
+    }
 }

+ 0 - 255
crates/disassembler/src/instructions.rs

@@ -1,255 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-use crate::{errors::DisassemblerError, opcodes::OpCode};
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
-pub struct Ix {
-    pub op: OpCode,
-    pub dst: u8,
-    pub src: u8,
-    pub off: i16,
-    pub imm: i64,
-}
-
-impl Ix {
-    pub fn off_str(&self) -> String {
-        match self.off.is_negative() {
-            true => self.off.to_string(),
-            false => format!("+{}", self.off),
-        }
-    }
-
-    pub fn dst_off(&self) -> String {
-        format!("[r{}{}]", self.dst, self.off_str())
-    }
-
-    pub fn src_off(&self) -> String {
-        format!("[r{}{}]", self.src, self.off_str())
-    }
-
-    pub fn op_imm_bits(&self) -> Result<String, DisassemblerError> {
-        Ok(match self.imm {
-            16 => format!("{}16", self.op),
-            32 => format!("{}32", self.op),
-            64 => format!("{}64", self.op),
-            _ => return Err(DisassemblerError::InvalidImmediate),
-        })
-    }
-}
-
-impl Ix {
-    pub fn from_bytes(b: &[u8]) -> Result<Self, DisassemblerError> {
-        if b.len() < 8 {
-            return Err(DisassemblerError::InvalidDataLength);
-        }
-
-        let op = OpCode::try_from(b[0])?;
-        let reg = b[1];
-        let src = reg >> 4;
-        let dst = reg & 0x0f;
-        let off = i16::from_le_bytes([b[2], b[3]]);
-
-        let imm = match op {
-            OpCode::Lddw => {
-                if b.len() < 16 {
-                    return Err(DisassemblerError::InvalidDataLength);
-                }
-                let mut imm_bytes = [0u8; 8];
-                imm_bytes[0..4].copy_from_slice(&b[4..8]);
-
-                if u32::from_le_bytes([b[8], b[9], b[10], b[11]]) != 0 {
-                    return Err(DisassemblerError::InvalidImmediate);
-                }
-
-                imm_bytes[4..8].copy_from_slice(&b[12..16]);
-                i64::from_le_bytes(imm_bytes)
-            }
-            _ => i32::from_le_bytes([b[4], b[5], b[6], b[7]]) as i64,
-        };
-
-        Ok(Ix {
-            op,
-            src,
-            dst,
-            off,
-            imm,
-        })
-    }
-
-    pub fn to_bytes(&self) -> Vec<u8> {
-        let mut b = vec![self.op.clone() as u8, self.src << 4 | self.dst];
-        b.extend_from_slice(&self.off.to_le_bytes());
-        b.extend_from_slice(&self.imm.to_le_bytes()[..4]);
-        if self.op == OpCode::Lddw {
-            b.extend_from_slice(&[0; 4]);
-            b.extend_from_slice(&self.imm.to_le_bytes()[4..]);
-        }
-        b
-    }
-
-    pub fn to_asm(&self) -> Result<String, DisassemblerError> {
-        Ok(match self.op {
-            // lddw - (load double word) takes up two instructions. The 64 bit value
-            // is made up of two halves with the upper half being the immediate
-            // of the lddw value and the lower half being the immediate of the
-            // following instruction
-            OpCode::Lddw => format!("{} r{}, {}", self.op, self.dst, self.imm),
-            // ldx - (load x) store a 8/16/32/64 bit (byte/half/word/double word)
-            // value in a register
-            OpCode::Ldxb |
-            OpCode::Ldxh |
-            OpCode::Ldxw |
-            OpCode::Ldxdw => format!("{} r{}, {}", self.op, self.dst, self.src_off()),
-            // stb - these instructions are deprecated
-            OpCode::Stb |
-            OpCode::Sth |
-            OpCode::Stw |
-            OpCode::Stdw => format!("{} {}, {}", self.op, self.dst_off(), self.imm),
-            // stx - store a 8/16/32/64 bit value from a source register into the offset
-            // of the destination register
-            OpCode::Stxb |
-            OpCode::Stxh |
-            OpCode::Stxw |
-            OpCode::Stxdw => format!("{} {}, r{}", self.op, self.dst_off(), self.src),
-            // Math
-            OpCode::Neg32 | // Deprecated in SBFv2
-            OpCode::Neg64 => format!("{} r{}", self.op, self.dst),
-            // LE and BE OpCodes act a little differently to others. In assembly form, they are
-            // notated as be16, be32 and b64. In byte form, the bit length of the operation is 
-            // determined by the immedate value of its parent instruction, 0x10, 0x20 and 0x40
-            // accordingly (the hex of 16/32/64)
-            OpCode::Le |
-            OpCode::Be => format!("{}{}", self.op_imm_bits()?, self.dst), // Docs for this seem wrong //DC01000010000000 DC01000020000000 DC01000040000000
-            // Immedate
-            OpCode::Add32Imm |
-            OpCode::Sub32Imm |
-            OpCode::Mul32Imm |
-            OpCode::Div32Imm |
-            OpCode::Or32Imm |
-            OpCode::And32Imm |
-            OpCode::Lsh32Imm |
-            OpCode::Rsh32Imm |
-            OpCode::Mod32Imm |
-            OpCode::Xor32Imm |
-            OpCode::Arsh32Imm |
-            OpCode::Mov32Imm |
-            OpCode::Lmul32Imm |
-            OpCode::Udiv32Imm |
-            OpCode::Urem32Imm |
-            OpCode::Sdiv32Imm |
-            OpCode::Srem32Imm |
-            OpCode::Add64Imm |
-            OpCode::Sub64Imm |
-            OpCode::Mul64Imm |
-            OpCode::Div64Imm |
-            OpCode::Or64Imm |
-            OpCode::And64Imm |
-            OpCode::Lsh64Imm |
-            OpCode::Rsh64Imm |
-            OpCode::Mod64Imm |
-            OpCode::Xor64Imm |
-            OpCode::Mov64Imm |
-            OpCode::Arsh64Imm |
-            OpCode::Hor64Imm |
-            OpCode::Lmul64Imm |
-            OpCode::Uhmul64Imm |
-            OpCode::Udiv64Imm |
-            OpCode::Urem64Imm |
-            OpCode::Shmul64Imm |
-            OpCode::Sdiv64Imm |
-            OpCode::Srem64Imm => format!("{} r{}, {}", self.op, self.dst, self.imm),
-            // Register
-            OpCode::Add32Reg |
-            OpCode::Sub32Reg |
-            OpCode::Mul32Reg |
-            OpCode::Div32Reg |
-            OpCode::Or32Reg |
-            OpCode::And32Reg |
-            OpCode::Lsh32Reg |
-            OpCode::Rsh32Reg |
-            OpCode::Mod32Reg |
-            OpCode::Xor32Reg |
-            OpCode::Mov32Reg |
-            OpCode::Arsh32Reg |
-            OpCode::Lmul32Reg |
-            OpCode::Udiv32Reg |
-            OpCode::Urem32Reg |
-            OpCode::Sdiv32Reg |
-            OpCode::Srem32Reg |
-            OpCode::Add64Reg |
-            OpCode::Sub64Reg |
-            OpCode::Mul64Reg |
-            OpCode::Div64Reg |
-            OpCode::Or64Reg |
-            OpCode::And64Reg |
-            OpCode::Lsh64Reg |
-            OpCode::Rsh64Reg |
-            OpCode::Mod64Reg |
-            OpCode::Xor64Reg |
-            OpCode::Mov64Reg |
-            OpCode::Arsh64Reg |
-            OpCode::Lmul64Reg |
-            OpCode::Uhmul64Reg |
-            OpCode::Udiv64Reg |
-            OpCode::Urem64Reg |
-            OpCode::Shmul64Reg |
-            OpCode::Sdiv64Reg |
-            OpCode::Srem64Reg => format!("{} r{}, r{}", self.op, self.dst, self.src),
-
-            // Jumps
-            OpCode::Ja => format!("{} {}", self.op, self.off_str()),
-
-            // Immediates
-            OpCode::JeqImm |
-            OpCode::JgtImm |
-            OpCode::JgeImm |
-            OpCode::JltImm |
-            OpCode::JleImm |
-            OpCode::JsetImm |
-            OpCode::JneImm |
-            OpCode::JsgtImm |
-            OpCode::JsgeImm |
-            OpCode::JsltImm |
-            OpCode::JsleImm => format!("{} r{}, {}, {}", self.op, self.dst, self.imm, self.off_str()),
-            // Registers
-            OpCode::JeqReg |
-            OpCode::JgtReg |
-            OpCode::JgeReg |
-            OpCode::JltReg |
-            OpCode::JleReg |
-            OpCode::JsetReg |
-            OpCode::JneReg |
-            OpCode::JsgtReg |
-            OpCode::JsgeReg |
-            OpCode::JsltReg |
-            OpCode::JsleReg => format!("{} r{}, r{}, {}", self.op, self.dst, self.src, self.off_str()),
-
-
-            // Calls
-            OpCode::Call => format!("call {}", self.imm),
-            OpCode::Callx => format!("call r{}", self.src),
-            OpCode::Exit => format!("{}", self.op),
-        })
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use hex_literal::hex;
-
-    use crate::instructions::Ix;
-
-    #[test]
-    fn serialize_e2e() {
-        let b = hex!("9700000000000000");
-        let i = Ix::from_bytes(&b).unwrap();
-        assert_eq!(i.to_bytes(), &b);
-    }
-
-    #[test]
-    fn serialize_e2e_lddw() {
-        let b = hex!("18010000000000000000000000000000");
-        let i = Ix::from_bytes(&b).unwrap();
-        assert_eq!(i.to_bytes(), &b);
-    }
-}

+ 0 - 2
crates/disassembler/src/lib.rs

@@ -1,7 +1,5 @@
 pub mod elf_header;
 pub mod errors;
-pub mod instructions;
-pub mod opcodes;
 pub mod program;
 pub mod program_header;
 pub mod section_header;

+ 0 - 388
crates/disassembler/src/opcodes.rs

@@ -1,388 +0,0 @@
-use core::str;
-use std::fmt::Display;
-
-use serde::{Deserialize, Serialize};
-
-use crate::errors::DisassemblerError;
-
-#[repr(u8)]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
-pub enum OpCode {
-    Lddw = 0x18,
-    Ldxb = 0x71,
-    Ldxh = 0x69,
-    Ldxw = 0x61,
-    Ldxdw = 0x79,
-    Stb = 0x72,
-    Sth = 0x6a,
-    Stw = 0x62,
-    Stdw = 0x7a,
-    Stxb = 0x73,
-    Stxh = 0x6b,
-    Stxw = 0x63,
-    Stxdw = 0x7b,
-    Add32Imm = 0x04,
-    Add32Reg = 0x0c,
-    Sub32Imm = 0x14,
-    Sub32Reg = 0x1c,
-    Mul32Imm = 0x24,
-    Mul32Reg = 0x2c,
-    Div32Imm = 0x34,
-    Div32Reg = 0x3c,
-    Or32Imm = 0x44,
-    Or32Reg = 0x4c,
-    And32Imm = 0x54,
-    And32Reg = 0x5c,
-    Lsh32Imm = 0x64,
-    Lsh32Reg = 0x6c,
-    Rsh32Imm = 0x74,
-    Rsh32Reg = 0x7c,
-    Neg32 = 0x84,
-    Mod32Imm = 0x94,
-    Mod32Reg = 0x9c,
-    Xor32Imm = 0xa4,
-    Xor32Reg = 0xac,
-    Mov32Imm = 0xb4,
-    Mov32Reg = 0xbc,
-    Arsh32Imm = 0xc4,
-    Arsh32Reg = 0xcc,
-    Lmul32Imm = 0x86,
-    Lmul32Reg = 0x8e,
-    Udiv32Imm = 0x46,
-    Udiv32Reg = 0x4e,
-    Urem32Imm = 0x66,
-    Urem32Reg = 0x6e,
-    Sdiv32Imm = 0xc6,
-    Sdiv32Reg = 0xce,
-    Srem32Imm = 0xe6,
-    Srem32Reg = 0xee,
-    Le = 0xd4,
-    Be = 0xdc,
-    Add64Imm = 0x07,
-    Add64Reg = 0x0f,
-    Sub64Imm = 0x17,
-    Sub64Reg = 0x1f,
-    Mul64Imm = 0x27,
-    Mul64Reg = 0x2f,
-    Div64Imm = 0x37,
-    Div64Reg = 0x3f,
-    Or64Imm = 0x47,
-    Or64Reg = 0x4f,
-    And64Imm = 0x57,
-    And64Reg = 0x5f,
-    Lsh64Imm = 0x67,
-    Lsh64Reg = 0x6f,
-    Rsh64Imm = 0x77,
-    Rsh64Reg = 0x7f,
-    Neg64 = 0x87,
-    Mod64Imm = 0x97,
-    Mod64Reg = 0x9f,
-    Xor64Imm = 0xa7,
-    Xor64Reg = 0xaf,
-    Mov64Imm = 0xb7,
-    Mov64Reg = 0xbf,
-    Arsh64Imm = 0xc7,
-    Arsh64Reg = 0xcf,
-    Hor64Imm = 0xf7,
-    Lmul64Imm = 0x96,
-    Lmul64Reg = 0x9e,
-    Uhmul64Imm = 0x36,
-    Uhmul64Reg = 0x3e,
-    Udiv64Imm = 0x56,
-    Udiv64Reg = 0x5e,
-    Urem64Imm = 0x76,
-    Urem64Reg = 0x7e,
-    Shmul64Imm = 0xb6,
-    Shmul64Reg = 0xbe,
-    Sdiv64Imm = 0xd6,
-    Sdiv64Reg = 0xde,
-    Srem64Imm = 0xf6,
-    Srem64Reg = 0xfe,
-    Ja = 0x05,
-    JeqImm = 0x15,
-    JeqReg = 0x1d,
-    JgtImm = 0x25,
-    JgtReg = 0x2d,
-    JgeImm = 0x35,
-    JgeReg = 0x3d,
-    JltImm = 0xa5,
-    JltReg = 0xad,
-    JleImm = 0xb5,
-    JleReg = 0xbd,
-    JsetImm = 0x45,
-    JsetReg = 0x4d,
-    JneImm = 0x55,
-    JneReg = 0x5d,
-    JsgtImm = 0x65,
-    JsgtReg = 0x6d,
-    JsgeImm = 0x75,
-    JsgeReg = 0x7d,
-    JsltImm = 0xc5,
-    JsltReg = 0xcd,
-    JsleImm = 0xd5,
-    JsleReg = 0xdd,
-    Call = 0x85,
-    Callx = 0x8d,
-    Exit = 0x95,
-}
-
-impl Display for OpCode {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.write_str(Into::<&str>::into(self.clone()))
-    }
-}
-
-impl TryFrom<u8> for OpCode {
-    type Error = DisassemblerError;
-
-    fn try_from(value: u8) -> Result<Self, Self::Error> {
-        Ok(match value {
-            0x18 => OpCode::Lddw,
-            0x71 => OpCode::Ldxb,
-            0x69 => OpCode::Ldxh,
-            0x61 => OpCode::Ldxw,
-            0x79 => OpCode::Ldxdw,
-            0x72 => OpCode::Stb,
-            0x6a => OpCode::Sth,
-            0x62 => OpCode::Stw,
-            0x7a => OpCode::Stdw,
-            0x73 => OpCode::Stxb,
-            0x6b => OpCode::Stxh,
-            0x63 => OpCode::Stxw,
-            0x7b => OpCode::Stxdw,
-            0x04 => OpCode::Add32Imm,
-            0x0c => OpCode::Add32Reg,
-            0x14 => OpCode::Sub32Imm,
-            0x1c => OpCode::Sub32Reg,
-            0x24 => OpCode::Mul32Imm,
-            0x2c => OpCode::Mul32Reg,
-            0x34 => OpCode::Div32Imm,
-            0x3c => OpCode::Div32Reg,
-            0x44 => OpCode::Or32Imm,
-            0x4c => OpCode::Or32Reg,
-            0x54 => OpCode::And32Imm,
-            0x5c => OpCode::And32Reg,
-            0x64 => OpCode::Lsh32Imm,
-            0x6c => OpCode::Lsh32Reg,
-            0x74 => OpCode::Rsh32Imm,
-            0x7c => OpCode::Rsh32Reg,
-            0x84 => OpCode::Neg32,
-            0x94 => OpCode::Mod32Imm,
-            0x9c => OpCode::Mod32Reg,
-            0xa4 => OpCode::Xor32Imm,
-            0xac => OpCode::Xor32Reg,
-            0xb4 => OpCode::Mov32Imm,
-            0xbc => OpCode::Mov32Reg,
-            0xc4 => OpCode::Arsh32Imm,
-            0xcc => OpCode::Arsh32Reg,
-            0x86 => OpCode::Lmul32Imm,
-            0x8e => OpCode::Lmul32Reg,
-            0x46 => OpCode::Udiv32Imm,
-            0x4e => OpCode::Udiv32Reg,
-            0x66 => OpCode::Urem32Imm,
-            0x6e => OpCode::Urem32Reg,
-            0xc6 => OpCode::Sdiv32Imm,
-            0xce => OpCode::Sdiv32Reg,
-            0xe6 => OpCode::Srem32Imm,
-            0xee => OpCode::Srem32Reg,
-            0xd4 => OpCode::Le,
-            0xdc => OpCode::Be,
-            0x07 => OpCode::Add64Imm,
-            0x0f => OpCode::Add64Reg,
-            0x17 => OpCode::Sub64Imm,
-            0x1f => OpCode::Sub64Reg,
-            0x27 => OpCode::Mul64Imm,
-            0x2f => OpCode::Mul64Reg,
-            0x37 => OpCode::Div64Imm,
-            0x3f => OpCode::Div64Reg,
-            0x47 => OpCode::Or64Imm,
-            0x4f => OpCode::Or64Reg,
-            0x57 => OpCode::And64Imm,
-            0x5f => OpCode::And64Reg,
-            0x67 => OpCode::Lsh64Imm,
-            0x6f => OpCode::Lsh64Reg,
-            0x77 => OpCode::Rsh64Imm,
-            0x7f => OpCode::Rsh64Reg,
-            0x87 => OpCode::Neg64,
-            0x97 => OpCode::Mod64Imm,
-            0x9f => OpCode::Mod64Reg,
-            0xa7 => OpCode::Xor64Imm,
-            0xaf => OpCode::Xor64Reg,
-            0xb7 => OpCode::Mov64Imm,
-            0xbf => OpCode::Mov64Reg,
-            0xc7 => OpCode::Arsh64Imm,
-            0xcf => OpCode::Arsh64Reg,
-            0xf7 => OpCode::Hor64Imm,
-            0x96 => OpCode::Lmul64Imm,
-            0x9e => OpCode::Lmul64Reg,
-            0x36 => OpCode::Uhmul64Imm,
-            0x3e => OpCode::Uhmul64Reg,
-            0x56 => OpCode::Udiv64Imm,
-            0x5e => OpCode::Udiv64Reg,
-            0x76 => OpCode::Urem64Imm,
-            0x7e => OpCode::Urem64Reg,
-            0xb6 => OpCode::Shmul64Imm,
-            0xbe => OpCode::Shmul64Reg,
-            0xd6 => OpCode::Sdiv64Imm,
-            0xde => OpCode::Sdiv64Reg,
-            0xf6 => OpCode::Srem64Imm,
-            0xfe => OpCode::Srem64Reg,
-            0x05 => OpCode::Ja,
-            0x15 => OpCode::JeqImm,
-            0x1d => OpCode::JeqReg,
-            0x25 => OpCode::JgtImm,
-            0x2d => OpCode::JgtReg,
-            0x35 => OpCode::JgeImm,
-            0x3d => OpCode::JgeReg,
-            0xa5 => OpCode::JltImm,
-            0xad => OpCode::JltReg,
-            0xb5 => OpCode::JleImm,
-            0xbd => OpCode::JleReg,
-            0x45 => OpCode::JsetImm,
-            0x4d => OpCode::JsetReg,
-            0x55 => OpCode::JneImm,
-            0x5d => OpCode::JneReg,
-            0x65 => OpCode::JsgtImm,
-            0x6d => OpCode::JsgtReg,
-            0x75 => OpCode::JsgeImm,
-            0x7d => OpCode::JsgeReg,
-            0xc5 => OpCode::JsltImm,
-            0xcd => OpCode::JsltReg,
-            0xd5 => OpCode::JsleImm,
-            0xdd => OpCode::JsleReg,
-            0x85 => OpCode::Call,
-            0x8d => OpCode::Callx,
-            0x95 => OpCode::Exit,
-            _ => return Err(DisassemblerError::InvalidOpcode),
-        })
-    }
-}
-
-impl From<OpCode> for u8 {
-    fn from(val: OpCode) -> Self {
-        val as u8
-    }
-}
-
-impl From<OpCode> for &str {
-    fn from(val: OpCode) -> Self {
-        match val {
-            OpCode::Lddw => "lddw",
-            OpCode::Ldxb => "ldxb",
-            OpCode::Ldxh => "ldxh",
-            OpCode::Ldxw => "ldxw",
-            OpCode::Ldxdw => "ldxdw",
-            OpCode::Stb => "stb",
-            OpCode::Sth => "sth",
-            OpCode::Stw => "stw",
-            OpCode::Stdw => "stdw",
-            OpCode::Stxb => "stxb",
-            OpCode::Stxh => "stxh",
-            OpCode::Stxw => "stxw",
-            OpCode::Stxdw => "stxdw",
-            OpCode::Add32Imm => "add32",
-            OpCode::Add32Reg => "add32",
-            OpCode::Sub32Imm => "sub32",
-            OpCode::Sub32Reg => "sub32",
-            OpCode::Mul32Imm => "mul32",
-            OpCode::Mul32Reg => "mul32",
-            OpCode::Div32Imm => "div32",
-            OpCode::Div32Reg => "div32",
-            OpCode::Or32Imm => "or32",
-            OpCode::Or32Reg => "or32",
-            OpCode::And32Imm => "and32",
-            OpCode::And32Reg => "and32",
-            OpCode::Lsh32Imm => "lsh32",
-            OpCode::Lsh32Reg => "lsh32",
-            OpCode::Rsh32Imm => "rsh32",
-            OpCode::Rsh32Reg => "rsh32",
-            OpCode::Neg32 => "neg32",
-            OpCode::Mod32Imm => "mod32",
-            OpCode::Mod32Reg => "mod32",
-            OpCode::Xor32Imm => "xor32",
-            OpCode::Xor32Reg => "xor32",
-            OpCode::Mov32Imm => "mov32",
-            OpCode::Mov32Reg => "mov32",
-            OpCode::Arsh32Imm => "arsh32",
-            OpCode::Arsh32Reg => "arsh32",
-            OpCode::Lmul32Imm => "lmul32",
-            OpCode::Lmul32Reg => "lmul32",
-            OpCode::Udiv32Imm => "udiv32",
-            OpCode::Udiv32Reg => "udiv32",
-            OpCode::Urem32Imm => "urem32",
-            OpCode::Urem32Reg => "urem32",
-            OpCode::Sdiv32Imm => "sdiv32",
-            OpCode::Sdiv32Reg => "sdiv32",
-            OpCode::Srem32Imm => "srem32",
-            OpCode::Srem32Reg => "srem32",
-            OpCode::Le => "le",
-            OpCode::Be => "be",
-            OpCode::Add64Imm => "add64",
-            OpCode::Add64Reg => "add64",
-            OpCode::Sub64Imm => "sub64",
-            OpCode::Sub64Reg => "sub64",
-            OpCode::Mul64Imm => "mul64",
-            OpCode::Mul64Reg => "mul64",
-            OpCode::Div64Imm => "div64",
-            OpCode::Div64Reg => "div64",
-            OpCode::Or64Imm => "or64",
-            OpCode::Or64Reg => "or64",
-            OpCode::And64Imm => "and64",
-            OpCode::And64Reg => "and64",
-            OpCode::Lsh64Imm => "lsh64",
-            OpCode::Lsh64Reg => "lsh64",
-            OpCode::Rsh64Imm => "rsh64",
-            OpCode::Rsh64Reg => "rsh64",
-            OpCode::Neg64 => "neg64",
-            OpCode::Mod64Imm => "mod64",
-            OpCode::Mod64Reg => "mod64",
-            OpCode::Xor64Imm => "xor64",
-            OpCode::Xor64Reg => "xor64",
-            OpCode::Mov64Imm => "mov64",
-            OpCode::Mov64Reg => "mov64",
-            OpCode::Arsh64Imm => "arsh64",
-            OpCode::Arsh64Reg => "arsh64",
-            OpCode::Hor64Imm => "hor64",
-            OpCode::Lmul64Imm => "lmul64",
-            OpCode::Lmul64Reg => "lmul64",
-            OpCode::Uhmul64Imm => "uhmul64",
-            OpCode::Uhmul64Reg => "uhmul64",
-            OpCode::Udiv64Imm => "udiv64",
-            OpCode::Udiv64Reg => "udiv64",
-            OpCode::Urem64Imm => "urem64",
-            OpCode::Urem64Reg => "urem64",
-            OpCode::Shmul64Imm => "shmul64",
-            OpCode::Shmul64Reg => "shmul64",
-            OpCode::Sdiv64Imm => "sdiv64",
-            OpCode::Sdiv64Reg => "sdiv64",
-            OpCode::Srem64Imm => "srem64",
-            OpCode::Srem64Reg => "srem64",
-            OpCode::Ja => "ja",
-            OpCode::JeqImm => "jeq",
-            OpCode::JeqReg => "jeq",
-            OpCode::JgtImm => "jgt",
-            OpCode::JgtReg => "jgt",
-            OpCode::JgeImm => "jge",
-            OpCode::JgeReg => "jge",
-            OpCode::JltImm => "jlt",
-            OpCode::JltReg => "jlt",
-            OpCode::JleImm => "jle",
-            OpCode::JleReg => "jle",
-            OpCode::JsetImm => "jset",
-            OpCode::JsetReg => "jset",
-            OpCode::JneImm => "jne",
-            OpCode::JneReg => "jne",
-            OpCode::JsgtImm => "jsgt",
-            OpCode::JsgtReg => "jsgt",
-            OpCode::JsgeImm => "jsge",
-            OpCode::JsgeReg => "jsge",
-            OpCode::JsltImm => "jslt",
-            OpCode::JsltReg => "jslt",
-            OpCode::JsleImm => "jsle",
-            OpCode::JsleReg => "jsle",
-            OpCode::Call => "call",
-            OpCode::Callx => "callx",
-            OpCode::Exit => "exit",
-        }
-    }
-}

+ 1 - 1
crates/disassembler/src/section_header.rs

@@ -27,7 +27,7 @@ pub enum SectionHeaderType {
     SHT_FINI_ARRAY = 0x0F,    // Array of destructors
     SHT_PREINIT_ARRAY = 0x10, // Array of pre-constructors
     SHT_GROUP = 0x11,         // Section group
-    SHT_SYMTAB_SHNDX = 0x12,  //	Extended section indices
+    SHT_SYMTAB_SHNDX = 0x12,  // Extended section indices
     SHT_NUM = 0x13,           // Number of defined types.
 }
 

+ 25 - 19
crates/disassembler/src/section_header_entry.rs

@@ -2,7 +2,9 @@ use std::fmt::Debug;
 
 use serde::{Deserialize, Serialize};
 
-use crate::{errors::DisassemblerError, instructions::Ix};
+use crate::errors::DisassemblerError;
+use sbpf_common::instruction::Instruction;
+use sbpf_common::opcode::Opcode;
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct SectionHeaderEntry {
@@ -10,7 +12,7 @@ pub struct SectionHeaderEntry {
     pub offset: usize,
     pub data: Vec<u8>,
     #[serde(skip_serializing_if = "Vec::is_empty")]
-    pub ixs: Vec<Ix>,
+    pub ixs: Vec<Instruction>,
     #[serde(skip_serializing_if = "String::is_empty")]
     pub utf8: String,
 }
@@ -39,11 +41,11 @@ impl SectionHeaderEntry {
         self.offset
     }
 
-    pub fn to_ixs(&self) -> Result<Vec<Ix>, DisassemblerError> {
+    pub fn to_ixs(&self) -> Result<Vec<Instruction>, DisassemblerError> {
         if self.data.len() % 8 != 0 {
             return Err(DisassemblerError::InvalidDataLength);
         }
-        let mut ixs: Vec<Ix> = vec![];
+        let mut ixs: Vec<Instruction> = vec![];
         let mut pos = 0;
 
         while pos < self.data.len() {
@@ -52,8 +54,8 @@ impl SectionHeaderEntry {
                 break;
             }
 
-            let ix = Ix::from_bytes(remaining)?;
-            if ix.op == crate::opcodes::OpCode::Lddw {
+            let ix = Instruction::from_bytes(remaining)?;
+            if ix.opcode == Opcode::Lddw {
                 pos += 16;
             } else {
                 pos += 8;
@@ -72,7 +74,9 @@ impl SectionHeaderEntry {
 
 #[cfg(test)]
 mod test {
-    use crate::{instructions::Ix, opcodes::OpCode, section_header_entry::SectionHeaderEntry};
+    use crate::section_header_entry::SectionHeaderEntry;
+    use sbpf_common::instruction::{Instruction, Number, Register};
+    use sbpf_common::opcode::Opcode;
 
     #[test]
     fn serialize_e2e() {
@@ -84,19 +88,21 @@ mod test {
         let h = SectionHeaderEntry::new(".text\0".to_string(), 128, data.clone()).unwrap();
 
         let ixs = vec![
-            Ix {
-                op: OpCode::Lddw,
-                dst: 1,
-                src: 0,
-                off: 0,
-                imm: 0,
+            Instruction {
+                opcode: Opcode::Lddw,
+                dst: Some(Register { n: 1 }),
+                src: None,
+                off: None,
+                imm: Some(Number::Int(0)),
+                span: 0..24,
             },
-            Ix {
-                op: OpCode::Exit,
-                dst: 0,
-                src: 0,
-                off: 0,
-                imm: 0,
+            Instruction {
+                opcode: Opcode::Exit,
+                dst: Some(Register { n: 0 }),
+                src: None,
+                off: None,
+                imm: None,
+                span: 0..8,
             },
         ];
         assert_eq!(ixs, h.to_ixs().unwrap());