aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2017-04-24 09:48:54 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2017-04-24 09:48:54 +0000
commitf86bf2a7ce0fb8a0e8b5de88c125118f00cca885 (patch)
tree3c9268e9519b060b1b8eb78b0205139aa1f1cd79
parent7b61abe47c66fd691c58d7b29821fcad3d877b54 (diff)
Merging r296105, r296016 and 296111:
------------------------------------------------------------------------ r296105 | sdardis | 2017-02-24 10:50:27 +0000 (Fri, 24 Feb 2017) | 13 lines [mips][mc] Fix a crash when disassembling odd sized sections Make the MIPS disassembler consistent with the other targets in returning a Size of zero when the input buffer cannot contain an instruction due to it's size. Previously it reported the minimum instruction size when it failed due to the buffer not being big enough for an instruction causing llvm-objdump to crash when disassembling all sections. Reviewers: slthakur Differential Revision: https://reviews.llvm.org/D29984 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r296106 | sdardis | 2017-02-24 10:51:27 +0000 (Fri, 24 Feb 2017) | 5 lines [mips][mc] Fix a crash when disassembling odd sized sections Corresponding test. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r296111 | rovka | 2017-02-24 12:47:11 +0000 (Fri, 24 Feb 2017) | 1 line Fixup r296105 - only run tests on Mips ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_40@301169 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp51
-rw-r--r--test/tools/llvm-objdump/Mips/disassemble-all.test16
-rw-r--r--test/tools/llvm-objdump/Mips/lit.local.cfg3
3 files changed, 40 insertions, 30 deletions
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index f80efb18507..04c81029382 100644
--- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -1106,6 +1106,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
raw_ostream &CStream) const {
uint32_t Insn;
DecodeStatus Result;
+ Size = 0;
if (IsMicroMips) {
Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
@@ -1168,98 +1169,88 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
}
}
- // This is an invalid instruction. Let the disassembler move forward by the
- // minimum instruction size.
+ // This is an invalid instruction. Claim that the Size is 2 bytes. Since
+ // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
+ // could form a valid instruction. The two bytes we rejected as an
+ // instruction could have actually beeen an inline constant pool that is
+ // unconditionally branched over.
Size = 2;
return MCDisassembler::Fail;
}
+ // Attempt to read the instruction so that we can attempt to decode it. If
+ // the buffer is not 4 bytes long, let the higher level logic figure out
+ // what to do with a size of zero and MCDisassembler::Fail.
Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
- if (Result == MCDisassembler::Fail) {
- Size = 4;
+ if (Result == MCDisassembler::Fail)
return MCDisassembler::Fail;
- }
+
+ // The only instruction size for standard encoded MIPS.
+ Size = 4;
if (hasCOP3()) {
DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
Result =
decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (hasMips32r6() && isGP64()) {
DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (hasMips32r6() && isPTR64()) {
DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (hasMips32r6()) {
DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (hasMips2() && isPTR64()) {
DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (hasCnMips()) {
DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
if (isGP64()) {
DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
}
DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
// Calling the auto-generated decoder function.
Result =
decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
- if (Result != MCDisassembler::Fail) {
- Size = 4;
+ if (Result != MCDisassembler::Fail)
return Result;
- }
- Size = 4;
return MCDisassembler::Fail;
}
diff --git a/test/tools/llvm-objdump/Mips/disassemble-all.test b/test/tools/llvm-objdump/Mips/disassemble-all.test
new file mode 100644
index 00000000000..4554a0e030a
--- /dev/null
+++ b/test/tools/llvm-objdump/Mips/disassemble-all.test
@@ -0,0 +1,16 @@
+# RUN: yaml2obj %s | llvm-objdump -D -
+
+# Test that -D does not crash llvm-objdump encounters a section who size is a
+# not a multiple of the size of an instruction.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_MIPS
+Sections:
+ - Name: .note.llvm.crash
+ Type: SHT_NOTE
+ Address: 0x0
+ Content: 002E746578
diff --git a/test/tools/llvm-objdump/Mips/lit.local.cfg b/test/tools/llvm-objdump/Mips/lit.local.cfg
new file mode 100644
index 00000000000..a3183a25afa
--- /dev/null
+++ b/test/tools/llvm-objdump/Mips/lit.local.cfg
@@ -0,0 +1,3 @@
+if not 'Mips' in config.root.targets:
+ config.unsupported = True
+