diff options
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/RuntimeDyld')
9 files changed, 85 insertions, 49 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index fa50182..93287a3 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -113,28 +113,12 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, llvm_unreachable("Attempting to remap address of unknown section!"); } -static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { - uint64_t Address; - if (std::error_code EC = Sym.getAddress(Address)) +static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec, + uint64_t &Result) { + ErrorOr<uint64_t> AddressOrErr = Sym.getAddress(); + if (std::error_code EC = AddressOrErr.getError()) return EC; - - if (Address == UnknownAddress) { - Result = UnknownAddress; - return std::error_code(); - } - - const ObjectFile *Obj = Sym.getObject(); - section_iterator SecI(Obj->section_begin()); - if (std::error_code EC = Sym.getSection(SecI)) - return EC; - - if (SecI == Obj->section_end()) { - Result = UnknownAddress; - return std::error_code(); - } - - uint64_t SectionAddress = SecI->getAddress(); - Result = Address - SectionAddress; + Result = *AddressOrErr - Sec.getAddress(); return std::error_code(); } @@ -184,12 +168,12 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { ErrorOr<StringRef> NameOrErr = I->getName(); Check(NameOrErr.getError()); StringRef Name = *NameOrErr; - uint64_t SectOffset; - Check(getOffset(*I, SectOffset)); section_iterator SI = Obj.section_end(); Check(I->getSection(SI)); if (SI == Obj.section_end()) continue; + uint64_t SectOffset; + Check(getOffset(*I, *SI, SectOffset)); StringRef SectionData; Check(SI->getContents(SectionData)); bool IsCode = SI->isText(); @@ -814,12 +798,16 @@ void RuntimeDyldImpl::resolveExternalSymbols() { report_fatal_error("Program used external function '" + Name + "' which could not be resolved!"); - DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t" - << format("0x%lx", Addr) << "\n"); - // This list may have been updated when we called getSymbolAddress, so - // don't change this code to get the list earlier. - RelocationList &Relocs = i->second; - resolveRelocationList(Relocs, Addr); + // If Resolver returned UINT64_MAX, the client wants to handle this symbol + // manually and we shouldn't resolve its relocations. + if (Addr != UINT64_MAX) { + DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t" + << format("0x%lx", Addr) << "\n"); + // This list may have been updated when we called getSymbolAddress, so + // don't change this code to get the list earlier. + RelocationList &Relocs = i->second; + resolveRelocationList(Relocs, Addr); + } } ExternalSymbolRelocations.erase(i); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 957571b..ae199b7 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -727,7 +727,9 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix, } bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const { - return getRTDyld().getSymbolLocalAddress(Symbol) != nullptr; + if (getRTDyld().getSymbolLocalAddress(Symbol)) + return true; + return !!getRTDyld().Resolver.findSymbol(Symbol); } uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index f5069c0..3787950 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -511,11 +511,54 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, Insn |= Value & 0xffff; writeBytesUnaligned(Insn, TargetPtr, 4); break; - case ELF::R_MIPS_PC32: + case ELF::R_MIPS_PC32: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + writeBytesUnaligned(Value - FinalAddress, (uint8_t *)TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC16: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffff0000; + Insn |= ((Value - FinalAddress) >> 2) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC19_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xfff80000; + Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC21_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffe00000; + Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC26_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xfc000000; + Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PCHI16: { uint32_t FinalAddress = (Section.LoadAddress + Offset); - writeBytesUnaligned(Value + Addend - FinalAddress, (uint8_t *)TargetPtr, 4); + Insn &= 0xffff0000; + Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); break; } + case ELF::R_MIPS_PCLO16: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffff0000; + Insn |= (Value - FinalAddress) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + } } void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { @@ -1263,12 +1306,24 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( Section.StubOffset += getMaxStubSize(); } } else { - if (RelType == ELF::R_MIPS_HI16) + // FIXME: Calculate correct addends for R_MIPS_HI16, R_MIPS_LO16, + // R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations. + if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) Value.Addend += (Opcode & 0x0000ffff) << 16; else if (RelType == ELF::R_MIPS_LO16) Value.Addend += (Opcode & 0x0000ffff); else if (RelType == ELF::R_MIPS_32) Value.Addend += Opcode; + else if (RelType == ELF::R_MIPS_PCLO16) + Value.Addend += SignExtend32<16>((Opcode & 0x0000ffff)); + else if (RelType == ELF::R_MIPS_PC16) + Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2); + else if (RelType == ELF::R_MIPS_PC19_S2) + Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2); + else if (RelType == ELF::R_MIPS_PC21_S2) + Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2); + else if (RelType == ELF::R_MIPS_PC26_S2) + Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2); processSimpleRelocation(SectionID, Offset, RelType, Value); } } else if (IsMipsN64ABI) { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 74b13d6..c074114 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -89,19 +89,11 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( } void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, - const ObjectFile &BaseTObj, const relocation_iterator &RI, unsigned OffsetToNextPC) { - const MachOObjectFile &Obj = - static_cast<const MachOObjectFile &>(BaseTObj); - MachO::any_relocation_info RelInfo = - Obj.getRelocation(RI->getRawDataRefImpl()); - - bool IsPCRel = Obj.getAnyRelocationPCRel(RelInfo); - if (IsPCRel) { - ErrorOr<uint64_t> RelocAddr = RI->getAddress(); - Value.Offset += *RelocAddr + OffsetToNextPC; - } + auto &O = *cast<MachOObjectFile>(RI->getObject()); + section_iterator SecI = O.getRelocationRelocatedSection(RI); + Value.Offset += RI->getOffset() + OffsetToNextPC + SecI->getAddress(); } void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE, diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 36ba8d1..0d7364f 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -95,7 +95,6 @@ protected: /// Make the RelocationValueRef addend PC-relative. void makeValueAddendPCRel(RelocationValueRef &Value, - const ObjectFile &BaseTObj, const relocation_iterator &RI, unsigned OffsetToNextPC); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index 99fd6e3..7bf7641 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -284,7 +284,7 @@ public: bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, RelI, 1 << RE.Size); RE.Addend = Value.Offset; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 0d9445e..0a24bb2 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -74,7 +74,7 @@ public: getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); if (RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 8); + makeValueAddendPCRel(Value, RelI, 8); if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24) processBranchRelocation(RE, Value, Stubs); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index aceb304..569a078 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -68,7 +68,7 @@ public: // Value.Addend += RelocAddr + 4; // } if (RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, RelI, 1 << RE.Size); RE.Addend = Value.Offset; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 4b3b01b..dd56e72 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -50,7 +50,7 @@ public: bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, RelI, 1 << RE.Size); if (RE.RelType == MachO::X86_64_RELOC_GOT || RE.RelType == MachO::X86_64_RELOC_GOT_LOAD) |