[PATCH] MC: Add associative selection mode for COFF COMDAT sections

Nico Rieck nico.rieck at gmail.com
Thu Jul 4 10:35:28 PDT 2013


This allows COFF COMDAT sections with the IMAGE_COMDAT_SELECT_ASSOCIATIVE characteristic. This allows for example tying exception handling sections to functions in COMDAT sections.

http://llvm-reviews.chandlerc.com/D1100

Files:
  include/llvm/MC/MCContext.h
  include/llvm/MC/MCSectionCOFF.h
  lib/MC/MCContext.cpp
  lib/MC/MCSectionCOFF.cpp
  lib/MC/WinCOFFObjectWriter.cpp

Index: include/llvm/MC/MCContext.h
===================================================================
--- include/llvm/MC/MCContext.h
+++ include/llvm/MC/MCContext.h
@@ -256,11 +256,17 @@
     const MCSectionELF *CreateELFGroupSection();
 
     const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
-                                    int Selection, SectionKind Kind);
+                                    int Selection, const MCSection *Assoc,
+                                    SectionKind Kind);
+
+    const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
+                                    int Selection, SectionKind Kind) {
+      return getCOFFSection (Section, Characteristics, Selection, 0, Kind);
+    }
 
     const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
                                     SectionKind Kind) {
-      return getCOFFSection (Section, Characteristics, 0, Kind);
+      return getCOFFSection (Section, Characteristics, 0, 0, Kind);
     }
 
 
Index: include/llvm/MC/MCSectionCOFF.h
===================================================================
--- include/llvm/MC/MCSectionCOFF.h
+++ include/llvm/MC/MCSectionCOFF.h
@@ -33,14 +33,22 @@
     /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
     int Selection;
 
+    /// Assoc - This is the associated section, if it is a COMDAT section
+    /// (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an associative
+    /// Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
+    const MCSection* Assoc;
+
   private:
     friend class MCContext;
     MCSectionCOFF(StringRef Section, unsigned Characteristics,
-                  int Selection, SectionKind K)
+                  int Selection, const MCSection *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();
 
@@ -58,6 +66,7 @@
     }
     unsigned getCharacteristics() const { return Characteristics; }
     int getSelection () const { return Selection; }
+    const MCSection *getAssocSection() const { return Assoc; }
 
     virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
                                       raw_ostream &OS,
Index: lib/MC/MCContext.cpp
===================================================================
--- lib/MC/MCContext.cpp
+++ lib/MC/MCContext.cpp
@@ -277,6 +277,7 @@
 const MCSection *MCContext::getCOFFSection(StringRef Section,
                                            unsigned Characteristics,
                                            int Selection,
+                                           const MCSection *Assoc,
                                            SectionKind Kind) {
   if (COFFUniquingMap == 0)
     COFFUniquingMap = new COFFUniqueMapTy();
@@ -288,7 +289,7 @@
 
   MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
                                                     Characteristics,
-                                                    Selection, Kind);
+                                                    Selection, Assoc, Kind);
 
   Entry.setValue(Result);
   return Result;
Index: lib/MC/MCSectionCOFF.cpp
===================================================================
--- lib/MC/MCSectionCOFF.cpp
+++ lib/MC/MCSectionCOFF.cpp
@@ -63,6 +63,11 @@
       case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
         OS << "\t.linkonce same_contents\n";
         break;
+      // FIXME: associative select needs the associated section. How should it
+      // be specified?
+      case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+      //  OS << "\t.linkonce associative\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.
Index: lib/MC/WinCOFFObjectWriter.cpp
===================================================================
--- lib/MC/WinCOFFObjectWriter.cpp
+++ lib/MC/WinCOFFObjectWriter.cpp
@@ -707,10 +707,13 @@
   // 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 +757,23 @@
     }
   }
 
+  // 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;
+
+    MCSectionCOFF const &MCSec =
+      static_cast<MCSectionCOFF const &>((*i)->MCData->getSection());
+    COFFSection *Sec = SectionMap[MCSec.getAssocSection()];
+    if (Sec->Number == -1)
+      continue;
+
+    (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Sec];
+  }
+
+
   // Assign file offsets to COFF object file structures.
 
   unsigned offset = 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1100.1.patch
Type: text/x-patch
Size: 5726 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130704/d8e30ac3/attachment.bin>


More information about the llvm-commits mailing list