diff options
author | Logan Chien <loganchien@google.com> | 2012-08-30 17:13:39 +0800 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2012-10-15 13:30:38 +0800 |
commit | 01b00ca302b92efedaa7287e8e9c58507904914a (patch) | |
tree | 5d2f956f8563cb8ce56fefd624e25592d6c84a0e | |
parent | 7cf19fd9bc27a52a7504a663ebeb5e96f1cc4ad6 (diff) | |
download | llvm-01b00ca302b92efedaa7287e8e9c58507904914a.tar.gz |
Backport .init_array/.fini_array work.
Android requires ".init_array" and ".fini_array" for
X86/MIPS as well, regardless the gcc version. This
patch is basing on following patches:
commit d6b43a317e71246380db55a50b799b062b53cdce
Author: Rafael Espindola <rafael.espindola@gmail.com>
Date: Tue Jun 19 00:48:28 2012 +0000
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.
commit 8af669f2f1d92436fe6dc43144bb084a620e7516
Author: Rafael Espindola <rafael.espindola@gmail.com>
Date: Tue Jun 19 01:26:10 2012 +0000
Add a -fuse-init-array option to cc1 and map to the UseInitArray target
option. On the driver, check if we are using libraries from gcc 4.7 or newer
and if so pass -fuse-init-array to the frontend.
The crtbegin*.o files in gcc 4.7 no longer call the constructors listed in
.ctors, so we have to use .init_array.
-rw-r--r-- | include/llvm/CodeGen/TargetLoweringObjectFileImpl.h | 3 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 48 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.cpp | 43 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetObjectFile.cpp | 1 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetObjectFile.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetObjectFile.h | 6 | ||||
-rw-r--r-- | test/CodeGen/X86/constructor.ll | 27 | ||||
-rw-r--r-- | tools/llc/llc.cpp | 5 |
11 files changed, 100 insertions, 54 deletions
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 5a4213625ba..9849e92f7de 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -33,6 +33,8 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { + bool UseInitArray; + public: virtual ~TargetLoweringObjectFileELF() {} @@ -66,6 +68,7 @@ public: getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const; + void InitializeELF(bool UseInitArray_); virtual const MCSection * getStaticCtorSection(unsigned Priority = 65535) const; virtual const MCSection * diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 12a27573153..bc60673589f 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -43,7 +43,7 @@ namespace llvm { StackAlignmentOverride(0), RealignStack(true), DisableJumpTables(false), EnableFastISel(false), PositionIndependentExecutable(false), EnableSegmentedStacks(false), - TrapFuncName(""), FloatABIType(FloatABI::Default) + UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -172,6 +172,10 @@ namespace llvm { unsigned EnableSegmentedStacks : 1; + /// UseInitArray - Use .init_array instead of .ctors for static + /// constructors. + unsigned UseInitArray : 1; + /// getTrapFunctionName - If this returns a non-empty string, this means /// isel should lower Intrinsic::trap to a call to the specified function /// name instead of an ISD::TRAP node. diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 9925185be12..3660cf7d84e 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -349,10 +349,17 @@ TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const { 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()); + if (UseInitArray) { + 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()); + } else { + 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 * @@ -362,10 +369,35 @@ TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const { 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()); + if (UseInitArray) { + 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()); + } else { + std::string Name = std::string(".dtors.") + utostr(65535 - Priority); + return getContext().getELFSection(Name, ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRel()); + } +} + +void +TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { + UseInitArray = UseInitArray_; + if (!UseInitArray) + return; + + StaticCtorSection = + getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, + SectionKind::getDataRel()); + StaticDtorSection = + getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, + SectionKind::getDataRel()); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp index a5ea1c202e2..3d85ca7d699 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -24,20 +24,11 @@ using namespace dwarf; void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { + bool isAAPCS_ABI = TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI(); TargetLoweringObjectFileELF::Initialize(Ctx, TM); - isAAPCS_ABI = TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI(); + InitializeELF(isAAPCS_ABI); if (isAAPCS_ABI) { - StaticCtorSection = - getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); - StaticDtorSection = - getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); LSDASection = NULL; } @@ -47,33 +38,3 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, 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()); -} diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h index ff210604148..c6a7261439d 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.h +++ b/lib/Target/ARM/ARMTargetObjectFile.h @@ -20,7 +20,6 @@ class TargetMachine; class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF { protected: const MCSection *AttributesSection; - bool isAAPCS_ABI; public: ARMElfTargetObjectFile() : TargetLoweringObjectFileELF(), @@ -32,9 +31,6 @@ public: virtual const MCSection *getAttributesSection() const { return AttributesSection; } - - const MCSection * getStaticCtorSection(unsigned Priority) const; - const MCSection * getStaticDtorSection(unsigned Priority) const; }; } // end namespace llvm diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp index 04dc60aa6b4..4ee79e19c95 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -26,6 +26,7 @@ SSThreshold("mips-ssection-threshold", cl::Hidden, void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); SmallDataSection = getContext().getELFSection(".sdata", ELF::SHT_PROGBITS, diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 04299f30080..eaebc595147 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -144,6 +144,8 @@ static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) { return new TargetLoweringObjectFileMachO(); } + if (Subtarget->isTargetLinux()) + return new X86LinuxTargetObjectFile(); if (Subtarget->isTargetELF()) return new TargetLoweringObjectFileELF(); if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho()) diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index 718f35ea84a..b8d673facc8 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -9,12 +9,15 @@ #include "X86TargetObjectFile.h" #include "X86TargetMachine.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Target/Mangler.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/ELF.h" using namespace llvm; using namespace dwarf; @@ -42,3 +45,9 @@ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const { return Mang->getSymbol(GV); } + +void +X86LinuxTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); +} diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h index a02a36809ef..7698b59d69a 100644 --- a/lib/Target/X86/X86TargetObjectFile.h +++ b/lib/Target/X86/X86TargetObjectFile.h @@ -32,6 +32,12 @@ namespace llvm { MachineModuleInfo *MMI) const; }; + /// X86LinuxTargetObjectFile - This implementation is used for linux x86 + /// and x86-64. + class X86LinuxTargetObjectFile : public TargetLoweringObjectFileELF { + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + }; + } // end namespace llvm #endif diff --git a/test/CodeGen/X86/constructor.ll b/test/CodeGen/X86/constructor.ll new file mode 100644 index 00000000000..f6dec160e91 --- /dev/null +++ b/test/CodeGen/X86/constructor.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s | FileCheck --check-prefix=CTOR %s +; RUN: llc -use-init-array < %s | FileCheck --check-prefix=INIT-ARRAY %s +@llvm.global_ctors = appending global [2 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }, { i32, void ()* } { i32 15, void ()* @g }] + +define void @f() { +entry: + ret void +} + +define void @g() { +entry: + ret void +} + +; CTOR: .section .ctors.65520,"aw",@progbits +; CTOR-NEXT: .align 8 +; CTOR-NEXT: .quad g +; CTOR-NEXT: .section .ctors,"aw",@progbits +; CTOR-NEXT: .align 8 +; CTOR-NEXT: .quad f + +; INIT-ARRAY: .section .init_array.15,"aw",@init_array +; INIT-ARRAY-NEXT: .align 8 +; INIT-ARRAY-NEXT: .quad g +; INIT-ARRAY-NEXT: .section .init_array,"aw",@init_array +; INIT-ARRAY-NEXT: .align 8 +; INIT-ARRAY-NEXT: .quad f diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index ceff8a6c8cc..9660e95f545 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -249,6 +249,10 @@ SegmentedStacks("segmented-stacks", cl::desc("Use segmented stacks if possible."), cl::init(false)); +static cl::opt<bool> +UseInitArray("use-init-array", + cl::desc("Use .init_array instead of .ctors."), + cl::init(false)); // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string @@ -448,6 +452,7 @@ int main(int argc, char **argv) { Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), |