From 91743f4062a89647f63c62fd006eec6319d8d203 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Tue, 10 Oct 2023 12:56:08 +0800 Subject: [PATCH 1/8] Support R_PPC64_GOT_TLSGD_PCREL34 --- .../llvm/ExecutionEngine/JITLink/ppc64.h | 1 + llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp | 16 ++++++++++++---- llvm/lib/ExecutionEngine/JITLink/ppc64.cpp | 2 ++ .../JITLink/ppc64/ELF_ppc64_relocations.s | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h index ff932f6022bdc..89a26b089a67b 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h @@ -61,6 +61,7 @@ enum EdgeKind_ppc64 : Edge::Kind { RequestCallNoTOC, RequestTLSDescInGOTAndTransformToTOCDelta16HA, RequestTLSDescInGOTAndTransformToTOCDelta16LO, + RequestTLSDescInGOTAndTransformToDelta34, }; enum PLTCallStubKind { diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp index a095059496dc1..c04ebaf517def 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp @@ -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) { @@ -372,6 +377,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); diff --git a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp index ac4a62a503919..27484aaf20590 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp @@ -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(K)); } diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s index bcee29d1d34f6..4a587435cbde8 100644 --- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s +++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s @@ -9,6 +9,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 @@ -20,6 +21,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__ @@ -255,6 +257,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: From 5546eab719b9ff2d1f3d1c7c2cf05fbfa1f12a26 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Wed, 11 Oct 2023 10:55:04 +0800 Subject: [PATCH 2/8] R_PPC64_TPREL34 unsupported --- llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp index c04ebaf517def..a54731ff78535 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp @@ -239,10 +239,15 @@ class ELFLinkGraphBuilder_ppc64 if (ELFReloc == ELF::R_PPC64_TLSLD) return make_error("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("Local-exec TLS model is not supported", + inconvertibleErrorCode()); + auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec); if (!ObjSymbol) return ObjSymbol.takeError(); From 99a765fdae7ffd3762caa6397d8be4d32aee8f46 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Wed, 11 Oct 2023 12:54:39 +0800 Subject: [PATCH 3/8] No __tls_get_addr under windows --- llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s index 4a587435cbde8..8f28a8662cbd6 100644 --- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s +++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s @@ -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 From c2f565ac7e3ce2617b8d319e1eb994aa86ea667e Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 13 Oct 2023 03:05:00 +0000 Subject: [PATCH 4/8] Add test case for host running on pwr10 --- .../Linux/ppc64/trivial-tls-pwr10.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp new file mode 100644 index 0000000000000..de57a8c22f3a6 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp @@ -0,0 +1,35 @@ +// RUN: %clangxx -fPIC -c -o %t %s +// RUN: %llvm_jitlink %t + +#include +#include +#include + +thread_local int x = 0; +thread_local int y = 1; +thread_local int z = -1; + +static int __attribute__((target("arch=pwr10"))) TestPOWER10() { + return x + y + z; +} + +static 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(); +} From 6847686dfd5a569ee4777d4a81be9d0f27ef4d9c Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 13 Oct 2023 04:54:54 +0000 Subject: [PATCH 5/8] Seperate modules --- .../trivial-tls-main.cpp} | 9 ++------- .../TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp | 5 +++++ .../orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) rename compiler-rt/test/orc/TestCases/Linux/ppc64/{trivial-tls-pwr10.cpp => Inputs/trivial-tls-main.cpp} (74%) create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp similarity index 74% rename from compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp rename to compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp index de57a8c22f3a6..d6757fdd4154c 100644 --- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp @@ -1,6 +1,3 @@ -// RUN: %clangxx -fPIC -c -o %t %s -// RUN: %llvm_jitlink %t - #include #include #include @@ -9,11 +6,9 @@ thread_local int x = 0; thread_local int y = 1; thread_local int z = -1; -static int __attribute__((target("arch=pwr10"))) TestPOWER10() { - return x + y + z; -} +extern int TestPOWER10(); -static int Test() { return x + y + z; } +int Test() { return x + y + z; } static bool CPUModelIsPOWER10() { std::string line; diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp new file mode 100644 index 0000000000000..a6fb3088af629 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp @@ -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; } diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test new file mode 100644 index 0000000000000..be7fa7832f728 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test @@ -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 object fil from normal object file due to +// currrent implementation only supports single PLT stub for the same symbol. +// For example, `__tls_get_addr` in one object file has only one PLT stub, +// however we need another one for `__tls_get_addr@notoc` which is not +// implemented. From 60ba484b1642017a8415cff06017996a49aad901 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 13 Oct 2023 04:58:55 +0000 Subject: [PATCH 6/8] Adjust comment --- .../orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test index be7fa7832f728..9afb47cb683c5 100644 --- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test @@ -2,8 +2,9 @@ // 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 object fil from normal object file due to +// FIXME: We seperate pwr10 object file from normal object file due to // currrent implementation only supports single PLT stub for the same symbol. -// For example, `__tls_get_addr` in one object file has only one PLT stub, -// however we need another one for `__tls_get_addr@notoc` which is not -// implemented. +// For example, `bl __tls_get_addr` in one object file has only one PLT stub, +// however we need additional one for `bl __tls_get_addr@notoc` relocation +// whose target symbol is also `__tls_get_addr`. + From dcafa2842c987eacd223b8f48d96c79e37928e1a Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 13 Oct 2023 05:09:35 +0000 Subject: [PATCH 7/8] Adjust comment --- .../test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test index 9afb47cb683c5..93561b1645c33 100644 --- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test +++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test @@ -2,9 +2,8 @@ // 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 object file from normal object file due to -// currrent implementation only supports single PLT stub for the same symbol. +// 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 additional one for `bl __tls_get_addr@notoc` relocation +// however we need another different PLT stub for `bl __tls_get_addr@notoc` // whose target symbol is also `__tls_get_addr`. - From ffaeaa5a32a33dbf48c6e250e7fff75b56ec0002 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 13 Oct 2023 05:24:18 +0000 Subject: [PATCH 8/8] Add FIXME --- llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h index 89a26b089a67b..b723914455986 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h @@ -203,6 +203,10 @@ class PLTTableManager : public TableManager> { 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();