diff --git a/arch/BPF/BPFDisassembler.c b/arch/BPF/BPFDisassembler.c index cc137c0171..6b3e00bdac 100644 --- a/arch/BPF/BPFDisassembler.c +++ b/arch/BPF/BPFDisassembler.c @@ -277,13 +277,12 @@ static bool decodeALU(cs_struct *ud, MCInst *MI, bpf_internal *bpf) if (BPF_OP(bpf->op) > BPF_ALU_END) return false; - /* ALU64 class doesn't have ENDian */ /* ENDian's imm must be one of 16, 32, 64 */ if (BPF_OP(bpf->op) == BPF_ALU_END) { - if (BPF_CLASS(bpf->op) == BPF_CLASS_ALU64) - return false; if (bpf->k != 16 && bpf->k != 32 && bpf->k != 64) return false; + if (BPF_CLASS(bpf->op) == BPF_CLASS_ALU64 && BPF_SRC(bpf->op) != BPF_SRC_LITTLE) + return false; } /* - op dst, imm diff --git a/arch/BPF/BPFMapping.c b/arch/BPF/BPFMapping.c index c2b7979462..17d3c55710 100644 --- a/arch/BPF/BPFMapping.c +++ b/arch/BPF/BPFMapping.c @@ -69,6 +69,9 @@ static const name_map insn_name_maps[BPF_INS_ENDING] = { { BPF_INS_BE16, "be16" }, { BPF_INS_BE32, "be32" }, { BPF_INS_BE64, "be64" }, + { BPF_INS_BSWAP16, "bswap16" }, + { BPF_INS_BSWAP32, "bswap32" }, + { BPF_INS_BSWAP64, "bswap64" }, { BPF_INS_LDW, "ldw" }, { BPF_INS_LDH, "ldh" }, @@ -211,6 +214,19 @@ static bpf_insn op2insn_alu(unsigned opcode) { /* Endian is a special case */ if (BPF_OP(opcode) == BPF_ALU_END) { + if (BPF_CLASS(opcode) == BPF_CLASS_ALU64) { + switch (opcode ^ BPF_CLASS_ALU64 ^ BPF_ALU_END ^ BPF_SRC_LITTLE) { + case (16 << 4): + return BPF_INS_BSWAP16; + case (32 << 4): + return BPF_INS_BSWAP32; + case (64 << 4): + return BPF_INS_BSWAP64; + default: + return BPF_INS_INVALID; + } + } + switch (opcode ^ BPF_CLASS_ALU ^ BPF_ALU_END) { case BPF_SRC_LITTLE | (16 << 4): return BPF_INS_LE16; diff --git a/bindings/python/capstone/bpf_const.py b/bindings/python/capstone/bpf_const.py index 671eca81bd..2dad952825 100644 --- a/bindings/python/capstone/bpf_const.py +++ b/bindings/python/capstone/bpf_const.py @@ -62,43 +62,46 @@ BPF_INS_BE16 = 30 BPF_INS_BE32 = 31 BPF_INS_BE64 = 32 -BPF_INS_LDW = 33 -BPF_INS_LDH = 34 -BPF_INS_LDB = 35 -BPF_INS_LDDW = 36 -BPF_INS_LDXW = 37 -BPF_INS_LDXH = 38 -BPF_INS_LDXB = 39 -BPF_INS_LDXDW = 40 -BPF_INS_STW = 41 -BPF_INS_STH = 42 -BPF_INS_STB = 43 -BPF_INS_STDW = 44 -BPF_INS_STXW = 45 -BPF_INS_STXH = 46 -BPF_INS_STXB = 47 -BPF_INS_STXDW = 48 -BPF_INS_XADDW = 49 -BPF_INS_XADDDW = 50 -BPF_INS_JMP = 51 -BPF_INS_JEQ = 52 -BPF_INS_JGT = 53 -BPF_INS_JGE = 54 -BPF_INS_JSET = 55 -BPF_INS_JNE = 56 -BPF_INS_JSGT = 57 -BPF_INS_JSGE = 58 -BPF_INS_CALL = 59 -BPF_INS_CALLX = 60 -BPF_INS_EXIT = 61 -BPF_INS_JLT = 62 -BPF_INS_JLE = 63 -BPF_INS_JSLT = 64 -BPF_INS_JSLE = 65 -BPF_INS_RET = 66 -BPF_INS_TAX = 67 -BPF_INS_TXA = 68 -BPF_INS_ENDING = 69 +BPF_INS_BSWAP16 = 33 +BPF_INS_BSWAP32 = 34 +BPF_INS_BSWAP64 = 35 +BPF_INS_LDW = 36 +BPF_INS_LDH = 37 +BPF_INS_LDB = 38 +BPF_INS_LDDW = 39 +BPF_INS_LDXW = 40 +BPF_INS_LDXH = 41 +BPF_INS_LDXB = 42 +BPF_INS_LDXDW = 43 +BPF_INS_STW = 44 +BPF_INS_STH = 45 +BPF_INS_STB = 46 +BPF_INS_STDW = 47 +BPF_INS_STXW = 48 +BPF_INS_STXH = 49 +BPF_INS_STXB = 50 +BPF_INS_STXDW = 51 +BPF_INS_XADDW = 52 +BPF_INS_XADDDW = 53 +BPF_INS_JMP = 54 +BPF_INS_JEQ = 55 +BPF_INS_JGT = 56 +BPF_INS_JGE = 57 +BPF_INS_JSET = 58 +BPF_INS_JNE = 59 +BPF_INS_JSGT = 60 +BPF_INS_JSGE = 61 +BPF_INS_CALL = 62 +BPF_INS_CALLX = 63 +BPF_INS_EXIT = 64 +BPF_INS_JLT = 65 +BPF_INS_JLE = 66 +BPF_INS_JSLT = 67 +BPF_INS_JSLE = 68 +BPF_INS_RET = 69 +BPF_INS_TAX = 70 +BPF_INS_TXA = 71 +BPF_INS_ENDING = 72 BPF_INS_LD = BPF_INS_LDW BPF_INS_LDX = BPF_INS_LDXW BPF_INS_ST = BPF_INS_STW diff --git a/include/capstone/bpf.h b/include/capstone/bpf.h index 5a5c927d51..12c8d1d0ea 100644 --- a/include/capstone/bpf.h +++ b/include/capstone/bpf.h @@ -131,6 +131,9 @@ typedef enum bpf_insn { BPF_INS_BE16, BPF_INS_BE32, BPF_INS_BE64, + BPF_INS_BSWAP16, + BPF_INS_BSWAP32, + BPF_INS_BSWAP64, ///< Load BPF_INS_LDW, ///< eBPF only diff --git a/suite/cstest/issues.cs b/suite/cstest/issues.cs index fecd353716..841b0bc52a 100644 --- a/suite/cstest/issues.cs +++ b/suite/cstest/issues.cs @@ -1,3 +1,15 @@ +!# issue 2323 eBPF bswap16 instruction +!# CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN+CS_MODE_BPF_EXTENDED, CS_OPT_DETAIL +0xd7,0x53,0x3f,0x0c,0x10,0x00,0x00,0x00 == bswap16 r3 + +!# issue 2323 eBPF bswap32 instruction +!# CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN+CS_MODE_BPF_EXTENDED, CS_OPT_DETAIL +0xd7,0x53,0x3f,0x0c,0x20,0x00,0x00,0x00 == bswap32 r3 + +!# issue 2323 eBPF bswap64 instruction +!# CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN+CS_MODE_BPF_EXTENDED, CS_OPT_DETAIL +0xd7,0x53,0x3f,0x0c,0x40,0x00,0x00,0x00 == bswap64 r3 + !# issue 2258 vcmpunordss incorrect read/modified register !# CS_ARCH_X86, CS_MODE_64, CS_OPT_DETAIL 0x62,0xd1,0x56,0x08,0xc2,0xca,0x03 == vcmpunordss k1, xmm5, xmm10 ; operands[0].access: WRITE ; operands[1].access: READ ; operands[2].access: READ