[lld] r174990 - add support for merging common strings

Shankar Easwaran shankare at codeaurora.org
Tue Feb 12 10:46:54 PST 2013


Author: shankare
Date: Tue Feb 12 12:46:53 2013
New Revision: 174990

URL: http://llvm.org/viewvc/llvm-project?rev=174990&view=rev
Log:
add support for merging common strings

Added:
    lld/trunk/test/elf/Inputs/bar.o.x86-64   (with props)
    lld/trunk/test/elf/Inputs/constants-merge.x86-64   (with props)
    lld/trunk/test/elf/Inputs/foo.o.x86-64   (with props)
    lld/trunk/test/elf/mergeatoms.objtxt
    lld/trunk/test/elf/mergeconstants.objtxt
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/test/elf/reloc.objtxt

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=174990&r1=174989&r2=174990&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Tue Feb 12 12:46:53 2013
@@ -69,9 +69,9 @@ public:
     return _addend;
   }
 
-  virtual void setAddend(Addend A) {
-    _addend = A;
-  }
+  virtual void setOffset(uint64_t off) { _offsetInAtom = off; }
+
+  virtual void setAddend(Addend A) { _addend = A; }
 
   virtual void setTarget(const Atom *newAtom) { _target = newAtom; }
 
@@ -438,8 +438,88 @@ private:
   uint64_t _ordinal;
   unsigned int _referenceStartIndex;
   unsigned int _referenceEndIndex;
-  std::vector<ELFReference<ELFT>*> &
-    _referenceList;
+  std::vector<ELFReference<ELFT> *> &_referenceList;
+};
+
+/// \brief This atom stores mergeable Strings
+template <class ELFT> class ELFMergeAtom LLVM_FINAL : public DefinedAtom {
+  typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+  ELFMergeAtom(const ELFFile<ELFT> &file, StringRef sectionName,
+               const Elf_Shdr *section, llvm::ArrayRef<uint8_t> contentData,
+               uint64_t offset)
+      : _owningFile(file), _sectionName(sectionName), _section(section),
+        _contentData(contentData), _offset(offset) {
+    static uint64_t orderNumber = 0;
+    _ordinal = ++orderNumber;
+  }
+
+  virtual const class ELFFile<ELFT> &file() const {
+    return _owningFile;
+  } virtual StringRef name() const {
+    return "";
+  }
+
+  virtual uint64_t offset() const { return _offset; }
+
+  virtual uint64_t ordinal() const { return _ordinal; }
+
+  virtual uint64_t size() const { return _contentData.size(); }
+
+  virtual Scope scope() const { return scopeTranslationUnit; }
+
+  virtual Interposable interposable() const { return interposeNo; }
+
+  virtual Merge merge() const { return mergeByContent; }
+
+  virtual ContentType contentType() const { return typeConstant; }
+
+  virtual Alignment alignment() const {
+    return Alignment(llvm::Log2_64(_section->sh_addralign));
+  }
+
+  virtual SectionChoice sectionChoice() const { return sectionCustomRequired; }
+
+  virtual StringRef customSectionName() const { return _sectionName; }
+
+  virtual SectionPosition sectionPosition() const { return sectionPositionAny; }
+
+  virtual DeadStripKind deadStrip() const { return deadStripNormal; }
+
+  virtual ContentPermissions permissions() const { return permR__; }
+
+  virtual bool isThumb() const { return false; }
+
+  virtual bool isAlias() const { return false; }
+
+  virtual llvm::ArrayRef<uint8_t> rawContent() const { return _contentData; }
+
+  DefinedAtom::reference_iterator begin() const {
+    uintptr_t index = 0;
+    const void *it = reinterpret_cast<const void *>(index);
+    return reference_iterator(*this, it);
+  }
+
+  DefinedAtom::reference_iterator end() const {
+    uintptr_t index = 0;
+    const void *it = reinterpret_cast<const void *>(index);
+    return reference_iterator(*this, it);
+  }
+
+  const Reference *derefIterator(const void *It) const { return nullptr; }
+
+  void incrementIterator(const void *&It) const {}
+
+private:
+
+  const ELFFile<ELFT> &_owningFile;
+  StringRef _sectionName;
+  const Elf_Shdr *_section;
+  /// \brief Holds the bits that make up the atom.
+  llvm::ArrayRef<uint8_t> _contentData;
+  uint64_t _ordinal;
+  uint64_t _offset;
 };
 
 /// \brief An atom from a shared library.

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=174990&r1=174989&r2=174990&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Tue Feb 12 12:46:53 2013
@@ -48,6 +48,69 @@ template <class ELFT> class ELFFile : pu
   typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 
