llvm.org GIT mirror llvm / d6b43a3
Move the support for using .init_array from ARM to the generic TargetLoweringObjectFileELF. Use this to support it on X86. Unlike ARM, on X86 it is not easy to find out if .init_array should be used or not, so the decision is made via TargetOptions and defaults to off. Add a command line option to llc that enables it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158692 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 8 years ago
10 changed file(s) with 99 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
3232
3333
3434 class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
35 bool UseInitArray;
36
3537 public:
3638 virtual ~TargetLoweringObjectFileELF() {}
3739
6567 getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
6668 MachineModuleInfo *MMI) const;
6769
70 void InitializeELF(bool UseInitArray_);
6871 virtual const MCSection *
6972 getStaticCtorSection(unsigned Priority = 65535) const;
7073 virtual const MCSection *
4242 StackAlignmentOverride(0), RealignStack(true),
4343 DisableJumpTables(false), EnableFastISel(false),
4444 PositionIndependentExecutable(false), EnableSegmentedStacks(false),
45 TrapFuncName(""), FloatABIType(FloatABI::Default)
45 UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default)
4646 {}
4747
4848 /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
171171
172172 unsigned EnableSegmentedStacks : 1;
173173
174 /// UseInitArray - Use .init_array instead of .ctors for static
175 /// constructors.
176 unsigned UseInitArray : 1;
177
174178 /// getTrapFunctionName - If this returns a non-empty string, this means
175179 /// isel should lower Intrinsic::trap to a call to the specified function
176180 /// name instead of an ISD::TRAP node.
348348 if (Priority == 65535)
349349 return StaticCtorSection;
350350
351 std::string Name = std::string(".ctors.") + utostr(65535 - Priority);
352 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
353 ELF::SHF_ALLOC |ELF::SHF_WRITE,
354 SectionKind::getDataRel());
351 if (UseInitArray) {
352 std::string Name = std::string(".init_array.") + utostr(Priority);
353 return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY,
354 ELF::SHF_ALLOC | ELF::SHF_WRITE,
355 SectionKind::getDataRel());
356 } else {
357 std::string Name = std::string(".ctors.") + utostr(65535 - Priority);
358 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
359 ELF::SHF_ALLOC |ELF::SHF_WRITE,
360 SectionKind::getDataRel());
361 }
355362 }
356363
357364 const MCSection *
361368 if (Priority == 65535)
362369 return StaticDtorSection;
363370
364 std::string Name = std::string(".dtors.") + utostr(65535 - Priority);
365 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
366 ELF::SHF_ALLOC |ELF::SHF_WRITE,
367 SectionKind::getDataRel());
371 if (UseInitArray) {
372 std::string Name = std::string(".fini_array.") + utostr(Priority);
373 return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY,
374 ELF::SHF_ALLOC | ELF::SHF_WRITE,
375 SectionKind::getDataRel());
376 } else {
377 std::string Name = std::string(".dtors.") + utostr(65535 - Priority);
378 return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
379 ELF::SHF_ALLOC |ELF::SHF_WRITE,
380 SectionKind::getDataRel());
381 }
382 }
383
384 void
385 TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {
386 UseInitArray = UseInitArray_;
387 if (!UseInitArray)
388 return;
389
390 StaticCtorSection =
391 getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
392 ELF::SHF_WRITE |
393 ELF::SHF_ALLOC,
394 SectionKind::getDataRel());
395 StaticDtorSection =
396 getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,
397 ELF::SHF_WRITE |
398 ELF::SHF_ALLOC,
399 SectionKind::getDataRel());
368400 }
369401
370402 //===----------------------------------------------------------------------===//
2323
2424 void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
2525 const TargetMachine &TM) {
26 bool isAAPCS_ABI = TM.getSubtarget().isAAPCS_ABI();
2627 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
27 isAAPCS_ABI = TM.getSubtarget().isAAPCS_ABI();
28 InitializeELF(isAAPCS_ABI);
2829
2930 if (isAAPCS_ABI) {
30 StaticCtorSection =
31 getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY,
32 ELF::SHF_WRITE |
33 ELF::SHF_ALLOC,
34 SectionKind::getDataRel());
35 StaticDtorSection =
36 getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY,
37 ELF::SHF_WRITE |
38 ELF::SHF_ALLOC,
39 SectionKind::getDataRel());
4031 LSDASection = NULL;
4132 }
4233
4637 0,
4738 SectionKind::getMetadata());
4839 }
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;
2322 public:
2423 ARMElfTargetObjectFile() :
2524 TargetLoweringObjectFileELF(),
3130 virtual const MCSection *getAttributesSection() const {
3231 return AttributesSection;
3332 }
34
35 const MCSection * getStaticCtorSection(unsigned Priority) const;
36 const MCSection * getStaticDtorSection(unsigned Priority) const;
3733 };
3834
3935 } // end namespace llvm
139139 return new TargetLoweringObjectFileMachO();
140140 }
141141
142 if (Subtarget->isTargetLinux())
143 return new X86LinuxTargetObjectFile();
142144 if (Subtarget->isTargetELF())
143145 return new TargetLoweringObjectFileELF();
144146 if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho())
88
99 #include "X86TargetObjectFile.h"
1010 #include "X86TargetMachine.h"
11 #include "llvm/ADT/StringExtras.h"
1112 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
1213 #include "llvm/MC/MCContext.h"
1314 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCSectionELF.h"
1416 #include "llvm/MC/MCSectionMachO.h"
1517 #include "llvm/Target/Mangler.h"
1618 #include "llvm/Support/Dwarf.h"
19 #include "llvm/Support/ELF.h"
1720 using namespace llvm;
1821 using namespace dwarf;
1922
4144 MachineModuleInfo *MMI) const {
4245 return Mang->getSymbol(GV);
4346 }
47
48 void
49 X86LinuxTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) {
50 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
51 InitializeELF(TM.Options.UseInitArray);
52 }
3131 MachineModuleInfo *MMI) const;
3232 };
3333
34 /// X86LinuxTargetObjectFile - This implementation is used for linux x86
35 /// and x86-64.
36 class X86LinuxTargetObjectFile : public TargetLoweringObjectFileELF {
37 virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
38 };
39
3440 } // end namespace llvm
3541
3642 #endif
0 ; RUN: llc < %s | FileCheck --check-prefix=CTOR %s
1 ; RUN: llc -use-init-array < %s | FileCheck --check-prefix=INIT-ARRAY %s
2 @llvm.global_ctors = appending global [2 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }, { i32, void ()* } { i32 15, void ()* @g }]
3
4 define void @f() {
5 entry:
6 ret void
7 }
8
9 define void @g() {
10 entry:
11 ret void
12 }
13
14 ; CTOR: .section .ctors.65520,"aw",@progbits
15 ; CTOR-NEXT: .align 8
16 ; CTOR-NEXT: .quad g
17 ; CTOR-NEXT: .section .ctors,"aw",@progbits
18 ; CTOR-NEXT: .align 8
19 ; CTOR-NEXT: .quad f
20
21 ; INIT-ARRAY: .section .init_array.15,"aw",@init_array
22 ; INIT-ARRAY-NEXT: .align 8
23 ; INIT-ARRAY-NEXT: .quad g
24 ; INIT-ARRAY-NEXT: .section .init_array,"aw",@init_array
25 ; INIT-ARRAY-NEXT: .align 8
26 ; INIT-ARRAY-NEXT: .quad f
243243 cl::desc("Use segmented stacks if possible."),
244244 cl::init(false));
245245
246 static cl::opt
247 UseInitArray("use-init-array",
248 cl::desc("Use .init_array instead of .ctors."),
249 cl::init(false));
246250
247251 // GetFileNameRoot - Helper function to get the basename of a filename.
248252 static inline std::string
417421 Options.TrapFuncName = TrapFuncName;
418422 Options.PositionIndependentExecutable = EnablePIE;
419423 Options.EnableSegmentedStacks = SegmentedStacks;
424 Options.UseInitArray = UseInitArray;
420425
421426 std::auto_ptr
422427 target(TheTarget->createTargetMachine(TheTriple.getTriple(),