aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2013-01-04 20:36:28 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2013-01-04 20:36:28 +0000
commit4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe (patch)
tree4caf73a9a9994c1aa9d6f82f8cf356b760a268ed /lib/ExecutionEngine
parente13f441e002b95bb64d883d173f6aff9615556fd (diff)
downloadexternal_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.cpp100
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;