From a8b2529facfbabfe4c8a0ca1a4387fe482d1c955 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 10 Aug 2016 12:41:21 +0530 Subject: [PATCH] Fix bpf disassembler for _FORTIFY_SOURCE It's illegal to skip positional operands for printf. Rearrange the printing of the instructions to use exactly the operands required. Also, fix printing of mod operations: s/%/%%/ in the print format. Also, fix printing of endian operations: remove extra spaces. --- libcpu/ChangeLog | 7 +- libcpu/bpf_disasm.c | 539 ++++++++++++++++++++--------- tests/ChangeLog | 7 +- tests/testfile-bpf-dis1.expect.bz2 | Bin 1497 -> 1467 bytes 4 files changed, 378 insertions(+), 175 deletions(-) diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog index 269e777b8..9f3566c02 100644 --- a/libcpu/ChangeLog +++ b/libcpu/ChangeLog @@ -1,4 +1,9 @@ -2016-06-28 Richard Henderson +2016-08-10 Richard Henderson + + * bpf_disasm.c (bpf_disasm): Rearrange the printing of instructions + to use exactly the operands required. + +2016-06-28 Richard Henderson * Makefile.am (noinst_LIBRARIES): Add libcpu_bpf.a. (libcpu_bpf_a_SOURCES, libcpu_bpf_a_CFLAGS): New. diff --git a/libcpu/bpf_disasm.c b/libcpu/bpf_disasm.c index 6301dccca..153dba9d2 100644 --- a/libcpu/bpf_disasm.c +++ b/libcpu/bpf_disasm.c @@ -52,136 +52,24 @@ static const char class_string[8][8] = { [BPF_ALU64] = "alu64", }; -/* Dest = 1$, Src = 2$, Imm = 3$, Off = 4$, Branch = 5$. */ - -#define DST "r%1$d" -#define DSTU "(u32)" DST -#define DSTS "(s64)" DST - -#define SRC "r%2$d" -#define SRCU "(u32)" SRC -#define SRCS "(s64)" SRC - -#define IMMS "%3$d" -#define IMMX "%3$#x" -#define OFF "%4$+d" -#define JMP "%5$#x" - -#define A32(O, S) DST " = " DSTU " " #O " " S -#define A64(O, S) DST " " #O "= " S -#define J64(D, O, S) "if " D " " #O " " S " goto " JMP -#define LOAD(T) DST " = *(" #T " *)(" SRC OFF ")" -#define STORE(T, S) "*(" #T " *)(" DST OFF ") = " S -#define XADD(T, S) "lock *(" #T " *)(" DST OFF ") += " S -#define LDSKB(T, S) "r0 = *(" #T " *)skb[" S "]" -/* 8 character field between opcode and arguments. */ -static const char * const code_fmts[256] = { - [BPF_ALU | BPF_ADD | BPF_K] = A32(+, IMMS), - [BPF_ALU | BPF_SUB | BPF_K] = A32(-, IMMS), - [BPF_ALU | BPF_MUL | BPF_K] = A32(*, IMMS), - [BPF_ALU | BPF_DIV | BPF_K] = A32(/, IMMS), - [BPF_ALU | BPF_OR | BPF_K] = A32(|, IMMX), - [BPF_ALU | BPF_AND | BPF_K] = A32(&, IMMX), - [BPF_ALU | BPF_LSH | BPF_K] = A32(<<, IMMS), - [BPF_ALU | BPF_RSH | BPF_K] = A32(>>, IMMS), - [BPF_ALU | BPF_MOD | BPF_K] = A32(%, IMMS), - [BPF_ALU | BPF_XOR | BPF_K] = A32(^, IMMX), - [BPF_ALU | BPF_MOV | BPF_K] = DST " = " IMMX, - [BPF_ALU | BPF_ARSH | BPF_K] = DST " = (u32)((s32)" DST " >> " IMMS ")", - - [BPF_ALU | BPF_ADD | BPF_X] = A32(+, SRCU), - [BPF_ALU | BPF_SUB | BPF_X] = A32(-, SRCU), - [BPF_ALU | BPF_MUL | BPF_X] = A32(*, SRCU), - [BPF_ALU | BPF_DIV | BPF_X] = A32(/, SRCU), - [BPF_ALU | BPF_OR | BPF_X] = A32(|, SRCU), - [BPF_ALU | BPF_AND | BPF_X] = A32(&, SRCU), - [BPF_ALU | BPF_LSH | BPF_X] = A32(<<, SRCU), - [BPF_ALU | BPF_RSH | BPF_X] = A32(>>, SRCU), - [BPF_ALU | BPF_MOD | BPF_X] = A32(%, SRCU), - [BPF_ALU | BPF_XOR | BPF_X] = A32(^, SRCU), - [BPF_ALU | BPF_MOV | BPF_X] = DST " = " SRCU, - [BPF_ALU | BPF_ARSH | BPF_X] = DST " = (u32)((s32)" DST " >> " SRC ")", - - [BPF_ALU64 | BPF_ADD | BPF_K] = A64(+, IMMS), - [BPF_ALU64 | BPF_SUB | BPF_K] = A64(-, IMMS), - [BPF_ALU64 | BPF_MUL | BPF_K] = A64(*, IMMS), - [BPF_ALU64 | BPF_DIV | BPF_K] = A64(/, IMMS), - [BPF_ALU64 | BPF_OR | BPF_K] = A64(|, IMMS), - [BPF_ALU64 | BPF_AND | BPF_K] = A64(&, IMMS), - [BPF_ALU64 | BPF_LSH | BPF_K] = A64(<<, IMMS), - [BPF_ALU64 | BPF_RSH | BPF_K] = A64(>>, IMMS), - [BPF_ALU64 | BPF_MOD | BPF_K] = A64(%, IMMS), - [BPF_ALU64 | BPF_XOR | BPF_K] = A64(^, IMMS), - [BPF_ALU64 | BPF_MOV | BPF_K] = DST " = " IMMS, - [BPF_ALU64 | BPF_ARSH | BPF_K] = DST " = (s64)" DST " >> " IMMS, - - [BPF_ALU64 | BPF_ADD | BPF_X] = A64(+, SRC), - [BPF_ALU64 | BPF_SUB | BPF_X] = A64(-, SRC), - [BPF_ALU64 | BPF_MUL | BPF_X] = A64(*, SRC), - [BPF_ALU64 | BPF_DIV | BPF_X] = A64(/, SRC), - [BPF_ALU64 | BPF_OR | BPF_X] = A64(|, SRC), - [BPF_ALU64 | BPF_AND | BPF_X] = A64(&, SRC), - [BPF_ALU64 | BPF_LSH | BPF_X] = A64(<<, SRC), - [BPF_ALU64 | BPF_RSH | BPF_X] = A64(>>, SRC), - [BPF_ALU64 | BPF_MOD | BPF_X] = A64(%, SRC), - [BPF_ALU64 | BPF_XOR | BPF_X] = A64(^, SRC), - [BPF_ALU64 | BPF_MOV | BPF_X] = DST " = " SRC, - [BPF_ALU64 | BPF_ARSH | BPF_X] = DST " = (s64)" DST " >> " SRC, - - [BPF_ALU | BPF_NEG] = DST " = (u32)-" DST, - [BPF_ALU64 | BPF_NEG] = DST " = -" DST, - - /* The imm field contains {16,32,64}. */ - [BPF_ALU | BPF_END | BPF_TO_LE] = DST " = le%3$-6d(" DST ")", - [BPF_ALU | BPF_END | BPF_TO_BE] = DST " = be%3$-6d(" DST ")", - - [BPF_JMP | BPF_JEQ | BPF_K] = J64(DST, ==, IMMS), - [BPF_JMP | BPF_JGT | BPF_K] = J64(DST, >, IMMS), - [BPF_JMP | BPF_JGE | BPF_K] = J64(DST, >=, IMMS), - [BPF_JMP | BPF_JSET | BPF_K] = J64(DST, &, IMMS), - [BPF_JMP | BPF_JNE | BPF_K] = J64(DST, !=, IMMS), - [BPF_JMP | BPF_JSGT | BPF_K] = J64(DSTS, >, IMMS), - [BPF_JMP | BPF_JSGE | BPF_K] = J64(DSTS, >=, IMMS), - - [BPF_JMP | BPF_JEQ | BPF_X] = J64(DST, ==, SRC), - [BPF_JMP | BPF_JGT | BPF_X] = J64(DST, >, SRC), - [BPF_JMP | BPF_JGE | BPF_X] = J64(DST, >=, SRC), - [BPF_JMP | BPF_JSET | BPF_X] = J64(DST, &, SRC), - [BPF_JMP | BPF_JNE | BPF_X] = J64(DST, !=, SRC), - [BPF_JMP | BPF_JSGT | BPF_X] = J64(DSTS, >, SRCS), - [BPF_JMP | BPF_JSGE | BPF_X] = J64(DSTS, >=, SRCS), - - [BPF_JMP | BPF_JA] = "goto " JMP, - [BPF_JMP | BPF_CALL] = "call " IMMS, - [BPF_JMP | BPF_EXIT] = "exit", - - [BPF_LDX | BPF_MEM | BPF_B] = LOAD(u8), - [BPF_LDX | BPF_MEM | BPF_H] = LOAD(u16), - [BPF_LDX | BPF_MEM | BPF_W] = LOAD(u32), - [BPF_LDX | BPF_MEM | BPF_DW] = LOAD(u64), - - [BPF_STX | BPF_MEM | BPF_B] = STORE(u8, SRC), - [BPF_STX | BPF_MEM | BPF_H] = STORE(u16, SRC), - [BPF_STX | BPF_MEM | BPF_W] = STORE(u32, SRC), - [BPF_STX | BPF_MEM | BPF_DW] = STORE(u64, SRC), - - [BPF_STX | BPF_XADD | BPF_W] = XADD(u32, SRC), - [BPF_STX | BPF_XADD | BPF_DW] = XADD(u64, SRC), - - [BPF_ST | BPF_MEM | BPF_B] = STORE(u8, IMMS), - [BPF_ST | BPF_MEM | BPF_H] = STORE(u16, IMMS), - [BPF_ST | BPF_MEM | BPF_W] = STORE(u32, IMMS), - [BPF_ST | BPF_MEM | BPF_DW] = STORE(u64, IMMS), - - [BPF_LD | BPF_ABS | BPF_B] = LDSKB(u8, IMMS), - [BPF_LD | BPF_ABS | BPF_H] = LDSKB(u16, IMMS), - [BPF_LD | BPF_ABS | BPF_W] = LDSKB(u32, IMMS), - - [BPF_LD | BPF_IND | BPF_B] = LDSKB(u8, SRC "+" IMMS), - [BPF_LD | BPF_IND | BPF_H] = LDSKB(u16, SRC "+" IMMS), - [BPF_LD | BPF_IND | BPF_W] = LDSKB(u32, SRC "+" IMMS), -}; +#define REG(N) "r%" #N "$d" +#define REGU(N) "(u32)" REG(N) +#define REGS(N) "(s64)" REG(N) + +#define IMMS(N) "%" #N "$d" +#define IMMX(N) "%" #N "$#x" + +#define OFF(N) "%" #N "$+d" +#define JMP(N) "%" #N "$#x" + +#define A32(O, S) REG(1) " = " REGU(1) " " #O " " S +#define A64(O, S) REG(1) " " #O "= " S +#define J64(D, O, S) "if " D " " #O " " S " goto " JMP(3) +#define LOAD(T) REG(1) " = *(" #T " *)(" REG(2) OFF(3) ")" +#define STORE(T, S) "*(" #T " *)(" REG(1) OFF(3) ") = " S +#define XADD(T, S) "lock *(" #T " *)(" REG(1) OFF(3) ") += " S +#define LDSKB(T, S) "r0 = *(" #T " *)skb[" S "]" static void bswap_bpf_insn (struct bpf_insn *p) @@ -222,59 +110,364 @@ bpf_disasm (Ebl *ebl, const uint8_t **startp, const uint8_t *end, memcpy(&i, start, sizeof(struct bpf_insn)); if (need_bswap) bswap_bpf_insn (&i); + start += sizeof(struct bpf_insn); addr += sizeof(struct bpf_insn); - - /* ??? We really should pass in CTX, so that we can detect - wrong endianness and do some swapping. */ + jmp = addr + i.off * sizeof(struct bpf_insn); code = i.code; - code_fmt = code_fmts[code]; - - if (code == (BPF_LD | BPF_IMM | BPF_DW)) + switch (code) { - struct bpf_insn i2; - uint64_t imm64; - - if (start + sizeof(struct bpf_insn) > end) - { - start -= sizeof(struct bpf_insn); - *startp = start; - goto done; - } - memcpy(&i2, start, sizeof(struct bpf_insn)); - if (need_bswap) - bswap_bpf_insn (&i2); - start += sizeof(struct bpf_insn); - addr += sizeof(struct bpf_insn); - - imm64 = (uint32_t)i.imm | ((uint64_t)i2.imm << 32); - switch (i.src_reg) - { - case 0: - code_fmt = DST " = %2$#" PRIx64; - break; - case BPF_PSEUDO_MAP_FD: - code_fmt = DST " = map_fd(%2$#" PRIx64 ")"; - break; - default: - code_fmt = DST " = ld_pseudo(%3$d, %2$#" PRIx64 ")"; - break; - } + case BPF_LD | BPF_IMM | BPF_DW: + { + struct bpf_insn i2; + uint64_t imm64; + + if (start + sizeof(struct bpf_insn) > end) + { + start -= sizeof(struct bpf_insn); + *startp = start; + goto done; + } + memcpy(&i2, start, sizeof(struct bpf_insn)); + if (need_bswap) + bswap_bpf_insn (&i2); + start += sizeof(struct bpf_insn); + addr += sizeof(struct bpf_insn); + + imm64 = (uint32_t)i.imm | ((uint64_t)i2.imm << 32); + switch (i.src_reg) + { + case 0: + code_fmt = REG(1) " = %2$#" PRIx64; + break; + case BPF_PSEUDO_MAP_FD: + code_fmt = REG(1) " = map_fd(%2$#" PRIx64 ")"; + break; + default: + code_fmt = REG(1) " = ld_pseudo(%3$d, %2$#" PRIx64 ")"; + break; + } + len = snprintf(buf, sizeof(buf), code_fmt, + i.dst_reg, imm64, i.src_reg); + } + break; + + case BPF_JMP | BPF_EXIT: + len = snprintf(buf, sizeof(buf), "exit"); + break; + case BPF_JMP | BPF_JA: + len = snprintf(buf, sizeof(buf), "goto " JMP(1), jmp); + break; + case BPF_JMP | BPF_CALL: + code_fmt = "call " IMMS(1); + goto do_imm; + + case BPF_ALU | BPF_END | BPF_TO_LE: + /* The imm field contains {16,32,64}. */ + code_fmt = REG(1) " = le" IMMS(2) "(" REG(1) ")"; + goto do_dst_imm; + case BPF_ALU | BPF_END | BPF_TO_BE: + code_fmt = REG(1) " = be" IMMS(2) "(" REG(1) ")"; + goto do_dst_imm; + + case BPF_ALU | BPF_ADD | BPF_K: + code_fmt = A32(+, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_SUB | BPF_K: + code_fmt = A32(-, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MUL | BPF_K: + code_fmt = A32(*, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_DIV | BPF_K: + code_fmt = A32(/, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_OR | BPF_K: + code_fmt = A32(|, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_AND | BPF_K: + code_fmt = A32(&, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_LSH | BPF_K: + code_fmt = A32(<<, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_RSH | BPF_K: + code_fmt = A32(>>, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MOD | BPF_K: + code_fmt = A32(%%, IMMS(2)); + goto do_dst_imm; + case BPF_ALU | BPF_XOR | BPF_K: + code_fmt = A32(^, IMMX(2)); + goto do_dst_imm; + case BPF_ALU | BPF_MOV | BPF_K: + code_fmt = REG(1) " = " IMMX(2); + goto do_dst_imm; + case BPF_ALU | BPF_ARSH | BPF_K: + code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " IMMS(2) ")"; + goto do_dst_imm; + + case BPF_ALU | BPF_ADD | BPF_X: + code_fmt = A32(+, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_SUB | BPF_X: + code_fmt = A32(-, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MUL | BPF_X: + code_fmt = A32(*, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_DIV | BPF_X: + code_fmt = A32(/, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_OR | BPF_X: + code_fmt = A32(|, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_AND | BPF_X: + code_fmt = A32(&, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_LSH | BPF_X: + code_fmt = A32(<<, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_RSH | BPF_X: + code_fmt = A32(>>, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MOD | BPF_X: + code_fmt = A32(%%, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_XOR | BPF_X: + code_fmt = A32(^, REGU(2)); + goto do_dst_src; + case BPF_ALU | BPF_MOV | BPF_X: + code_fmt = REG(1) " = " REGU(2); + goto do_dst_src; + case BPF_ALU | BPF_ARSH | BPF_X: + code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " REG(2) ")"; + goto do_dst_src; + + case BPF_ALU64 | BPF_ADD | BPF_K: + code_fmt = A64(+, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_SUB | BPF_K: + code_fmt = A64(-, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MUL | BPF_K: + code_fmt = A64(*, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_DIV | BPF_K: + code_fmt = A64(/, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_OR | BPF_K: + code_fmt = A64(|, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_AND | BPF_K: + code_fmt = A64(&, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_LSH | BPF_K: + code_fmt = A64(<<, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_RSH | BPF_K: + code_fmt = A64(>>, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MOD | BPF_K: + code_fmt = A64(%%, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_XOR | BPF_K: + code_fmt = A64(^, IMMS(2)); + goto do_dst_imm; + case BPF_ALU64 | BPF_MOV | BPF_K: + code_fmt = REG(1) " = " IMMS(2); + goto do_dst_imm; + case BPF_ALU64 | BPF_ARSH | BPF_K: + code_fmt = REG(1) " = (s64)" REG(1) " >> " IMMS(2); + goto do_dst_imm; + + case BPF_ALU64 | BPF_ADD | BPF_X: + code_fmt = A64(+, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_SUB | BPF_X: + code_fmt = A64(-, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MUL | BPF_X: + code_fmt = A64(*, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_DIV | BPF_X: + code_fmt = A64(/, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_OR | BPF_X: + code_fmt = A64(|, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_AND | BPF_X: + code_fmt = A64(&, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_LSH | BPF_X: + code_fmt = A64(<<, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_RSH | BPF_X: + code_fmt = A64(>>, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MOD | BPF_X: + code_fmt = A64(%%, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_XOR | BPF_X: + code_fmt = A64(^, REG(2)); + goto do_dst_src; + case BPF_ALU64 | BPF_MOV | BPF_X: + code_fmt = REG(1) " = " REG(2); + goto do_dst_src; + case BPF_ALU64 | BPF_ARSH | BPF_X: + code_fmt = REG(1) " = (s64)" REG(1) " >> " REG(2); + goto do_dst_src; + + case BPF_ALU | BPF_NEG: + code_fmt = REG(1) " = (u32)-" REG(1); + goto do_dst_src; + case BPF_ALU64 | BPF_NEG: + code_fmt = REG(1) " = -" REG(1); + goto do_dst_src; + + case BPF_JMP | BPF_JEQ | BPF_K: + code_fmt = J64(REG(1), ==, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JGT | BPF_K: + code_fmt = J64(REG(1), >, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JGE | BPF_K: + code_fmt = J64(REG(1), >=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSET | BPF_K: + code_fmt = J64(REG(1), &, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JNE | BPF_K: + code_fmt = J64(REG(1), !=, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSGT | BPF_K: + code_fmt = J64(REGS(1), >, IMMS(2)); + goto do_dst_imm_jmp; + case BPF_JMP | BPF_JSGE | BPF_K: + code_fmt = J64(REGS(1), >=, IMMS(2)); + goto do_dst_imm_jmp; + + case BPF_JMP | BPF_JEQ | BPF_X: + code_fmt = J64(REG(1), ==, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JGT | BPF_X: + code_fmt = J64(REG(1), >, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JGE | BPF_X: + code_fmt = J64(REG(1), >=, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSET | BPF_X: + code_fmt = J64(REG(1), &, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JNE | BPF_X: + code_fmt = J64(REG(1), !=, REG(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSGT | BPF_X: + code_fmt = J64(REGS(1), >, REGS(2)); + goto do_dst_src_jmp; + case BPF_JMP | BPF_JSGE | BPF_X: + code_fmt = J64(REGS(1), >=, REGS(2)); + goto do_dst_src_jmp; + + case BPF_LDX | BPF_MEM | BPF_B: + code_fmt = LOAD(u8); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_H: + code_fmt = LOAD(u16); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_W: + code_fmt = LOAD(u32); + goto do_dst_src_off; + case BPF_LDX | BPF_MEM | BPF_DW: + code_fmt = LOAD(u64); + goto do_dst_src_off; + + case BPF_STX | BPF_MEM | BPF_B: + code_fmt = STORE(u8, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_H: + code_fmt = STORE(u16, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_W: + code_fmt = STORE(u32, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_MEM | BPF_DW: + code_fmt = STORE(u64, REG(2)); + goto do_dst_src_off; + + case BPF_STX | BPF_XADD | BPF_W: + code_fmt = XADD(u32, REG(2)); + goto do_dst_src_off; + case BPF_STX | BPF_XADD | BPF_DW: + code_fmt = XADD(u64, REG(2)); + goto do_dst_src_off; + + case BPF_ST | BPF_MEM | BPF_B: + code_fmt = STORE(u8, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_H: + code_fmt = STORE(u16, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_W: + code_fmt = STORE(u32, IMMS(2)); + goto do_dst_imm_off; + case BPF_ST | BPF_MEM | BPF_DW: + code_fmt = STORE(u64, IMMS(2)); + goto do_dst_imm_off; + + case BPF_LD | BPF_ABS | BPF_B: + code_fmt = LDSKB(u8, IMMS(1)); + goto do_imm; + case BPF_LD | BPF_ABS | BPF_H: + code_fmt = LDSKB(u16, IMMS(1)); + goto do_imm; + case BPF_LD | BPF_ABS | BPF_W: + code_fmt = LDSKB(u32, IMMS(1)); + goto do_imm; + + case BPF_LD | BPF_IND | BPF_B: + code_fmt = LDSKB(u8, REG(1) "+" IMMS(2)); + goto do_src_imm; + case BPF_LD | BPF_IND | BPF_H: + code_fmt = LDSKB(u16, REG(1) "+" IMMS(2)); + goto do_src_imm; + case BPF_LD | BPF_IND | BPF_W: + code_fmt = LDSKB(u32, REG(1) "+" IMMS(2)); + goto do_src_imm; + + do_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.imm); + break; + do_dst_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm); + break; + do_src_imm: + len = snprintf(buf, sizeof(buf), code_fmt, i.src_reg, i.imm); + break; + do_dst_src: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.src_reg); + break; + do_dst_imm_jmp: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, jmp); + break; + do_dst_src_jmp: len = snprintf(buf, sizeof(buf), code_fmt, - i.dst_reg, imm64, i.src_reg); - } - else if (code_fmt != NULL) - { - jmp = addr + i.off * sizeof(struct bpf_insn); - len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.src_reg, - i.imm, i.off, jmp); - } - else - { + i.dst_reg, i.src_reg, jmp); + break; + do_dst_imm_off: + len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, i.off); + break; + do_dst_src_off: + len = snprintf(buf, sizeof(buf), code_fmt, + i.dst_reg, i.src_reg, i.off); + break; + + default: class = BPF_CLASS(code); len = snprintf(buf, sizeof(buf), "invalid class %s", class_string[class]); + break; } *startp = start; diff --git a/tests/ChangeLog b/tests/ChangeLog index 58a023c24..d782ec300 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2016-08-10 Richard Henderson + + * file-bpf-dis1.expect.bz2: Fix expected mod and endian operations + output. + 2016-07-08 Mark Wielaard * update3_LDADD: Use libdw instead of libebl. @@ -39,7 +44,7 @@ (emptyfile_LDADD): New variable. * emptyfile.c: New test. -2016-06-28 Richard Henderson +2016-06-28 Richard Henderson * Makefile.am (TESTS): Add run-disasm-bpf.sh, conditionally. (EXTRA_DIST): Add run-disasm-bpf.sh, testfile-bpf-dis1.expect.bz2, diff --git a/tests/testfile-bpf-dis1.expect.bz2 b/tests/testfile-bpf-dis1.expect.bz2 index b4a778e03882796d5c0682e2ac46daf8ecf4f53c..21b55e94431e96914d38ad86683b54f29c58c617 100644 GIT binary patch literal 1467 zc-noGdsNbA7{`Bj$Gm`MGuJUNgfvSj^ODlQF$Yv$5Hv)MAv*76mR34NQzJE}pq9=Y znpc!+3SMWlO3yY$E4&=FWLjqGl$9x~Q@S7Z&-Twge?8}YpYM6z=lMS8^$L!1#}XLm z0EShP83FjbSjjyH3s2ot>j1zOnM}!H8CV_;dq_~Gout$DY%}c;R{BMY%6)x*=eQ7% zb~i2vAr%NCs&MCm|6+!WPW!?R(2$p&JJNV#4dGc27eXXgoE2!iV$I*IY7Ivmu_ieK zfR!=u6}hQN6+p4BkGW7)6a|V{G%9reMYL}KLb1!6%LX3x7sKIjx%#>CFV#v&+Vh?$ zX!1kzNAWBl=5e!Sq3sl26R0E5b6uyNv@f{s9mt)##*0}TS4-9l82b{IeumMYMGm~8$*k1AM=$mdy+xAe`({VkWREQhPNNC)skE1)n zM^|oFRTXXq$-*+e*Y|C^KRX-kI6cdtR!7SOqj&fs4ds;+hPXtmQ(Jq?wxuT>?ikzC zzQZ0#ftAbheUq(jbQ+&h3D9iY%O-93R0^51mH(k@uX@~%YjURu?EKJs^XBKr1QGy~ z#{mH1Q}9fiBZw<)89VYcEo^Oqej=l~Md|hd4*8PiKT&} zp{zb^Hq(AI6f3XkL)-zk|aqq|x>7=mcs+p{{8s;+Yt z^x~p;Fn1K6j4D(3`9ye;WBlPe_m}mx&*Z{%h(sb|88mHMKeiw~9QY4AE#%C{o#NPv z67dpcOd^h10a=$e!XVRk?$3>lN$b!o5=M!Pr-s|>9UxQ-lT}nL*RPdS>MPx$Sn@#8iCsbWETf%a>;X)elm4>Oj@Oa z?RmMP3T`vfdFii@LfGnth4zBk2P&6pl{dRpN?AJAAc0{(!c@y))XK1T%R3Tps_RrQ zxnJfjxw{Owut;cFHWK@>GS3T^jj{Gjj$3Rk>6|U$rNHedsfqWUP-ak_ECQlPvsiT(U&x&Lwi(nc8^oGWAaBwe?oP!FV}(EYSD+gp>yCW3zQ z$p9YsA8;AanPTf4clw%OZhN$7Z9FvDTja7Nj;&ERBlytWB<-m` zq4;vhTDZ06xmQ!eAXI{Bb&955Byyi}2PY6Q*N2 z0~~V(O=)>k%S>f%7;q6%wKClfCe)>a5c{~q$jC@=Fj8?W)l_4N_oo}}k$T6g3&k5f zkV&;HUTM*il%L$EW%6n`TGjgM=Ml{5W~(-8_fnl5srJ%d`$0eQmVz9esuSZcg3NjB zY66<48p!^GW>$lr!^JF2ZY_1A2dU5W|F|ex9SvM~Q8D~bs6`R#8uC1Blj$pf1$Fml zCASTCYvCo=f1}$T4W@;?qb!di1iI5jg%NxBdWBQ-xj8ZLp&z1ZMWvW^Iys<0^F0{A Y0R4JVH+tyu7qcs*217G#A2tc`598j7GXMYp literal 1497 zc-nnbX;2eJ7~LcsAz+#yC~`O?

