diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-01-04 20:36:28 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-01-04 20:36:28 +0000 |
commit | 4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe (patch) | |
tree | 4caf73a9a9994c1aa9d6f82f8cf356b760a268ed /lib/ExecutionEngine | |
parent | e13f441e002b95bb64d883d173f6aff9615556fd (diff) | |
download | external_llvm-4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe.zip external_llvm-4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe.tar.gz external_llvm-4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe.tar.bz2 |
[Object][ELF] Add a maximum alignment. This is used by createELFObjectFile to create a properly aligned reader.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171520 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 100 |
1 files changed, 51 insertions, 49 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index efb34df..0a68f4e 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -28,6 +28,8 @@ using namespace llvm; using namespace llvm::object; +using support::endianness; + namespace { static inline @@ -38,19 +40,22 @@ error_code check(error_code Err) { return Err; } -template<support::endianness target_endianness, bool is64Bits> -class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) +template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +class DyldELFObject + : public ELFObjectFile<target_endianness, max_alignment, is64Bits> { + LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) - typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; - typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; - typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; - typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; + typedef Elf_Shdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Shdr; + typedef Elf_Sym_Impl<target_endianness, max_alignment, is64Bits> Elf_Sym; + typedef + Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, false> Elf_Rel; + typedef + Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, true> Elf_Rela; - typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr; + typedef Elf_Ehdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Ehdr; typedef typename ELFDataTypeTypedefHelper< - target_endianness, is64Bits>::value_type addr_type; + target_endianness, max_alignment, is64Bits>::value_type addr_type; public: DyldELFObject(MemoryBuffer *Wrapper, error_code &ec); @@ -60,24 +65,25 @@ public: // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { - return (isa<ELFObjectFile<target_endianness, is64Bits> >(v) - && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v))); + return (isa<ELFObjectFile<target_endianness, max_alignment, is64Bits> >(v) + && classof(cast<ELFObjectFile + <target_endianness, max_alignment, is64Bits> >(v))); } static inline bool classof( - const ELFObjectFile<target_endianness, is64Bits> *v) { + const ELFObjectFile<target_endianness, max_alignment, is64Bits> *v) { return v->isDyldType(); } }; -template<support::endianness target_endianness, bool is64Bits> +template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> class ELFObjectImage : public ObjectImageCommon { protected: - DyldELFObject<target_endianness, is64Bits> *DyldObj; + DyldELFObject<target_endianness, max_alignment, is64Bits> *DyldObj; bool Registered; public: ELFObjectImage(ObjectBuffer *Input, - DyldELFObject<target_endianness, is64Bits> *Obj) + DyldELFObject<target_endianness, max_alignment, is64Bits> *Obj) : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {} @@ -113,17 +119,16 @@ 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<support::endianness target_endianness, bool is64Bits> -DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Wrapper, - error_code &ec) - : ELFObjectFile<target_endianness, is64Bits>(Wrapper, ec) { +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) { this->isDyldELFObject = true; } -template<support::endianness target_endianness, bool is64Bits> -void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress( - const SectionRef &Sec, - uint64_t Addr) { +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) { DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); Elf_Shdr *shdr = const_cast<Elf_Shdr*>( reinterpret_cast<const Elf_Shdr *>(ShdrRef.p)); @@ -133,14 +138,13 @@ void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress( shdr->sh_addr = static_cast<addr_type>(Addr); } -template<support::endianness target_endianness, bool is64Bits> -void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( - const SymbolRef &SymRef, - uint64_t 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){ Elf_Sym *sym = const_cast<Elf_Sym*>( - ELFObjectFile<target_endianness, is64Bits>:: - getSymbol(SymRef.getRawDataRefImpl())); + ELFObjectFile<target_endianness, max_align, is64Bits> + ::getSymbol(SymRef.getRawDataRefImpl())); // This assumes the address passed in matches the target address bitness // The template-based type cast handles everything else. @@ -149,7 +153,6 @@ void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( } // namespace - namespace llvm { ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { @@ -161,24 +164,24 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { error_code ec; if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, false> *Obj = - new DyldELFObject<support::little, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, false>(Buffer, Obj); + DyldELFObject<support::little, 4, false> *Obj = + new DyldELFObject<support::little, 4, false>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::little, 4, false>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, false> *Obj = - new DyldELFObject<support::big, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, false>(Buffer, Obj); + DyldELFObject<support::big, 4, false> *Obj = + new DyldELFObject<support::big, 4, false>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::big, 4, false>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, true> *Obj = - new DyldELFObject<support::big, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, true>(Buffer, Obj); + DyldELFObject<support::big, 8, true> *Obj = + new DyldELFObject<support::big, 8, true>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::big, 8, true>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, true> *Obj = - new DyldELFObject<support::little, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, true>(Buffer, Obj); + DyldELFObject<support::little, 8, true> *Obj = + new DyldELFObject<support::little, 8, true>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::little, 8, true>(Buffer, Obj); } else llvm_unreachable("Unexpected ELF format"); @@ -207,7 +210,7 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section, case ELF::R_X86_64_32S: { Value += Addend; assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) || - (Type == ELF::R_X86_64_32S && + (Type == ELF::R_X86_64_32S && ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN))); uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); uint32_t *Target = reinterpret_cast<uint32_t*>(Section.Address + Offset); @@ -288,7 +291,7 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, default: llvm_unreachable("Not implemented relocation type!"); - // Write a 32bit value to relocation address, taking into account the + // Write a 32bit value to relocation address, taking into account the // implicit addend encoded in the target. case ELF::R_ARM_TARGET1 : case ELF::R_ARM_ABS32 : @@ -299,7 +302,7 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, // Last 4 bit should be shifted. case ELF::R_ARM_MOVW_ABS_NC : // We are not expecting any other addend in the relocation address. - // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 + // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 // non-contiguous fields. assert((*TargetPtr & 0x000F0FFF) == 0); Value = Value & 0xFFFF; @@ -550,7 +553,6 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, } } - void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, @@ -630,9 +632,9 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, // Default to 'true' in case isText fails (though it never does). bool isCode = true; si->isText(isCode); - Value.SectionID = findOrEmitSection(Obj, - (*si), - isCode, + Value.SectionID = findOrEmitSection(Obj, + (*si), + isCode, ObjSectionToID); Value.Addend = Addend; break; |