<div dir="ltr">ELF uses exactly the same technique for .init_array, and you can use .init_array.priority to get adjust the order of your initializers.  Are you handling it the same way that ELF does, or is this something else?<div>
<br></div><div>I think link.exe will only dead strip if you use /Gy, which has the effect of putting all functions in COMDATs.  It looks like it will not dead strip data like these function pointers.</div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Fri, Oct 18, 2013 at 4:54 PM, Rui Ueyama <span dir="ltr"><<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: ruiu<br>
Date: Fri Oct 18 18:54:55 2013<br>
New Revision: 193017<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193017&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193017&view=rev</a><br>
Log:<br>
[PECOFF] Only COMDAT symbols are allowed to be dead-stripped.<br>
<br>
We should dead-strip atoms only if they are created for COMDAT symbols. If we<br>
remove non-COMDAT atoms from a binary, it will no longer be guaranteed that<br>
the binary will work correctly.<br>
<br>
In COFF, you can manipulate the order of section contents in the resulting<br>
binary by section name. For example, if you have four sections<br>
.data$unique_prefix_{a,b,c,d}, it's guaranteed that the contents of A, B, C,<br>
and D will be consecutive in the resulting .data section in that order.<br>
Thus, you can access B's and C's contents by incrementing a pointer pointing<br>
to A until it reached to D. That's why we cannot dead-strip B or C even if<br>
no one is directly referencing to them.<br>
<br>
Some object files in the standard library actually use that technique.<br>
<br>
Modified:<br>
    lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h<br>
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp<br>
    lld/trunk/test/pecoff/grouped-sections.test<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h?rev=193017&r1=193016&r2=193017&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h?rev=193017&r1=193016&r2=193017&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h Fri Oct 18 18:54:55 2013<br>
@@ -181,17 +181,24 @@ private:<br>
 class COFFDefinedAtom : public COFFDefinedFileAtom {<br>
 public:<br>
   COFFDefinedAtom(const File &file, StringRef name, StringRef sectionName,<br>
-                  Scope scope, ContentType type, ContentPermissions perms,<br>
-                  Merge merge, ArrayRef<uint8_t> data, uint64_t ordinal)<br>
+                  Scope scope, ContentType type, bool isComdat,<br>
+                  ContentPermissions perms, Merge merge, ArrayRef<uint8_t> data,<br>
+                  uint64_t ordinal)<br>
       : COFFDefinedFileAtom(file, name, sectionName, scope, type, perms,<br>
                             ordinal),<br>
-        _merge(merge), _dataref(data) {}<br>
+        _isComdat(isComdat), _merge(merge), _dataref(data) {}<br>
<br>
   virtual Merge merge() const { return _merge; }<br>
   virtual uint64_t size() const { return _dataref.size(); }<br>
   virtual ArrayRef<uint8_t> rawContent() const { return _dataref; }<br>
<br>
+  virtual DeadStripKind deadStrip() const {<br>
+    // Only COMDAT symbols would be dead-stripped.<br>
+    return _isComdat ? deadStripNormal : deadStripNever;<br>
+  }<br>
+<br>
 private:<br>
+  bool _isComdat;<br>
   Merge _merge;<br>
   ArrayRef<uint8_t> _dataref;<br>
 };<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=193017&r1=193016&r2=193017&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=193017&r1=193016&r2=193017&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Fri Oct 18 18:54:55 2013<br>
@@ -397,6 +397,8 @@ private:<br>
       if (!(sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_COMDAT))<br>
         continue;<br>
<br>
+      _comdatSections.insert(sec);<br>
+<br>
       if (sym->NumberOfAuxSymbols == 0)<br>
         return llvm::object::object_error::parse_failed;<br>
       const coff_aux_section_definition *aux =<br>
@@ -473,13 +475,14 @@ private:<br>
<br>
     DefinedAtom::ContentType type = getContentType(section);<br>
     DefinedAtom::ContentPermissions perms = getPermissions(section);<br>
+    bool isComdat = (_comdatSections.count(section) == 1);<br>
<br>
     // Create an atom for the entire section.<br>
     if (symbols.empty()) {<br>
       ArrayRef<uint8_t> data(secData.data(), secData.size());<br>
       auto *atom = new (_alloc)<br>
           COFFDefinedAtom(*this, "", sectionName, Atom::scopeTranslationUnit,<br>
-                          type, perms, _merge[section], data, 0);<br>
+                          type, isComdat, perms, _merge[section], data, 0);<br>
       atoms.push_back(atom);<br>
       _definedAtomLocations[section][0].push_back(atom);<br>
       return error_code::success();<br>
@@ -490,9 +493,9 @@ private:<br>
     if (symbols[0]->Value != 0) {<br>
       uint64_t size = symbols[0]->Value;<br>
       ArrayRef<uint8_t> data(secData.data(), size);<br>
-      auto *atom = new (_alloc)<br>
-          COFFDefinedAtom(*this, "", sectionName, Atom::scopeTranslationUnit,<br>
-                          type, perms, _merge[section], data, ++ordinal);<br>
+      auto *atom = new (_alloc) COFFDefinedAtom(<br>
+          *this, "", sectionName, Atom::scopeTranslationUnit, type, isComdat,<br>
+          perms, _merge[section], data, ++ordinal);<br>
       atoms.push_back(atom);<br>
       _definedAtomLocations[section][0].push_back(atom);<br>
     }<br>
@@ -503,9 +506,9 @@ private:<br>
       const uint8_t *end = (si + 1 == se) ? secData.data() + secData.size()<br>
                                           : secData.data() + (*(si + 1))->Value;<br>
       ArrayRef<uint8_t> data(start, end);<br>
-      auto *atom = new (_alloc)<br>
-          COFFDefinedAtom(*this, _symbolName[*si], sectionName, getScope(*si),<br>
-                          type, perms, _merge[section], data, ++ordinal);<br>
+      auto *atom = new (_alloc) COFFDefinedAtom(<br>
+          *this, _symbolName[*si], sectionName, getScope(*si), type, isComdat,<br>
+          perms, _merge[section], data, ++ordinal);<br>
       atoms.push_back(atom);<br>
       _symbolAtom[*si] = atom;<br>
       _definedAtomLocations[section][(*si)->Value].push_back(atom);<br>
@@ -696,6 +699,9 @@ private:<br>
   // A map from section to its atoms.<br>
   std::map<const coff_section *, vector<COFFDefinedFileAtom *> > _sectionAtoms;<br>
<br>
+  // A set of COMDAT sections.<br>
+  std::set<const coff_section *> _comdatSections;<br>
+<br>
   // A map to get whether the section allows its contents to be merged or not.<br>
   std::map<const coff_section *, DefinedAtom::Merge> _merge;<br>
<br>
<br>
Modified: lld/trunk/test/pecoff/grouped-sections.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/grouped-sections.test?rev=193017&r1=193016&r2=193017&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/grouped-sections.test?rev=193017&r1=193016&r2=193017&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/test/pecoff/grouped-sections.test (original)<br>
+++ lld/trunk/test/pecoff/grouped-sections.test Fri Oct 18 18:54:55 2013<br>
@@ -1,6 +1,6 @@<br>
 # RUN: yaml2obj %p/Inputs/grouped-sections.obj.yaml > %t.obj<br>
 #<br>
-# RUN: lld -flavor link /out:%t1 /subsystem:console /force /opt:noref \<br>
+# RUN: lld -flavor link /out:%t1 /subsystem:console /force \<br>
 # RUN:   -- %t.obj && llvm-objdump -s %t1 | FileCheck %s<br>
 #<br>
 # The file "grouped-sections.obj" has three data sections in the following<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>