dIQ^E~S5`oGQ&L9R#w17a8CL9WK$)SRgK}Rr= zqZtJ`6DMfVAmvawii}_Y#Y8UAQa}hTMM@*!(O~=6zS$pdcD}dY?t9-XB{I>KK&D%T z(f81P`W={*AIZ-^C1ih8X#k*m|NczeQMl3mty3d`f>o7R>ey=JF|}ufXpGMa8y>5r zI`w!51q0Xta`gx+OH6foCz|uz6rHD%03ZS=KCecK$BmX&1yt<(5~8J3t94CW%yJej zdL_O;$gBp5#)(9TenVl<*m}^q&l8_s+PY^D^MDTv0F)@8gg;udL|liN1E4jQVvNON zUEEZv%=WgPV$YMmbzGlHuI;kM3F+DBfU_Mfo3;=NV zaA=$lwCM-dUIPG}?^VBD+u(AJpzewPbPi*EGWfHdTsrEhb0)h&X9*t z2J1BKH95Bs%-5kToUM(F9^5j6gy{_g&{U4j5o9h51StA4; zXtFl_dTH1rb@`1_QLe|Qrutfl8|w&Xp#Ftu^hVWU2h}C{Rkbm*p~@?HqtDCBYvtaS zdgX)9BiBYj#V7fNN${-mXjsRDTqHW9qA!yT|57p4{f8W&9P>R?TrPXoa zf~$-GPo~2uGC$r~D;K#yvXcEm)iuL7YL0;2x;Plic3*~KkscUi+NHC$EeWo&kkZ5__q;@AAaLP` z8d?H7QZ8-yPfg}{r_VilKI8MYe;0d@Vb2IO>chY(J9FP}-3?$iRH&O%P-=e)LoT?o z{X+TmIEtHP6U<*s8MFqX_Lui%q?uIzQ z?%U@O^3I0%%)SG|JxN9F${Pf)LEEO}UZ}5Ux1pw@cVl@nB4g6uzr$(t_S9;#N8747 z)YqcSGC2Do;6ZiMNbY0cn*oK#+7;>5tbmWF&EZy?%tk7m2g-acu5$qPkb3G4^VArN zk*SU918Ozt4W2{X2+3B#GAn2Nqo-RtlTJ~PlGcsIp{3$g^EGM3nsc_$VsOdMnkX)7u*31|Ys;$nnvdWU^`o%6)8eb#XFs6lMH0Uz lG40xTxMh%*`Xd15B(PU3o)do8lK0D0X`q3HR=908=^v$#g8u*j -- 2.47.3