forked from OSchip/llvm-project
Properly emit ctors / dtors with priorities into desired sections
and let linker handle the rest. This finally fixes PR5329 llvm-svn: 148990
This commit is contained in:
parent
f7f102f81a
commit
7722a2d4e3
|
@ -471,7 +471,7 @@ namespace llvm {
|
|||
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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,10 +22,6 @@ namespace llvm {
|
|||
class MCContext;
|
||||
class MCSection;
|
||||
class Triple;
|
||||
|
||||
namespace Structors {
|
||||
enum OutputOrder { None, PriorityOrder, ReversePriorityOrder };
|
||||
}
|
||||
|
||||
class MCObjectFileInfo {
|
||||
protected:
|
||||
|
@ -167,11 +163,6 @@ protected:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
return EHFrameSection;
|
||||
}
|
||||
|
||||
Structors::OutputOrder getStructorOutputOrder() const {
|
||||
return StructorOutputOrder;
|
||||
}
|
||||
|
||||
private:
|
||||
enum Environment { IsMachO, IsELF, IsCOFF };
|
||||
Environment Env;
|
||||
|
|
|
@ -121,7 +121,18 @@ public:
|
|||
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,
|
||||
|
|
|
@ -1207,12 +1207,8 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
|
|||
|
||||
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 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
|
|||
}
|
||||
|
||||
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 @@ void AsmPrinter::EmitLLVMUsedList(const Constant *List) {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ static bool priority_order(const Structor& lhs, const Structor& rhs) {
|
|||
|
||||
/// 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 @@ void AsmPrinter::EmitXXStructorList(const Constant *List) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -340,6 +340,32 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
|
|||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -31,8 +31,6 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
|
|||
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 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
|
|||
}
|
||||
}
|
||||
|
||||
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::InitELFMCObjectFileInfo(Triple T) {
|
|||
|
||||
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
|
||||
// COFF
|
||||
StructorOutputOrder = Structors::ReversePriorityOrder;
|
||||
|
||||
TextSection =
|
||||
Ctx->getCOFFSection(".text",
|
||||
COFF::IMAGE_SCN_CNT_CODE |
|
||||
|
|
|
@ -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 @@ using namespace dwarf;
|
|||
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 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
|
|||
ELF::SHF_WRITE |
|
||||
ELF::SHF_ALLOC,
|
||||
SectionKind::getDataRel());
|
||||
StructorOutputOrder = Structors::PriorityOrder;
|
||||
LSDASection = NULL;
|
||||
}
|
||||
|
||||
|
@ -46,3 +47,33 @@ 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());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ class TargetMachine;
|
|||
class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
|
||||
protected:
|
||||
const MCSection *AttributesSection;
|
||||
bool isAAPCS_ABI;
|
||||
public:
|
||||
ARMElfTargetObjectFile() :
|
||||
TargetLoweringObjectFileELF(),
|
||||
|
@ -31,6 +32,9 @@ public:
|
|||
virtual const MCSection *getAttributesSection() const {
|
||||
return AttributesSection;
|
||||
}
|
||||
|
||||
const MCSection * getStaticCtorSection(unsigned Priority) const;
|
||||
const MCSection * getStaticDtorSection(unsigned Priority) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -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 } ]
|
||||
|
|
|
@ -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",@progbits
|
||||
; CHECK-DEFAULT: .long construct_1
|
||||
; CHECK-DEFAULT: .section .ctors.63535,"aw",@progbits
|
||||
; CHECK-DEFAULT: .long construct_2
|
||||
; CHECK-DEFAULT: .section .ctors.62535,"aw",@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",@progbits
|
||||
; CHECK-DEFAULT: .long destruct_1
|
||||
; CHECK-DEFAULT: .section .dtors.63535,"aw",@progbits
|
||||
; CHECK-DEFAULT: .long destruct_2
|
||||
; CHECK-DEFAULT: .section .dtors.62535,"aw",@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()
|
||||
|
|
Loading…
Reference in New Issue