+  // A Map is used to hold the atoms that have been divided up
+  // after reading the section that contains Merge String attributes
+  struct MergeSectionKey {
+    MergeSectionKey(const Elf_Shdr *shdr, int32_t offset)
+        : _shdr(shdr), _offset(offset) {
+    }
+    // Data members
+    const Elf_Shdr *_shdr;
+    int32_t _offset;
+  };
+  struct MergeSectionEq {
+    int64_t operator()(const MergeSectionKey &k) const {
+      return llvm::hash_combine((int64_t)(k._shdr->sh_name),
+                                (int64_t) k._offset);
+    }
+    bool operator()(const MergeSectionKey &lhs,
+                    const MergeSectionKey &rhs) const {
+      return ((lhs._shdr->sh_name == rhs._shdr->sh_name) &&
+              (lhs._offset == rhs._offset));
+    }
+  };
+
+  struct MergeString {
+    MergeString(int32_t offset, StringRef str, const Elf_Shdr *shdr,
+                StringRef sectionName)
+        : _offset(offset), _string(str), _shdr(shdr),
+          _sectionName(sectionName) {
+    }
+    // the offset of this atom
+    int32_t _offset;
+    // The content 
+    StringRef _string;
+    // Section header
+    const Elf_Shdr *_shdr;
+    // Section name
+    StringRef _sectionName;
+  };
+
+  // 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 {
+    uint64_t _offset;
+    FindByOffset(uint64_t offset) : _offset(offset) {}
+    bool operator()(const ELFMergeAtom<ELFT> *a) {
+      uint64_t off = a->offset();
+      return ((_offset >= off) && (_offset <= off + a->size()));
+    }
+  };
+
+  /// \brief find a merge atom given a offset
+  MergeAtomsIter findMergeAtom(uint64_t offset) {
+    return std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
+                        FindByOffset(offset));
+  }
+
+  typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
+                             MergeSectionEq> MergedSectionMapT;
+  typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
+
 public:
   ELFFile(const ELFTargetInfo &ti, StringRef name)
       : File(name), _elfTargetInfo(ti) {
@@ -77,6 +140,9 @@ public:
 
     std::map<const Elf_Shdr *, std::vector<const Elf_Sym *> > sectionSymbols;
 
+    // Sections that have merge string property
+    std::vector<const Elf_Shdr *> mergeStringSections;
+
     // Handle: SHT_REL and SHT_RELA sections:
     // Increment over the sections, when REL/RELA section types are found add
     // the contents to the RelocationReferences map.
@@ -97,6 +163,18 @@ public:
       if (section->sh_size == 0)
         continue;
 
+      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
+      if ((section->sh_entsize < 2) &&
+          (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
+        mergeStringSections.push_back(section);
+        continue;
+      }
+
       // Create a sectionSymbols entry for every progbits section.
       if (section->sh_type == llvm::ELF::SHT_PROGBITS)
         sectionSymbols[section];
@@ -136,6 +214,43 @@ public:
       }
     }
 
+    // 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) {
+      StringRef sectionContents;
+      StringRef sectionName;
+      if ((EC = _objFile->getSectionName(msi, sectionName)))
+        return;
+
+      if ((EC = _objFile->getSectionContents(msi, sectionContents)))
+        return;
+
+      unsigned int prev = 0;
+      for (std::size_t i = 0, e = sectionContents.size(); i != e; ++i) {
+        if (sectionContents[i] == '\0') {
+          tokens.push_back(new (_readerStorage) MergeString(
+              prev, sectionContents.slice(prev, i + 1), msi, sectionName));
+          prev = i + 1;
+        }
+      }
+    }
+
+    // Create Mergeable atoms
+    for (auto tai : tokens) {
+      ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
+                                tai->_string.size());
+      ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage) ELFMergeAtom<ELFT>(
+          *this, tai->_sectionName, tai->_shdr, content, tai->_offset);
+      const MergeSectionKey mergedSectionKey(tai->_shdr, tai->_offset);
+      if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
+        _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
+      _definedAtoms._atoms.push_back(mergeAtom);
+      _mergeAtoms.push_back(mergeAtom);
+    }
+
     // Increment over all the symbols collecting atoms and symbol names for
     // later use.
     llvm::object::symbol_iterator it(_objFile->begin_symbols());
