[llvm] r185753 - MC: Implement COFF .linkonce directive

Nico Rieck nico.rieck at gmail.com
Sat Jul 6 05:13:11 PDT 2013


Author: nrieck
Date: Sat Jul  6 07:13:10 2013
New Revision: 185753

URL: http://llvm.org/viewvc/llvm-project?rev=185753&view=rev
Log:
MC: Implement COFF .linkonce directive

Added:
    llvm/trunk/test/MC/COFF/linkonce-invalid.s
    llvm/trunk/test/MC/COFF/linkonce.s
Modified:
    llvm/trunk/docs/Extensions.rst
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCSectionCOFF.h
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
    llvm/trunk/lib/MC/MCSectionCOFF.cpp
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
    llvm/trunk/lib/MC/WinCOFFStreamer.cpp

Modified: llvm/trunk/docs/Extensions.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Extensions.rst?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/docs/Extensions.rst (original)
+++ llvm/trunk/docs/Extensions.rst Sat Jul  6 07:13:10 2013
@@ -4,7 +4,6 @@ LLVM Extensions
 
 .. contents::
    :local:
-   :depth: 1
 
 .. toctree::
    :hidden:
@@ -21,6 +20,9 @@ Machine-specific Assembly Syntax
 X86/COFF-Dependent
 ------------------
 
+Relocations
+^^^^^^^^^^^
+
 The following additional relocation type is supported:
 
 **@IMGREL** (AT&T syntax only) generates an image-relative relocation that
@@ -37,3 +39,55 @@ corresponds to the COFF relocation types
     .long fun at IMGREL
     .long (fun at imgrel + 0x3F)
     .long $unwind$fun at imgrel
+
+
+``.linkonce`` Directive
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+
+   ``.linkonce [ comdat type [ section identifier ] ]``
+
+Supported COMDAT types:
+
+``discard``
+   Discards duplicate sections with the same COMDAT symbol. This is the default
+   if no type is specified.
+
+``one_only``
+   If the symbol is defined multiple times, the linker issues an error.
+
+``same_size``
+   Duplicates are discarded, but the linker issues an error if any have
+   different sizes.
+
+``same_contents``
+   Duplicates are discarded, but the linker issues an error if any duplicates
+   do not have exactly the same content.
+
+``associative``
+   Links the section if a certain other COMDAT section is linked. This other
+   section is indicated by its section identifier following the comdat type.
+   The following restrictions apply to the associated section:
+
+   1. It must be the name of a section already defined.
+   2. It must differ from the current section.
+   3. It must be a COMDAT section.
+   4. It cannot be another associative COMDAT section.
+
+``largest``
+   Links the largest section from among the duplicates.
+
+``newest``
+   Links the newest section from among the duplicates.
+
+
+.. code-block:: gas
+
+  .section .text$foo
+  .linkonce
+    ...
+
+  .section .xdata$foo
+  .linkonce associative .text$foo
+    ...

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Sat Jul  6 07:13:10 2013
@@ -38,6 +38,7 @@ namespace llvm {
   class Twine;
   class MCSectionMachO;
   class MCSectionELF;
+  class MCSectionCOFF;
 
   /// MCContext - Context object for machine code objects.  This class owns all
   /// of the sections that it creates.
@@ -255,14 +256,12 @@ namespace llvm {
 
     const MCSectionELF *CreateELFGroupSection();
 
-    const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
-                                    int Selection, SectionKind Kind);
-
-    const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
-                                    SectionKind Kind) {
-      return getCOFFSection (Section, Characteristics, 0, Kind);
-    }
+    const MCSectionCOFF *getCOFFSection(StringRef Section,
+                                        unsigned Characteristics,
+                                        SectionKind Kind, int Selection = 0,
+                                        const MCSectionCOFF *Assoc = 0);
 
+    const MCSectionCOFF *getCOFFSection(StringRef Section);
 
     /// @}
 

Modified: llvm/trunk/include/llvm/MC/MCSectionCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionCOFF.h?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSectionCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSectionCOFF.h Sat Jul  6 07:13:10 2013
@@ -25,22 +25,33 @@ namespace llvm {
     // The memory for this string is stored in the same MCContext as *this.
     StringRef SectionName;
 
+    // FIXME: The following fields should not be mutable, but are for now so
+    // the asm parser can honor the .linkonce directive.
+
     /// Characteristics - This is the Characteristics field of a section,
-    //  drawn from the enums below.
-    unsigned Characteristics;
+    /// drawn from the enums below.
+    mutable unsigned Characteristics;
 
     /// Selection - This is the Selection field for the section symbol, if
     /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
-    int Selection;
+    mutable int Selection;
+
+    /// Assoc - This is name of the associated section, if it is a COMDAT
+    /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an
+    /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
+    mutable const MCSectionCOFF *Assoc;
 
   private:
     friend class MCContext;
     MCSectionCOFF(StringRef Section, unsigned Characteristics,
-                  int Selection, SectionKind K)
+                  int Selection, const MCSectionCOFF *Assoc, SectionKind K)
       : MCSection(SV_COFF, K), SectionName(Section),
