Add getSymbolAlignment to the ObjectFile interface.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 29 Apr 2013 22:24:22 +0000 (22:24 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 29 Apr 2013 22:24:22 +0000 (22:24 +0000)
For regular object files this is only meaningful for common symbols. An object
file format with direct support for atoms should be able to provide alignment
information for all symbols.

This replaces getCommonSymbolAlignment and fixes
test-common-symbols-alignment.ll on darwin. This also includes a fix to
MachOObjectFile::getSymbolFlags. It was marking undefined symbols as common
(already tested by existing mcjit tests now that it is used).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180736 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELF.h
include/llvm/Object/MachO.h
include/llvm/Object/ObjectFile.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
lib/Object/MachOObjectFile.cpp
lib/Object/ObjectFile.cpp
test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll

index 4f0e5b8db8ff80818ff77c953ea9a7c5761e1b1b..b36460ca52cf67aa8926d7affbb46319fea78e31 100644 (file)
@@ -682,6 +682,7 @@ protected:
   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
   virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
+  virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
   virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
@@ -1114,6 +1115,21 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
   }
 }
 
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
+                                                   uint32_t &Res) const {
+  uint32_t flags;
+  getSymbolFlags(Symb, flags);
+  if (flags & SymbolRef::SF_Common) {
+    uint64_t Value;
+    getSymbolValue(Symb, Value);
+    Res = Value;
+  } else {
+    Res = 0;
+  }
+  return object_error::success;
+}
+
 template<class ELFT>
 error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
                                               uint64_t &Result) const {
index 98d3788e44cac1fdfe4faced565daf98ac641d8d..17a8fc2bff7aad2d68a036b64d0c806c63c404e0 100644 (file)
@@ -39,6 +39,7 @@ public:
   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
   virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
+  virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
   virtual error_code getSymbolType(DataRefImpl Symb,
                                    SymbolRef::Type &Res) const;
index cbe7ec92d3c5fda9f05481cffbd643afae3d0e55..eb53cc0aab58e347172dcf06793d3b6b12f73e49 100644 (file)
@@ -217,6 +217,8 @@ public:
   /// mapped).
   error_code getAddress(uint64_t &Result) const;
   error_code getFileOffset(uint64_t &Result) const;
+  /// @brief Get the alignment of this symbol as the actual value (not log 2).
+  error_code getAlignment(uint32_t &Result) const;
   error_code getSize(uint64_t &Result) const;
   error_code getType(SymbolRef::Type &Result) const;
 
@@ -292,6 +294,7 @@ protected:
   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
   virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
+  virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
   virtual error_code getSymbolType(DataRefImpl Symb,
                                    SymbolRef::Type &Res) const = 0;
@@ -425,6 +428,10 @@ inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
   return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
 }
 
+inline error_code SymbolRef::getAlignment(uint32_t &Result) const {
+  return OwningObject->getSymbolAlignment(SymbolPimpl, Result);
+}
+
 inline error_code SymbolRef::getSize(uint64_t &Result) const {
   return OwningObject->getSymbolSize(SymbolPimpl, Result);
 }
index 354795dc5f856e198a6daa1f842e4b74d3cd411b..7b32db7f0e05a040dabfc72d042b4247e68d6f8d 100644 (file)
@@ -96,7 +96,8 @@ 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);
+      uint32_t Align;
+      Check(i->getAlignment(Align));
       uint64_t Size = 0;
       Check(i->getSize(Size));
       CommonSize += Size + Align;
index ef4a4050e9efb90ea435d66ae9d7c07e20aa2b3e..c5bad8e41640188674ec1798e82efbf7308e8314 100644 (file)
@@ -848,13 +848,6 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
   }
 }
 
-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;
index b6ddf2d6a7aee18a77fece44606fc06cb1da71eb..102b1c6b593e949340b1708c0700d23d8070c9d7 100644 (file)
@@ -68,9 +68,6 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
                               int64_t Addend);
 
 
-  unsigned getCommonSymbolAlignment(const SymbolRef &Sym);
-
-
   uint64_t findPPC64TOC() const;
   void findOPDEntrySection(ObjectImage &Obj,
                            ObjSectionToIDMap &LocalSections,
index 3211a1c7eafd5488504419cbee7e794f30ab90e0..51873b1f4bf01fb1c154a80daf09acf52b7f2a62 100644 (file)
@@ -194,13 +194,6 @@ 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);
index bb6ca93176ddb673daa844123001f4c01cb3d87a..f6840b8c15d5873c78a7790c3d7e6ef7f04855a5 100644 (file)
@@ -495,6 +495,19 @@ MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
   return object_error::success;
 }
 
+error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
+                                               uint32_t &Result) const {
+  uint32_t flags;
+  this->getSymbolFlags(DRI, flags);
+  if (flags & SymbolRef::SF_Common) {
+    SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);
+    Result = 1 << MachO::GET_COMM_ALIGN(Entry.Flags);
+  } else {
+    Result = 0;
+  }
+  return object_error::success;
+}
+
 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
                                           uint64_t &Result) const {
   uint64_t BeginOffset;
@@ -609,8 +622,12 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
 
   if (MachOType & MachO::NlistMaskExternal) {
     Result |= SymbolRef::SF_Global;
-    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
-      Result |= SymbolRef::SF_Common;
+    if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) {
+      uint64_t Value;
+      getSymbolAddress(DRI, Value);
+      if (Value)
+        Result |= SymbolRef::SF_Common;
+    }
   }
 
   if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
index 518959aa059da65a6fbebe47879293e4f405bd71..77fd995cf0e4f997d9f78cb490480141a0be78b5 100644 (file)
@@ -27,6 +27,12 @@ ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *source)
   : Binary(Type, source) {
 }
 
+error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI,
+                                          uint32_t &Result) const {
+  Result = 0;
+  return object_error::success;
+}
+
 ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
   if (!Object || Object->getBufferSize() < 64)
     return 0;
index 43256c4492c2a5cceef817136943d54fa13f07c1..989a473423395c40e0574eab27698a6f3dd0ff11 100644 (file)
@@ -1,5 +1,4 @@
 ; RUN: %lli_mcjit -O0 %s
-; XFAIL: darwin
 
 ; This test checks that common symbols have been allocated addresses honouring
 ; the alignment requirement.