llvm.org GIT mirror llvm / 4a99f59
Properly emit ctors / dtors with priorities into desired sections and let linker handle the rest. This finally fixes PR5329 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148990 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 7 years ago
11 changed file(s) with 123 addition(s) and 64 deletion(s). Raw diff Collapse all Expand all
470470 const MachineBasicBlock *MBB,
471471 unsigned uid) const;
472472 void EmitLLVMUsedList(const Constant *List);
473 void EmitXXStructorList(const Constant *List);
473 void EmitXXStructorList(const Constant *List, bool isCtor);
474474 GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
475475 };
476476 }
6464 virtual MCSymbol *
6565 getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
6666 MachineModuleInfo *MMI) const;
67
68 virtual const MCSection *
69 getStaticCtorSection(unsigned Priority = 65535) const;
70 virtual const MCSection *
71 getStaticDtorSection(unsigned Priority = 65535) const;
6772 };
6873
6974
2121 class MCContext;
2222 class MCSection;
2323 class Triple;
24
25 namespace Structors {
26 enum OutputOrder { None, PriorityOrder, ReversePriorityOrder };
27 }
2824
2925 class MCObjectFileInfo {
3026 protected:
166162 const MCSection *DrectveSection;
167163 const MCSection *PDataSection;
168164 const MCSection *XDataSection;
169
170 /// StructorOutputOrder - Whether the static ctor/dtor list should be output
171 /// in no particular order, in order of increasing priority or the reverse:
172 /// in order of decreasing priority (the default).
173 Structors::OutputOrder StructorOutputOrder; // Default is reverse order.
174165
175166 public:
176167 void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
196187 const MCSection *getTextSection() const { return TextSection; }
197188 const MCSection *getDataSection() const { return DataSection; }
198189 const MCSection *getBSSSection() const { return BSSSection; }
199 const MCSection *getStaticCtorSection() const { return StaticCtorSection; }
200 const MCSection *getStaticDtorSection() const { return StaticDtorSection; }
201190 const MCSection *getLSDASection() const { return LSDASection; }
202191 const MCSection *getCompactUnwindSection() const{
203192 return CompactUnwindSection;
299288 return EHFrameSection;
300289 }
301290
302 Structors::OutputOrder getStructorOutputOrder() const {
303 return StructorOutputOrder;
304 }
305
306291 private:
307292 enum Environment { IsMachO, IsELF, IsCOFF };
308293 Environment Env;
120120 const MCExpr *
121121 getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
122122 MCStreamer &Streamer) const;
123
123
124 virtual const MCSection *
125 getStaticCtorSection(unsigned Priority = 65535) const {
126 (void)Priority;
127 return StaticCtorSection;
128 }
129 virtual const MCSection *
130 getStaticDtorSection(unsigned Priority = 65535) const {
131 (void)Priority;
132 return StaticDtorSection;
133 }
134
124135 protected:
125136 virtual const MCSection *
126137 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
12061206
12071207 assert(GV->hasInitializer() && "Not a special LLVM global!");
12081208
1209 const TargetData *TD = TM.getTargetData();
1210 unsigned Align = Log2_32(TD->getPointerPrefAlignment());
12111209 if (GV->getName() == "llvm.global_ctors") {
1212 OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
1213 EmitAlignment(Align);
1214 EmitXXStructorList(GV->getInitializer());
1210 EmitXXStructorList(GV->getInitializer(), /* isCtor */ true);
12151211
12161212 if (TM.getRelocationModel() == Reloc::Static &&
12171213 MAI->hasStaticCtorDtorReferenceInStaticMode()) {
12231219 }
12241220
12251221 if (GV->getName() == "llvm.global_dtors") {
1226 OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
1227 EmitAlignment(Align);
1228 EmitXXStructorList(GV->getInitializer());
1222 EmitXXStructorList(GV->getInitializer(), /* isCtor */ false);
12291223
12301224 if (TM.getRelocationModel() == Reloc::Static &&
12311225 MAI->hasStaticCtorDtorReferenceInStaticMode()) {
12551249 }
12561250 }
12571251
1258 typedef std::pair<int, Constant*> Structor;
1252 typedef std::pair<unsigned, Constant*> Structor;
12591253
12601254 static bool priority_order(const Structor& lhs, const Structor& rhs) {
12611255 return lhs.first < rhs.first;
12631257
12641258 /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
12651259 /// priority.
1266 void AsmPrinter::EmitXXStructorList(const Constant *List) {
1260 void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
12671261 // Should be an array of '{ int, void ()* }' structs. The first value is the
12681262 // init priority.
12691263 if (!isa(List)) return;
12891283 CS->getOperand(1)));
12901284 }
12911285
1292 // Emit the function pointers in reverse priority order.
1293 switch (getObjFileLowering().getStructorOutputOrder()) {
1294 case Structors::None:
1295 break;
1296 case Structors::PriorityOrder:
1297 std::sort(Structors.begin(), Structors.end(), priority_order);
1298 break;
1299 case Structors::ReversePriorityOrder:
1300 std::sort(Structors.rbegin(), Structors.rend(), priority_order);
1301 break;
1302 }
1303 for (unsigned i = 0, e = Structors.size(); i != e; ++i)
1286 // Emit the function pointers in the target-specific order
1287 const TargetData *TD = TM.getTargetData();
1288 unsigned Align = Log2_32(TD->getPointerPrefAlignment());
1289 std::stable_sort(Structors.begin(), Structors.end(), priority_order);
1290 for (unsigned i = 0, e = Structors.size(); i != e; ++i) {
1291 const MCSection *OutputSection =
1292 (isCtor ?
1293 getObjFileLowering().getStaticCtorSection(Structors[i].first) :
1294 getObjFileLowering().getStaticDtorSection(Structors[i].first));
1295 OutStreamer.SwitchSection(OutputSection);
1296 if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection())
1297 EmitAlignment(Align);
13041298 EmitGlobalConstant(Structors[i].second);
1299 }
13051300 }
13061301
13071302 //===--------------------------------------------------------------------===//
339339 getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
340340 }
341341
342 const MCSection *
343 TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const {
344 // The default scheme is .ctor / .dtor, so we have to invert the priority
345 // numbering.
346 if (Priority == 65535)
347 return StaticCtorSection;
348
349 std::string Name = std::string(".ctors.") + utostr(65535 - Priority);
350 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
351 ELF::SHF_ALLOC |ELF::SHF_WRITE,
352 SectionKind::getDataRel());
353 }
354
355 const MCSection *
356 TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const {
357 // The default scheme is .ctor / .dtor, so we have to invert the priority
358 // numbering.
359 if (Priority == 65535)
360 return StaticDtorSection;
361
362 std::string Name = std::string(".dtors.") + utostr(65535 - Priority);
363 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
364 ELF::SHF_ALLOC |ELF::SHF_WRITE,
365 SectionKind::getDataRel());
366 }
367
342368 //===----------------------------------------------------------------------===//
343369 // MachO
344370 //===----------------------------------------------------------------------===//
2929 // .comm doesn't support alignment before Leopard.
3030 if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5))
3131 CommDirectiveSupportsAlignment = false;
32
33 StructorOutputOrder = Structors::PriorityOrder;
3432
3533 TextSection // .text
3634 = Ctx->getMachOSection("__TEXT", "__text",
259257 }
260258 }
261259
262 StructorOutputOrder = Structors::ReversePriorityOrder;
263
264260 // ELF
265261 BSSSection =
266262 Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
267 ELF::SHF_WRITE |ELF::SHF_ALLOC,
263 ELF::SHF_WRITE | ELF::SHF_ALLOC,
268264 SectionKind::getBSS());
269265
270266 TextSection =
388384
389385 void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
390386 // COFF
391 StructorOutputOrder = Structors::ReversePriorityOrder;
392
393387 TextSection =
394388 Ctx->getCOFFSection(".text",
395389 COFF::IMAGE_SCN_CNT_CODE |
1313 #include "llvm/Support/Dwarf.h"
1414 #include "llvm/Support/ELF.h"
1515 #include "llvm/Target/TargetMachine.h"
16 #include "llvm/ADT/StringExtras.h"
1617 using namespace llvm;
1718 using namespace dwarf;
1819
2324 void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
2425 const TargetMachine &TM) {
2526 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
27 isAAPCS_ABI = TM.getSubtarget().isAAPCS_ABI();
2628
27 if (TM.getSubtarget().isAAPCS_ABI()) {
29 if (isAAPCS_ABI) {
2830 StaticCtorSection =
2931 getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
3032 ELF::SHF_WRITE |
3537 ELF::SHF_WRITE |
3638 ELF::SHF_ALLOC,
3739 SectionKind::getDataRel());
38 StructorOutputOrder = Structors::PriorityOrder;
3940 LSDASection = NULL;
4041 }
4142
4546 0,
4647 SectionKind::getMetadata());
4748 }
49
50 const MCSection *
51 ARMElfTargetObjectFile::getStaticCtorSection(unsigned Priority) const {
52 if (!isAAPCS_ABI)
53 return TargetLoweringObjectFileELF::getStaticCtorSection(Priority);
54
55 if (Priority == 65535)
56 return StaticCtorSection;
57
58 // Emit ctors in priority order.
59 std::string Name = std::string(".init_array.") + utostr(Priority);
60 return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY,
61 ELF::SHF_ALLOC | ELF::SHF_WRITE,
62 SectionKind::getDataRel());
63 }
64
65 const MCSection *
66 ARMElfTargetObjectFile::getStaticDtorSection(unsigned Priority) const {
67 if (!isAAPCS_ABI)
68 return TargetLoweringObjectFileELF::getStaticDtorSection(Priority);
69
70 if (Priority == 65535)
71 return StaticDtorSection;
72
73 // Emit dtors in priority order.
74 std::string Name = std::string(".fini_array.") + utostr(Priority);
75 return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY,
76 ELF::SHF_ALLOC | ELF::SHF_WRITE,
77 SectionKind::getDataRel());
78 }
1919 class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
2020 protected:
2121 const MCSection *AttributesSection;
22 bool isAAPCS_ABI;
2223 public:
2324 ARMElfTargetObjectFile() :
2425 TargetLoweringObjectFileELF(),
3031 virtual const MCSection *getAttributesSection() const {
3132 return AttributesSection;
3233 }
34
35 const MCSection * getStaticCtorSection(unsigned Priority) const;
36 const MCSection * getStaticDtorSection(unsigned Priority) const;
3337 };
3438
3539 } // end namespace llvm
55 ; DARWIN: .long _f151
66 ; DARWIN-NEXT: .long _f152
77
8 ; ELF: .section .ctors,"aw",%progbits
8 ; ELF: .section .ctors.65384,"aw",%progbits
9 ; ELF: .long f151
10 ; ELF: .section .ctors.65383,"aw",%progbits
911 ; ELF: .long f152
10 ; ELF-NEXT: .long f151
1112
12 ; GNUEABI: .section .init_array,"aw",%init_array
13 ; GNUEABI: .section .init_array.151,"aw",%init_array
1314 ; GNUEABI: .long f151
14 ; GNUEABI-NEXT: .long f152
15 ; GNUEABI: .section .init_array.152,"aw",%init_array
16 ; GNUEABI: .long f152
1517
1618
1719 @llvm.global_ctors = appending global [2 x { i32, void ()* }] [ { i32, void ()* } { i32 151, void ()* @f151 }, { i32, void ()* } { i32 152, void ()* @f152 } ]
22 ; PR5329
33
44 @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 }]
5 ; CHECK-DEFAULT: construct_3
6 ; CHECK-DEFAULT: construct_2
7 ; CHECK-DEFAULT: construct_1
5 ; CHECK-DEFAULT .section .ctors.64535,"aw",@progbits
6 ; CHECK-DEFAULT: .long construct_1
7 ; CHECK-DEFAULT: .section .ctors.63535,"aw",@progbits
8 ; CHECK-DEFAULT: .long construct_2
9 ; CHECK-DEFAULT: .section .ctors.62535,"aw",@progbits
10 ; CHECK-DEFAULT: .long construct_3
811
9 ; CHECK-DARWIN: construct_1
10 ; CHECK-DARWIN: construct_2
11 ; CHECK-DARWIN: construct_3
12 ; CHECK-DARWIN: .long _construct_1
13 ; CHECK-DARWIN-NEXT: .long _construct_2
14 ; CHECK-DARWIN-NEXT: .long _construct_3
1215
1316 @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 }]
14 ; CHECK-DEFAULT: destruct_3
15 ; CHECK-DEFAULT: destruct_2
16 ; CHECK-DEFAULT: destruct_1
17 ; CHECK-DEFAULT: .section .dtors.64535,"aw",@progbits
18 ; CHECK-DEFAULT: .long destruct_1
19 ; CHECK-DEFAULT: .section .dtors.63535,"aw",@progbits
20 ; CHECK-DEFAULT: .long destruct_2
21 ; CHECK-DEFAULT: .section .dtors.62535,"aw",@progbits
22 ; CHECK-DEFAULT: .long destruct_3
1723
18 ; CHECK-DARWIN: destruct_1
19 ; CHECK-DARWIN: destruct_2
20 ; CHECK-DARWIN: destruct_3
24 ; CHECK-DARWIN: .long _destruct_1
25 ; CHECK-DARWIN-NEXT: .long _destruct_2
26 ; CHECK-DARWIN-NEXT: .long _destruct_3
2127
2228 declare void @construct_1()
2329 declare void @construct_2()