[lld] r183696 - [ELF] Refactor File.h.

Rui Ueyama ruiu at google.com
Mon Jun 10 14:32:45 PDT 2013


Author: ruiu
Date: Mon Jun 10 16:32:44 2013
New Revision: 183696

URL: http://llvm.org/viewvc/llvm-project?rev=183696&view=rev
Log:
[ELF] Refactor File.h.

 - Split createAtom() in lib/ReaderWriter/ELF/File.h into small methods.
 - Added comments to code in other methods.

No functionality changes.

Reviewers: shankarke

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D921

Modified:
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/test/elf/X86_64/weak-override.test

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=183696&r1=183695&r2=183696&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Mon Jun 10 16:32:44 2013
@@ -89,7 +89,6 @@ template <class ELFT> class ELFFile : pu
   // This is used to find the MergeAtom given a relocation
   // offset
   typedef std::vector<ELFMergeAtom<ELFT> *> MergeAtomsT;
-  typedef typename MergeAtomsT::iterator MergeAtomsIter;
 
   /// \brief find a mergeAtom given a start offset
   struct FindByOffset {
@@ -106,9 +105,11 @@ template <class ELFT> class ELFFile : pu
   };
 
   /// \brief find a merge atom given a offset
-  MergeAtomsIter findMergeAtom(const Elf_Shdr *shdr, uint64_t offset) {
-    return std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
-                        FindByOffset(shdr, offset));
+  ELFMergeAtom<ELFT> *findMergeAtom(const Elf_Shdr *shdr, uint64_t offset) {
+    auto it = std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
+                           FindByOffset(shdr, offset));
+    assert(it != _mergeAtoms.end());
+    return *it;
   }
 
   typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
@@ -141,23 +142,22 @@ public:
 
     _doStringsMerge = _elfTargetInfo.mergeCommonStrings();
 
-    // Read input sections from the input file
-    // that need to be converted to
+    // Read input sections from the input file that need to be converted to
     // atoms
     if (createAtomizableSections(EC))
       return;
 
-    // For mergeable strings, we would need to split the section
-    // into various atoms
+    // For mergeable strings, we would need to split the section into various
+    // atoms
     if (createMergeableAtoms(EC))
       return;
 
-    // Create the necessary symbols that are part of the section
-    // that we created in createAtomizableSections function
+    // Create the necessary symbols that are part of the section that we
+    // created in createAtomizableSections function
     if (createSymbolsFromAtomizableSections(EC))
       return;
 
-    // Create the appropriate atoms fom the file
+    // Create the appropriate atoms from the file
     if (createAtoms(EC))
       return;
   }
@@ -181,7 +181,7 @@ public:
       if (isIgnoredSection(section))
         continue;
 
