[llvm-commits] [llvm] r166919 - in /llvm/trunk: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll

Tim Northover Tim.Northover at arm.com
Mon Oct 29 03:47:05 PDT 2012


Author: tnorthover
Date: Mon Oct 29 05:47:04 2012
New Revision: 166919

URL: http://llvm.org/viewvc/llvm-project?rev=166919&view=rev
Log:
Make use of common-symbol alignment info in ELF loader.

Patch by Amara Emerson.

Added:
    llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll   (with props)
Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=166919&r1=166918&r2=166919&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Mon Oct 29 05:47:04 2012
@@ -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 @@
 
 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 @@
   // 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 @@
     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 @@
   // 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;
   }

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=166919&r1=166918&r2=166919&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Mon Oct 29 05:47:04 2012
@@ -796,6 +796,13 @@
   }
 }
 
+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;

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=166919&r1=166918&r2=166919&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Mon Oct 29 05:47:04 2012
@@ -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 @@
                                     const SymbolTableMap &Symbols,
                                     StubMap &Stubs);
 
+  unsigned getCommonSymbolAlignment(const SymbolRef &Sym);
+
   virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
 
   uint64_t findPPC64TOC() const;

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=166919&r1=166918&r2=166919&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Mon Oct 29 05:47:04 2012
@@ -140,8 +140,10 @@
   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 @@
     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);

Added: llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll?rev=166919&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll (added)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll Mon Oct 29 05:47:04 2012
@@ -0,0 +1,32 @@
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 %s
+
+; This test checks that common symbols have been allocated addresses honouring
+; the alignment requirement.
+
+ at CS1 = common global i32 0, align 16
+ at CS2 = common global i8 0, align 1
+ at CS3 = common global i32 0, align 16
+
+define i32 @main() nounwind {
+entry:
+    %retval = alloca i32, align 4
+    %ptr = alloca i32, align 4
+    store i32 0, i32* %retval
+    store i32 ptrtoint (i32* @CS3 to i32), i32* %ptr, align 4
+    %0 = load i32* %ptr, align 4
+    %and = and i32 %0, 15
+    %tobool = icmp ne i32 %and, 0
+    br i1 %tobool, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+    store i32 1, i32* %retval
+    br label %return
+
+if.else:                                          ; preds = %entry
+    store i32 0, i32* %retval
+    br label %return
+
+return:                                           ; preds = %if.else, %if.then
+    %1 = load i32* %retval
+    ret i32 %1
+}

Propchange: llvm/trunk/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll
------------------------------------------------------------------------------
    svn:eol-style = native





More information about the llvm-commits mailing list