Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -415,6 +415,25 @@ DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment); } +bool RuntimeDyldImpl::relocationNeedsStub(const RelocationRef &R) { + 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; + } +} + // compute stub buffer size for the given section unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section) { @@ -432,10 +451,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: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -404,6 +404,9 @@ // \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. + bool relocationNeedsStub(const RelocationRef &R); + public: RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver) Index: test/ExecutionEngine/RuntimeDyld/X86/ELF_x86_64_StubBuf.s =================================================================== --- /dev/null +++ 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: test/ExecutionEngine/RuntimeDyld/X86/Inputs/ELF_x86_64_StubBuf.ll =================================================================== --- /dev/null +++ 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: tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- tools/llvm-rtdyld/llvm-rtdyld.cpp +++ 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 @@ -217,6 +223,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 */); @@ -233,6 +243,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 */);