[llvm-commits] [llvm] r148990 - in /llvm/trunk: include/llvm/CodeGen/AsmPrinter.h include/llvm/CodeGen/TargetLoweringObjectFileImpl.h include/llvm/MC/MCObjectFileInfo.h include/llvm/Target/TargetLoweringObjectFile.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/TargetLoweringObjectFileImpl.cpp lib/MC/MCObjectFileInfo.cpp lib/Target/ARM/ARMTargetObjectFile.cpp lib/Target/ARM/ARMTargetObjectFile.h test/CodeGen/ARM/ctor_order.ll test/CodeGen/X86/2011-08-29-InitOrder.ll

Anton Korobeynikov asl at math.spbu.ru
Wed Jan 25 14:24:20 PST 2012


Author: asl
Date: Wed Jan 25 16:24:19 2012
New Revision: 148990

URL: http://llvm.org/viewvc/llvm-project?rev=148990&view=rev
Log:
Properly emit ctors / dtors with priorities into desired sections
and let linker handle the rest.

This finally fixes PR5329


Modified:
    llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
    llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/MC/MCObjectFileInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp
    llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h
    llvm/trunk/test/CodeGen/ARM/ctor_order.ll
    llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll

Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Wed Jan 25 16:24:19 2012
@@ -471,7 +471,7 @@
                             const MachineBasicBlock *MBB,
                             unsigned uid) const;
     void EmitLLVMUsedList(const Constant *List);
-    void EmitXXStructorList(const Constant *List);
+    void EmitXXStructorList(const Constant *List, bool isCtor);
     GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
   };
 }

Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Wed Jan 25 16:24:19 2012
@@ -65,6 +65,11 @@
   virtual MCSymbol *
   getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
                           MachineModuleInfo *MMI) const;
+
+  virtual const MCSection *
+  getStaticCtorSection(unsigned Priority = 65535) const;
+  virtual const MCSection *
+  getStaticDtorSection(unsigned Priority = 65535) const;
 };
 
 

Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Wed Jan 25 16:24:19 2012
@@ -22,10 +22,6 @@
   class MCContext;
   class MCSection;
   class Triple;
-  
-  namespace Structors {
-    enum OutputOrder { None, PriorityOrder, ReversePriorityOrder };
-  }
 
 class MCObjectFileInfo {  
 protected:
@@ -167,11 +163,6 @@
   const MCSection *DrectveSection;
   const MCSection *PDataSection;
   const MCSection *XDataSection;
-  
-  /// StructorOutputOrder - Whether the static ctor/dtor list should be output
-  /// in no particular order, in order of increasing priority or the reverse:
-  /// in order of decreasing priority (the default).
-  Structors::OutputOrder StructorOutputOrder; // Default is reverse order.
 
 public:
   void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
@@ -197,8 +188,6 @@
   const MCSection *getTextSection() const { return TextSection; }
   const MCSection *getDataSection() const { return DataSection; }
   const MCSection *getBSSSection() const { return BSSSection; }
-  const MCSection *getStaticCtorSection() const { return StaticCtorSection; }
-  const MCSection *getStaticDtorSection() const { return StaticDtorSection; }
   const MCSection *getLSDASection() const { return LSDASection; }
   const MCSection *getCompactUnwindSection() const{
     return CompactUnwindSection;
@@ -300,10 +289,6 @@
     return EHFrameSection;
   }
 
-  Structors::OutputOrder getStructorOutputOrder() const {
-    return StructorOutputOrder;
-  }
-
 private:
   enum Environment { IsMachO, IsELF, IsCOFF };
   Environment Env;

Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Wed Jan 25 16:24:19 2012
@@ -121,7 +121,18 @@
   const MCExpr *
   getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
                            MCStreamer &Streamer) const;
-  
+
+  virtual const MCSection *
+  getStaticCtorSection(unsigned Priority = 65535) const {
+    (void)Priority;
+    return StaticCtorSection;
+  }
+  virtual const MCSection *
+  getStaticDtorSection(unsigned Priority = 65535) const {
+    (void)Priority;
+    return StaticDtorSection;
+  }
+
 protected:
   virtual const MCSection *
   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Wed Jan 25 16:24:19 2012
@@ -1207,12 +1207,8 @@
 
   assert(GV->hasInitializer() && "Not a special LLVM global!");
 
-  const TargetData *TD = TM.getTargetData();
-  unsigned Align = Log2_32(TD->getPointerPrefAlignment());
   if (GV->getName() == "llvm.global_ctors") {
-    OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
-    EmitAlignment(Align);
-    EmitXXStructorList(GV->getInitializer());
+    EmitXXStructorList(GV->getInitializer(), /* isCtor */ true);
 
     if (TM.getRelocationModel() == Reloc::Static &&
         MAI->hasStaticCtorDtorReferenceInStaticMode()) {
@@ -1224,9 +1220,7 @@
   }
 
   if (GV->getName() == "llvm.global_dtors") {
-    OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
-    EmitAlignment(Align);
-    EmitXXStructorList(GV->getInitializer());
+    EmitXXStructorList(GV->getInitializer(), /* isCtor */ false);
 
     if (TM.getRelocationModel() == Reloc::Static &&
         MAI->hasStaticCtorDtorReferenceInStaticMode()) {
@@ -1256,7 +1250,7 @@
   }
 }
 
-typedef std::pair<int, Constant*> Structor;
+typedef std::pair<unsigned, Constant*> Structor;
 
 static bool priority_order(const Structor& lhs, const Structor& rhs) {
   return lhs.first < rhs.first;
@@ -1264,7 +1258,7 @@
 
 /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
 /// priority.
-void AsmPrinter::EmitXXStructorList(const Constant *List) {
+void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
   // Should be an array of '{ int, void ()* }' structs.  The first value is the
   // init priority.
   if (!isa<ConstantArray>(List)) return;
@@ -1290,19 +1284,20 @@
                                        CS->getOperand(1)));
   }
 
