Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -774,7 +774,14 @@ // Ignore relocations for sections that were not loaded if (Sections[RE.SectionID].Address == nullptr) continue; - resolveRelocation(RE, Value); + if (Arch == Triple::mips64el || Arch == Triple::mips64) + // MIPS64 N64 ABI is specific in resolving relocations since + // there are three relocation types in a single entry and may be + // applied a number of relocation operations to a single instruction. + // Call MIPS64 specific routine that is aware of this. + resolveMIPS64Relocation(Relocs, Value, i); + else + resolveRelocation(RE, Value); } } Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -27,6 +27,9 @@ uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset = 0); + void resolveMIPS64Relocation(const RelocationList &Relocs, uint64_t Value, + unsigned RelocIndex) override; + void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset); @@ -43,6 +46,10 @@ void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset, uint32_t Value, uint32_t Type, int32_t Addend); + void resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + SID SectionID, uint64_t SymOffset); + void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); @@ -114,6 +121,22 @@ // that consume more than one slot) unsigned CurrentGOTIndex; + // Apply relocation in instruction (Mips64 specific) + bool applyRelocation; + + // True if using the result of the previous relocation type (Mips64 specific) + bool useCalculatedValue; + + // The result of the previous relocation type (Mips64 specific) + int64_t calculatedValue; + + // A map from section to a GOT section that has entries for section's GOT + // relocations. (Mips64 specific) + DenseMap SectionToGOTMap; + + // A map to avoid duplicate got entries (Mips64 specific) + StringMap GOTSymbolOffsets; + // When a module is loaded we save the SectionID of the EH frame section // in a table until we receive a request to register all unregistered // EH frame sections with the memory manager. Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -186,8 +186,9 @@ RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver) - : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {} -RuntimeDyldELF::~RuntimeDyldELF() {} + : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0), + applyRelocation(true), useCalculatedValue(false), calculatedValue(0) {} +RuntimeDyldELF::~RuntimeDyldELF() { SectionToGOTMap.clear(); } void RuntimeDyldELF::registerEHFrames() { for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { @@ -509,6 +510,235 @@ } } +void RuntimeDyldELF::resolveMIPS64Relocation(const RelocationList &Relocs, + uint64_t Value, + unsigned RelocIndex) { + const RelocationEntry &RE = Relocs[RelocIndex]; + const SectionEntry &Section = Sections[RE.SectionID]; + + uint32_t r_type = RE.RelType & 0xff; + uint32_t r_type2 = (RE.RelType >> 8) & 0xff; + uint32_t r_type3 = (RE.RelType >> 16) & 0xff; + + // If next type is R_MIPS_NONE, apply the relocation, + // otherwise use the result of this type of relocation as addend for + // next type of the same relocation entry. + useCalculatedValue = !applyRelocation; + applyRelocation = r_type2 == ELF::R_MIPS_NONE; + resolveMIPS64Relocation(Section, RE.Offset, Value, r_type, RE.Addend, + RE.SectionID, RE.SymOffset); + + useCalculatedValue = !applyRelocation; + applyRelocation = r_type3 == ELF::R_MIPS_NONE; + resolveMIPS64Relocation(Section, RE.Offset, Value, r_type2, RE.Addend, + RE.SectionID, RE.SymOffset); + + // If the next relocation entry is not for the same instruction, + // apply the relocation, otherwise use the result as addend for + // next relocation entry + useCalculatedValue = !applyRelocation; + if (RelocIndex + 1 == Relocs.size()) + applyRelocation = true; + else { + const RelocationEntry &REnext = Relocs[RelocIndex + 1]; + applyRelocation = REnext.SectionID != RE.SectionID || + REnext.Offset != RE.Offset; + } + resolveMIPS64Relocation(Section, RE.Offset, Value, r_type3, RE.Addend, + RE.SectionID, RE.SymOffset); +} + +void RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type, int64_t Addend, + SID SectionID, + uint64_t SymOffset) { + if (useCalculatedValue) { + Addend = calculatedValue; + Value = 0; + } + + DEBUG(dbgs() << "resolveMips64Relocation, LocalAddress: 0x" + << format("%llx", Section.Address + Offset) + << " FinalAddress: 0x" + << format("%llx", Section.LoadAddress + Offset) + << " Value: 0x" << format("%llx", Value) << " Type: 0x" + << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) + << " SymOffset: " << format("%x", SymOffset) + << "\n"); + + switch (Type) { + default: + llvm_unreachable("Not implemented relocation type!"); + break; + case ELF::R_MIPS_JALR: + case ELF::R_MIPS_NONE: + break; + case ELF::R_MIPS_32: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = Value + Addend; + if (applyRelocation) + *TargetPtr = calculatedValue; + break; + } + case ELF::R_MIPS_64: { + uint64_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = Value + Addend; + if (applyRelocation) + *TargetPtr = calculatedValue; + break; + } + case ELF::R_MIPS_26: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = ((Value + Addend) & 0x0fffffff) >> 2; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xfc000000) | calculatedValue; + break; + } + case ELF::R_MIPS_GPREL16: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + calculatedValue = Value + Addend - (GOTAddr + 0x7ff0); + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | (calculatedValue & 0xffff); + break; + } + case ELF::R_MIPS_SUB: { + uint64_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = Value - Addend; + if (applyRelocation) + *TargetPtr = calculatedValue; + break; + } + case ELF::R_MIPS_HI16: { + // Get the higher 16-bits. Also add 1 if bit 15 is 1. + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = ((Value + Addend + 0x8000) >> 16) & 0xffff; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | calculatedValue; + break; + } + case ELF::R_MIPS_LO16: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = (Value + Addend) & 0xffff; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | calculatedValue; + break; + } + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GOT_DISP: + case ELF::R_MIPS_GOT_PAGE: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t *LocalGOTAddr = + (uint64_t *)(getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset); + + Value += Addend; + if (Type == ELF::R_MIPS_GOT_PAGE) + Value = (Value + 0x8000) & 0xffffffffffff0000; + + if (*LocalGOTAddr) + assert(*LocalGOTAddr == Value && + "GOT entry has two different addresses."); + else + *LocalGOTAddr = Value; + + calculatedValue = SymOffset - 0x7ff0; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | (calculatedValue & 0xffff); + break; + } + case ELF::R_MIPS_GOT_OFST: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + calculatedValue = (Value + Addend) & 0xffff; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | calculatedValue; + break; + } + case ELF::R_MIPS_GPREL32: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + calculatedValue = Value + Addend - (GOTAddr + 0x7ff0); + if (applyRelocation) + *TargetPtr = calculatedValue; + break; + } + case ELF::R_MIPS_PC16: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - FinalAddress - 4) >> 2; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | (calculatedValue & 0xffff); + break; + } + case ELF::R_MIPS_PC18_S3: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - ((FinalAddress | 7) ^ 7)) >> 3; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xfffc0000) | (calculatedValue & 0x3ffff); + break; + } + case ELF::R_MIPS_PC19_S2: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - FinalAddress) >> 2; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xfff80000) | (calculatedValue & 0x7ffff); + break; + } + case ELF::R_MIPS_PC21_S2: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - FinalAddress) >> 2; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffe00000) | (calculatedValue & 0x1fffff); + break; + } + case ELF::R_MIPS_PC26_S2: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - FinalAddress) >> 2; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xfc000000) | (calculatedValue & 0x3ffffff); + break; + } + case ELF::R_MIPS_PCHI16: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = + ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | calculatedValue; + break; + } + case ELF::R_MIPS_PCLO16: { + uint32_t *TargetPtr = reinterpret_cast(Section.Address + + Offset); + uint64_t FinalAddress = (Section.LoadAddress + Offset); + calculatedValue = (Value + Addend - FinalAddress) & 0xffff; + if (applyRelocation) + *TargetPtr = ((*TargetPtr) & 0xffff0000) | calculatedValue; + break; + } + } +} + // Return the .TOC. section and offset. void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj, ObjSectionToIDMap &LocalSections, @@ -1056,6 +1286,23 @@ Value.Addend += *Placeholder; processSimpleRelocation(SectionID, Offset, RelType, Value); } + } else if (Arch == Triple::mips64el || Arch == Triple::mips64) { + uint32_t r_type = RelType & 0xff; + RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); + if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE + || r_type == ELF::R_MIPS_GOT_DISP) { + StringMap::iterator i = GOTSymbolOffsets.find(TargetName); + if (i != GOTSymbolOffsets.end()) + RE.SymOffset = i->second; + else { + RE.SymOffset = allocateGOTEntries(SectionID, 1); + GOTSymbolOffsets[TargetName] = RE.SymOffset; + } + } + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { if (RelType == ELF::R_PPC64_REL24) { // Determine ABI variant in use for this object. @@ -1353,6 +1600,8 @@ case Triple::ppc64: case Triple::ppc64le: case Triple::systemz: + case Triple::mips64el: + case Triple::mips64: Result = sizeof(uint64_t); break; case Triple::x86: @@ -1415,6 +1664,25 @@ // 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); + if (Arch == Triple::mips64el || Arch == Triple::mips64) { + unsigned AbiVariant; + Obj.getPlatformFlags(AbiVariant); + if ((AbiVariant & ELF::EF_MIPS_ABI2) || + (AbiVariant & ELF::EF_MIPS_ABI_O32)) + llvm_unreachable("N32 ABI and O32 ABI are not supported on Mips64"); + // To correctly resolve Mips GOT relocations, we need a mapping from + // object's sections to GOTs. + for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); + SI != SE; ++SI) { + if (SI->relocation_begin() != SI->relocation_end()) { + section_iterator RelocatedSection = SI->getRelocatedSection(); + ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection); + assert (i != SectionMap.end()); + SectionToGOTMap[i->second] = GOTSectionID; + } + } + GOTSymbolOffsets.clear(); + } } // Look for and record the EH frame section. Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -417,6 +417,11 @@ void resolveRelocations(); + virtual void resolveMIPS64Relocation(const RelocationList &Relocs, + uint64_t Value, unsigned RelocId) { + llvm_unreachable("Mips64 relocations are only implemented for ELF"); + } + void reassignSectionAddress(unsigned SectionID, uint64_t Addr); void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); Index: lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp =================================================================== --- lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp +++ lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp @@ -23,9 +23,9 @@ /*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel"); RegisterTarget A(TheMips64Target, "mips64", "Mips64 [experimental]"); + /*HasJIT=*/true> A(TheMips64Target, "mips64", "Mips64 [experimental]"); RegisterTarget B(TheMips64elTarget, + /*HasJIT=*/true> B(TheMips64elTarget, "mips64el", "Mips64el [experimental]"); } Index: test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll +++ test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() Index: test/ExecutionEngine/MCJIT/eh-lg-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/eh-lg-pic.ll +++ test/ExecutionEngine/MCJIT/eh-lg-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=large %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) Index: test/ExecutionEngine/MCJIT/eh-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/eh-sm-pic.ll +++ test/ExecutionEngine/MCJIT/eh-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=small %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) Index: test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll +++ test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() Index: test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll +++ test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() Index: test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll +++ test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() Index: test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll +++ test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 Index: test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll +++ test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -remote-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 Index: test/ExecutionEngine/MCJIT/stubs-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/stubs-sm-pic.ll +++ test/ExecutionEngine/MCJIT/stubs-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s -; XFAIL: mips, i686, i386, aarch64, arm +; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm define i32 @main() nounwind { entry: Index: test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll +++ test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 Index: test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll =================================================================== --- test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll +++ test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 Index: test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll +++ test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() Index: test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll +++ test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=large %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) Index: test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) Index: test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll +++ test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() Index: test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll +++ test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() Index: test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll +++ test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() Index: test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 Index: test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 Index: test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s -; XFAIL: mips, i686, i386, aarch64, arm +; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm define i32 @main() nounwind { entry: Index: test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 Index: test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll =================================================================== --- test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll +++ test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 Index: test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64N64_PIC_relocations.s =================================================================== --- /dev/null +++ test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64N64_PIC_relocations.s @@ -0,0 +1,86 @@ +# RUN: llvm-mc -triple=mips64el-unknown-linux -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_Mips64N64.o %s +# RUN: llvm-rtdyld -triple=mips64el-unknown-linux -verify -check=%s %/T/test_ELF_Mips64N64.o + + .file "ELF_Mips64N64_PIC_relocations.ll" + .text + .globl bar + .align 3 + .type bar,@function + .set nomicromips + .set nomips16 + .ent bar +bar: # @bar + .frame $sp,0,$ra + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + .set noat +# BB#0: + jr $ra + addiu $2, $zero, 0 + .set at + .set macro + .set reorder + .end bar +$func_end0: + .size bar, ($func_end0)-bar + + .globl main + .align 3 + .type main,@function + .set nomicromips + .set nomips16 + .ent main +main: # @main + .frame $sp,16,$ra + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + .set noat +# BB#0: + daddiu $sp, $sp, -16 +$tmp0: + sd $ra, 8($sp) + sd $gp, 0($sp) + +# Check upper 16-bits of offset between the address of main function +# and the global offset table. +# rtdyld-check: decode_operand(inst1, 1)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main + 0x8000)[31:16] +inst1: + lui $1, %hi(%neg(%gp_rel(main))) + daddu $1, $1, $25 + +# Check lower 16-bits of offset between the address of main function +# and the global offset table. +# rtdyld-check: decode_operand(inst2, 2)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main)[15:0] +inst2: + daddiu $gp, $1, %lo(%neg(%gp_rel(main))) + +# $gp register contains address of the .got section + 0x7FF0. 0x7FF0 is +# the offset of $gp from the beginning of the .got section. Check that we are +# loading address of bar from correct offset. In this case bar is +# the first entry in the .got section, so offset will be 0 - 0x7FF0. +# rtdyld-check: decode_operand(inst3, 2)[15:0] = 0x8010 +# +# Check that the address of the bar is at the beginning of the +# global offset table +# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got)) = bar +inst3: + ld $25, %call16(bar)($gp) + jalr $25 + nop + ld $gp, 0($sp) + ld $ra, 8($sp) + jr $ra + daddiu $sp, $sp, 16 + .set at + .set macro + .set reorder + .end main +$func_end1: + .size main, ($func_end1)-main + + + .section ".note.GNU-stack","",@progbits Index: test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg =================================================================== --- /dev/null +++ test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg @@ -0,0 +1,3 @@ +if not 'Mips' in config.root.targets: + config.unsupported = True + Index: unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp =================================================================== --- unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -127,6 +127,8 @@ SupportedArchs.push_back(Triple::aarch64); SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); + SupportedArchs.push_back(Triple::mips64); + SupportedArchs.push_back(Triple::mips64el); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64); Index: unittests/ExecutionEngine/MCJIT/MCJITTestBase.h =================================================================== --- unittests/ExecutionEngine/MCJIT/MCJITTestBase.h +++ unittests/ExecutionEngine/MCJIT/MCJITTestBase.h @@ -298,6 +298,8 @@ SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); SupportedArchs.push_back(Triple::mipsel); + SupportedArchs.push_back(Triple::mips64); + SupportedArchs.push_back(Triple::mips64el); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64);