@@ -151,6 +266,15 @@ 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
+      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;
@@ -278,14 +402,12 @@ public:
         // Check to see if we need to add the FollowOn Reference
         // We dont want to do for symbols that are
         // a) common symbols
-        // b) the atoms have the merge attribute set
         // so, lets add a follow-on reference from the previous atom to the 
         // current atom as well as lets add a preceded-by reference from the 
         // current atom to the previous atom, so that the previous atom 
         // is not removed in any case
         ELFReference<ELFT> *followOn = nullptr;
-        if (!isCommon && previous_atom &&
-            previous_atom->merge() == DefinedAtom::mergeNo) {
+        if (!isCommon && previous_atom) {
           followOn = new (_readerStorage)
               ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
           previous_atom->addReference(followOn);
@@ -297,15 +419,22 @@ public:
         // If we are inserting a followOn reference, lets add a precededBy 
         // reference too
         if (followOn) {
-          ELFReference<ELFT> *precededBy = nullptr;
+          ELFReference<ELFT> *precededby = nullptr;
           followOn->setTarget(newAtom);
-          precededBy = new (_readerStorage)
-              ELFReference<ELFT>(lld::Reference::kindLayoutBefore);
-          precededBy->setTarget(previous_atom);
-          newAtom->addReference(precededBy);
+          // 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);
+          }
         }
 
-        previous_atom = newAtom;
+        // The previous atom is always the atom created before unless
+        // the atom is a weak atom
+        if ((*si)->getBinding() != llvm::ELF::STB_WEAK)
+          previous_atom = newAtom;
 
         _definedAtoms._atoms.push_back(newAtom);
         _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
@@ -319,7 +448,31 @@ public:
     for (auto &ri : _references) {
       if (ri->kind() >= lld::Reference::kindTargetLow) {
         const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
-        ri->setTarget(findAtom(Symbol));
+        const Elf_Shdr *shdr = _objFile->getSection(Symbol);
+        int64_t sectionFlags = 0;
+        if (shdr)
+          sectionFlags = shdr->sh_flags;
+        sectionFlags &= ~llvm::ELF::SHF_ALLOC;
+
+        // If the section has mergeable strings, then make the relocation
+        // refer to the MergeAtom to allow deduping
+        if (shdr && (shdr->sh_entsize < 2) &&
+            (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
+          const MergeSectionKey ms(shdr, ri->addend());
+          if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
+            MergeAtomsIter mai = findMergeAtom(ri->addend());
+            if (mai != _mergeAtoms.end()) {
+              ri->setOffset(ri->addend() - ((*mai)->offset()));
+              ri->setAddend(0);
+              ri->setTarget(*mai);
+            } // check
+                else
+              llvm_unreachable("unable to find a merge atom");
+          } // find
+              else
+            ri->setTarget(_mergedSectionMap[ms]);
+        } else
+          ri->setTarget(findAtom(Symbol));
       }
     }
   }
@@ -347,6 +500,7 @@ public:
   }
 
 private:
+
   ELFDefinedAtom<ELFT> *createDefinedAtomAndAssignRelocations(
       StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
       const Elf_Shdr *section, ArrayRef<uint8_t> content) {
@@ -380,6 +534,11 @@ private:
             (ri->r_offset < symbol->st_value + content.size())) {
           auto *ERef = new (_readerStorage)
               ELFReference<ELFT>(ri, ri->r_offset - symbol->st_value, nullptr);
+          // 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);
         }
       }
@@ -403,12 +562,14 @@ private:
   /// the SHT_REL(A) section name.
   std::unordered_map<StringRef,
                      std::vector<const Elf_Rela *> > _relocationAddendRefences;
+  MergedSectionMapT _mergedSectionMap;
   std::unordered_map<StringRef,
                      std::vector<const Elf_Rel *> > _relocationReferences;
   std::vector<ELFReference<ELFT> *> _references;
   llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
   llvm::BumpPtrAllocator _readerStorage;
   const ELFTargetInfo &_elfTargetInfo;
