Index: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -432,10 +432,9 @@ if (!(RelSecI == Section)) continue; - for (const RelocationRef &Reloc : SI->relocations()) { - (void)Reloc; - StubBufSize += StubSize; - } + for (const RelocationRef &Reloc : SI->relocations()) + if (relocationNeedsStub(Reloc)) + StubBufSize += StubSize; } // Get section data size and alignment Index: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h =================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -152,6 +152,8 @@ SmallVector UnregisteredEHFrameSections; SmallVector RegisteredEHFrameSections; + bool relocationNeedsStub(const RelocationRef &R) const override; + public: RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver); Index: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -1851,4 +1851,23 @@ return Obj.isELF(); } +bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const { + if (Arch != Triple::x86_64) + return true; // Conservative answer + + switch (R.getType()) { + default: + return true; // Conservative answer + + + case ELF::R_X86_64_GOTPCREL: + case ELF::R_X86_64_PC32: + case ELF::R_X86_64_PC64: + case ELF::R_X86_64_64: + // We know that these reloation types won't need a stub function. This list + // can be extended as needed. + return false; + } +} + } // namespace llvm Index: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h =================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -416,6 +416,11 @@ // \brief Implementation of the generic part of the loadObject algorithm. ObjSectionToIDMap loadObjectImpl(const object::ObjectFile &Obj); + // \brief Return true if the relocation R may require allocating a stub. + virtual bool relocationNeedsStub(const RelocationRef &R) const { + return true; // Conservative answer + } + public: RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver) Index: llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s =================================================================== --- llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple=x86_64-apple-macosx10.10.0 -filetype=obj -o %T/test_ELF_x86_64_StubBuf.o %s +# RUN: llvm-rtdyld -print-alloc-requests -triple=x86_64-pc-linux -dummy-extern _g=196608 -verify %T/test_ELF_x86_64_StubBuf.o + +# Compiled from Inputs/ELF/ELF_x86_64_StubBuf.ll + +# CHECK: allocateCodeSection(Size = 42, Alignment = 16, SectionName = __text) + + .section __TEXT,__text,regular,pure_instructions + .macosx_version_min 10, 10 + .globl _f + .align 4, 0x90 +_f: ## @f + .cfi_startproc +## BB#0: ## %entry + pushq %rax +Ltmp0: + .cfi_def_cfa_offset 16 + callq _g + callq _g + callq _g + popq %rax + retq + .cfi_endproc + + +.subsections_via_symbols Index: llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll =================================================================== --- llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll +++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll @@ -0,0 +1,12 @@ +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.10.0" + +declare void @g() + +define void @f() { + entry: + call void @g() + call void @g() + call void @g() + ret void +} Index: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -132,6 +132,12 @@ cl::ZeroOrMore, cl::Hidden); +static cl::opt +PrintAllocationRequests("print-alloc-requests", + cl::desc("Print allocation requests made to the memory " + "manager by RuntimeDyld"), + cl::Hidden); + /* *** */ // A trivial memory manager that doesn't do anything fancy, just uses the @@ -211,6 +217,10 @@ unsigned Alignment, unsigned SectionID, StringRef SectionName) { + if (PrintAllocationRequests) + outs() << "allocateCodeSection(Size = " << Size << ", Alignment = " + << Alignment << ", SectionName = " << SectionName << ")\n"; + if (UsePreallocation) return allocateFromSlab(Size, Alignment, true /* isCode */); @@ -227,6 +237,10 @@ unsigned SectionID, StringRef SectionName, bool IsReadOnly) { + if (PrintAllocationRequests) + outs() << "allocateDataSection(Size = " << Size << ", Alignment = " + << Alignment << ", SectionName = " << SectionName << ")\n"; + if (UsePreallocation) return allocateFromSlab(Size, Alignment, false /* isCode */);