Skip to content

[PAC][MC][ELF][AArch64] Support signed TLSDESC #120010

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,16 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
} else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
TLSModel::Model Model;
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
Model = Printer.TM.getTLSModel(GV);
if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
Model == TLSModel::LocalDynamic)
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
if (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()) {
Model = TLSModel::GeneralDynamic;

} else {
const GlobalValue *GV = MO.getGlobal();
Model = Printer.TM.getTLSModel(GV);
if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
Model == TLSModel::LocalDynamic)
Model = TLSModel::GeneralDynamic;
}
} else {
assert(MO.isSymbol() &&
StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
Expand All @@ -218,10 +222,18 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
case TLSModel::LocalDynamic:
RefFlags |= AArch64MCExpr::VK_DTPREL;
break;
case TLSModel::GeneralDynamic:
RefFlags |= AArch64MCExpr::VK_TLSDESC;
case TLSModel::GeneralDynamic: {
// TODO: it's probably better to introduce MO_TLS_AUTH or smth and avoid
// running hasELFSignedGOT() every time, but existing flags already
// cover all 12 bits of SubReg_TargetFlags field in MachineOperand, and
// making the field wider breaks static assertions.
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
RefFlags |= MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
? AArch64MCExpr::VK_TLSDESC_AUTH
: AArch64MCExpr::VK_TLSDESC;
break;
}
}
} else if (MO.getTargetFlags() & AArch64II::MO_PREL) {
RefFlags |= AArch64MCExpr::VK_PREL;
} else {
Expand Down
109 changes: 58 additions & 51 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,7 @@ class AArch64Operand : public MCParsedAsmOperand {
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) {
Expand Down Expand Up @@ -1021,6 +1022,7 @@ class AArch64Operand : public MCParsedAsmOperand {
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
}
Expand Down Expand Up @@ -3314,7 +3316,8 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE &&
ELFRefKind != AArch64MCExpr::VK_TLSDESC_AUTH_PAGE) {
// The operand must be an @page or @gotpage qualified symbolref.
return Error(S, "page or gotpage label reference expected");
}
Expand Down Expand Up @@ -4398,56 +4401,59 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
return TokError("expect relocation specifier in operand after ':'");

std::string LowerCase = getTok().getIdentifier().lower();
RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
.Case("lo12", AArch64MCExpr::VK_LO12)
.Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
.Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
.Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
.Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
.Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
.Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
.Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
.Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
.Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
.Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
.Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
.Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
.Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
.Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
.Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
.Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
.Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
.Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
.Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
.Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
.Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
.Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
.Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
.Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
.Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
.Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
.Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
.Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
.Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
.Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
.Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
.Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
.Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
.Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
.Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
.Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
.Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
.Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
.Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
.Default(AArch64MCExpr::VK_INVALID);
RefKind =
StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
.Case("lo12", AArch64MCExpr::VK_LO12)
.Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
.Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
.Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
.Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
.Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
.Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
.Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
.Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
.Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
.Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
.Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
.Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
.Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
.Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
.Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
.Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
.Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
.Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
.Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
.Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
.Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
.Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
.Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
.Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
.Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
.Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
.Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
.Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
.Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
.Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
.Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
.Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
.Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
.Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
.Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
.Case("tlsdesc_auth_lo12", AArch64MCExpr::VK_TLSDESC_AUTH_LO12)
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
.Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
.Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
.Case("tlsdesc_auth", AArch64MCExpr::VK_TLSDESC_AUTH_PAGE)
.Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
.Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
.Default(AArch64MCExpr::VK_INVALID);

if (RefKind == AArch64MCExpr::VK_INVALID)
return TokError("expect relocation specifier in operand after ':'");
Expand Down Expand Up @@ -5821,6 +5827,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) &&
(Inst.getOpcode() == AArch64::ADDXri ||
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
return R_CLS(TLSDESC_ADR_PAGE21);
if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH && !IsNC) {
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
"ILP32 ADRP AUTH relocation not supported "
"(LP64 eqv: AUTH_TLSDESC_ADR_PAGE21)");
return ELF::R_AARCH64_NONE;
}
return ELF::R_AARCH64_AUTH_TLSDESC_ADR_PAGE21;
}
Ctx.reportError(Fixup.getLoc(),
"invalid symbol kind for ADRP relocation");
return ELF::R_AARCH64_NONE;
Expand Down Expand Up @@ -267,6 +276,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return R_CLS(TLSLE_ADD_TPREL_LO12);
if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
return R_CLS(TLSDESC_ADD_LO12);
if (RefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12) {
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
"ILP32 ADD AUTH relocation not supported "
"(LP64 eqv: AUTH_TLSDESC_ADD_LO12)");
return ELF::R_AARCH64_NONE;
}
return ELF::R_AARCH64_AUTH_TLSDESC_ADD_LO12;
}
if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
Expand Down Expand Up @@ -411,6 +429,14 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
"TLSDESC_LD64_LO12)");
return ELF::R_AARCH64_NONE;
}
if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH) {
if (!IsILP32)
return ELF::R_AARCH64_AUTH_TLSDESC_LD64_LO12;
Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store AUTH "
"relocation not supported (LP64 eqv: "
"AUTH_TLSDESC_LD64_LO12)");
return ELF::R_AARCH64_NONE;
}
Ctx.reportError(Fixup.getLoc(),
"invalid fixup for 64-bit load/store instruction");
return ELF::R_AARCH64_NONE;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ StringRef AArch64MCExpr::getVariantKindName() const {
case VK_TPREL_LO12: return ":tprel_lo12:";
case VK_TPREL_LO12_NC: return ":tprel_lo12_nc:";
case VK_TLSDESC_LO12: return ":tlsdesc_lo12:";
case VK_TLSDESC_AUTH_LO12: return ":tlsdesc_auth_lo12:";
case VK_ABS_PAGE: return "";
case VK_ABS_PAGE_NC: return ":pg_hi21_nc:";
case VK_GOT: return ":got:";
Expand All @@ -81,6 +82,8 @@ StringRef AArch64MCExpr::getVariantKindName() const {
case VK_GOTTPREL_G0_NC: return ":gottprel_g0_nc:";
case VK_TLSDESC: return "";
case VK_TLSDESC_PAGE: return ":tlsdesc:";
case VK_TLSDESC_AUTH: return "";
case VK_TLSDESC_AUTH_PAGE: return ":tlsdesc_auth:";
case VK_SECREL_LO12: return ":secrel_lo12:";
case VK_SECREL_HI12: return ":secrel_hi12:";
case VK_GOT_AUTH: return ":got_auth:";
Expand Down Expand Up @@ -154,6 +157,7 @@ void AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
case VK_GOTTPREL:
case VK_TPREL:
case VK_TLSDESC:
case VK_TLSDESC_AUTH:
break;
}

Expand Down
Loading
Loading