///
Type *getType() const { return Ty; }
- /// getRelocationInfo - This method classifies the entry according to
- /// whether or not it may generate a relocation entry. This must be
- /// conservative, so if it might codegen to a relocatable entry, it should say
- /// so. The return values are the same as Constant::getRelocationInfo().
- virtual unsigned getRelocationInfo() const = 0;
-
virtual int getExistingMachineCPValue(MachineConstantPool *CP,
unsigned Alignment) = 0;
Type *getType() const;
- /// getRelocationInfo - This method classifies the entry according to
- /// whether or not it may generate a relocation entry. This must be
- /// conservative, so if it might codegen to a relocatable entry, it should say
- /// so. The return values are:
- ///
- /// 0: This constant pool entry is guaranteed to never have a relocation
- /// applied to it (because it holds a simple constant like '4').
- /// 1: This entry has relocations, but the entries are guaranteed to be
- /// resolvable by the static linker, so the dynamic linker will never see
- /// them.
- /// 2: This entry may have arbitrary relocations.
- unsigned getRelocationInfo() const;
+ /// This method classifies the entry according to whether or not it may
+ /// generate a relocation entry. This must be conservative, so if it might
+ /// codegen to a relocatable entry, it should say so.
+ bool needsRelocation() const;
SectionKind getSectionKind(const DataLayout *DL) const;
};
/// exprs and other dangling things.
bool isConstantUsed() const;
- enum PossibleRelocationsTy {
- NoRelocation = 0,
- LocalRelocation = 1,
- GlobalRelocations = 2
- };
-
/// This method classifies the entry according to whether or not it may
/// generate a relocation entry. This must be conservative, so if it might
- /// codegen to a relocatable entry, it should say so. The return values are:
- ///
- /// NoRelocation: This constant pool entry is guaranteed to never have a
- /// relocation applied to it (because it holds a simple constant like
- /// '4').
- /// LocalRelocation: This entry has relocations, but the entries are
- /// guaranteed to be resolvable by the static linker, so the dynamic
- /// linker will never see them.
- /// GlobalRelocations: This entry may have arbitrary relocations.
+ /// codegen to a relocatable entry, it should say so.
///
/// FIXME: This really should not be in IR.
- PossibleRelocationsTy getRelocationInfo() const;
+ bool needsRelocation() const;
/// getAggregateElement - For aggregates (struct/array/vector) return the
/// constant that corresponds to the specified element if possible, or null if
// ELF specific sections.
MCSection *DataRelSection;
- const MCSection *DataRelLocalSection;
MCSection *DataRelROSection;
- MCSection *DataRelROLocalSection;
MCSection *MergeableConst4Section;
MCSection *MergeableConst8Section;
MCSection *MergeableConst16Section;
// ELF specific sections.
MCSection *getDataRelSection() const { return DataRelSection; }
- const MCSection *getDataRelLocalSection() const {
- return DataRelLocalSection;
- }
MCSection *getDataRelROSection() const { return DataRelROSection; }
- MCSection *getDataRelROLocalSection() const { return DataRelROLocalSection; }
const MCSection *getMergeableConst4Section() const {
return MergeableConst4Section;
}
/// globals.
DataRel,
- /// DataRelLocal - This is writeable data that has a non-zero
- /// initializer and has relocations in it, but all of the
- /// relocations are known to be within the final linked image
- /// the global is linked into.
- DataRelLocal,
-
/// DataNoRel - This is writeable data that has a non-zero
/// initializer, but whose initializer is known to have no
/// relocations.
/// can write to them. If it chooses to, the dynamic linker can
/// mark the pages these globals end up on as read-only after it is
/// done with its relocation phase.
- ReadOnlyWithRel,
-
- /// ReadOnlyWithRelLocal - This is data that is readonly by the
- /// program, but must be writeable so that the dynamic linker
- /// can perform relocations in it. This is used when we know
- /// that all the relocations are to globals in this final
- /// linked image.
- ReadOnlyWithRelLocal
-
+ ReadOnlyWithRel
} K : 8;
public:
bool isCommon() const { return K == Common; }
bool isDataRel() const {
- return K == DataRel || K == DataRelLocal || K == DataNoRel;
- }
-
- bool isDataRelLocal() const {
- return K == DataRelLocal || K == DataNoRel;
+ return K == DataRel || K == DataNoRel;
}
bool isDataNoRel() const { return K == DataNoRel; }
bool isReadOnlyWithRel() const {
- return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
- }
-
- bool isReadOnlyWithRelLocal() const {
- return K == ReadOnlyWithRelLocal;
+ return K == ReadOnlyWithRel;
}
private:
static SectionKind get(Kind K) {
static SectionKind getBSSExtern() { return get(BSSExtern); }
static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); }
- static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); }
static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
- static SectionKind getReadOnlyWithRelLocal(){
- return get(ReadOnlyWithRelLocal);
- }
};
} // end namespace llvm
bool AllZeroInitValue) {
// If there is init value, use .data.rel.local section;
// otherwise use the .data section.
- MCSection *TLSVarSection = const_cast<MCSection*>(
- (GV->hasInitializer() && !AllZeroInitValue)
- ? getObjFileLowering().getDataRelLocalSection()
- : getObjFileLowering().getDataSection());
+ MCSection *TLSVarSection =
+ const_cast<MCSection *>((GV->hasInitializer() && !AllZeroInitValue)
+ ? getObjFileLowering().getDataRelSection()
+ : getObjFileLowering().getDataSection());
OutStreamer->SwitchSection(TLSVarSection);
MCSymbol *GVSym = getSymbol(GV);
EmitLinkage(GV, EmittedSym); // same linkage as GV
bool IsEmuTLSVar =
GV->getThreadLocalMode() != llvm::GlobalVariable::NotThreadLocal &&
TM.Options.EmulatedTLS;
- assert((!IsEmuTLSVar || getObjFileLowering().getDataRelLocalSection()) &&
- "Need relocatable local section for emulated TLS variables");
assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&
"No emulated TLS variables in the common section");
return Val.ConstVal->getType();
}
-
-unsigned MachineConstantPoolEntry::getRelocationInfo() const {
+bool MachineConstantPoolEntry::needsRelocation() const {
if (isMachineConstantPoolEntry())
- return Val.MachineCPVal->getRelocationInfo();
- return Val.ConstVal->getRelocationInfo();
+ return true;
+ return Val.ConstVal->needsRelocation();
}
SectionKind
MachineConstantPoolEntry::getSectionKind(const DataLayout *DL) const {
- SectionKind Kind;
- switch (getRelocationInfo()) {
+ if (needsRelocation())
+ return SectionKind::getReadOnlyWithRel();
+ switch (DL->getTypeAllocSize(getType())) {
+ case 4:
+ return SectionKind::getMergeableConst4();
+ case 8:
+ return SectionKind::getMergeableConst8();
+ case 16:
+ return SectionKind::getMergeableConst16();
default:
- llvm_unreachable("Unknown section kind");
- case Constant::GlobalRelocations:
- Kind = SectionKind::getReadOnlyWithRel();
- break;
- case Constant::LocalRelocation:
- Kind = SectionKind::getReadOnlyWithRelLocal();
- break;
- case Constant::NoRelocation:
- switch (DL->getTypeAllocSize(getType())) {
- case 4:
- Kind = SectionKind::getMergeableConst4();
- break;
- case 8:
- Kind = SectionKind::getMergeableConst8();
- break;
- case 16:
- Kind = SectionKind::getMergeableConst16();
- break;
- default:
- Kind = SectionKind::getReadOnly();
- break;
- }
+ return SectionKind::getReadOnly();
}
- return Kind;
}
MachineConstantPool::~MachineConstantPool() {
return ".tbss";
if (Kind.isDataNoRel())
return ".data";
- if (Kind.isDataRelLocal())
- return ".data.rel.local";
if (Kind.isDataRel())
return ".data.rel";
- if (Kind.isReadOnlyWithRelLocal())
- return ".data.rel.ro.local";
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
return ".data.rel.ro";
}
if (Kind.isReadOnly())
return ReadOnlySection;
- if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
return DataRelROSection;
}
return false;
}
-Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
- if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
- return LocalRelocation; // Local to this file/library.
- return GlobalRelocations; // Global reference.
- }
-
+bool Constant::needsRelocation() const {
+ if (isa<GlobalValue>(this))
+ return true; // Global reference.
+
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
- return BA->getFunction()->getRelocationInfo();
-
+ return BA->getFunction()->needsRelocation();
+
// While raw uses of blockaddress need to be relocated, differences between
// two of them don't when they are for labels in the same function. This is a
// common idiom when creating a table for the indirect goto extension, so we
if (CE->getOpcode() == Instruction::Sub) {
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
- if (LHS && RHS &&
- LHS->getOpcode() == Instruction::PtrToInt &&
+ if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
RHS->getOpcode() == Instruction::PtrToInt &&
isa<BlockAddress>(LHS->getOperand(0)) &&
isa<BlockAddress>(RHS->getOperand(0)) &&
cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
- cast<BlockAddress>(RHS->getOperand(0))->getFunction())
- return NoRelocation;
+ cast<BlockAddress>(RHS->getOperand(0))->getFunction())
+ return false;
}
- PossibleRelocationsTy Result = NoRelocation;
+ bool Result = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- Result = std::max(Result,
- cast<Constant>(getOperand(i))->getRelocationInfo());
+ Result |= cast<Constant>(getOperand(i))->needsRelocation();
return Result;
}
DataRelSection = Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE);
- DataRelLocalSection = Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC | ELF::SHF_WRITE);
-
DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE);
- DataRelROLocalSection = Ctx->getELFSection(
- ".data.rel.ro.local", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE);
-
MergeableConst4Section =
Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, "");
&ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
- addDirectiveHandler<
- &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local");
addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
ELF::SHF_WRITE,
SectionKind::getReadOnlyWithRel());
}
- bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC |
- ELF::SHF_WRITE,
- SectionKind::getReadOnlyWithRelLocal());
- }
bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC |
bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
- unsigned getRelocationInfo() const override { return 2; }
-
int getExistingMachineCPValue(MachineConstantPool *CP,
unsigned Alignment) override;
if (Kind.isReadOnly()) {
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
- if (GVar && GVar->isConstant() &&
- (GVar->getInitializer()->getRelocationInfo() ==
- Constant::GlobalRelocations))
+ if (GVar && GVar->isConstant() && GVar->getInitializer()->needsRelocation())
Kind = SectionKind::getReadOnlyWithRel();
}
return new SystemZConstantPoolValue(GV, Modifier);
}
-unsigned SystemZConstantPoolValue::getRelocationInfo() const {
- switch (Modifier) {
- case SystemZCP::TLSGD:
- case SystemZCP::TLSLDM:
- case SystemZCP::DTPOFF:
- // May require a dynamic relocation.
- return 2;
- case SystemZCP::NTPOFF:
- // May require a relocation, but the relocations are always resolved
- // by the static linker.
- return 1;
- }
- llvm_unreachable("Unknown modifier");
-}
-
int SystemZConstantPoolValue::
getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) {
unsigned AlignMask = Alignment - 1;
Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier);
// Override MachineConstantPoolValue.
- unsigned getRelocationInfo() const override;
int getExistingMachineCPValue(MachineConstantPool *CP,
unsigned Alignment) override;
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
// If the initializer for the global contains something that requires a
// relocation, then we may have to drop this into a writable data section
// even though it is marked const.
- switch (C->getRelocationInfo()) {
- case Constant::NoRelocation:
+ if (!C->needsRelocation()) {
// If the global is required to have a unique address, it can't be put
// into a mergable section: just drop it into the general read-only
// section instead.
if (!GVar->hasUnnamedAddr())
return SectionKind::getReadOnly();
-
+
// If initializer is a null-terminated string, put it in a "cstring"
// section of the right width.
if (ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
return SectionKind::getReadOnly();
}
- case Constant::LocalRelocation:
- // In static relocation model, the linker will resolve all addresses, so
- // the relocation entries will actually be constants by the time the app
- // starts up. However, we can't put this into a mergable section, because
- // the linker doesn't take relocations into consideration when it tries to
- // merge entries in the section.
- if (ReloModel == Reloc::Static)
- return SectionKind::getReadOnly();
-
- // Otherwise, the dynamic linker needs to fix it up, put it in the
- // writable data.rel.local section.
- return SectionKind::getReadOnlyWithRelLocal();
-
- case Constant::GlobalRelocations:
+ } else {
// In static relocation model, the linker will resolve all addresses, so
// the relocation entries will actually be constants by the time the app
// starts up. However, we can't put this into a mergable section, because
if (ReloModel == Reloc::Static)
return SectionKind::getDataNoRel();
- switch (C->getRelocationInfo()) {
- case Constant::NoRelocation:
- return SectionKind::getDataNoRel();
- case Constant::LocalRelocation:
- return SectionKind::getDataRelLocal();
- case Constant::GlobalRelocations:
+ if (C->needsRelocation())
return SectionKind::getDataRel();
- }
- llvm_unreachable("Invalid relocation");
+ return SectionKind::getDataNoRel();
}
/// This method computes the appropriate section to emit the specified global
; ARM_64: .section .rodata,
; ARM_64-LABEL: __emutls_t.external_y:
; ARM_64-NEXT: .byte 7
-; ARM_64: .section .data.rel.local
+; ARM_64: .section .data.rel
; ARM_64: .align 3
; ARM_64-LABEL: __emutls_v.internal_y:
; ARM_64-NEXT: .xword 8
; ARM_32: .long __emutls_v.internal_y
; ARM_32-NOT: __emutls_t.external_x
; ARM_32-NOT: __emutls_v.external_x:
-; ARM_32: .section .data.rel.local
+; ARM_32: .section .data.rel
; ARM_32: .align 2
; ARM_32-LABEL: __emutls_v.external_y:
; ARM_32-NEXT: .long 1
; ARM_32: .section .rodata,
; ARM_32-LABEL: __emutls_t.external_y:
; ARM_32-NEXT: .byte 7
-; ARM_32: .section .data.rel.local
+; ARM_32: .section .data.rel
; ARM_32: .align 2
; ARM_32-LABEL: __emutls_v.internal_y:
; ARM_32-NEXT: .long 8
; MIPS_32: lw {{.+}}call16(__emutls_get_address
; MIPS_32-NOT: __emutls_t.external_x
; MIPS_32-NOT: __emutls_v.external_x:
-; MIPS_32: .section .data.rel.local
+; MIPS_32: .section .data.rel
; MIPS_32: .align 2
; MIPS_32-LABEL: __emutls_v.external_y:
; MIPS_32: .section .rodata,
; MIPS_32-LABEL: __emutls_t.external_y:
; MIPS_32-NEXT: .byte 7
-; MIPS_32: .section .data.rel.local
+; MIPS_32: .section .data.rel
; MIPS_32: .align 2
; MIPS_32-LABEL: __emutls_v.internal_y:
; MIPS_32-NEXT: .4byte 8
; MIPS_64: .section .rodata,
; MIPS_64-LABEL: __emutls_t.external_y:
; MIPS_64-NEXT: .byte 7
-; MIPS_64: .section .data.rel.local
+; MIPS_64: .section .data.rel
; MIPS_64: .align 3
; MIPS_64-LABEL: __emutls_v.internal_y:
; MIPS_64-NEXT: .8byte 8
;;;;; 32-bit targets
-; X32: .section .data.rel.local,
+; X32: .section .data.rel,
; X32-LABEL: __emutls_v.i:
; X32-NEXT: .long 4
; X32-NEXT: .long 4
; X32-LABEL: __emutls_t.i:
; X32-NEXT: .long 15
-; X32: .section .data.rel.local,
+; X32: .section .data.rel,
; X32-LABEL: __emutls_v.j:
; X32-NEXT: .long 4
; X32-NEXT: .long 4
;;;;; 64-bit targets
-; X64: .section .data.rel.local,
+; X64: .section .data.rel,
; X64-LABEL: __emutls_v.i:
; X64-NEXT: .quad 4
; X64-NEXT: .quad 4
; X64-LABEL: __emutls_t.i:
; X64-NEXT: .long 15
-; X64: .section .data.rel.local,
+; X64: .section .data.rel,
; X64-LABEL: __emutls_v.j:
; X64-NEXT: .quad 4
; X64-NEXT: .quad 4
;;;;; 32-bit targets
-; X32: .section .data.rel.local,
+; X32: .section .data.rel,
; X32-LABEL: __emutls_v.i:
; X32-NEXT: .long 4
; X32-NEXT: .long 4
;;;;; 64-bit targets
-; X64: .section .data.rel.local,
+; X64: .section .data.rel,
; X64-LABEL: __emutls_v.i:
; X64-NEXT: .quad 4
; X64-NEXT: .quad 4
; X86_32: calll __emutls_get_address
; X86_32-NOT: __emutls_t.external_x
; X86_32-NOT: __emutls_v.external_x:
-; X86_32: .section .data.rel.local
+; X86_32: .section .data.rel
; X86_32: .align 4
; X86_32-LABEL: __emutls_v.external_y:
; X86_32-NEXT: .long 1
; X86_32: .section .rodata,
; X86_32-LABEL: __emutls_t.external_y:
; X86_32-NEXT: .byte 7
-; X86_32: .section .data.rel.local
+; X86_32: .section .data.rel
; X86_32: .align 4
; X86_32-LABEL: __emutls_v.internal_y:
; X86_32-NEXT: .long 8
; X86_64: .section .rodata,
; X86_64-LABEL: __emutls_t.external_y:
; X86_64-NEXT: .byte 7
-; X86_64: .section .data.rel.local
+; X86_64: .section .data.rel
; X86_64: .align 8
; X86_64-LABEL: __emutls_v.internal_y:
; X86_64-NEXT: .quad 8
; PIC: .section .rodata.cst16,"aM",@progbits,16
; PIC: e:
; PIC: e1:
-; PIC: .section .data.rel.ro.local,"aw",@progbits
+; PIC: .section .data.rel.ro,"aw",@progbits
; PIC: p:
; PIC: t:
-; PIC: .section .data.rel.ro,"aw",@progbits
+; PIC-NOT: .section
; PIC: p1:
; PIC: t1:
; PIC: .section .data.rel,"aw",@progbits
; PIC: p2:
; PIC: t2:
-; PIC: .section .data.rel.local,"aw",@progbits
+; PIC-NOT: .section
; PIC: p3:
; PIC: t3: