diff options
author | Stephen Hines <srhines@google.com> | 2013-03-05 23:27:24 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2013-03-05 23:27:24 -0800 |
commit | 5adb136be579e8fff3734461580cb34d1d2983b8 (patch) | |
tree | bff1a422e9c9789df563aaf9a7e91e63e8ec0384 /lib/ExecutionEngine/RuntimeDyld | |
parent | 227a4a4ade38716ba9eb3205f48b52910f3b955e (diff) | |
parent | b3201c5cf1e183d840f7c99ff779d57f1549d8e5 (diff) | |
download | external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.zip external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.gz external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.bz2 |
Merge commit 'b3201c5cf1e183d840f7c99ff779d57f1549d8e5' into merge_20130226
Conflicts:
include/llvm/Support/ELF.h
lib/Support/DeltaAlgorithm.cpp
Change-Id: I24a4fbce62eb39d924efee3c687b55e1e17b30cd
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld')
4 files changed, 65 insertions, 49 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h index 28b4f0f..89350cc 100644 --- a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h +++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h @@ -58,6 +58,8 @@ public: virtual StringRef getData() const { return ObjFile->getData(); } + virtual object::ObjectFile* getObjectFile() const { return ObjFile; } + // Subclasses can override these methods to update the image with loaded // addresses for sections and common symbols virtual void updateSectionAddress(const object::SectionRef &Sec, diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index c5b807b..409b25f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -432,14 +432,20 @@ void RuntimeDyldImpl::resolveExternalSymbols() { RelocationList &Relocs = i->second; SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); if (Loc == GlobalSymbolTable.end()) { - // This is an external symbol, try to get it address from - // MemoryManager. - uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(), + if (Name.size() == 0) { + // This is an absolute symbol, use an address of zero. + DEBUG(dbgs() << "Resolving absolute relocations." << "\n"); + resolveRelocationList(Relocs, 0); + } else { + // This is an external symbol, try to get its address from + // MemoryManager. + uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(), true); - DEBUG(dbgs() << "Resolving relocations Name: " << Name - << "\t" << format("%p", Addr) - << "\n"); - resolveRelocationList(Relocs, (uintptr_t)Addr); + DEBUG(dbgs() << "Resolving relocations Name: " << Name + << "\t" << format("%p", Addr) + << "\n"); + resolveRelocationList(Relocs, (uintptr_t)Addr); + } } else { report_fatal_error("Expected external symbol"); } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 0a68f4e..b8537b1 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -28,8 +28,6 @@ using namespace llvm; using namespace llvm::object; -using support::endianness; - namespace { static inline @@ -40,22 +38,22 @@ error_code check(error_code Err) { return Err; } -template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +template<class ELFT> class DyldELFObject - : public ELFObjectFile<target_endianness, max_alignment, is64Bits> { - LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) + : public ELFObjectFile<ELFT> { + LLVM_ELF_IMPORT_TYPES(ELFT) - typedef Elf_Shdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Shdr; - typedef Elf_Sym_Impl<target_endianness, max_alignment, is64Bits> Elf_Sym; + typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; + typedef Elf_Sym_Impl<ELFT> Elf_Sym; typedef - Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, false> Elf_Rel; + Elf_Rel_Impl<ELFT, false> Elf_Rel; typedef - Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, true> Elf_Rela; + Elf_Rel_Impl<ELFT, true> Elf_Rela; - typedef Elf_Ehdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Ehdr; + typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; typedef typename ELFDataTypeTypedefHelper< - target_endianness, max_alignment, is64Bits>::value_type addr_type; + ELFT>::value_type addr_type; public: DyldELFObject(MemoryBuffer *Wrapper, error_code &ec); @@ -65,25 +63,25 @@ public: // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { - return (isa<ELFObjectFile<target_endianness, max_alignment, is64Bits> >(v) + return (isa<ELFObjectFile<ELFT> >(v) && classof(cast<ELFObjectFile - <target_endianness, max_alignment, is64Bits> >(v))); + <ELFT> >(v))); } static inline bool classof( - const ELFObjectFile<target_endianness, max_alignment, is64Bits> *v) { + const ELFObjectFile<ELFT> *v) { return v->isDyldType(); } }; -template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +template<class ELFT> class ELFObjectImage : public ObjectImageCommon { protected: - DyldELFObject<target_endianness, max_alignment, is64Bits> *DyldObj; + DyldELFObject<ELFT> *DyldObj; bool Registered; public: ELFObjectImage(ObjectBuffer *Input, - DyldELFObject<target_endianness, max_alignment, is64Bits> *Obj) + DyldELFObject<ELFT> *Obj) : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {} @@ -119,16 +117,15 @@ class ELFObjectImage : public ObjectImageCommon { // The MemoryBuffer passed into this constructor is just a wrapper around the // actual memory. Ultimately, the Binary parent class will take ownership of // this MemoryBuffer object but not the underlying memory. -template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> -DyldELFObject<target_endianness, max_alignment, is64Bits> - ::DyldELFObject(MemoryBuffer *Wrapper, error_code &ec) - : ELFObjectFile<target_endianness, max_alignment, is64Bits>(Wrapper, ec) { +template<class ELFT> +DyldELFObject<ELFT>::DyldELFObject(MemoryBuffer *Wrapper, error_code &ec) + : ELFObjectFile<ELFT>(Wrapper, ec) { this->isDyldELFObject = true; } -template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> -void DyldELFObject<target_endianness, max_alignment, is64Bits> - ::updateSectionAddress(const SectionRef &Sec, uint64_t Addr) { +template<class ELFT> +void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec, + uint64_t Addr) { DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); Elf_Shdr *shdr = const_cast<Elf_Shdr*>( reinterpret_cast<const Elf_Shdr *>(ShdrRef.p)); @@ -138,13 +135,12 @@ void DyldELFObject<target_endianness, max_alignment, is64Bits> shdr->sh_addr = static_cast<addr_type>(Addr); } -template<endianness target_endianness, std::size_t max_align, bool is64Bits> -void DyldELFObject<target_endianness, max_align, is64Bits> - ::updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr){ +template<class ELFT> +void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef, + uint64_t Addr) { Elf_Sym *sym = const_cast<Elf_Sym*>( - ELFObjectFile<target_endianness, max_align, is64Bits> - ::getSymbol(SymRef.getRawDataRefImpl())); + ELFObjectFile<ELFT>::getSymbol(SymRef.getRawDataRefImpl())); // This assumes the address passed in matches the target address bitness // The template-based type cast handles everything else. @@ -164,24 +160,28 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { error_code ec; if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, 4, false> *Obj = - new DyldELFObject<support::little, 4, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, 4, false>(Buffer, Obj); + DyldELFObject<ELFType<support::little, 4, false> > *Obj = + new DyldELFObject<ELFType<support::little, 4, false> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::little, 4, false> >(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, 4, false> *Obj = - new DyldELFObject<support::big, 4, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, 4, false>(Buffer, Obj); + DyldELFObject<ELFType<support::big, 4, false> > *Obj = + new DyldELFObject<ELFType<support::big, 4, false> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::big, 4, false> >(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, 8, true> *Obj = - new DyldELFObject<support::big, 8, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, 8, true>(Buffer, Obj); + DyldELFObject<ELFType<support::big, 8, true> > *Obj = + new DyldELFObject<ELFType<support::big, 8, true> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::big, 8, true> >(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, 8, true> *Obj = - new DyldELFObject<support::little, 8, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, 8, true>(Buffer, Obj); + DyldELFObject<ELFType<support::little, 8, true> > *Obj = + new DyldELFObject<ELFType<support::little, 8, true> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::little, 8, true> >(Buffer, Obj); } else llvm_unreachable("Unexpected ELF format"); @@ -523,7 +523,7 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, case ELF::R_PPC64_ADDR32 : { int32_t Result = static_cast<int32_t>(Value + Addend); if (SignExtend32<32>(Result) != Result) - llvm_unreachable("Relocation R_PPC64_REL32 overflow"); + llvm_unreachable("Relocation R_PPC64_ADDR32 overflow"); writeInt32BE(LocalAddress, Result); } break; case ELF::R_PPC64_REL24 : { @@ -534,6 +534,13 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, // Generates a 'bl <address>' instruction writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC)); } break; + case ELF::R_PPC64_REL32 : { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend); + if (SignExtend32<32>(delta) != delta) + llvm_unreachable("Relocation R_PPC64_REL32 overflow"); + writeInt32BE(LocalAddress, delta); + } break; case ELF::R_PPC64_ADDR64 : writeInt64BE(LocalAddress, Value + Addend); break; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index d2310b5..bcc3df1 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -96,6 +96,7 @@ bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, *p++ = (uint8_t)(ValueToWrite & 0xff); ValueToWrite >>= 8; } + return false; } case macho::RIT_Difference: case macho::RIT_Generic_LocalDifference: |