-        Characteristics(Characteristics), Selection (Selection) {
+        Characteristics(Characteristics), Selection(Selection), Assoc(Assoc) {
       assert ((Characteristics & 0x00F00000) == 0 &&
         "alignment must not be set upon section creation");
+      assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
+              (Assoc != 0) &&
+        "associative COMDAT section must have an associated section");
     }
     ~MCSectionCOFF();
 
@@ -57,7 +68,10 @@ namespace llvm {
       return SectionName.str() + "_end";
     }
     unsigned getCharacteristics() const { return Characteristics; }
-    int getSelection () const { return Selection; }
+    int getSelection() const { return Selection; }
+    const MCSectionCOFF *getAssocSection() const { return Assoc; }
+
+    void setSelection(int Selection, const MCSectionCOFF *Assoc = 0) const;
 
     virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
                                       raw_ostream &OS,

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Sat Jul  6 07:13:10 2013
@@ -732,8 +732,8 @@ getExplicitSectionGlobal(const GlobalVal
   }
   return getContext().getCOFFSection(Name,
                                      Characteristics,
-                                     Selection,
-                                     Kind);
+                                     Kind,
+                                     Selection);
 }
 
 static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
@@ -769,7 +769,7 @@ SelectSectionForGlobal(const GlobalValue
     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
 
     return getContext().getCOFFSection(Name.str(), Characteristics,
-                          COFF::IMAGE_COMDAT_SELECT_ANY, Kind);
+                                       Kind, COFF::IMAGE_COMDAT_SELECT_ANY);
   }
 
   if (Kind.isText())

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Sat Jul  6 07:13:10 2013
@@ -274,10 +274,10 @@ const MCSectionELF *MCContext::CreateELF
   return Result;
 }
 
-const MCSection *MCContext::getCOFFSection(StringRef Section,
-                                           unsigned Characteristics,
-                                           int Selection,
-                                           SectionKind Kind) {
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
+                                               unsigned Characteristics,
+                                               SectionKind Kind, int Selection,
+                                               const MCSectionCOFF *Assoc) {
   if (COFFUniquingMap == 0)
     COFFUniquingMap = new COFFUniqueMapTy();
   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
@@ -288,12 +288,20 @@ const MCSection *MCContext::getCOFFSecti
 
   MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
                                                     Characteristics,
-                                                    Selection, Kind);
+                                                    Selection, Assoc, Kind);
 
   Entry.setValue(Result);
   return Result;
 }
 
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
+  if (COFFUniquingMap == 0)
+    COFFUniquingMap = new COFFUniqueMapTy();
+  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
+
+  return Map.lookup(Section);
+}
+
 //===----------------------------------------------------------------------===//
 // Dwarf Management
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp Sat Jul  6 07:13:10 2013
@@ -51,6 +51,7 @@ class COFFAsmParser : public MCAsmParser
     addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
     addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
     addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
+    addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
 
     // Win64 EH directives.
     addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
@@ -110,6 +111,7 @@ class COFFAsmParser : public MCAsmParser
   bool ParseDirectiveType(StringRef, SMLoc);
   bool ParseDirectiveEndef(StringRef, SMLoc);
   bool ParseDirectiveSecRel32(StringRef, SMLoc);
+  bool ParseDirectiveLinkOnce(StringRef, SMLoc);
 
   // Win64 EH directives.
   bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -407,6 +409,64 @@ bool COFFAsmParser::ParseDirectiveSecRel
   return false;
 }
 