+  MergeAtomsT _mergeAtoms;
 };
 } // end namespace elf
 } // end namespace lld

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

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

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

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

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

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

Added: lld/trunk/test/elf/mergeatoms.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/mergeatoms.objtxt?rev=174990&view=auto
==============================================================================
--- lld/trunk/test/elf/mergeatoms.objtxt (added)
+++ lld/trunk/test/elf/mergeatoms.objtxt Tue Feb 12 12:46:53 2013
@@ -0,0 +1,5 @@
+RUN: lld-core -reader ELF -writer ELF -o %t1 %p/Inputs/foo.o.x86-64 \
+RUN: %p/Inputs/bar.o.x86-64
+RUN: llvm-objdump -s %t1 |  FileCheck -check-prefix=mergeAtoms %s
+
+mergeAtoms:  1000 62617200 666f6f00                    bar.foo.

Added: lld/trunk/test/elf/mergeconstants.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/mergeconstants.objtxt?rev=174990&view=auto
==============================================================================
--- lld/trunk/test/elf/mergeconstants.objtxt (added)
+++ lld/trunk/test/elf/mergeconstants.objtxt Tue Feb 12 12:46:53 2013
@@ -0,0 +1,16 @@
+RUN: lld-core -reader ELF %p/Inputs/constants-merge.x86-64 | FileCheck -check-prefix=mergeAtoms %s
+
+mergeAtoms:  - name:            foo
+mergeAtoms:    scope:           global
+mergeAtoms:    type:            data
+mergeAtoms:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+mergeAtoms:    alignment:       2^3
+mergeAtoms:    section-choice:  custom-required
+mergeAtoms:    section-name:    .data
+mergeAtoms:    references:      
+mergeAtoms:      - kind:            <unknown>
+mergeAtoms:        offset:          3
+mergeAtoms:        target:          L001
+mergeAtoms:      - kind:            layout-before
+mergeAtoms:        offset:          0
+mergeAtoms:        target:          bar

Modified: lld/trunk/test/elf/reloc.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/reloc.objtxt?rev=174990&r1=174989&r2=174990&view=diff
==============================================================================
--- lld/trunk/test/elf/reloc.objtxt (original)
+++ lld/trunk/test/elf/reloc.objtxt Tue Feb 12 12:46:53 2013
@@ -1,73 +1,85 @@
 RUN: lld-core -reader ELF %p/Inputs/reloc-test.elf-i386 | FileCheck %s -check-prefix ELF-i386
 
