LCOV - code coverage report
Current view: top level - src/assembly - instruction.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 0.0 % 112 0
Test Date: 2024-11-30:00:00:00 Functions: 0.0 % 20 0

            Line data    Source code
       1              : //! Module related to assembly instructions
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::to_slice;
       6              : 
       7              : use crate::common::FromFFI;
       8              : 
       9              : use super::aarch64;
      10              : use super::x86;
      11              : use super::arm;
      12              : use super::mips;
      13              : use super::powerpc;
      14              : use super::riscv;
      15              : use super::ebpf;
      16              : 
      17              : /// This trait is shared by all [`Instructions`] supported by LIEF
      18              : pub trait Instruction {
      19              :     #[doc(hidden)]
      20              :     fn as_generic(&self) -> &ffi::asm_Instruction;
      21              : 
      22              :     /// Address of the instruction
      23            0 :     fn address(&self) -> u64 {
      24            0 :         self.as_generic().address()
      25            0 :     }
      26              : 
      27              :     /// Size of the instruction in bytes
      28            0 :     fn size(&self) -> u64 {
      29            0 :         self.as_generic().size()
      30            0 :     }
      31              : 
      32              :     /// Raw bytes of the current instruction
      33            0 :     fn raw(&self) -> &[u8] {
      34            0 :         to_slice!(self.as_generic().raw());
      35            0 :     }
      36              : 
      37              :     /// Instruction mnemonic (e.g. `br`)
      38            0 :     fn mnemonic(&self) -> String {
      39            0 :         self.as_generic().mnemonic().to_string()
      40            0 :     }
      41              : 
      42              :     /// Representation of the current instruction in a pretty assembly way
      43            0 :     fn to_string(&self) -> String {
      44            0 :         self.as_generic().to_string().to_string()
      45            0 :     }
      46              : 
      47              :     /// Same as [`Instruction::to_string`] but without the address as prefix
      48            0 :     fn to_string_no_address(&self) -> String {
      49            0 :         self.as_generic().to_string_no_address().to_string()
      50            0 :     }
      51              : 
      52              :     /// True if the instruction is a call
      53            0 :     fn is_call(&self) -> bool {
      54            0 :         self.as_generic().is_call()
      55            0 :     }
      56              : 
      57              :     /// True if the instruction marks the end of a basic block
      58            0 :     fn is_terminator(&self) -> bool {
      59            0 :         self.as_generic().is_terminator()
      60            0 :     }
      61              : 
      62              :     /// True if the instruction is a branch
      63            0 :     fn is_branch(&self) -> bool {
      64            0 :         self.as_generic().is_branch()
      65            0 :     }
      66              : 
      67              :     /// True if the instruction is a syscall
      68            0 :     fn is_syscall(&self) -> bool {
      69            0 :         self.as_generic().is_syscall()
      70            0 :     }
      71              : }
      72              : 
      73              : /// All instruction variants supported by LIEF
      74              : pub enum Instructions {
      75              :     /// An AArch64 instruction
      76              :     AArch64(aarch64::Instruction),
      77              : 
      78              :     /// A x86/x86-64 instruction
      79              :     X86(x86::Instruction),
      80              : 
      81              :     /// An ARM/thumb instruction
      82              :     ARM(arm::Instruction),
      83              : 
      84              :     /// An eBPF instruction
      85              :     EBPF(ebpf::Instruction),
      86              : 
      87              :     /// A PowerPC (ppc64/ppc32) instruction
      88              :     PowerPC(powerpc::Instruction),
      89              : 
      90              :     /// A Mips (mips32/mips64) instruction
      91              :     Mips(mips::Instruction),
      92              : 
      93              :     /// A RISC-V (32 or 64 bit) instruction
      94              :     RiscV(riscv::Instruction),
      95              : 
      96              :     /// A generic instruction that doesn't have an extended structure
      97              :     Generic(Generic),
      98              : }
      99              : 
     100              : impl FromFFI<ffi::asm_Instruction> for Instructions {
     101            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_Instruction>) -> Self {
     102            0 :         unsafe {
     103            0 :            let inst_ref = ptr.as_ref().unwrap();
     104            0 :            if ffi::asm_aarch64_Instruction::classof(inst_ref) {
     105            0 :                let raw = {
     106            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     107            0 :                    type To   = cxx::UniquePtr<ffi::asm_aarch64_Instruction>;
     108            0 :                    std::mem::transmute::<From, To>(ptr)
     109            0 :                };
     110            0 :                return Instructions::AArch64(aarch64::Instruction::from_ffi(raw));
     111              :            }
     112            0 :            else if ffi::asm_x86_Instruction::classof(inst_ref) {
     113            0 :                let raw = {
     114            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     115            0 :                    type To   = cxx::UniquePtr<ffi::asm_x86_Instruction>;
     116            0 :                    std::mem::transmute::<From, To>(ptr)
     117            0 :                };
     118            0 :                return Instructions::X86(x86::Instruction::from_ffi(raw));
     119              :            }
     120            0 :            else if ffi::asm_arm_Instruction::classof(inst_ref) {
     121            0 :                let raw = {
     122            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     123            0 :                    type To   = cxx::UniquePtr<ffi::asm_arm_Instruction>;
     124            0 :                    std::mem::transmute::<From, To>(ptr)
     125            0 :                };
     126            0 :                return Instructions::ARM(arm::Instruction::from_ffi(raw));
     127              :            }
     128            0 :            else if ffi::asm_mips_Instruction::classof(inst_ref) {
     129            0 :                let raw = {
     130            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     131            0 :                    type To   = cxx::UniquePtr<ffi::asm_mips_Instruction>;
     132            0 :                    std::mem::transmute::<From, To>(ptr)
     133            0 :                };
     134            0 :                return Instructions::Mips(mips::Instruction::from_ffi(raw));
     135              :            }
     136            0 :            else if ffi::asm_powerpc_Instruction::classof(inst_ref) {
     137            0 :                let raw = {
     138            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     139            0 :                    type To   = cxx::UniquePtr<ffi::asm_powerpc_Instruction>;
     140            0 :                    std::mem::transmute::<From, To>(ptr)
     141            0 :                };
     142            0 :                return Instructions::PowerPC(powerpc::Instruction::from_ffi(raw));
     143              :            }
     144            0 :            else if ffi::asm_riscv_Instruction::classof(inst_ref) {
     145            0 :                let raw = {
     146            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     147            0 :                    type To   = cxx::UniquePtr<ffi::asm_riscv_Instruction>;
     148            0 :                    std::mem::transmute::<From, To>(ptr)
     149            0 :                };
     150            0 :                return Instructions::RiscV(riscv::Instruction::from_ffi(raw));
     151              :            }
     152              : 
     153            0 :            else if ffi::asm_ebpf_Instruction::classof(inst_ref) {
     154            0 :                let raw = {
     155            0 :                    type From = cxx::UniquePtr<ffi::asm_Instruction>;
     156            0 :                    type To   = cxx::UniquePtr<ffi::asm_ebpf_Instruction>;
     157            0 :                    std::mem::transmute::<From, To>(ptr)
     158            0 :                };
     159            0 :                return Instructions::EBPF(ebpf::Instruction::from_ffi(raw));
     160            0 :            }
     161            0 :            return Instructions::Generic(Generic::from_ffi(ptr));
     162              :         }
     163            0 :     }
     164              : }
     165              : 
     166              : impl Instruction for Instructions {
     167              :     #[doc(hidden)]
     168            0 :     fn as_generic(&self) -> &ffi::asm_Instruction {
     169            0 :         match &self {
     170            0 :             Instructions::Generic(inst) => {
     171            0 :                 inst.as_generic()
     172              :             }
     173            0 :             Instructions::AArch64(inst) => {
     174            0 :                 inst.as_generic()
     175              :             }
     176            0 :             Instructions::X86(inst) => {
     177            0 :                 inst.as_generic()
     178              :             }
     179            0 :             Instructions::ARM(inst) => {
     180            0 :                 inst.as_generic()
     181              :             }
     182            0 :             Instructions::Mips(inst) => {
     183            0 :                 inst.as_generic()
     184              :             }
     185            0 :             Instructions::PowerPC(inst) => {
     186            0 :                 inst.as_generic()
     187              :             }
     188            0 :             Instructions::EBPF(inst) => {
     189            0 :                 inst.as_generic()
     190              :             }
     191            0 :             Instructions::RiscV(inst) => {
     192            0 :                 inst.as_generic()
     193              :             }
     194              :         }
     195            0 :     }
     196              : }
     197              : 
     198              : /// Generic Instruction
     199              : pub struct Generic {
     200              :     ptr: cxx::UniquePtr<ffi::asm_Instruction>,
     201              : }
     202              : 
     203              : impl FromFFI<ffi::asm_Instruction> for Generic {
     204            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_Instruction>) -> Self {
     205            0 :         Self {
     206            0 :             ptr,
     207            0 :         }
     208            0 :     }
     209              : }
     210              : 
     211              : impl Instruction for Generic {
     212              :     #[doc(hidden)]
     213            0 :     fn as_generic(&self) -> &ffi::asm_Instruction {
     214            0 :         self.ptr.as_ref().unwrap()
     215            0 :     }
     216              : }
        

Generated by: LCOV version 2.1-1