Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -49,6 +49,7 @@ void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); + // Get the maximum necessary stub space needed for one relocation unsigned getMaxStubSize() override { if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) return 20; // movz; movk; movk; movk; br @@ -59,13 +60,23 @@ else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) return 44; else if (Arch == Triple::x86_64) - return 6; // 2-byte jmp instruction + 32-bit relative address + return 16; // but we may need to allocate up to two GOT entries (=16). else if (Arch == Triple::systemz) return 16; else return 0; } + // Get the size of just the function itself. + // This is in general smaller than getMaxStubSize if the stub + // function also needs a GOT entry. + unsigned getMaxStubFunctionSize() { + if (Arch == Triple::x86_64) + return 6; // 2-byte jmp instruction + 32-bit relative address + else + return getMaxStubSize(); + } + unsigned getStubAlignment() override { if (Arch == Triple::systemz) return 8; Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -1316,7 +1316,7 @@ createStubFunction((uint8_t *)StubAddress); // Bump our stub offset counter - Section.StubOffset = StubOffset + getMaxStubSize(); + Section.StubOffset = StubOffset + getMaxStubFunctionSize(); // Allocate a GOT Entry uint64_t GOTOffset = allocateGOTEntries(SectionID, 1); @@ -1385,53 +1385,28 @@ uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned SectionID, unsigned no) { - (void)SectionID; // The GOT Section is the same for all section in the object file - if (GOTSectionID == 0) { - GOTSectionID = Sections.size(); - // Reserve a section id. We'll allocate the section later - // once we know the total size - Sections.push_back(SectionEntry(".got", 0, 0, 0)); - } - uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize(); - CurrentGOTIndex += no; - return StartOffset; + SectionEntry &Section = getSection(SectionID); + uint64_t Offset = Section.StubOffset; + Section.StubOffset += 8*no; + return Offset; } void RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset, uint64_t GOTOffset) { - // Fill in the relative address of the GOT Entry into the stub - RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32, GOTOffset); - addRelocationForSection(GOTRE, GOTSectionID); + SectionEntry &Section = getSection(SectionID); + resolveRelocation(Section, Offset, + (uint64_t)Section.Address + GOTOffset, ELF::R_X86_64_PC32, + 0); } RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID, uint64_t GOTOffset, uint64_t SymbolOffset, uint32_t Type) { - (void)SectionID; // The GOT Section is the same for all section in the object file - return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset); + return RelocationEntry(SectionID, GOTOffset, Type, SymbolOffset); } void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) { - // If necessary, allocate the global offset table - if (GOTSectionID != 0) { - // Allocate memory for the section - size_t TotalSize = CurrentGOTIndex * getGOTEntrySize(); - uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(), - GOTSectionID, ".got", false); - if (!Addr) - report_fatal_error("Unable to allocate memory for GOT!"); - - Sections[GOTSectionID] = SectionEntry(".got", Addr, TotalSize, 0); - - if (Checker) - Checker->registerSection(Obj.getFileName(), GOTSectionID); - - // For now, initialize all GOT entries to zero. We'll fill them in as - // needed when GOT-based relocations are applied. - memset(Addr, 0, TotalSize); - } - // Look for and record the EH frame section. ObjSectionToIDMap::iterator i, e; for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {