@@ -27,12 +27,67 @@ using namespace llvm::jitlink;
2727namespace {
2828
2929constexpr StringRef ELFGOTSymbolName = " _GLOBAL_OFFSET_TABLE_" ;
30+ constexpr StringRef ELFTLSInfoSectionName = " $__TLSINFO" ;
31+
32+ // TLS Info Builder.
33+ class TLSInfoTableManager_ELF_systemz
34+ : public TableManager<TLSInfoTableManager_ELF_systemz> {
35+ public:
36+ static StringRef getSectionName () { return ELFTLSInfoSectionName; }
37+
38+ static const uint8_t TLSInfoEntryContent[16 ];
39+
40+ bool visitEdge (LinkGraph &G, Block *B, Edge &E) {
41+ if (E.getKind () ==
42+ systemz::RequestTLSDescInGOTAndTransformToDelta64FromGOT) {
43+ LLVM_DEBUG ({
44+ dbgs () << " Fixing " << G.getEdgeKindName (E.getKind ()) << " edge at "
45+ << formatv (" {0:x}" , B->getFixupAddress (E)) << " ("
46+ << formatv (" {0:x}" , B->getAddress ()) << " + "
47+ << formatv (" {0:x}" , E.getOffset ()) << " )\n " ;
48+ });
49+ E.setKind (systemz::Delta64FromGOT);
50+ E.setTarget (getEntryForTarget (G, E.getTarget ()));
51+ return true ;
52+ }
53+ return false ;
54+ }
55+
56+ Symbol &createEntry (LinkGraph &G, Symbol &Target) {
57+ // the TLS Info entry's key value will be written by the fixTLVSectionByName
58+ // pass, so create mutable content.
59+ auto &TLSInfoEntry = G.createMutableContentBlock (
60+ getTLSInfoSection (G), G.allocateContent (getTLSInfoEntryContent ()),
61+ orc::ExecutorAddr (), 8 , 0 );
62+ TLSInfoEntry.addEdge (systemz::Pointer64, 8 , Target, 0 );
63+ return G.addAnonymousSymbol (TLSInfoEntry, 0 , 16 , false , false );
64+ }
65+
66+ private:
67+ Section &getTLSInfoSection (LinkGraph &G) {
68+ if (!TLSInfoTable)
69+ TLSInfoTable = &G.createSection (getSectionName (), orc::MemProt::Read);
70+ return *TLSInfoTable;
71+ }
72+
73+ ArrayRef<char > getTLSInfoEntryContent () const {
74+ return {reinterpret_cast <const char *>(TLSInfoEntryContent),
75+ sizeof (TLSInfoEntryContent)};
76+ }
77+
78+ Section *TLSInfoTable = nullptr ;
79+ };
80+
81+ const uint8_t TLSInfoTableManager_ELF_systemz::TLSInfoEntryContent[16 ] = {
82+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
83+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
3084
3185Error buildTables_ELF_systemz (LinkGraph &G) {
3286 LLVM_DEBUG (dbgs () << " Visiting edges in graph:\n " );
3387 systemz::GOTTableManager GOT;
3488 systemz::PLTTableManager PLT (GOT);
35- visitExistingEdges (G, GOT, PLT);
89+ TLSInfoTableManager_ELF_systemz TLSInfo;
90+ visitExistingEdges (G, GOT, PLT, TLSInfo);
3691 return Error::success ();
3792}
3893
@@ -329,6 +384,15 @@ class ELFLinkGraphBuilder_systemz
329384 Kind = systemz::Delta32dblGOTBase;
330385 break ;
331386 }
387+ // Tag for function call in general dynamic TLS code.
388+ case ELF::R_390_TLS_GDCALL: {
389+ break ;
390+ }
391+ // Direct 64 bit for general dynamic thread local data.
392+ case ELF::R_390_TLS_GD64: {
393+ Kind = systemz::RequestTLSDescInGOTAndTransformToDelta64FromGOT;
394+ break ;
395+ }
332396 default :
333397 return make_error<JITLinkError>(
334398 " In " + G->getName () + " : Unsupported systemz relocation type " +
0 commit comments