aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
committerStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
commit5adb136be579e8fff3734461580cb34d1d2983b8 (patch)
treebff1a422e9c9789df563aaf9a7e91e63e8ec0384 /lib/ExecutionEngine/RuntimeDyld
parent227a4a4ade38716ba9eb3205f48b52910f3b955e (diff)
parentb3201c5cf1e183d840f7c99ff779d57f1549d8e5 (diff)
downloadexternal_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')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp20
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp91
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp1
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: