Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <fstream>
#include <iostream>
#include <string>

thread_local int x = 0;
thread_local int y = 1;
thread_local int z = -1;

extern int TestPOWER10();

int Test() { return x + y + z; }

static bool CPUModelIsPOWER10() {
std::string line;
std::ifstream cpuinfo("/proc/cpuinfo", std::ios::in);
if (!cpuinfo.is_open())
return false;
while (std::getline(cpuinfo, line)) {
if (line.find("cpu") != std::string::npos &&
line.find("POWER10") != std::string::npos)
return true;
}
return false;
}

int main() {
if (CPUModelIsPOWER10())
return TestPOWER10();
return Test();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extern thread_local int x;
extern thread_local int y;
extern thread_local int z;

int __attribute__((target("arch=pwr10"))) TestPOWER10() { return x + y + z; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clangxx -fPIC -c -o %t/main.o %S/Inputs/trivial-tls-main.cpp
// RUN: %clangxx -fPIC -c -o %t/pwr10.o %S/Inputs/trivial-tls-pwr10.cpp
// RUN: %llvm_jitlink %t/main.o %t/pwr10.o
// FIXME: We seperate pwr10 code from main object file due to currrent
// implementation only supports one PLT stub for the same symbol.
// For example, `bl __tls_get_addr` in one object file has only one PLT stub,
// however we need another different PLT stub for `bl __tls_get_addr@notoc`
// whose target symbol is also `__tls_get_addr`.
5 changes: 5 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ enum EdgeKind_ppc64 : Edge::Kind {
RequestCallNoTOC,
RequestTLSDescInGOTAndTransformToTOCDelta16HA,
RequestTLSDescInGOTAndTransformToTOCDelta16LO,
RequestTLSDescInGOTAndTransformToDelta34,
};

enum PLTCallStubKind {
Expand Down Expand Up @@ -202,6 +203,10 @@ class PLTTableManager : public TableManager<PLTTableManager<Endianness>> {

static StringRef getSectionName() { return "$__STUBS"; }

// FIXME: One external symbol can only have one PLT stub in a object file.
// This is a limitation when we need different PLT stubs for the same symbol.
// For example, we need two different PLT stubs for `bl __tls_get_addr` and
// `bl __tls_get_addr@notoc`.
bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
bool isExternal = E.getTarget().isExternal();
Edge::Kind K = E.getKind();
Expand Down
21 changes: 17 additions & 4 deletions llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,22 @@ class TLSInfoTableManager_ELF_ppc64

bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
Edge::Kind K = E.getKind();
if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA) {
switch (K) {
case ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA:
E.setKind(ppc64::TOCDelta16HA);
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
return true;
}
if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO) {
case ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO:
E.setKind(ppc64::TOCDelta16LO);
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
return true;
case ppc64::RequestTLSDescInGOTAndTransformToDelta34:
E.setKind(ppc64::Delta34);
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
return true;
default:
return false;
}
return false;
}

Symbol &createEntry(LinkGraph &G, Symbol &Target) {
Expand Down Expand Up @@ -234,10 +239,15 @@ class ELFLinkGraphBuilder_ppc64
if (ELFReloc == ELF::R_PPC64_TLSLD)
return make_error<StringError>("Local-dynamic TLS model is not supported",
inconvertibleErrorCode());

if (ELFReloc == ELF::R_PPC64_PCREL_OPT)
// TODO: Support PCREL optimization, now ignore it.
return Error::success();

if (ELFReloc == ELF::R_PPC64_TPREL34)
return make_error<StringError>("Local-exec TLS model is not supported",
inconvertibleErrorCode());

auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
if (!ObjSymbol)
return ObjSymbol.takeError();
Expand Down Expand Up @@ -372,6 +382,9 @@ class ELFLinkGraphBuilder_ppc64
case ELF::R_PPC64_GOT_TLSGD16_LO:
Kind = ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO;
break;
case ELF::R_PPC64_GOT_TLSGD_PCREL34:
Kind = ppc64::RequestTLSDescInGOTAndTransformToDelta34;
break;
}

Edge GE(Kind, Offset, *GraphSymbol, Addend);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ const char *getEdgeKindName(Edge::Kind K) {
return "RequestTLSDescInGOTAndTransformToTOCDelta16HA";
case RequestTLSDescInGOTAndTransformToTOCDelta16LO:
return "RequestTLSDescInGOTAndTransformToTOCDelta16LO";
case RequestTLSDescInGOTAndTransformToDelta34:
return "RequestTLSDescInGOTAndTransformToDelta34";
default:
return getGenericEdgeKindName(static_cast<Edge::Kind>(K));
}
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# REQUIRES: system-linux
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc --triple=powerpc64le-unknown-linux-gnu --filetype=obj -o \
# RUN: %t/elf_reloc.o --defsym LE=1 %s
Expand All @@ -9,6 +10,7 @@
# RUN: --abs external_addr16_data=0x6000 \
# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --abs pcrel_external_var=0x36668860 \
# RUN: --abs pcrel_external_tls=0x36668880 \
# RUN: --check %s %t/elf_reloc.o
# RUN: llvm-mc --triple=powerpc64-unknown-linux-gnu --filetype=obj -o \
# RUN: %t/elf_reloc.o %s
Expand All @@ -20,6 +22,7 @@
# RUN: --abs external_addr16_data=0x6000 \
# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --abs pcrel_external_var=0x36668860 \
# RUN: --abs pcrel_external_tls=0x36668880 \
# RUN: --check %s %t/elf_reloc.o

# jitlink-check: section_addr(elf_reloc.o, $__GOT) + 0x8000 = __TOC__
Expand Down Expand Up @@ -255,6 +258,22 @@ reloc_got_pcrel34:
blr
.size reloc_got_pcrel34,.-reloc_got_pcrel34

.global reloc_tlsgd_pcrel34
.p2align 4
.type reloc_tlsgd_pcrel34,@function
reloc_tlsgd_pcrel34:
mflr 0
std 0, 16(1)
stdu 1, -32(1)
paddi 3, 0, pcrel_external_tls@got@tlsgd@pcrel, 1
bl __tls_get_addr@notoc(a@tlsgd)
lwa 3, 0(3)
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.size reloc_tlsgd_pcrel34,.-reloc_tlsgd_pcrel34

.type .L.str,@object
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
Expand Down