From 82c3cadad6177c93d979803e6f3cc92ace0b8838 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Wed, 14 Apr 2010 01:17:37 +0000 Subject: [PATCH] Fixed an assert() exposed by fuzzing. Now, instead of assert when an invalid instruction encoding is encountered, we just return a NULL ARMBasicMCBuilder instance and the client just returns false to indicate disassembly error. llvm-svn: 101201 --- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 3 +++ .../ARM/Disassembler/ARMDisassemblerCore.h | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 98bb6716c7fa..aedd22eb3e81 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -3257,6 +3257,9 @@ ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format, /// are responsible for freeing up of the allocated memory. Cacheing can be /// performed by the API clients to improve performance. ARMBasicMCBuilder *llvm::CreateMCBuilder(unsigned Opcode, ARMFormat Format) { + // For "Unknown format", fail by returning a NULL pointer. + if ((unsigned)Format >= (array_lengthof(FuncPtrs) - 1)) + return 0; return new ARMBasicMCBuilder(Opcode, Format, ARMInsts[Opcode].getNumOperands()); diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h index 307523037089..f6cba5268dd7 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h @@ -171,24 +171,33 @@ typedef ARMBasicMCBuilder *BO; typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO Builder); +/// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC +/// infrastructure of an MCInst given the Opcode and Format of the instr. +/// Return NULL if it fails to create/return a proper builder. API clients +/// are responsible for freeing up of the allocated memory. Cacheing can be +/// performed by the API clients to improve performance. +extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format); + /// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that /// knows how to build up the MCOperand list. class ARMBasicMCBuilder { + friend ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format); unsigned Opcode; ARMFormat Format; unsigned short NumOps; DisassembleFP Disasm; Session *SP; +private: + /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder. + ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num); + public: ARMBasicMCBuilder(ARMBasicMCBuilder &B) : Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm), SP(B.SP) {} - /// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder. - ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num); - virtual ~ARMBasicMCBuilder() {} void setSession(Session *sp) { @@ -236,13 +245,6 @@ private: } }; -/// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC -/// infrastructure of an MCInst given the Opcode and Format of the instr. -/// Return NULL if it fails to create/return a proper builder. API clients -/// are responsible for freeing up of the allocated memory. Cacheing can be -/// performed by the API clients to improve performance. -extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format); - } // namespace llvm #endif