Skip to content

Commit f0b2f69

Browse files
committed
[AIX][TLS] Generate .extern and .ref references to __tls_get_addr for local-exec accesses.
Compiling with TLS variables requires -pthread, but if the user omits this option, the compiler will not show any obvious indication during compilation that -pthread is needed for programs using TLS variables. Instead, the user will experience a segmentation fault when running programs with TLS variables in them and without specifying -pthread. This patch aims to generate .extern/.ref references to __tls_get_addr[DS] for local-exec accesses, in order to trigger an error from the linker to indicate that there is an undefined symbol to __tls_get_addr. Doing so will remind the user to compile/link with -pthread. Differential Revision: https://reviews.llvm.org/D151335
1 parent be0e42c commit f0b2f69

File tree

7 files changed

+217
-108
lines changed

7 files changed

+217
-108
lines changed

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ class PPCAsmPrinter : public AsmPrinter {
171171
TOCType_EHBlock
172172
};
173173

174+
// Controls whether or not to emit a .ref reference to __tls_get_addr.
175+
// This is currently used for TLS models that do not generate calls to
176+
// TLS functions, such as for the local-exec model on AIX 64-bit.
177+
bool HasRefGetTLSAddr = false;
178+
174179
MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym, TOCEntryType Type,
175180
MCSymbolRefExpr::VariantKind Kind =
176181
MCSymbolRefExpr::VariantKind::VK_None);
@@ -615,12 +620,17 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
615620
/// This helper function creates the TlsGetAddr MCSymbol for AIX. We will
616621
/// create the csect and use the qual-name symbol instead of creating just the
617622
/// external symbol.
618-
static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc) {
619-
StringRef SymName =
620-
MIOpc == PPC::GETtlsTpointer32AIX ? ".__get_tpointer" : ".__tls_get_addr";
623+
static MCSymbol *
624+
createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc,
625+
XCOFF::StorageMappingClass SMC = XCOFF::XMC_PR) {
626+
StringRef SymName;
627+
if (MIOpc == PPC::GETtlsTpointer32AIX)
628+
SymName = ".__get_tpointer";
629+
else
630+
SymName = (SMC == XCOFF::XMC_DS) ? "__tls_get_addr" : ".__tls_get_addr";
621631
return Ctx
622632
.getXCOFFSection(SymName, SectionKind::getText(),
623-
XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER))
633+
XCOFF::CsectProperties(SMC, XCOFF::XTY_ER))
624634
->getQualNameSymbol();
625635
}
626636

@@ -832,8 +842,11 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
832842
if (MO.getTargetFlags() & PPCII::MO_TPREL_FLAG) {
833843
assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n");
834844
TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());
835-
if (Model == TLSModel::LocalExec)
845+
if (Model == TLSModel::LocalExec) {
846+
if (IsPPC64)
847+
HasRefGetTLSAddr = true;
836848
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
849+
}
837850
if (Model == TLSModel::InitialExec)
838851
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
839852
llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
@@ -2862,6 +2875,22 @@ bool PPCAIXAsmPrinter::doFinalization(Module &M) {
28622875
OutStreamer->doFinalizationAtSectionEnd(
28632876
OutStreamer->getContext().getObjectFileInfo()->getTextSection());
28642877

2878+
// Add a single .ref reference to __tls_get_addr[DS] for the local-exec TLS
2879+
// model on AIX 64-bit. For TLS models that do not generate calls to TLS
2880+
// functions, this reference to __tls_get_addr helps generate a linker error
2881+
// to an undefined symbol to __tls_get_addr, which indicates to the user that
2882+
// compiling with -pthread is required for programs that use TLS variables.
2883+
if (HasRefGetTLSAddr) {
2884+
// Specifically for 64-bit AIX, a load from the TOC is generated to load
2885+
// the variable offset needed for local-exec accesses.
2886+
MCSymbol *TlsGetAddrDescriptor =
2887+
createMCSymbolForTlsGetAddr(OutContext, PPC::GETtlsADDR64AIX,
2888+
XCOFF::XMC_DS);
2889+
2890+
ExtSymSDNodeSymbols.insert(TlsGetAddrDescriptor);
2891+
OutStreamer->emitXCOFFRefDirective(TlsGetAddrDescriptor);
2892+
}
2893+
28652894
for (MCSymbol *Sym : ExtSymSDNodeSymbols)
28662895
OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
28672896
return PPCAsmPrinter::doFinalization(M);

llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-double.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,13 @@ entry:
635635
ret double %add
636636
}
637637

638+
; (64-bit only) External symbol reference checks for __tls_get_addr[DS]
639+
640+
; SMALL64: .ref __tls_get_addr[DS]
641+
; SMALL64: .extern __tls_get_addr[DS]
642+
; LARGE64: .ref __tls_get_addr[DS]
643+
; LARGE64: .extern __tls_get_addr[DS]
644+
638645
; TOC Entry Checks.
639646

640647
; SMALL64-LABEL: .toc

llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-float.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,13 @@ entry:
635635
ret float %add
636636
}
637637

638+
; (64-bit only) External symbol reference checks for __tls_get_addr[DS]
639+
640+
; SMALL64: .ref __tls_get_addr[DS]
641+
; SMALL64: .extern __tls_get_addr[DS]
642+
; LARGE64: .ref __tls_get_addr[DS]
643+
; LARGE64: .extern __tls_get_addr[DS]
644+
638645
; TOC Entry Checks.
639646

640647
; SMALL64-LABEL: .toc

llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-int.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,13 @@ entry:
651651
ret i32 %add
652652
}
653653

654+
; (64-bit only) External symbol reference checks for __tls_get_addr[DS]
655+
656+
; SMALL64: .ref __tls_get_addr[DS]
657+
; SMALL64: .extern __tls_get_addr[DS]
658+
; LARGE64: .ref __tls_get_addr[DS]
659+
; LARGE64: .extern __tls_get_addr[DS]
660+
654661
; TOC Entry Checks.
655662

656663
; SMALL64-LABEL: .toc

llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,13 @@ entry:
707707
ret i64 %add
708708
}
709709

710+
; (64-bit only) External symbol reference checks for __tls_get_addr[DS]
711+
712+
; SMALL64: .ref __tls_get_addr[DS]
713+
; SMALL64: .extern __tls_get_addr[DS]
714+
; LARGE64: .ref __tls_get_addr[DS]
715+
; LARGE64: .extern __tls_get_addr[DS]
716+
710717
; TOC Entry Checks.
711718

712719
; SMALL64-LABEL: .toc

0 commit comments

Comments
 (0)