-  // Emit the function pointers in reverse priority order.
-  switch (getObjFileLowering().getStructorOutputOrder()) {
-  case Structors::None:
-    break;
-  case Structors::PriorityOrder:
-    std::sort(Structors.begin(), Structors.end(), priority_order);
-    break;
-  case Structors::ReversePriorityOrder:
-    std::sort(Structors.rbegin(), Structors.rend(), priority_order);
-    break;
-  }
-  for (unsigned i = 0, e = Structors.size(); i != e; ++i)
+  // Emit the function pointers in the target-specific order
+  const TargetData *TD = TM.getTargetData();
+  unsigned Align = Log2_32(TD->getPointerPrefAlignment());
+  std::stable_sort(Structors.begin(), Structors.end(), priority_order);
+  for (unsigned i = 0, e = Structors.size(); i != e; ++i) {
+    const MCSection *OutputSection =
+      (isCtor ?
+       getObjFileLowering().getStaticCtorSection(Structors[i].first) :
+       getObjFileLowering().getStaticDtorSection(Structors[i].first));
+    OutStreamer.SwitchSection(OutputSection);
+    if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection())
+      EmitAlignment(Align);
     EmitGlobalConstant(Structors[i].second);
+  }
 }
 
 //===--------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Wed Jan 25 16:24:19 2012
@@ -340,6 +340,32 @@
     getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
 }
 
+const MCSection *
+TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const {
+  // The default scheme is .ctor / .dtor, so we have to invert the priority
+  // numbering.
+  if (Priority == 65535)
+    return StaticCtorSection;
+
+  std::string Name = std::string(".ctors.") + utostr(65535 - Priority);
+  return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
+                                    ELF::SHF_ALLOC |ELF::SHF_WRITE,
+                                    SectionKind::getDataRel());
+}
+
+const MCSection *
+TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const {
+  // The default scheme is .ctor / .dtor, so we have to invert the priority
+  // numbering.
+  if (Priority == 65535)
+    return StaticDtorSection;
+
+  std::string Name = std::string(".dtors.") + utostr(65535 - Priority);
+  return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
+                                    ELF::SHF_ALLOC |ELF::SHF_WRITE,
+                                    SectionKind::getDataRel());
+}
+
 //===----------------------------------------------------------------------===//
 //                                 MachO
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Wed Jan 25 16:24:19 2012
@@ -31,8 +31,6 @@
   if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5))
     CommDirectiveSupportsAlignment = false;
 
-  StructorOutputOrder = Structors::PriorityOrder;
-
   TextSection // .text
     = Ctx->getMachOSection("__TEXT", "__text",
                            MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
@@ -260,12 +258,10 @@
     }
   }
 
-  StructorOutputOrder = Structors::ReversePriorityOrder;
-
   // ELF
   BSSSection =
     Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
-                       ELF::SHF_WRITE |ELF::SHF_ALLOC,
+                       ELF::SHF_WRITE | ELF::SHF_ALLOC,
                        SectionKind::getBSS());
 
   TextSection =
@@ -389,8 +385,6 @@
 
 void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
   // COFF
-  StructorOutputOrder = Structors::ReversePriorityOrder;
-
   TextSection =
     Ctx->getCOFFSection(".text",
                         COFF::IMAGE_SCN_CNT_CODE |

Modified: llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp Wed Jan 25 16:24:19 2012
@@ -14,6 +14,7 @@
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 using namespace dwarf;
 
@@ -24,8 +25,9 @@
 void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
                                         const TargetMachine &TM) {
   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
+  isAAPCS_ABI = TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI();
 
-  if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
+  if (isAAPCS_ABI) {
     StaticCtorSection =
       getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
                                  ELF::SHF_WRITE |
@@ -36,7 +38,6 @@
                                  ELF::SHF_WRITE |
                                  ELF::SHF_ALLOC,
                                  SectionKind::getDataRel());
-    StructorOutputOrder = Structors::PriorityOrder;
     LSDASection = NULL;
   }
 
@@ -46,3 +47,33 @@
                                0,
                                SectionKind::getMetadata());
 }
