From 5788d1a169db3346a612a13113348d2709bdd15b Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 10 Dec 2008 02:32:19 +0000 Subject: [PATCH] Fix MachineCodeEmitter to use uintptr_t instead of intptr_t. This avoids some overflow issues. Patch by Thomas Jablin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60828 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineCodeEmitter.h | 53 +++++++++++++---------- include/llvm/CodeGen/MachineRelocation.h | 14 +++--- include/llvm/Target/TargetJITInfo.h | 2 +- lib/CodeGen/ELFWriter.cpp | 8 ++-- lib/CodeGen/MachOWriter.cpp | 14 +++--- lib/ExecutionEngine/JIT/JITEmitter.cpp | 35 +++++++++------ lib/Target/ARM/ARMCodeEmitter.cpp | 2 +- lib/Target/X86/X86CodeEmitter.cpp | 2 +- lib/Target/X86/X86JITInfo.cpp | 2 +- lib/Target/X86/X86JITInfo.h | 8 ++-- 10 files changed, 76 insertions(+), 64 deletions(-) diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index d83591b8859..1161704490a 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -98,7 +98,7 @@ public: /// written to the output stream in little-endian format. /// void emitWordLE(unsigned W) { - if (CurBufferPtr+4 <= BufferEnd) { + if (4 <= BufferEnd-CurBufferPtr) { *CurBufferPtr++ = (unsigned char)(W >> 0); *CurBufferPtr++ = (unsigned char)(W >> 8); *CurBufferPtr++ = (unsigned char)(W >> 16); @@ -112,7 +112,7 @@ public: /// written to the output stream in big-endian format. /// void emitWordBE(unsigned W) { - if (CurBufferPtr+4 <= BufferEnd) { + if (4 <= BufferEnd-CurBufferPtr) { *CurBufferPtr++ = (unsigned char)(W >> 24); *CurBufferPtr++ = (unsigned char)(W >> 16); *CurBufferPtr++ = (unsigned char)(W >> 8); @@ -126,7 +126,7 @@ public: /// written to the output stream in little-endian format. /// void emitDWordLE(uint64_t W) { - if (CurBufferPtr+8 <= BufferEnd) { + if (8 <= BufferEnd-CurBufferPtr) { *CurBufferPtr++ = (unsigned char)(W >> 0); *CurBufferPtr++ = (unsigned char)(W >> 8); *CurBufferPtr++ = (unsigned char)(W >> 16); @@ -144,7 +144,7 @@ public: /// written to the output stream in big-endian format. /// void emitDWordBE(uint64_t W) { - if (CurBufferPtr+8 <= BufferEnd) { + if (8 <= BufferEnd-CurBufferPtr) { *CurBufferPtr++ = (unsigned char)(W >> 56); *CurBufferPtr++ = (unsigned char)(W >> 48); *CurBufferPtr++ = (unsigned char)(W >> 40); @@ -162,12 +162,15 @@ public: /// alignment (saturated to BufferEnd of course). void emitAlignment(unsigned Alignment) { if (Alignment == 0) Alignment = 1; - // Move the current buffer ptr up to the specified alignment. - CurBufferPtr = - (unsigned char*)(((intptr_t)CurBufferPtr+Alignment-1) & - ~(intptr_t)(Alignment-1)); - if (CurBufferPtr > BufferEnd) + + if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) { + // Move the current buffer ptr up to the specified alignment. + CurBufferPtr = + (unsigned char*)(((uintptr_t)CurBufferPtr+Alignment-1) & + ~(uintptr_t)(Alignment-1)); + } else { CurBufferPtr = BufferEnd; + } } @@ -210,7 +213,7 @@ public: /// emitInt32 - Emit a int32 directive. void emitInt32(int Value) { - if (CurBufferPtr+4 <= BufferEnd) { + if (4 <= BufferEnd-CurBufferPtr) { *((uint32_t*)CurBufferPtr) = Value; CurBufferPtr += 4; } else { @@ -220,7 +223,7 @@ public: /// emitInt64 - Emit a int64 directive. void emitInt64(uint64_t Value) { - if (CurBufferPtr+8 <= BufferEnd) { + if (8 <= BufferEnd-CurBufferPtr) { *((uint64_t*)CurBufferPtr) = Value; CurBufferPtr += 8; } else { @@ -247,18 +250,20 @@ public: /// allocateSpace - Allocate a block of space in the current output buffer, /// returning null (and setting conditions to indicate buffer overflow) on /// failure. Alignment is the alignment in bytes of the buffer desired. - virtual void *allocateSpace(intptr_t Size, unsigned Alignment) { + virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) { emitAlignment(Alignment); - void *Result = CurBufferPtr; - - // Allocate the space. - CurBufferPtr += Size; + void *Result; // Check for buffer overflow. - if (CurBufferPtr >= BufferEnd) { + if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) { CurBufferPtr = BufferEnd; Result = 0; + } else { + // Allocate the space. + Result = CurBufferPtr; + CurBufferPtr += Size; } + return Result; } @@ -270,13 +275,13 @@ public: /// getCurrentPCValue - This returns the address that the next emitted byte /// will be output to. /// - virtual intptr_t getCurrentPCValue() const { - return (intptr_t)CurBufferPtr; + virtual uintptr_t getCurrentPCValue() const { + return (uintptr_t)CurBufferPtr; } /// getCurrentPCOffset - Return the offset from the start of the emitted /// buffer that we are currently writing to. - intptr_t getCurrentPCOffset() const { + uintptr_t getCurrentPCOffset() const { return CurBufferPtr-BufferBegin; } @@ -290,23 +295,23 @@ public: /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in /// the constant pool that was last emitted with the emitConstantPool method. /// - virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const = 0; + virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0; /// getJumpTableEntryAddress - Return the address of the jump table with index /// 'Index' in the function that last called initJumpTableInfo. /// - virtual intptr_t getJumpTableEntryAddress(unsigned Index) const = 0; + virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0; /// getMachineBasicBlockAddress - Return the address of the specified /// MachineBasicBlock, only usable after the label for the MBB has been /// emitted. /// - virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0; + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0; /// getLabelAddress - Return the address of the specified LabelID, only usable /// after the LabelID has been emitted. /// - virtual intptr_t getLabelAddress(uint64_t LabelID) const = 0; + virtual uintptr_t getLabelAddress(uint64_t LabelID) const = 0; /// Specifies the MachineModuleInfo object. This is used for exception handling /// purposes. diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h index 2181e20aeb9..c5397819aee 100644 --- a/include/llvm/CodeGen/MachineRelocation.h +++ b/include/llvm/CodeGen/MachineRelocation.h @@ -49,7 +49,7 @@ class MachineRelocation { /// Offset - This is the offset from the start of the code buffer of the /// relocation to perform. - intptr_t Offset; + uintptr_t Offset; /// ConstantVal - A field that may be used by the target relocation type. intptr_t ConstantVal; @@ -79,7 +79,7 @@ public: /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue. /// - static MachineRelocation getGV(intptr_t offset, unsigned RelocationType, + static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType, GlobalValue *GV, intptr_t cst = 0, bool NeedStub = 0, bool GOTrelative = 0) { @@ -98,7 +98,7 @@ public: /// MachineRelocation::getIndirectSymbol - Return a relocation entry for an /// indirect symbol. - static MachineRelocation getIndirectSymbol(intptr_t offset, + static MachineRelocation getIndirectSymbol(uintptr_t offset, unsigned RelocationType, GlobalValue *GV, intptr_t cst = 0, bool NeedStub = 0, @@ -118,7 +118,7 @@ public: /// MachineRelocation::getBB - Return a relocation entry for a BB. /// - static MachineRelocation getBB(intptr_t offset,unsigned RelocationType, + static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType, MachineBasicBlock *MBB, intptr_t cst = 0) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); MachineRelocation Result; @@ -136,7 +136,7 @@ public: /// MachineRelocation::getExtSym - Return a relocation entry for an external /// symbol, like "free". /// - static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType, + static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, const char *ES, intptr_t cst = 0, bool GOTrelative = 0) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); @@ -155,7 +155,7 @@ public: /// MachineRelocation::getConstPool - Return a relocation entry for a constant /// pool entry. /// - static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType, + static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType, unsigned CPI, intptr_t cst = 0, bool letTargetResolve = false) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); @@ -174,7 +174,7 @@ public: /// MachineRelocation::getJumpTable - Return a relocation entry for a jump /// table entry. /// - static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType, + static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType, unsigned JTI, intptr_t cst = 0, bool letTargetResolve = false) { assert((RelocationType & ~63) == 0 && "Relocation type too large!"); diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h index 0ae24169b86..e60933799ed 100644 --- a/include/llvm/Target/TargetJITInfo.h +++ b/include/llvm/Target/TargetJITInfo.h @@ -60,7 +60,7 @@ namespace llvm { /// getPICJumpTableEntry - Returns the value of the jumptable entry for the /// specific basic block. - virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase) { + virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) { assert(0 && "This target doesn't implement getPICJumpTableEntry!"); return 0; } diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index ea12d503a50..001bad98324 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -85,21 +85,21 @@ namespace llvm { virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { } - virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const { + virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { assert(0 && "CP not implementated yet!"); return 0; } - virtual intptr_t getJumpTableEntryAddress(unsigned Index) const { + virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { assert(0 && "JT not implementated yet!"); return 0; } - virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { assert(0 && "JT not implementated yet!"); return 0; } - virtual intptr_t getLabelAddress(uint64_t Label) const { + virtual uintptr_t getLabelAddress(uint64_t Label) const { assert(0 && "Label address not implementated yet!"); abort(); return 0; diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index 613f680bc79..a34204f4e81 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -75,7 +75,7 @@ namespace llvm { /// CPLocations - This is a map of constant pool indices to offsets from the /// start of the section for that constant pool index. - std::vector CPLocations; + std::vector CPLocations; /// CPSections - This is a map of constant pool indices to the MachOSection /// containing the constant pool entry for that index. @@ -83,12 +83,12 @@ namespace llvm { /// JTLocations - This is a map of jump table indices to offsets from the /// start of the section for that jump table index. - std::vector JTLocations; + std::vector JTLocations; /// MBBLocations - This vector is a mapping from MBB ID's to their address. /// It is filled in by the StartMachineBasicBlock callback and queried by /// the getMachineBasicBlockAddress callback. - std::vector MBBLocations; + std::vector MBBLocations; public: MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) { @@ -106,11 +106,11 @@ namespace llvm { void emitConstantPool(MachineConstantPool *MCP); void emitJumpTables(MachineJumpTableInfo *MJTI); - virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const { + virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { assert(CPLocations.size() > Index && "CP not emitted!"); return CPLocations[Index]; } - virtual intptr_t getJumpTableEntryAddress(unsigned Index) const { + virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { assert(JTLocations.size() > Index && "JT not emitted!"); return JTLocations[Index]; } @@ -121,13 +121,13 @@ namespace llvm { MBBLocations[MBB->getNumber()] = getCurrentPCOffset(); } - virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); return MBBLocations[MBB->getNumber()]; } - virtual intptr_t getLabelAddress(uint64_t Label) const { + virtual uintptr_t getLabelAddress(uint64_t Label) const { assert(0 && "get Label not implemented"); abort(); return 0; diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index a74f53d2ab9..e041767f8f3 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -467,7 +467,7 @@ namespace { /// MBBLocations - This vector is a mapping from MBB ID's to their address. /// It is filled in by the StartMachineBasicBlock callback and queried by /// the getMachineBasicBlockAddress callback. - std::vector MBBLocations; + std::vector MBBLocations; /// ConstantPool - The constant pool for the current function. /// @@ -493,7 +493,7 @@ namespace { /// LabelLocations - This vector is a mapping from Label ID's to their /// address. - std::vector LabelLocations; + std::vector LabelLocations; /// MMI - Machine module info for exception informations MachineModuleInfo* MMI; @@ -537,7 +537,7 @@ namespace { /// allocateSpace - Reserves space in the current block if any, or /// allocate a new one of the given size. - virtual void *allocateSpace(intptr_t Size, unsigned Alignment); + virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); virtual void addRelocation(const MachineRelocation &MR) { Relocations.push_back(MR); @@ -551,10 +551,10 @@ namespace { << (void*) getCurrentPCValue() << "]\n"; } - virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const; - virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const; + virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; + virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; - virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); return MBBLocations[MBB->getNumber()]; @@ -572,7 +572,7 @@ namespace { LabelLocations[LabelID] = getCurrentPCValue(); } - virtual intptr_t getLabelAddress(uint64_t LabelID) const { + virtual uintptr_t getLabelAddress(uint64_t LabelID) const { assert(LabelLocations.size() > (unsigned)LabelID && LabelLocations[LabelID] && "Label not emitted!"); return LabelLocations[LabelID]; @@ -963,6 +963,13 @@ bool JITEmitter::finishFunction(MachineFunction &F) { unsigned char *FnEnd = CurBufferPtr; MemMgr->endFunctionBody(F.getFunction(), BufferBegin, FnEnd); + + if (CurBufferPtr == BufferEnd) { + // FIXME: Allocate more space, then try again. + cerr << "JIT: Ran out of space for generated machine code!\n"; + abort(); + } + BufferBegin = CurBufferPtr = 0; NumBytes += FnEnd-FnStart; @@ -1044,7 +1051,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { return false; } -void* JITEmitter::allocateSpace(intptr_t Size, unsigned Alignment) { +void* JITEmitter::allocateSpace(uintptr_t Size, unsigned Alignment) { if (BufferBegin) return MachineCodeEmitter::allocateSpace(Size, Alignment); @@ -1129,9 +1136,9 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { const std::vector &MBBs = JT[i].MBBs; // Store the offset of the basic block for this jump table slot in the // memory we allocated for the jump table in 'initJumpTableInfo' - intptr_t Base = (intptr_t)SlotPtr; + uintptr_t Base = (uintptr_t)SlotPtr; for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { - intptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); + uintptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base); } } @@ -1174,17 +1181,17 @@ void *JITEmitter::finishGVStub(const GlobalValue* GV) { // in the constant pool that was last emitted with the 'emitConstantPool' // method. // -intptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { +uintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { assert(ConstantNum < ConstantPool->getConstants().size() && "Invalid ConstantPoolIndex!"); - return (intptr_t)ConstantPoolBase + + return (uintptr_t)ConstantPoolBase + ConstantPool->getConstants()[ConstantNum].Offset; } // getJumpTableEntryAddress - Return the address of the JumpTable with index // 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' // -intptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { +uintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { const std::vector &JT = JumpTable->getJumpTables(); assert(Index < JT.size() && "Invalid jump table index!"); @@ -1196,7 +1203,7 @@ intptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { Offset *= EntrySize; - return (intptr_t)((char *)JumpTableBase + Offset); + return (uintptr_t)((char *)JumpTableBase + Offset); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 56fc55315f7..c27fc5f1eaf 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -1078,7 +1078,7 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) { void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) { // Remember the base address of the inline jump table. - intptr_t JTBase = MCE.getCurrentPCValue(); + uintptr_t JTBase = MCE.getCurrentPCValue(); JTI->addJumpTableBaseAddr(JTIndex, JTBase); DOUT << " ** Jump Table #" << JTIndex << " @ " << (void*)JTBase << '\n'; diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 033d3b61e33..dbcb52a4816 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -555,7 +555,7 @@ void Emitter::emitInstruction(const MachineInstr &MI, MCE.emitByte(BaseOpcode); emitConstant(0, X86InstrInfo::sizeOfImm(Desc)); // Remember PIC base. - PICBaseOffset = MCE.getCurrentPCOffset(); + PICBaseOffset = (intptr_t) MCE.getCurrentPCOffset(); X86JITInfo *JTI = TM.getJITInfo(); JTI->setPICBase(MCE.getCurrentPCValue()); break; diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp index 951999640ab..b7b7667f046 100644 --- a/lib/Target/X86/X86JITInfo.cpp +++ b/lib/Target/X86/X86JITInfo.cpp @@ -476,7 +476,7 @@ void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn, /// getPICJumpTableEntry - Returns the value of the jumptable entry for the /// specific basic block. -intptr_t X86JITInfo::getPICJumpTableEntry(intptr_t BB, intptr_t Entry) { +uintptr_t X86JITInfo::getPICJumpTableEntry(uintptr_t BB, uintptr_t Entry) { #if defined(X86_64_JIT) return BB - Entry; #else diff --git a/lib/Target/X86/X86JITInfo.h b/lib/Target/X86/X86JITInfo.h index dd266364333..ed660b0b585 100644 --- a/lib/Target/X86/X86JITInfo.h +++ b/lib/Target/X86/X86JITInfo.h @@ -22,7 +22,7 @@ namespace llvm { class X86JITInfo : public TargetJITInfo { X86TargetMachine &TM; - intptr_t PICBase; + uintptr_t PICBase; char* TLSOffset; public: explicit X86JITInfo(X86TargetMachine &tm) : TM(tm) { @@ -51,7 +51,7 @@ namespace llvm { /// getPICJumpTableEntry - Returns the value of the jumptable entry for the /// specific basic block. - virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase); + virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase); /// getLazyResolverFunction - Expose the lazy resolver to the JIT. virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); @@ -69,8 +69,8 @@ namespace llvm { /// setPICBase / getPICBase - Getter / setter of PICBase, used to compute /// PIC jumptable entry. - void setPICBase(intptr_t Base) { PICBase = Base; } - intptr_t getPICBase() const { return PICBase; } + void setPICBase(uintptr_t Base) { PICBase = Base; } + uintptr_t getPICBase() const { return PICBase; } }; }