+/// ParseDirectiveLinkOnce
+///  ::= .linkonce [ identifier [ identifier ] ]
+bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
+  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
+
+  if (getLexer().is(AsmToken::Identifier)) {
+    StringRef TypeId = getTok().getIdentifier();
+
+    Type = StringSwitch<COFF::COMDATType>(TypeId)
+      .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
+      .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
+      .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
+      .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
+      .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+      .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
+      .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
+      .Default((COFF::COMDATType)0);
+
+    if (Type == 0)
+      return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
+
+    Lex();
+  }
+  
+  const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
+                                       getStreamer().getCurrentSection().first);
+
+  const MCSectionCOFF *Assoc = 0;
+  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+    StringRef AssocName;
+    SMLoc Loc = getTok().getLoc();
+    if (ParseSectionName(AssocName))
+      return TokError("expected associated section name");
+
+    Assoc = static_cast<const MCSectionCOFF*>(
+                                        getContext().getCOFFSection(AssocName));
+    if (!Assoc)
+      return Error(Loc, "cannot associate unknown section '" + AssocName + "'");
+    if (Assoc == Current)
+      return Error(Loc, "cannot associate a section with itself");
+    if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT))
+      return Error(Loc, "associated section must be a COMDAT section");
+    if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+      return Error(Loc, "associated section cannot be itself associative");
+  }
+
+  if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
+    return Error(Loc, Twine("section '") + Current->getSectionName() +
+                                                       "' is already linkonce");
+
+  Current->setSelection(Type, Assoc);
+
+  if (getLexer().isNot(AsmToken::EndOfStatement))
+    return TokError("unexpected token in directive");
+
+  return false;
+}
+
 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
   StringRef SymbolID;
   if (getParser().parseIdentifier(SymbolID))

Modified: llvm/trunk/lib/MC/MCSectionCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionCOFF.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSectionCOFF.cpp (original)
+++ llvm/trunk/lib/MC/MCSectionCOFF.cpp Sat Jul  6 07:13:10 2013
@@ -28,6 +28,17 @@ bool MCSectionCOFF::ShouldOmitSectionDir
   return false;
 }
 