+
+const MCSection *
+ARMElfTargetObjectFile::getStaticCtorSection(unsigned Priority) const {
+  if (!isAAPCS_ABI)
+    return TargetLoweringObjectFileELF::getStaticCtorSection(Priority);
+
+  if (Priority == 65535)
+    return StaticCtorSection;
+
+  // Emit ctors in priority order.
+  std::string Name = std::string(".init_array.") + utostr(Priority);
+  return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY,
+                                    ELF::SHF_ALLOC | ELF::SHF_WRITE,
+                                    SectionKind::getDataRel());
+}
+
+const MCSection *
+ARMElfTargetObjectFile::getStaticDtorSection(unsigned Priority) const {
+  if (!isAAPCS_ABI)
+    return TargetLoweringObjectFileELF::getStaticDtorSection(Priority);
+
+  if (Priority == 65535)
+    return StaticDtorSection;
+
+  // Emit dtors in priority order.
+  std::string Name = std::string(".fini_array.") + utostr(Priority);
+  return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY,
+                                    ELF::SHF_ALLOC | ELF::SHF_WRITE,
+                                    SectionKind::getDataRel());
+}

Modified: llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h Wed Jan 25 16:24:19 2012
@@ -20,6 +20,7 @@
 class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
 protected:
   const MCSection *AttributesSection;
+  bool isAAPCS_ABI;
 public:
   ARMElfTargetObjectFile() :
     TargetLoweringObjectFileELF(),
@@ -31,6 +32,9 @@
   virtual const MCSection *getAttributesSection() const {
     return AttributesSection;
   }
+
+  const MCSection * getStaticCtorSection(unsigned Priority) const;
+  const MCSection * getStaticDtorSection(unsigned Priority) const;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/test/CodeGen/ARM/ctor_order.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ctor_order.ll?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/ctor_order.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/ctor_order.ll Wed Jan 25 16:24:19 2012
@@ -6,13 +6,15 @@
 ; DARWIN:      .long _f151
 ; DARWIN-NEXT: .long _f152
 
-; ELF:      .section .ctors,"aw",%progbits
+; ELF:      .section .ctors.65384,"aw",%progbits
+; ELF:      .long    f151
+; ELF:      .section .ctors.65383,"aw",%progbits
 ; ELF:      .long    f152
-; ELF-NEXT: .long    f151
 
-; GNUEABI:      .section .init_array,"aw",%init_array
+; GNUEABI:      .section .init_array.151,"aw",%init_array
 ; GNUEABI:      .long    f151
-; GNUEABI-NEXT: .long    f152
+; GNUEABI:      .section .init_array.152,"aw",%init_array
+; GNUEABI:      .long    f152
 
 
 @llvm.global_ctors = appending global [2 x { i32, void ()* }] [ { i32, void ()* } { i32 151, void ()* @f151 }, { i32, void ()* } { i32 152, void ()* @f152 } ]

Modified: llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll?rev=148990&r1=148989&r2=148990&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll Wed Jan 25 16:24:19 2012
@@ -3,22 +3,28 @@
 ; PR5329
 
 @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 2000, void ()* @construct_2 }, { i32, void ()* } { i32 3000, void ()* @construct_3 }, { i32, void ()* } { i32 1000, void ()* @construct_1 }]
-; CHECK-DEFAULT: construct_3
-; CHECK-DEFAULT: construct_2
-; CHECK-DEFAULT: construct_1
+; CHECK-DEFAULT  .section        .ctors.64535,"aw", at progbits
+; CHECK-DEFAULT: .long construct_1
+; CHECK-DEFAULT: .section        .ctors.63535,"aw", at progbits
+; CHECK-DEFAULT: .long construct_2
+; CHECK-DEFAULT: .section        .ctors.62535,"aw", at progbits
+; CHECK-DEFAULT: .long construct_3
 
-; CHECK-DARWIN: construct_1
-; CHECK-DARWIN: construct_2
-; CHECK-DARWIN: construct_3
+; CHECK-DARWIN: .long _construct_1
+; CHECK-DARWIN-NEXT: .long _construct_2
+; CHECK-DARWIN-NEXT: .long _construct_3
 
 @llvm.global_dtors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 2000, void ()* @destruct_2 }, { i32, void ()* } { i32 1000, void ()* @destruct_1 }, { i32, void ()* } { i32 3000, void ()* @destruct_3 }]
-; CHECK-DEFAULT: destruct_3
-; CHECK-DEFAULT: destruct_2
-; CHECK-DEFAULT: destruct_1
+; CHECK-DEFAULT: .section        .dtors.64535,"aw", at progbits
+; CHECK-DEFAULT: .long destruct_1
+; CHECK-DEFAULT: .section        .dtors.63535,"aw", at progbits
+; CHECK-DEFAULT: .long destruct_2
+; CHECK-DEFAULT: .section        .dtors.62535,"aw", at progbits
+; CHECK-DEFAULT: .long destruct_3
 
-; CHECK-DARWIN: destruct_1
-; CHECK-DARWIN: destruct_2
-; CHECK-DARWIN: destruct_3
+; CHECK-DARWIN:      .long _destruct_1
+; CHECK-DARWIN-NEXT: .long _destruct_2
+; CHECK-DARWIN-NEXT: .long _destruct_3
 
 declare void @construct_1()
 declare void @construct_2()





More information about the llvm-commits mailing list