@@ -31,6 +31,70 @@ using namespace llvm::jitlink;
31
31
constexpr StringRef ELFTOCSymbolName = " .TOC." ;
32
32
constexpr StringRef TOCSymbolAliasIdent = " __TOC__" ;
33
33
constexpr uint64_t ELFTOCBaseOffset = 0x8000 ;
34
+ constexpr StringRef ELFTLSInfoSectionName = " $__TLSINFO" ;
35
+
36
+ template <support::endianness Endianness>
37
+ class TLSInfoTableManager_ELF_ppc64
38
+ : public TableManager<TLSInfoTableManager_ELF_ppc64<Endianness>> {
39
+ public:
40
+ static const uint8_t TLSInfoEntryContent[16 ];
41
+
42
+ static StringRef getSectionName () { return ELFTLSInfoSectionName; }
43
+
44
+ bool visitEdge (LinkGraph &G, Block *B, Edge &E) {
45
+ Edge::Kind K = E.getKind ();
46
+ if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA) {
47
+ E.setKind (ppc64::TOCDelta16HA);
48
+ E.setTarget (this ->getEntryForTarget (G, E.getTarget ()));
49
+ return true ;
50
+ }
51
+ if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO) {
52
+ E.setKind (ppc64::TOCDelta16LO);
53
+ E.setTarget (this ->getEntryForTarget (G, E.getTarget ()));
54
+ return true ;
55
+ }
56
+ return false ;
57
+ }
58
+
59
+ Symbol &createEntry (LinkGraph &G, Symbol &Target) {
60
+ // The TLS Info entry's key value will be written by
61
+ // `fixTLVSectionsAndEdges`, so create mutable content.
62
+ auto &TLSInfoEntry = G.createMutableContentBlock (
63
+ getTLSInfoSection (G), G.allocateContent (getTLSInfoEntryContent ()),
64
+ orc::ExecutorAddr (), 8 , 0 );
65
+ TLSInfoEntry.addEdge (ppc64::Pointer64, 8 , Target, 0 );
66
+ return G.addAnonymousSymbol (TLSInfoEntry, 0 , 16 , false , false );
67
+ }
68
+
69
+ private:
70
+ Section &getTLSInfoSection (LinkGraph &G) {
71
+ if (!TLSInfoTable)
72
+ TLSInfoTable =
73
+ &G.createSection (ELFTLSInfoSectionName, orc::MemProt::Read);
74
+ return *TLSInfoTable;
75
+ }
76
+
77
+ ArrayRef<char > getTLSInfoEntryContent () const {
78
+ return {reinterpret_cast <const char *>(TLSInfoEntryContent),
79
+ sizeof (TLSInfoEntryContent)};
80
+ }
81
+
82
+ Section *TLSInfoTable = nullptr ;
83
+ };
84
+
85
+ template <>
86
+ const uint8_t TLSInfoTableManager_ELF_ppc64<
87
+ support::endianness::little>::TLSInfoEntryContent[16 ] = {
88
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , /* pthread key */
89
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 /* data address*/
90
+ };
91
+
92
+ template <>
93
+ const uint8_t TLSInfoTableManager_ELF_ppc64<
94
+ support::endianness::big>::TLSInfoEntryContent[16 ] = {
95
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , /* pthread key */
96
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 /* data address*/
97
+ };
34
98
35
99
template <support::endianness Endianness>
36
100
Symbol &createELFGOTHeader (LinkGraph &G,
@@ -91,8 +155,8 @@ Error buildTables_ELF_ppc64(LinkGraph &G) {
91
155
registerExistingGOTEntries (G, TOC);
92
156
93
157
ppc64::PLTTableManager<Endianness> PLT (TOC);
94
- visitExistingEdges (G, TOC, PLT) ;
95
- // TODO: Add TLS support.
158
+ TLSInfoTableManager_ELF_ppc64<Endianness> TLSInfo ;
159
+ visitExistingEdges (G, TOC, PLT, TLSInfo);
96
160
97
161
// After visiting edges in LinkGraph, we have GOT entries built in the
98
162
// synthesized section.
@@ -164,6 +228,13 @@ class ELFLinkGraphBuilder_ppc64
164
228
if (LLVM_UNLIKELY (ELFReloc == ELF::R_PPC64_NONE))
165
229
return Error::success ();
166
230
231
+ // TLS model markers. We only support global-dynamic model now.
232
+ if (ELFReloc == ELF::R_PPC64_TLSGD)
233
+ return Error::success ();
234
+ if (ELFReloc == ELF::R_PPC64_TLSLD)
235
+ return make_error<StringError>(" Local-dynamic TLS model is not supported" ,
236
+ inconvertibleErrorCode ());
237
+
167
238
auto ObjSymbol = Base::Obj.getRelocationSymbol (Rel, Base::SymTabSec);
168
239
if (!ObjSymbol)
169
240
return ObjSymbol.takeError ();
@@ -234,6 +305,12 @@ class ELFLinkGraphBuilder_ppc64
234
305
case ELF::R_PPC64_PCREL34:
235
306
Kind = ppc64::Delta34;
236
307
break ;
308
+ case ELF::R_PPC64_GOT_TLSGD16_HA:
309
+ Kind = ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA;
310
+ break ;
311
+ case ELF::R_PPC64_GOT_TLSGD16_LO:
312
+ Kind = ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO;
313
+ break ;
237
314
}
238
315
239
316
Edge GE (Kind, Offset, *GraphSymbol, Addend);
0 commit comments