Skip to content

Commit

Permalink
Backport TLS PCREL relocation
Browse files Browse the repository at this point in the history
  • Loading branch information
bzEq committed Dec 17, 2023
1 parent d218a58 commit 28b6037
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
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
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
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

0 comments on commit 28b6037

Please sign in to comment.