+void MCSectionCOFF::setSelection(int Selection,
+                                 const MCSectionCOFF *Assoc) const {
+  assert(Selection != 0 && "invalid COMDAT selection type");
+  assert((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
+         (Assoc != 0) &&
+    "associative COMDAT section must have an associated section");
+  this->Selection = Selection;
+  this->Assoc = Assoc;
+  Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+}
+
 void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
                                          raw_ostream &OS,
                                          const MCExpr *Subsection) const {
@@ -63,12 +74,15 @@ void MCSectionCOFF::PrintSwitchToSection
       case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
         OS << "\t.linkonce same_contents\n";
         break;
-    //NOTE: as of binutils 2.20, there is no way to specifiy select largest
-    //      with the .linkonce directive. For now, we treat it as an invalid
-    //      comdat selection value.
+      case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+        OS << "\t.linkonce associative " << Assoc->getSectionName() << "\n";
+        break;
       case COFF::IMAGE_COMDAT_SELECT_LARGEST:
-    //  OS << "\t.linkonce largest\n";
-    //  break;
+        OS << "\t.linkonce largest\n";
+        break;
+      case COFF::IMAGE_COMDAT_SELECT_NEWEST:
+        OS << "\t.linkonce newest\n";
+        break;
       default:
         assert (0 && "unsupported COFF selection type");
         break;

Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Sat Jul  6 07:13:10 2013
@@ -18,6 +18,7 @@
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCAsmLayout.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
@@ -707,10 +708,13 @@ void WinCOFFObjectWriter::WriteObject(MC
   // Assign symbol and section indexes and offsets.
   Header.NumberOfSections = 0;
 
+  DenseMap<COFFSection *, uint16_t> SectionIndices;
   for (sections::iterator i = Sections.begin(),
                           e = Sections.end(); i != e; i++) {
     if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
-      MakeSectionReal(**i, ++Header.NumberOfSections);
+      size_t Number = ++Header.NumberOfSections;
+      SectionIndices[*i] = Number;
+      MakeSectionReal(**i, Number);
     } else {
       (*i)->Number = -1;
     }
@@ -754,6 +758,31 @@ void WinCOFFObjectWriter::WriteObject(MC
     }
   }
 
+  // Fixup associative COMDAT sections.
+  for (sections::iterator i = Sections.begin(),
+                          e = Sections.end(); i != e; i++) {
+    if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
+        COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+      continue;
+
+    const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>(
+                                                    (*i)->MCData->getSection());
+
+    COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
+    if (!Assoc) {
+      report_fatal_error(Twine("Missing associated COMDAT section ") +
+                         MCSec.getAssocSection()->getSectionName() +
+                         " for section " + MCSec.getSectionName());
+    }
+
+    // Skip this section if the associated section is unused.
+    if (Assoc->Number == -1)
+      continue;
+
+    (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
+  }
+
+
   // Assign file offsets to COFF object file structures.
 
   unsigned offset = 0;

Modified: llvm/trunk/lib/MC/WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFStreamer.cpp?rev=185753&r1=185752&r2=185753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFStreamer.cpp Sat Jul  6 07:13:10 2013
@@ -155,7 +155,7 @@ void WinCOFFStreamer::AddCommonSymbol(MC
   int Selection = COFF::IMAGE_COMDAT_SELECT_LARGEST;
 
   const MCSection *Section = MCStreamer::getContext().getCOFFSection(
-    SectionName, Characteristics, Selection, SectionKind::getBSS());
+    SectionName, Characteristics, SectionKind::getBSS(), Selection);
 
   MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
 

Added: llvm/trunk/test/MC/COFF/linkonce-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/linkonce-invalid.s?rev=185753&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/linkonce-invalid.s (added)
+++ llvm/trunk/test/MC/COFF/linkonce-invalid.s Sat Jul  6 07:13:10 2013
@@ -0,0 +1,40 @@
+// Test invalid use of the .linkonce directive.
+//
+// RUN: not llvm-mc -triple i386-pc-win32 -filetype=obj %s 2>&1 | FileCheck %s
+
+.section non_comdat
+
+.section comdat
+.linkonce discard
+
+.section assoc
+.linkonce associative comdat
+
+
+.section invalid
+
+// CHECK: error: unrecognized COMDAT type 'unknown'
+.linkonce unknown
+
+// CHECK: error: unexpected token in directive
+.linkonce discard foo
+
+// CHECK: error: expected associated section name
+.linkonce associative
+
+// CHECK: error: cannot associate unknown section 'unknown'
+.linkonce associative unknown
+
+// CHECK: error: cannot associate a section with itself
+.linkonce associative invalid
+
+// CHECK: error: associated section must be a COMDAT section
+.linkonce associative non_comdat
+
+// CHECK: error: associated section cannot be itself associative
+.linkonce associative assoc
+
+// CHECK: error: section 'multi' is already linkonce
+.section multi
+.linkonce discard
+.linkonce same_size

Added: llvm/trunk/test/MC/COFF/linkonce.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/linkonce.s?rev=185753&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/linkonce.s (added)
+++ llvm/trunk/test/MC/COFF/linkonce.s Sat Jul  6 07:13:10 2013
@@ -0,0 +1,179 @@
+// Test section manipulation via .linkonce directive.
+//
+// RUN: llvm-mc -triple i386-pc-win32 -filetype=obj %s | llvm-readobj -s -t | FileCheck %s
+// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -s -t | FileCheck %s
+
+.section s1
+.linkonce
+.long 1
+
+.section s2
+.linkonce one_only
+.long 1
+
+.section s3
+.linkonce discard
+.long 1
+
+.section s4
+.linkonce same_size
+.long 1
+
+.section s5
+.linkonce same_contents
+.long 1
+
+.section s6
+.linkonce associative s1
+.long 1
+
+.section s7
+.linkonce largest
+.long 1
+
+.section s8
+.linkonce newest
+.long 1
+
+.section .foo$bar
+.linkonce discard
+.long 1
+
+// Check that valid '.section' names can be associated.
+.section multi
+.linkonce associative .foo$bar
+.long 1
+
+
+// CHECK: Sections [
+// CHECK:   Section {
+// CHECK:     Name: s1
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s2
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s3
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s4
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s5
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s6
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s7
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: s8
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK:   Section {
+// CHECK:     Name: multi
+// CHECK:     Characteristics [
+// CHECK:       IMAGE_SCN_LNK_COMDAT
+// CHECK:     ]
+// CHECK:   }
+// CHECK: ]
+// CHECK: Symbols [
+// CHECK:   Symbol {
+// CHECK:     Name: s1
+// CHECK:     Section: s1 (1)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 1
+// CHECK:       Selection: Any (0x2)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s2
+// CHECK:     Section: s2 (2)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 2
+// CHECK:       Selection: NoDuplicates (0x1)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s3
+// CHECK:     Section: s3 (3)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 3
+// CHECK:       Selection: Any (0x2)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s4
+// CHECK:     Section: s4 (4)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 4
+// CHECK:       Selection: SameSize (0x3)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s5
+// CHECK:     Section: s5 (5)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 5
+// CHECK:       Selection: ExactMatch (0x4)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s6
+// CHECK:     Section: s6 (6)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 1
+// CHECK:       Selection: Associative (0x5)
+// CHECK:       AssocSection: s1
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s7
+// CHECK:     Section: s7 (7)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 7
+// CHECK:       Selection: Largest (0x6)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: s8
+// CHECK:     Section: s8 (8)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 8
+// CHECK:       Selection: Newest (0x7)
+// CHECK:     }
+// CHECK:   }
+// CHECK:   Symbol {
+// CHECK:     Name: multi
+// CHECK:     Value: 0
+// CHECK:     Section: multi (10)
+// CHECK:     AuxSectionDef {
+// CHECK:       Number: 9
+// CHECK:       Selection: Associative (0x5)
+// CHECK:       AssocSection: .foo$bar
+// CHECK:     }
+// CHECK:   }





More information about the llvm-commits mailing list