-ELF-i386:---
-ELF-i386:defined-atoms:
-ELF-i386:    - name:              .text
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .text
-
-ELF-i386:    - name:              .data
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .data
-
-ELF-i386:    - name:              .bss
-ELF-i386:      type:              zero-fill
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .bss
-
-ELF-i386:    - name:              .rodata.str1.1
-ELF-i386:      type:              constant
-ELF-i386:      content:           [ 68, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 00 ]
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .rodata.str1.1
-
-ELF-i386:    - name:              .text.startup
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .text.startup
-
-ELF-i386:    - name:              main
-ELF-i386:      scope:             global
-ELF-i386:      content:           [ 55, 89, E5, 83, E4, F0, 83, EC, 10, C7, 04, 24,
-ELF-i386:                           00, 00, 00, 00, E8, FC, FF, FF, FF, 31, C0, C9,
-ELF-i386:                           C3 ]
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .text.startup
-ELF-i386:      references:
-ELF-i386:      - kind:              <unknown>
-ELF-i386:        offset:            12
-ELF-i386:        target:            .rodata.str1.1
-ELF-i386:      - kind:              call32
-ELF-i386:        offset:            17
-ELF-i386:        target:            puts
-
-ELF-i386:    - name:              .comment
-ELF-i386:      type:              constant
-ELF-i386:      content:           [ 00, 47, 43, 43, 3A, 20, 28, 47, 4E, 55, 29, 20,
-ELF-i386:                           34, 2E, 37, 2E, 30, 00 ]
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .comment
-
-ELF-i386:    - name:              .note.GNU-stack
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .note.GNU-stack
-
-ELF-i386:    - name:              .eh_frame
-ELF-i386:      content:           [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
-ELF-i386:                           01, 7C, 08, 01, 1B, 0C, 04, 04, 88, 01, 00, 00,
-ELF-i386:                           1C, 00, 00, 00, 1C, 00, 00, 00, 00, 00, 00, 00,
-ELF-i386:                           19, 00, 00, 00, 00, 41, 0E, 08, 85, 02, 42, 0D,
-ELF-i386:                           05, 55, C5, 0C, 04, 04, 00, 00 ]
-ELF-i386:      section-choice:    custom-required
-ELF-i386:      section-name:      .eh_frame
-ELF-i386:      references:
-ELF-i386:      - kind:              call32
-ELF-i386:        offset:            32
-ELF-i386:        target:            .text.startup
-
-ELF-i386:undefined-atoms:
-ELF-i386:    - name:              puts
-
-ELF-i386:absolute-atoms:
-ELF-i386:    - name:              test.c
-ELF-i386:      value:             0x0
-ELF-i386:...
+ELF-i386: defined-atoms:   
+ELF-i386:   - ref-name:        L000
+ELF-i386:     type:            constant
+ELF-i386:     content:         [ 68, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 00 ]
+ELF-i386:     merge:           by-content
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .rodata.str1.1
+ELF-i386:   - type:            constant
+ELF-i386:     content:         [ 00 ]
+ELF-i386:     merge:           by-content
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .comment
+ELF-i386:   - type:            constant
+ELF-i386:     content:         [ 47, 43, 43, 3A, 20, 28, 47, 4E, 55, 29, 20, 34, 
+ELF-i386:                        2E, 37, 2E, 30, 00 ]
+ELF-i386:     merge:           by-content
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .comment
+ELF-i386:   - name:            .text
+ELF-i386:     alignment:       2^2
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .text
+ELF-i386:   - name:            .data
+ELF-i386:     type:            data
+ELF-i386:     alignment:       2^2
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .data
+ELF-i386:   - name:            .bss
+ELF-i386:     type:            zero-fill
+ELF-i386:     alignment:       2^2
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .bss
+ELF-i386:   - name:            .text.startup
+ELF-i386:     alignment:       2^4
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .text.startup
+ELF-i386:     references:      
+ELF-i386:       - kind:            layout-after
+ELF-i386:         offset:          0
+ELF-i386:         target:          main
+ELF-i386:   - name:            main
+ELF-i386:     scope:           global
+ELF-i386:     content:         [ 55, 89, E5, 83, E4, F0, 83, EC, 10, C7, 04, 24, 
+ELF-i386:                        00, 00, 00, 00, E8, FC, FF, FF, FF, 31, C0, C9, 
+ELF-i386:                        C3 ]
+ELF-i386:     alignment:       2^4
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .text.startup
+ELF-i386:     references:      
+ELF-i386:       - kind:            <unknown>
+ELF-i386:         offset:          12
+ELF-i386:         target:          L000
+ELF-i386:       - kind:            call32
+ELF-i386:         offset:          17
+ELF-i386:         target:          puts
+ELF-i386:         addend:          252
+ELF-i386:       - kind:            layout-before
+ELF-i386:         offset:          0
+ELF-i386:         target:          .text.startup
+ELF-i386:   - name:            .note.GNU-stack
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .note.GNU-stack
+ELF-i386:     permissions:     r--
+ELF-i386:   - name:            .eh_frame
+ELF-i386:     content:         [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00, 
+ELF-i386:                        01, 7C, 08, 01, 1B, 0C, 04, 04, 88, 01, 00, 00, 
+ELF-i386:                        1C, 00, 00, 00, 1C, 00, 00, 00, 00, 00, 00, 00, 
+ELF-i386:                        19, 00, 00, 00, 00, 41, 0E, 08, 85, 02, 42, 0D, 
+ELF-i386:                        05, 55, C5, 0C, 04, 04, 00, 00 ]
+ELF-i386:     alignment:       2^2
+ELF-i386:     section-choice:  custom-required
+ELF-i386:     section-name:    .eh_frame
+ELF-i386:     permissions:     r--
+ELF-i386:     references:      
+ELF-i386:       - kind:            call32
+ELF-i386:         offset:          32
+ELF-i386:         target:          .text.startup
+ELF-i386: undefined-atoms: 
+ELF-i386:   - name:            puts
+ELF-i386: absolute-atoms:  
+ELF-i386:   - name:            test.c
+ELF-i386:     scope:           static
+ELF-i386:     value:           0x0000000000000000





More information about the llvm-commits mailing list