@@ -1194,18 +1194,34 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
11941194 MCSymbolRefExpr::create (TM.getSymbol (RHS), getContext ()), getContext ());
11951195}
11961196
1197+ // Reference the function or its PLT entry (`Equiv`), optionally with a
1198+ // subtrahend (`RHS`).
11971199const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent (
1198- const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
1200+ const DSOLocalEquivalent *Equiv, const MCSymbolRefExpr *RHS,
1201+ const TargetMachine &TM) const {
11991202 assert (supportDSOLocalEquivalentLowering ());
12001203
1204+ // If GV is dso_local, reference the function itself. Return GV or GV-RHS.
12011205 const auto *GV = Equiv->getGlobalValue ();
1202-
1203- // A PLT entry is not needed for dso_local globals.
1206+ const MCExpr *Res = MCSymbolRefExpr::create (TM.getSymbol (GV), getContext ());
1207+ if (RHS)
1208+ Res = MCBinaryExpr::createSub (Res, RHS, getContext ());
12041209 if (GV->isDSOLocal () || GV->isImplicitDSOLocal ())
1205- return MCSymbolRefExpr::create (TM.getSymbol (GV), getContext ());
1206-
1207- return MCSymbolRefExpr::create (TM.getSymbol (GV), PLTRelativeSpecifier,
1208- getContext ());
1210+ return Res;
1211+
1212+ // Otherwise, reference the PLT. Return a relocatable expression with the PLT
1213+ // specifier, %plt(GV) or %plt(GV-RHS).
1214+ Res = createTargetMCExpr (Res, PLTRelativeSpecifier);
1215+ if (Res)
1216+ return Res;
1217+
1218+ // If the target only supports the legacy syntax @plt, return GV@plt or
1219+ // GV@plt - RHS.
1220+ Res = MCSymbolRefExpr::create (TM.getSymbol (GV), PLTRelativeSpecifier,
1221+ getContext ());
1222+ if (RHS)
1223+ Res = MCBinaryExpr::createSub (Res, RHS, getContext ());
1224+ return Res;
12091225}
12101226
12111227MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines () const {
0 commit comments