-      if (isMergeableSection(section)) {
+      if (isMergeableStringSection(section)) {
         _mergeStringSections.push_back(section);
         continue;
       }
@@ -227,13 +227,12 @@ public:
   /// \brief Create mergeable atoms from sections that have the merge attribute
   /// set
   bool createMergeableAtoms(llvm::error_code &EC) {
-
     // Divide the section that contains mergeable strings into tokens
     // TODO
     // a) add resolver support to recognize multibyte chars
     // b) Create a seperate section chunk to write mergeable atoms
     std::vector<MergeString *> tokens;
-    for (auto msi : _mergeStringSections) {
+    for (const Elf_Shdr *msi : _mergeStringSections) {
       StringRef sectionContents;
       StringRef sectionName;
       if ((EC = _objFile->getSectionName(msi, sectionName)))
@@ -253,7 +252,7 @@ public:
     }
 
     // Create Mergeable atoms
-    for (auto tai : tokens) {
+    for (const MergeString *tai : tokens) {
       ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
                                 tai->_string.size());
       ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage) ELFMergeAtom<ELFT>(
@@ -336,141 +335,72 @@ public:
 
   /// \brief Create individual atoms
   bool createAtoms(llvm::error_code &EC) {
-
-    // Cached value of the targetHandler
-    TargetHandler<ELFT> &targetHandler =
-        _elfTargetInfo.template getTargetHandler<ELFT>();
-
     for (auto &i : _sectionSymbols) {
-      auto &symbols = i.second;
-        // Sort symbols by position.
+      const Elf_Shdr *section = i.first;
+      std::vector<const Elf_Sym *> &symbols = i.second;
+
+      // Sort symbols by position.
       std::stable_sort(symbols.begin(), symbols.end(),
-                       [](const Elf_Sym * A, const Elf_Sym * B) {
+                       [](const Elf_Sym *A, const Elf_Sym *B) {
         return A->st_value < B->st_value;
       });
 
+      StringRef sectionName;
       StringRef sectionContents;
-      if ((EC = _objFile->getSectionContents(i.first, sectionContents)))
+      if ((EC = _objFile->getSectionName(section, sectionName)))
         return true;
-
-      StringRef sectionName;
-      if ((EC = _objFile->getSectionName(i.first, sectionName)))
+      if ((EC = _objFile->getSectionContents(section, sectionContents)))
         return true;
 
       // If the section has no symbols, create a custom atom for it.
-      if (i.first->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty() &&
+      if (section->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty() &&
           !sectionContents.empty()) {
-        Elf_Sym *sym = new (_readerStorage) Elf_Sym;
-        sym->st_name = 0;
-        sym->setBindingAndType(llvm::ELF::STB_LOCAL, llvm::ELF::STT_SECTION);
-        sym->st_other = 0;
-        sym->st_shndx = 0;
-        sym->st_value = 0;
-        sym->st_size = 0;
-        ArrayRef<uint8_t> content((const uint8_t *)sectionContents.data(),
-                                  sectionContents.size());
-        auto newAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
-            *this, "", sectionName, sym, i.first, content, 0, 0, _references);
-        newAtom->setOrdinal(++_ordinal);
+        ELFDefinedAtom<ELFT> *newAtom = createSectionAtom(
+            section, sectionName, sectionContents);
         _definedAtoms._atoms.push_back(newAtom);
         continue;
       }
 
-      ELFDefinedAtom<ELFT> *previous_atom = nullptr;
-      // Don't allocate content to a weak symbol, as they may be merged away.
-      // Create an anonymous atom to hold the data.
-      ELFDefinedAtom<ELFT> *anonAtom = nullptr;
-      ELFReference<ELFT> *anonPrecededBy = nullptr;
+      ELFDefinedAtom<ELFT> *previousAtom = nullptr;
       ELFReference<ELFT> *anonFollowedBy = nullptr;
 
-      // i.first is the section the symbol lives in
       for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
+        const Elf_Sym *symbol = *si;
         StringRef symbolName = "";
-        if ((*si)->getType() != llvm::ELF::STT_SECTION)
-          if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
+        if (symbol->getType() != llvm::ELF::STT_SECTION)
+          if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
             return true;
 
-        const Elf_Shdr *section = _objFile->getSection(*si);
-
-        bool isCommon = (*si)->getType() == llvm::ELF::STT_COMMON ||
-                        (*si)->st_shndx == llvm::ELF::SHN_COMMON;
-
-        if (isTargetAtom(section, *si)) {
-          TargetAtomHandler<ELFT> &_targetAtomHandler =
-              targetHandler.targetAtomHandler();
-          isCommon =
-              ((_targetAtomHandler.getType(*si)) == llvm::ELF::STT_COMMON);
-        }
-
-        // Get the symbol's content size
-        uint64_t contentSize = 0;
-        if (si + 1 == se) {
-          // if this is the last symbol, take up the remaining data.
-          contentSize = isCommon ? 0 : i.first->sh_size - (*si)->st_value;
-        } else {
-          contentSize = isCommon ? 0 : (*(si + 1))->st_value - (*si)->st_value;
-        }
+        bool isCommon = isCommonSymbol(section, symbol);
+        uint64_t contentSize = isCommon ? 0 : symbolContentSize(
+            section, symbol, (si + 1 == se) ? nullptr : *(si + 1));
 
         // Check to see if we need to add the FollowOn Reference
         // We dont want to do for symbols that are
         // a) common symbols
         ELFReference<ELFT> *followOn = nullptr;
-        if (!isCommon && previous_atom) {
-          // Replace the followon atom with the anonymous
-          // atom that we created, so that the next symbol
-          // that we create is a followon from the anonymous
-          // atom
-          if (!anonFollowedBy) {
+        if (!isCommon && previousAtom) {
+          // Replace the followon atom with the anonymous atom that we created,
+          // so that the next symbol that we create is a followon from the
+          // anonymous atom.
+          if (anonFollowedBy) {
+            followOn = anonFollowedBy;
+          } else {
             followOn = new (_readerStorage)
                 ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
-            previous_atom->addReference(followOn);
+            previousAtom->addReference(followOn);
           }
-          else
-            followOn = anonFollowedBy;
         }
 
-        // Don't allocate content to a weak symbol, as they may be merged away.
-        // Create an anonymous atom to hold the data.
-        anonAtom = nullptr;
-        anonPrecededBy = nullptr;
-        anonFollowedBy = nullptr;
-        if ((*si)->getBinding() == llvm::ELF::STB_WEAK && contentSize != 0) {
-          // Create a new non-weak ELF symbol.
-          auto sym = new (_readerStorage) Elf_Sym;
-          *sym = **si;
-          sym->setBinding(llvm::ELF::STB_GLOBAL);
-          anonAtom = createDefinedAtomAndAssignRelocations(
-              "", sectionName, sym, i.first,
-              ArrayRef<uint8_t>(
-                  (uint8_t *)sectionContents.data() + (*si)->st_value,
-                  contentSize));
-          anonAtom->setOrdinal(++_ordinal);
-
-          // If this is the last atom, lets not create a followon
-          // reference
-          if ((si + 1) != se)
-            anonFollowedBy = new (_readerStorage)
-               ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
-          anonPrecededBy = new (_readerStorage)
-              ELFReference<ELFT>(lld::Reference::kindLayoutBefore);
-          // Add the references to the anonymous atom that we created
-          if (anonFollowedBy)
-            anonAtom->addReference(anonFollowedBy);
-          anonAtom->addReference(anonPrecededBy);
-          if (previous_atom)
-            anonPrecededBy->setTarget(previous_atom);
-          contentSize = 0;
-        }
-
-        ArrayRef<uint8_t> symbolData = ArrayRef<uint8_t>(
-            (uint8_t *)sectionContents.data() + (*si)->st_value, contentSize);
+        ArrayRef<uint8_t> symbolData(
+            (uint8_t *)sectionContents.data() + symbol->st_value, contentSize);
 
         // 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
-        if (isMergeableSection(section)) {
-          if ((*si)->getBinding() == llvm::ELF::STB_GLOBAL) {
+        if (isMergeableStringSection(section)) {
+          if (symbol->getBinding() == llvm::ELF::STB_GLOBAL) {
             auto definedMergeAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
                 *this, symbolName, sectionName, (*si), section, symbolData,
                 _references.size(), _references.size(), _references);
@@ -479,48 +409,59 @@ public:
           continue;
         }
 
-        auto newAtom = createDefinedAtomAndAssignRelocations(
-            symbolName, sectionName, *si, i.first, symbolData);
+        // Don't allocate content to a weak symbol, as they may be merged away.
+        // Create an anonymous atom to hold the data.
+        ELFDefinedAtom<ELFT> *anonAtom = nullptr;
+        anonFollowedBy = nullptr;
+        if (symbol->getBinding() == llvm::ELF::STB_WEAK && contentSize != 0) {
+          // Create anonymous new non-weak ELF symbol that holds the symbol
+          // data.
+          auto sym = new (_readerStorage) Elf_Sym(*symbol);
+          sym->setBinding(llvm::ELF::STB_GLOBAL);
+          anonAtom = createDefinedAtomAndAssignRelocations(
+              "", sectionName, sym, section, symbolData);
+          anonAtom->setOrdinal(++_ordinal);
+          symbolData = ArrayRef<uint8_t>();
+
+          if (previousAtom)
+            createEdge(anonAtom, previousAtom,
+                       lld::Reference::kindLayoutBefore);
+        }
 
+        ELFDefinedAtom<ELFT> *newAtom = createDefinedAtomAndAssignRelocations(
+            symbolName, sectionName, symbol, section, symbolData);
         newAtom->setOrdinal(++_ordinal);
 
-        // If the atom was a weak symbol, lets create a followon
-        // reference to the anonymous atom that we created
-        if ((*si)->getBinding() == llvm::ELF::STB_WEAK && anonAtom) {
-          ELFReference<ELFT> *wFollowedBy = new (_readerStorage)
+        // If this is the last atom, lets not create a followon reference.
+        if (anonAtom && (si + 1) != se) {
+          anonFollowedBy = new (_readerStorage)
               ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
-          wFollowedBy->setTarget(anonAtom);
-          newAtom->addReference(wFollowedBy);
+          anonAtom->addReference(anonFollowedBy);
         }
 
-        if (followOn) {
-          ELFReference<ELFT> *precededby = nullptr;
-          // Set the followon atom to the weak atom
-          // that we have created, so that they would
-          // alias when the file gets written
-          if (anonAtom)
-            followOn->setTarget(anonAtom);
-          else
-            followOn->setTarget(newAtom);
-          // Add a preceded by reference only if the current atom is not a
-          // weak atom
-          if ((*si)->getBinding() != llvm::ELF::STB_WEAK) {
-            precededby = new (_readerStorage)
-                ELFReference<ELFT>(lld::Reference::kindLayoutBefore);
-            precededby->setTarget(previous_atom);
-            newAtom->addReference(precededby);
-          }
+        // If the atom was a weak symbol, lets create a followon reference to
+        // the anonymous atom that we created.
+        if (anonAtom)
+          createEdge(newAtom, anonAtom, lld::Reference::kindLayoutAfter);
+
+        if (!isCommon && previousAtom) {
+          // Set the followon atom to the weak atom that we have created, so
+          // that they would alias when the file gets written.
+          followOn->setTarget(anonAtom ? anonAtom : newAtom);
+
+          // Add a preceded-by reference only if the current atom is not a weak
+          // atom.
+          if (symbol->getBinding() != llvm::ELF::STB_WEAK)
+            createEdge(newAtom, previousAtom,
+                       lld::Reference::kindLayoutBefore);
         }
 
-        // The previous atom is always the atom created before unless
-        // the atom is a weak atom
-        if (anonAtom)
-          previous_atom = anonAtom;
-        else
-          previous_atom = newAtom;
+        // The previous atom is always the atom created before unless the atom
+        // is a weak atom.
+        previousAtom = anonAtom ? anonAtom : newAtom;
 
         _definedAtoms._atoms.push_back(newAtom);
-        _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
+        _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
         if (anonAtom)
           _definedAtoms._atoms.push_back(anonAtom);
       }
@@ -563,11 +504,10 @@ private:
 
     // Add Rela (those with r_addend) references:
     auto rari = _relocationAddendReferences.find(sectionName);
-    auto rri = _relocationReferences.find(sectionName);
-    if (rari != _relocationAddendReferences.end())
-      for (auto &rai : rari->second) {
-        if (!((rai.r_offset >= symbol->st_value) &&
-              (rai.r_offset < symbol->st_value + content.size())))
+    if (rari != _relocationAddendReferences.end()) {
+      for (const Elf_Rela &rai : rari->second) {
+        if (rai.r_offset < symbol->st_value ||
+            symbol->st_value + content.size() <= rai.r_offset)
           continue;
         bool isMips64EL = _objFile->isMips64EL();
         Reference::Kind kind = (Reference::Kind) rai.getType(isMips64EL);
@@ -577,81 +517,87 @@ private:
                                kind, symbolIndex);
         _references.push_back(ERef);
       }
+    }
 
     // Add Rel references.
-    if (rri != _relocationReferences.end())
-      for (auto &ri : rri->second) {
-        if ((ri.r_offset >= symbol->st_value) &&
-            (ri.r_offset < symbol->st_value + content.size())) {
-          bool isMips64EL = _objFile->isMips64EL();
-          Reference::Kind kind = (Reference::Kind) ri.getType(isMips64EL);
-          uint32_t symbolIndex = ri.getSymbol(isMips64EL);
-          auto *ERef = new (_readerStorage)
-              ELFReference<ELFT>(&ri, ri.r_offset - symbol->st_value, nullptr,
-                                 kind, symbolIndex);
-          // Read the addend from the section contents
-          // TODO : We should move the way lld reads relocations totally from
-          // ELFObjectFile
-          int32_t addend = *(content.data() + ri.r_offset - symbol->st_value);
-          ERef->setAddend(addend);
-          _references.push_back(ERef);
-        }
+    auto rri = _relocationReferences.find(sectionName);
+    if (rri != _relocationReferences.end()) {
+      for (const Elf_Rel &ri : rri->second) {
+        if (ri.r_offset < symbol->st_value ||
+            symbol->st_value + content.size() <= ri.r_offset)
+          continue;
+        bool isMips64EL = _objFile->isMips64EL();
+        Reference::Kind kind = (Reference::Kind) ri.getType(isMips64EL);
+        uint32_t symbolIndex = ri.getSymbol(isMips64EL);
+        auto *ERef = new (_readerStorage)
+            ELFReference<ELFT>(&ri, ri.r_offset - symbol->st_value, nullptr,
+                               kind, symbolIndex);
+        // Read the addend from the section contents
+        // TODO : We should move the way lld reads relocations totally from
+        // ELFObjectFile
+        int32_t addend = *(content.data() + ri.r_offset - symbol->st_value);
+        ERef->setAddend(addend);
+        _references.push_back(ERef);
       }
+    }
 
     // Create the DefinedAtom and add it to the list of DefinedAtoms.
-    auto ret = new (_readerStorage) ELFDefinedAtom<
-        ELFT>(*this, symbolName, sectionName, symbol, section, content,
-              referenceStart, _references.size(), _references);
-    ret->permissions();
-    ret->contentType();
-    return ret;
+    return new (_readerStorage) ELFDefinedAtom<ELFT>(
+        *this, symbolName, sectionName, symbol, section, content,
+        referenceStart, _references.size(), _references);
   }
 
   /// \brief After all the Atoms and References are created, update each
   /// Reference's target with the Atom pointer it refers to.
   void updateReferences() {
-
     /// cached value of target relocation handler
     const TargetRelocationHandler<ELFT> &_targetRelocationHandler =
         _elfTargetInfo.template getTargetHandler<ELFT>().getRelocationHandler();
 
     for (auto &ri : _references) {
       if (ri->kind() >= lld::Reference::kindTargetLow) {
-        const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
-        const Elf_Shdr *shdr = _objFile->getSection(Symbol);
-        if (isMergeableSection(shdr)) {
-          int64_t relocAddend = _targetRelocationHandler.relocAddend(*ri);
-          uint64_t addend = ri->addend() + relocAddend;
-          const MergeSectionKey ms(shdr, addend);
-          auto msec = _mergedSectionMap.find(ms);
-          if (msec == _mergedSectionMap.end()) {
-            if (Symbol->getType() != llvm::ELF::STT_SECTION)
-              addend = Symbol->st_value + addend;
-            MergeAtomsIter mai = findMergeAtom(shdr, addend);
-            if (mai != _mergeAtoms.end()) {
-              ri->setOffset(addend - ((*mai)->offset()));
-              ri->setAddend(0);
-              ri->setTarget(*mai);
-            } // check
-                else
-              llvm_unreachable("unable to find a merge atom");
-          } // find
-              else
-            ri->setTarget(msec->second);
-        } else
-          ri->setTarget(findAtom(Symbol));
+        const Elf_Sym *symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
+        const Elf_Shdr *shdr = _objFile->getSection(symbol);
+
+        // If the atom is not in mergeable string section, the target atom is
+        // simply that atom.
+        if (!isMergeableStringSection(shdr)) {
+          ri->setTarget(findAtom(symbol));
+          continue;
+        }
+
+        // If the target atom is mergeable string atom, the atom might have been
+        // merged with other atom having the same contents. Try to find the
+        // merged one if that's the case.
+        int64_t relocAddend = _targetRelocationHandler.relocAddend(*ri);
+        uint64_t addend = ri->addend() + relocAddend;
+        const MergeSectionKey ms(shdr, addend);
+        auto msec = _mergedSectionMap.find(ms);
+        if (msec != _mergedSectionMap.end()) {
+          ri->setTarget(msec->second);
+          continue;
+        }
+
+        // The target atom was not merged. Mergeable atoms are not in
+        // _symbolToAtomMapping, so we cannot find it by calling findAtom(). We
+        // instead call findMergeAtom().
+        if (symbol->getType() != llvm::ELF::STT_SECTION)
+          addend = symbol->st_value + addend;
+        ELFMergeAtom<ELFT> *mergedAtom = findMergeAtom(shdr, addend);
+        ri->setOffset(addend - mergedAtom->offset());
+        ri->setAddend(0);
+        ri->setTarget(mergedAtom);
       }
     }
   }
 
-  /// \brief Is the atom corresponding to the value of the section and the
-  /// symbol a targetAtom ? If so, let the target determine its contentType
-  inline bool isTargetAtom(const Elf_Shdr *shdr, const Elf_Sym *sym) {
-    if ((shdr && shdr->sh_flags & llvm::ELF::SHF_MASKPROC) ||
-        ((sym->st_shndx >= llvm::ELF::SHN_LOPROC) &&
-         (sym->st_shndx <= llvm::ELF::SHN_HIPROC)))
-      return true;
-    return false;
+  /// \Brief Return true if the symbol is corresponding to an architecture
+  /// specific section. We will let the TargetHandler to handle such atoms.
+  inline bool isTargetSpecificAtom(const Elf_Shdr *shdr,
+                                   const Elf_Sym *sym) {
+    return ((shdr->sh_flags & llvm::ELF::SHF_MASKPROC) ||
+            (sym->st_shndx >= llvm::ELF::SHN_LOPROC &&
+             sym->st_shndx <= llvm::ELF::SHN_HIPROC));
   }
 
   /// \brief Do we want to ignore the section. Ignored sections are
@@ -671,14 +617,16 @@ private:
     return false;
   }
 
-  /// \brief Is the current section be treated as a mergeable string section
-  bool isMergeableSection(const Elf_Shdr *section) {
+  /// \brief Is the current section be treated as a mergeable string section.
+  /// The contents of a mergeable string section are null-terminated strings.
+  /// If the section have mergeable strings, the linker would need to split
+  /// the section into multiple atoms and mark them mergeByContent.
+  bool isMergeableStringSection(const Elf_Shdr *section) {
     if (_doStringsMerge && section) {
       int64_t sectionFlags = section->sh_flags;
       sectionFlags &= ~llvm::ELF::SHF_ALLOC;
-      // If the section have mergeable strings, the linker would
-      // need to split the section into multiple atoms and mark them
-      // mergeByContent
+      // Mergeable string sections have both SHF_MERGE and SHF_STRINGS flags
+      // set. sh_entsize is the size of each character which is normally 1.
       if ((section->sh_entsize < 2) &&
           (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
         return true;
@@ -687,6 +635,64 @@ private:
     return false;
   }
 
+  /// \brief Returns a new anonymous atom whose size is equal to the
+  /// section size. That atom will be used to represent the entire
+  /// section that have no symbols.
+  ELFDefinedAtom<ELFT> *createSectionAtom(const Elf_Shdr *section,
+                                          StringRef sectionName,
+                                          StringRef sectionContents) {
+    Elf_Sym *sym = new (_readerStorage) Elf_Sym;
+    sym->st_name = 0;
+    sym->setBindingAndType(llvm::ELF::STB_LOCAL, llvm::ELF::STT_SECTION);
+    sym->st_other = 0;
+    sym->st_shndx = 0;
+    sym->st_value = 0;
+    sym->st_size = 0;
+    ArrayRef<uint8_t> content((const uint8_t *)sectionContents.data(),
+                              sectionContents.size());
+    auto *newAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
+        *this, "", sectionName, sym, section, content, 0, 0, _references);
+    newAtom->setOrdinal(++_ordinal);
+    return newAtom;
+  }
+
+  /// Returns true if the symbol is common symbol. A common symbol represents a
+  /// tentive definition in C. It has name, size and alignment constraint, but
+  /// actual storage has not yet been allocated. (The linker will allocate
+  /// storage for them in the later pass after coalescing tentative symbols by
+  /// name.)
+  bool isCommonSymbol(const Elf_Shdr *section, const Elf_Sym *symbol) {
+    // This method handles only architecture independent stuffs, and don't know
+    // whether an architecture dependent section is for common symbols or
+    // not. Let the TargetHandler to make a decision if that's the case.
+    if (isTargetSpecificAtom(section, symbol)) {
+      TargetHandler<ELFT> &targetHandler =
+          _elfTargetInfo.template getTargetHandler<ELFT>();
+      TargetAtomHandler<ELFT> &targetAtomHandler =
+          targetHandler.targetAtomHandler();
+      return targetAtomHandler.getType(symbol) == llvm::ELF::STT_COMMON;
+    }
+    return symbol->getType() == llvm::ELF::STT_COMMON ||
+        symbol->st_shndx == llvm::ELF::SHN_COMMON;
+  }
+
+  /// Returns the symbol's content size. The nextSymbol should be null if the
+  /// symbol is the last one in the section.
+  uint64_t symbolContentSize(const Elf_Shdr *section, const Elf_Sym *symbol,
+                             const Elf_Sym *nextSymbol) {
+    // if this is the last symbol, take up the remaining data.
+    return nextSymbol
+        ? nextSymbol->st_value - symbol->st_value
+        : section->sh_size - symbol->st_value;
+  }
+
+  void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
+                  lld::Reference::Kind kind) {
+    auto reference = new (_readerStorage) ELFReference<ELFT>(kind);
+    reference->setTarget(to);
+    from->addReference(reference);
+  }
+
   llvm::BumpPtrAllocator _readerStorage;
   std::unique_ptr<llvm::object::ELFObjectFile<ELFT> > _objFile;
   atom_collection_vector<DefinedAtom> _definedAtoms;

Modified: lld/trunk/test/elf/X86_64/weak-override.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/weak-override.test?rev=183696&r1=183695&r2=183696&view=diff
==============================================================================
--- lld/trunk/test/elf/X86_64/weak-override.test (original)
+++ lld/trunk/test/elf/X86_64/weak-override.test Mon Jun 10 16:32:44 2013
@@ -22,12 +22,12 @@ WEAKATOMSORDER:    scope:           glob
 WEAKATOMSORDER:    content:         [ 55, 48, 89, E5, BF, 00, 00, 00, 00, E8, 00, 00, 
 WEAKATOMSORDER:                       00, 00, 5D, C3 ]
 WEAKATOMSORDER:    references:      
-WEAKATOMSORDER:      - kind:            layout-after
-WEAKATOMSORDER:        offset:          0
-WEAKATOMSORDER:        target:          main
 WEAKATOMSORDER:      - kind:            layout-before
 WEAKATOMSORDER:        offset:          0
 WEAKATOMSORDER:        target:          fn
+WEAKATOMSORDER:      - kind:            layout-after
+WEAKATOMSORDER:        offset:          0
+WEAKATOMSORDER:        target:          main
 WEAKATOMSORDER:  - name:            main
 WEAKATOMSORDER:    scope:           global
 WEAKATOMSORDER:    content:         [ 55, 48, 89, E5, B8, 00, 00, 00, 00, E8, 00, 00, 





More information about the llvm-commits mailing list