diff options
Diffstat (limited to 'src/armv8')
| -rw-r--r-- | src/armv8/a64.rs | 64 | 
1 files changed, 40 insertions, 24 deletions
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index 68f2337..4c9da27 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -7,6 +7,8 @@ use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, Read  #[allow(non_snake_case)]  mod docs { +    use crate::armv8::a64::DecodeError; +      #[test]      fn test_ones() {          assert_eq!(Ones(0), 0x00); @@ -77,9 +79,12 @@ mod docs {      }      // helper functions from the ARMv8 Architecture Reference Manual -    pub fn DecodeBitMasks_32(immN: u8, imms: u8, immr: u8) -> (u32, u32) { +    pub fn DecodeBitMasks_32(immN: u8, imms: u8, immr: u8) -> Result<(u32, u32), DecodeError> {          // should the !imms be ~imms          let len = HighestSetBit(7, ((immN << 6) | ((!imms) & 0x3f)) as u64); +        if len == 0xff { +            return Err(DecodeError::InvalidOperand); +        }          let levels = (Ones(len) & 0x3f) as u8; // should ZeroExtend to at least 6 bits, but this is u8. @@ -93,12 +98,15 @@ mod docs {          let telem = Ones(d + 1);          let wmask = Replicate(ROR(welem, esize, R), esize, 32) as u32;          let tmask = Replicate(telem, esize, 32) as u32; -        (wmask, tmask) +        Ok((wmask, tmask))      } -    pub fn DecodeBitMasks_64(immN: u8, imms: u8, immr: u8) -> (u64, u64) { +    pub fn DecodeBitMasks_64(immN: u8, imms: u8, immr: u8) -> Result<(u64, u64), DecodeError> {          // should the !imms be ~imms          let len = HighestSetBit(7, ((immN << 6) | ((!imms) & 0x3f)) as u64); +        if len == 0xff { +            return Err(DecodeError::InvalidOperand); +        }          let levels = (Ones(len) & 0x3f) as u8; // should ZeroExtend to at least 6 bits, but this is u8. @@ -112,7 +120,7 @@ mod docs {          let telem = Ones(d + 1);          let wmask = Replicate(ROR(welem, esize, R), esize, 64);          let tmask = Replicate(telem, esize, 64); -        (wmask, tmask) +        Ok((wmask, tmask))      }      pub fn DecodeShift(op: u8) -> super::ShiftStyle { @@ -1560,8 +1568,8 @@ impl Decoder<ARMv8> for InstDecoder {                              Operand::Register(size, Rd),                              Operand::Register(size, Rn),                              match size { -                                SizeCode::W => Operand::Immediate(docs::DecodeBitMasks_32(N as u8, imms as u8, immr as u8).0), -                                SizeCode::X => Operand::Imm64(docs::DecodeBitMasks_64(N as u8, imms as u8, immr as u8).0) +                                SizeCode::W => Operand::Immediate(docs::DecodeBitMasks_32(N as u8, imms as u8, immr as u8)?.0), +                                SizeCode::X => Operand::Imm64(docs::DecodeBitMasks_64(N as u8, imms as u8, immr as u8)?.0)                              },                              Operand::Nothing                          ]; @@ -1785,7 +1793,7 @@ impl Decoder<ARMv8> for InstDecoder {                                          Operand::Nothing,                                      ];                                  } else { -                                    unreachable!("Lo checked for validity already"); +                                    return Err(DecodeError::InvalidOpcode);                                  };                                  if size == 0b00 {                                      match (Lo1, o0) { @@ -1949,7 +1957,8 @@ impl Decoder<ARMv8> for InstDecoder {                                  SizeCode::X                              }                              0b11 => { -                                unimplemented!("PRFM is not supported"); +                                // PRFM is not supported +                                return Err(DecodeError::IncompleteDecoder);                              }                              _ => {                                  unreachable!("opc is two bits"); @@ -1997,13 +2006,15 @@ impl Decoder<ARMv8> for InstDecoder {                          // load/store no-allocate pair (offset)                          // V == 0                          let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); -                        unimplemented!("C3.3.7 V==0, opc_L: {}", opc_L); +                        // eprintln!("C3.3.7 V==0, opc_L: {}", opc_L); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b10100 => {                          // load/store no-allocate pair (offset)                          // V == 1                          let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); -                        unimplemented!("C3.3.7 V==1, opc_L: {}", opc_L); +                        // eprintln!("C3.3.7 V==1, opc_L: {}", opc_L); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b10001 => {                          // load/store register pair (post-indexed) @@ -2120,7 +2131,8 @@ impl Decoder<ARMv8> for InstDecoder {                          // load/store register pair (offset)                          // V == 1                          let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); -                        unimplemented!("C3.3.14 V==1, opc_L: {}", opc_L); +                        // eprintln!("C3.3.14 V==1, opc_L: {}", opc_L); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b10011 => {                          // load/store register pair (pre-indexed) @@ -2178,7 +2190,8 @@ impl Decoder<ARMv8> for InstDecoder {                          // load/store register pair (pre-indexed)                          // V == 1                          let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); -                        unimplemented!("C3.3.16 V==1, opc_L: {}", opc_L); +                        // eprintln!("C3.3.16 V==1, opc_L: {}", opc_L); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b11000 |                      0b11001 => { @@ -2257,7 +2270,8 @@ impl Decoder<ARMv8> for InstDecoder {                                          SizeCode::X                                      },                                      0b1110 => { -                                        unimplemented!("PRFM is not supported yet"); +                                        // eprintln!("PRFM is not supported yet"); +                                        return Err(DecodeError::IncompleteDecoder);  //                                        inst.opcode = Opcode::PRFM;  //                                        SizeCode::X                                      }, @@ -2371,7 +2385,8 @@ impl Decoder<ARMv8> for InstDecoder {                                              SizeCode::X                                          }                                          0b1110 => { -                                            unimplemented!("PRFUM not handled yet"); +                                            // eprintln!("PRFUM not handled yet"); +                                            return Err(DecodeError::IncompleteDecoder);                                          },                                          0b1111 => {                                              inst.opcode = Opcode::Invalid; @@ -2556,7 +2571,7 @@ impl Decoder<ARMv8> for InstDecoder {                           * unprivileged, immediate pre-indexd, register offset}                           * V == 1                           */ -                        unimplemented!("load/store register (unscaled immediate), load/store register (immediate post-indexed), V==1"); +                        return Err(DecodeError::IncompleteDecoder);                      }                      0b11010 |                      0b11011 => { @@ -2686,7 +2701,8 @@ impl Decoder<ARMv8> for InstDecoder {                                  ];                              }                              0b1110 => { -                                unimplemented!("PRFM not yet supported"); +                                // PRFM not yet supported +                                return Err(DecodeError::IncompleteDecoder);                              }                              0b1111 => { inst.opcode = Opcode::Invalid; }                              _ => { unreachable!("size and opc are four bits"); } @@ -2696,23 +2712,23 @@ impl Decoder<ARMv8> for InstDecoder {                      0b11111 => {                          // load/store register (unsigned immediate)                          // V == 1 -                        unimplemented!("load/store register (unsigned immediate) V==1"); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b00100 => {                          // AdvSIMD load/store multiple structures -                        unimplemented!("AdvSIMD load/store multiple structures"); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b00101 => {                          // AdvSIMD load/store multiple structures (post-indexed) -                        unimplemented!("AdvSIMD load/store multiple structures (post-indexed)"); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b00110 => {                          // AdvSIMD load/store single structure -                        unimplemented!("AdvSIMD load/store single structure"); +                        return Err(DecodeError::IncompleteDecoder);                      },                      0b00111 => {                          // AdvSIMD load/store single structure (post-indexed) -                        unimplemented!("AdvSIMD load/store single structures (post-indexed)"); +                        return Err(DecodeError::IncompleteDecoder);                      }                      _ => {                          inst.opcode = Opcode::Invalid; @@ -2952,7 +2968,7 @@ impl Decoder<ARMv8> for InstDecoder {                                  }                                  0b001 => {                                      inst.opcode = Opcode::SYS; -                                    panic!("TODO"); +                                    return Err(DecodeError::IncompleteDecoder);                                  }                                  0b010 |                                  0b011 => { @@ -2963,7 +2979,7 @@ impl Decoder<ARMv8> for InstDecoder {                                  }                                  0b101 => {                                      inst.opcode = Opcode::SYSL; -                                    panic!("TODO"); +                                    return Err(DecodeError::IncompleteDecoder);                                  }                                  0b110 |                                  0b111 => { @@ -3047,7 +3063,7 @@ impl Decoder<ARMv8> for InstDecoder {                      }                      _ => {                          // TODO: invalid -                        panic!("Illegal instruction"); +                        return Err(DecodeError::InvalidOpcode);                      }                  }              },  | 
