summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorTim Northover <Tim.Northover@arm.com>2012-10-29 10:47:04 +0000
committerTim Northover <Tim.Northover@arm.com>2012-10-29 10:47:04 +0000
commitf00677d74f1be5b4c7c73e1681a64c9062f4c7ee (patch)
tree055c21d0903a30c5697b6969427135c3f5a5bbd8 /lib/ExecutionEngine
parenta41dce3c642e50775352cce49e3a3d0cd004d393 (diff)
downloadllvm-f00677d74f1be5b4c7c73e1681a64c9062f4c7ee.tar.gz
llvm-f00677d74f1be5b4c7c73e1681a64c9062f4c7ee.tar.bz2
llvm-f00677d74f1be5b4c7c73e1681a64c9062f4c7ee.tar.xz
Make use of common-symbol alignment info in ELF loader.
Patch by Amara Emerson. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166919 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp31
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp7
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h14
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h13
4 files changed, 47 insertions, 18 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index ff05c82aec..fb07cb9021 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -17,6 +17,7 @@
#include "RuntimeDyldELF.h"
#include "RuntimeDyldMachO.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/MathExtras.h"
using namespace llvm;
using namespace llvm::object;
@@ -27,16 +28,6 @@ RuntimeDyldImpl::~RuntimeDyldImpl() {}
namespace llvm {
-namespace {
- // Helper for extensive error checking in debug builds.
- error_code Check(error_code Err) {
- if (Err) {
- report_fatal_error(Err.message());
- }
- return Err;
- }
-} // end anonymous namespace
-
// Resolve the relocations for all symbols we currently know about.
void RuntimeDyldImpl::resolveRelocations() {
// First, resolve relocations associated with external symbols.
@@ -78,9 +69,9 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) {
// Used sections from the object file
ObjSectionToIDMap LocalSections;
- // Common symbols requiring allocation, and the total size required to
- // allocate all common symbols.
+ // Common symbols requiring allocation, with their sizes and alignments
CommonSymbolMap CommonSymbols;
+ // Maximum required total memory to allocate all common symbols
uint64_t CommonSize = 0;
error_code err;
@@ -100,10 +91,11 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) {
bool isCommon = flags & SymbolRef::SF_Common;
if (isCommon) {
// Add the common symbols to a list. We'll allocate them all below.
+ uint64_t Align = getCommonSymbolAlignment(*i);
uint64_t Size = 0;
Check(i->getSize(Size));
- CommonSize += Size;
- CommonSymbols[*i] = Size;
+ CommonSize += Size + Align;
+ CommonSymbols[*i] = CommonSymbolInfo(Size, Align);
} else {
if (SymType == object::SymbolRef::ST_Function ||
SymType == object::SymbolRef::ST_Data ||
@@ -201,11 +193,20 @@ void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
// Assign the address of each symbol
for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(),
itEnd = CommonSymbols.end(); it != itEnd; it++) {
+ uint64_t Size = it->second.first;
+ uint64_t Align = it->second.second;
StringRef Name;
it->first.getName(Name);
+ if (Align) {
+ // This symbol has an alignment requirement.
+ uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align);
+ Addr += AlignOffset;
+ Offset += AlignOffset;
+ DEBUG(dbgs() << "Allocating common symbol " << Name << " address " <<
+ format("0x%x\n", Addr));
+ }
Obj.updateSymbolAddress(it->first, (uint64_t)Addr);
SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset);
- uint64_t Size = it->second;
Offset += Size;
Addr += Size;
}
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 1073c6fc52..b9c5f8b864 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -796,6 +796,13 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
}
}
+unsigned RuntimeDyldELF::getCommonSymbolAlignment(const SymbolRef &Sym) {
+ // In ELF, the value of an SHN_COMMON symbol is its alignment requirement.
+ uint64_t Align;
+ Check(Sym.getValue(Align));
+ return Align;
+}
+
bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {
if (Buffer->getBufferSize() < strlen(ELF::ElfMagic))
return false;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index 6c31f0dc12..cbdc0dbc6b 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -18,8 +18,18 @@
using namespace llvm;
-
namespace llvm {
+
+namespace {
+ // Helper for extensive error checking in debug builds.
+ error_code Check(error_code Err) {
+ if (Err) {
+ report_fatal_error(Err.message());
+ }
+ return Err;
+ }
+} // end anonymous namespace
+
class RuntimeDyldELF : public RuntimeDyldImpl {
protected:
void resolveX86_64Relocation(uint8_t *LocalAddress,
@@ -64,6 +74,8 @@ protected:
const SymbolTableMap &Symbols,
StubMap &Stubs);
+ unsigned getCommonSymbolAlignment(const SymbolRef &Sym);
+
virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
uint64_t findPPC64TOC() const;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index 45633e735c..3baec3cf2a 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -140,8 +140,10 @@ protected:
typedef StringMap<SymbolLoc> SymbolTableMap;
SymbolTableMap GlobalSymbolTable;
- // Keep a map of common symbols to their sizes
- typedef std::map<SymbolRef, unsigned> CommonSymbolMap;
+ // Pair representing the size and alignment requirement for a common symbol.
+ typedef std::pair<unsigned, unsigned> CommonSymbolInfo;
+ // Keep a map of common symbols to their info pairs
+ typedef std::map<SymbolRef, CommonSymbolInfo> CommonSymbolMap;
// For each symbol, keep a list of relocations based on it. Anytime
// its address is reassigned (the JIT re-compiled the function, e.g.),
@@ -192,6 +194,13 @@ protected:
return (uint8_t*)Sections[SectionID].Address;
}
+ // Subclasses can override this method to get the alignment requirement of
+ // a common symbol. Returns no alignment requirement if not implemented.
+ virtual unsigned getCommonSymbolAlignment(const SymbolRef &Sym) {
+ return 0;
+ }
+
+
void writeInt16BE(uint8_t *Addr, uint16_t Value) {
if (sys::isLittleEndianHost())
Value = sys::SwapByteOrder(Value);