diff options
| author | Alexei Starovoitov <alexei.starovoitov@gmail.com> | 2017-04-28 16:51:01 +0000 |
|---|---|---|
| committer | Alexei Starovoitov <alexei.starovoitov@gmail.com> | 2017-04-28 16:51:01 +0000 |
| commit | f7bd5ebd3b62989f335efc0eb8263be40301a861 (patch) | |
| tree | d9e75876b92c76a1777ef56247f65f6dd9f664c5 /llvm/lib/Target | |
| parent | ea8702d393e28e2fdbd6ae70e08e65bcb1ead33b (diff) | |
| download | bcm5719-llvm-f7bd5ebd3b62989f335efc0eb8263be40301a861.tar.gz bcm5719-llvm-f7bd5ebd3b62989f335efc0eb8263be40301a861.zip | |
[bpf] add bigendian support to disassembler
. swap 4-bit register encoding, 16-bit offset and 32-bit imm to support big endian archs
. add a test
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
llvm-svn: 301653
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp index 9beefcdcc1d..b98621ca474 100644 --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -17,6 +17,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCFixedLenDisassembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" @@ -88,9 +90,9 @@ static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn, } #include "BPFGenDisassemblerTables.inc" - static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address, - uint64_t &Size, uint64_t &Insn) { + uint64_t &Size, uint64_t &Insn, + bool IsLittleEndian) { uint64_t Lo, Hi; if (Bytes.size() < 8) { @@ -99,8 +101,14 @@ static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address, } Size = 8; - Hi = (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 0) | (Bytes[3] << 8); - Lo = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[6] << 16) | (Bytes[7] << 24); + if (IsLittleEndian) { + Hi = (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 0) | (Bytes[3] << 8); + Lo = (Bytes[4] << 0) | (Bytes[5] << 8) | (Bytes[6] << 16) | (Bytes[7] << 24); + } else { + Hi = (Bytes[0] << 24) | ((Bytes[1] & 0x0F) << 20) | ((Bytes[1] & 0xF0) << 12) | + (Bytes[2] << 8) | (Bytes[3] << 0); + Lo = (Bytes[4] << 24) | (Bytes[5] << 16) | (Bytes[6] << 8) | (Bytes[7] << 0); + } Insn = Make_64(Hi, Lo); return MCDisassembler::Success; @@ -111,10 +119,11 @@ DecodeStatus BPFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const { - uint64_t Insn; + bool IsLittleEndian = getContext().getAsmInfo()->isLittleEndian(); + uint64_t Insn, Hi; DecodeStatus Result; - Result = readInstruction64(Bytes, Address, Size, Insn); + Result = readInstruction64(Bytes, Address, Size, Insn, IsLittleEndian); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; Result = decodeInstruction(DecoderTableBPF64, Instr, Insn, @@ -128,7 +137,10 @@ DecodeStatus BPFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, return MCDisassembler::Fail; } Size = 16; - uint64_t Hi = (Bytes[12] << 0) | (Bytes[13] << 8) | (Bytes[14] << 16) | (Bytes[15] << 24); + if (IsLittleEndian) + Hi = (Bytes[12] << 0) | (Bytes[13] << 8) | (Bytes[14] << 16) | (Bytes[15] << 24); + else + Hi = (Bytes[12] << 24) | (Bytes[13] << 16) | (Bytes[14] << 8) | (Bytes[15] << 0); auto& Op = Instr.getOperand(1); Op.setImm(Make_64(Hi, Op.getImm())); break; |

