1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

Drop prelink support.

The way prelink used to work was

* The compiler decides if a given section only has relocations that
are know to point to the same DSO. If so, it names it
.data.rel.ro.local<something>.
* The static linker puts all of these together.
* The prelinker program assigns addresses to each library and resolves
the local relocations.

There are many problems with this:
* It is incompatible with address space randomization.
* The information passed by the compiler is redundant. The linker
knows if a given relocation is in the same DSO or not. If could sort
by that if so desired.
* There are newer ways of speeding up DSO (gnu hash for example).
* Even if we want to implement this again in the compiler, the previous
  implementation is pretty broken. It talks about relocations that are
  "resolved by the static linker". If they are resolved, there are none
  left for the prelinker. What one needs to track is if an expression
  will require only dynamic relocations that point to the same DSO.

At this point it looks like the prelinker is an historical curiosity.
For example, fedora has retired it because it failed to build for two
releases
(http://pkgs.fedoraproject.org/cgit/prelink.git/commit/?id=eb43100a8331d91c801ee3dcdb0a0bb9babfdc1f)

This patch removes support for it. That is, it stops printing the
".local" sections.

llvm-svn: 253280
This commit is contained in:
Rafael Espindola 2015-11-17 00:51:23 +00:00
parent 088a172bf6
commit 47008fdea7
22 changed files with 61 additions and 203 deletions

View File

@ -46,12 +46,6 @@ public:
///
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;
@ -106,18 +100,10 @@ public:
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;
};

View File

@ -86,26 +86,12 @@ public:
/// 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

View File

@ -150,9 +150,7 @@ protected:
// ELF specific sections.
MCSection *DataRelSection;
const MCSection *DataRelLocalSection;
MCSection *DataRelROSection;
MCSection *DataRelROLocalSection;
MCSection *MergeableConst4Section;
MCSection *MergeableConst8Section;
MCSection *MergeableConst16Section;
@ -279,11 +277,7 @@ public:
// 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;
}

View File

@ -104,12 +104,6 @@ class SectionKind {
/// 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.
@ -121,15 +115,7 @@ class SectionKind {
/// 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:
@ -179,21 +165,13 @@ 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) {
@ -225,12 +203,8 @@ public:
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

View File

@ -357,10 +357,10 @@ void AsmPrinter::EmitEmulatedTLSControlVariable(const GlobalVariable *GV,
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
@ -390,8 +390,6 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *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");

View File

@ -816,42 +816,26 @@ Type *MachineConstantPoolEntry::getType() const {
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() {

View File

@ -235,12 +235,8 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
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";
}
@ -362,7 +358,6 @@ MCSection *TargetLoweringObjectFileELF::getSectionForConstant(
if (Kind.isReadOnly())
return ReadOnlySection;
if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
return DataRelROSection;
}

View File

@ -414,16 +414,13 @@ bool Constant::isConstantUsed() const {
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
@ -432,20 +429,18 @@ Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {
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;
}

View File

@ -455,15 +455,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
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, "");

View File

@ -51,8 +51,6 @@ public:
&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");
@ -123,12 +121,6 @@ public:
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 |

View File

@ -102,8 +102,6 @@ public:
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;

View File

@ -42,9 +42,7 @@ MCSection *PPC64LinuxTargetObjectFile::SelectSectionForGlobal(
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();
}

View File

@ -26,21 +26,6 @@ SystemZConstantPoolValue::Create(const GlobalValue *GV,
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;

View File

@ -43,7 +43,6 @@ public:
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;

View File

@ -169,14 +169,13 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
// 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())) {
@ -207,20 +206,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
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
@ -243,15 +229,9 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
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

View File

@ -47,7 +47,7 @@ entry:
; 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

View File

@ -39,7 +39,7 @@ entry:
; 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
@ -49,7 +49,7 @@ entry:
; 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

View File

@ -30,13 +30,13 @@ entry:
; 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
@ -58,7 +58,7 @@ entry:
; 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

View File

@ -103,7 +103,7 @@ entry:
;;;;; 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
@ -114,7 +114,7 @@ entry:
; 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
@ -136,7 +136,7 @@ entry:
;;;;; 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
@ -147,7 +147,7 @@ entry:
; 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

View File

@ -100,7 +100,7 @@ entry:
;;;;; 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
@ -116,7 +116,7 @@ entry:
;;;;; 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

View File

@ -55,7 +55,7 @@ entry:
; 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
@ -65,7 +65,7 @@ entry:
; 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
@ -95,7 +95,7 @@ entry:
; 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

View File

@ -32,15 +32,15 @@ target triple = "x86_64-unknown-linux-gnu"
; 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: