[lld] r175636 - functionality to handle global atoms in Merge sections

Shankar Easwaran shankare at codeaurora.org
Wed Feb 20 09:38:38 PST 2013


Author: shankare
Date: Wed Feb 20 11:38:37 2013
New Revision: 175636

URL: http://llvm.org/viewvc/llvm-project?rev=175636&view=rev
Log:
functionality to handle global atoms in Merge sections

Added:
    lld/trunk/test/elf/Inputs/globalconst.c
    lld/trunk/test/elf/Inputs/globalconst.o.x86-64   (with props)
    lld/trunk/test/elf/mergeglobalatoms.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=175636&r1=175635&r2=175636&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Wed Feb 20 11:38:37 2013
@@ -274,17 +274,6 @@ public:
       const Elf_Shdr *section = _objFile->getElfSection(sit);
       const Elf_Sym *symbol = _objFile->getElfSymbol(it);
 
-      // If its a merge section, the atoms have already 
-      // been created, lets not create the atoms again
-      if (doStringsMerge) {
-        int64_t sectionFlags = section->sh_flags;
-        sectionFlags &= ~llvm::ELF::SHF_ALLOC;
-        if ((section->sh_entsize < 2) &&
-            (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
-          continue;
-        }
-      }
-
       StringRef symbolName;
       if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
         return;
@@ -364,6 +353,8 @@ public:
         if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
           return;
 
+        const Elf_Shdr *section = _objFile->getSection(*si);
+
         bool isCommon = (*si)->getType() == llvm::ELF::STT_COMMON ||
                         (*si)->st_shndx == llvm::ELF::SHN_COMMON;
 
@@ -423,6 +414,25 @@ public:
           previous_atom->addReference(followOn);
         }
 
+        // If the linker finds that a section has global atoms that are in a 
+        // mergeable section, treat them as defined atoms as they shouldnt be
+        // merged away as well as these symbols have to be part of symbol
+        // resolution
+        int64_t sectionFlags = 0;
+        if (section)
+          sectionFlags = section->sh_flags;
+        sectionFlags &= ~llvm::ELF::SHF_ALLOC;
+        if (doStringsMerge && section && (section->sh_entsize < 2) &&
+            (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
+          if ((*si)->getBinding() == llvm::ELF::STB_GLOBAL) {
+            auto definedMergeAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
+                *this, symbolName, sectionName, (*si), section, symbolData,
+                _references.size(), _references.size(), _references);
+            _definedAtoms._atoms.push_back(definedMergeAtom);
+          }
+          continue;
+        }
+
         auto newAtom = createDefinedAtomAndAssignRelocations(
             symbolName, sectionName, *si, i.first, symbolData);
 
@@ -468,11 +478,14 @@ public:
         // refer to the MergeAtom to allow deduping
         if (doStringsMerge && shdr && (shdr->sh_entsize < 2) &&
             (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
-          const MergeSectionKey ms(shdr, ri->addend());
+          const TargetRelocationHandler<ELFT> &relHandler = _elfTargetInfo
+              .template getTargetHandler<ELFT>().getRelocationHandler();
+          int64_t relocAddend = relHandler.relocAddend(*ri);
+          uint64_t addend = ri->addend() + relocAddend;
+          const MergeSectionKey ms(shdr, addend);
           if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
-            uint64_t addend = ri->addend();
             if (Symbol->getType() != llvm::ELF::STT_SECTION)
-              addend = Symbol->st_value + ri->addend();
+              addend = Symbol->st_value + addend;
             MergeAtomsIter mai = findMergeAtom(shdr, addend);
             if (mai != _mergeAtoms.end()) {
               ri->setOffset(addend - ((*mai)->offset()));

Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=175636&r1=175635&r2=175636&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Wed Feb 20 11:38:37 2013
@@ -33,6 +33,7 @@
 namespace lld {
 namespace elf {
 template <class ELFT> class ELFDefinedAtom;
+template <class ELFT> class ELFReference;
 class ELFWriter;
 template <class ELFT> class Header;
 template <class ELFT> class Section;
@@ -54,17 +55,20 @@ public:
     return DefinedAtom::typeZeroFill;
   }
 
-  virtual DefinedAtom::ContentPermissions contentPermissions(
-      const ELFDefinedAtom<ELFT> *atom) const {
+  virtual DefinedAtom::ContentPermissions
+  contentPermissions(const ELFDefinedAtom<ELFT> *atom) const {
     return atom->permissions();
   }
+
 };
 
 template <class ELFT> class TargetRelocationHandler {
 public:
-  virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
-                                        const AtomLayout &,
-                                        const Reference &)const = 0;
+  virtual ErrorOr<void>
+  applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &,
+                  const Reference &)const = 0;
+
+  virtual int64_t relocAddend(const Reference &)const { return 0; }
 };
 
 /// \brief An interface to override functions that are provided by the 

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=175636&r1=175635&r2=175636&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Wed Feb 20 11:38:37 2013
@@ -52,6 +52,16 @@ void reloc32S(uint8_t *location, uint64_
 }
 } // end anon namespace
 
+int64_t X86_64TargetRelocationHandler::fixupAddend(const Reference &ref) const {
+  switch (ref.kind()) {
+  case R_X86_64_PC32:
+    return 4;
+  default:
+    return 0;
+  }
+  return 0;
+}
+
 ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
     const Reference &ref) const {

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=175636&r1=175635&r2=175636&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Wed Feb 20 11:38:37 2013
@@ -26,9 +26,11 @@ public:
   X86_64TargetRelocationHandler(const X86_64TargetInfo &ti)
       : _tlsSize(0), _targetInfo(ti) {}
 
-  virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
-                                        const AtomLayout &,
-                                        const Reference &)const;
+  virtual ErrorOr<void>
+  applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &,
+                  const Reference &)const;
+
+  virtual int64_t fixupAddend(const Reference &)const;
 
 private:
   // Cached size of the TLS segment.

Added: lld/trunk/test/elf/Inputs/globalconst.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/globalconst.c?rev=175636&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/globalconst.c (added)
+++ lld/trunk/test/elf/Inputs/globalconst.c Wed Feb 20 11:38:37 2013
@@ -0,0 +1,2 @@
+/* compile the code with -fmerge-all-constants */
+const char mystr[] = "foobar";

Added: lld/trunk/test/elf/Inputs/globalconst.o.x86-64
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/globalconst.o.x86-64?rev=175636&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/globalconst.o.x86-64
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/mergeglobalatoms.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/mergeglobalatoms.test?rev=175636&view=auto
==============================================================================
--- lld/trunk/test/elf/mergeglobalatoms.test (added)
+++ lld/trunk/test/elf/mergeglobalatoms.test Wed Feb 20 11:38:37 2013
@@ -0,0 +1,10 @@
+# ELF files can have mergeable strings which are global!, treat them as global
+# defined atoms
+RUN: lld-core -merge-strings=true -reader ELF %p/Inputs/globalconst.o.x86-64 | FileCheck -check-prefix=globalatoms %s
+
+globalatoms:  - name:            mystr
+globalatoms:    scope:           global
+globalatoms:    type:            constant
+globalatoms:    content:         [ 66, 6F, 6F, 62, 61, 72, 00 ]
+globalatoms:    section-choice:  custom-required
+globalatoms:    section-name:    .rodata.str1.1





More information about the llvm-commits mailing list