Skip to content

NativeAOT/Arm64: Do not overwrite gcinfo tracking registers for TLS #112469

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 1 commit into from
Feb 13, 2025
Merged
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
25 changes: 18 additions & 7 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ void emitter::emitInsSanityCheck(instrDesc* id)
case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD())
{
assert(isGeneralRegister(id->idReg1()));
assert(id->idAddr()->iiaAddr != nullptr);
}
else
Expand Down Expand Up @@ -9239,11 +9238,14 @@ void emitter::emitIns_Call(EmitCallType callType,
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_TLSGD_RELOC(retSize))
{
// For NativeAOT linux/arm64, we need to also record the relocation of methHnd.
// Since we do not have space to embed it in instrDesc, we store the register in
// reg1 and instead use the `iiaAdd` to store the method handle. Likewise, during
// emitOutputInstr, we retrieve the register from reg1 for this specific case.
// Since we do not have space to embed it in instrDesc, we use the `iiaAddr` to
// store the method handle.
// The target handle need to be always in R2 and hence the assert check.
// We cannot use reg1 and reg2 fields of instrDesc because they contain the gc
// registers (emitEncodeCallGCregs()) that are live across the call.

assert(ireg == REG_R2);
id->idSetTlsGD();
id->idReg1(ireg);
id->idAddr()->iiaAddr = (BYTE*)methHnd;
}
else
Expand Down Expand Up @@ -11045,12 +11047,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idAddr()->iiaAddr,
IMAGE_REL_AARCH64_TLSDESC_CALL);
code |= insEncodeReg_Rn(id->idReg1()); // nnnnn
code |= insEncodeReg_Rn(REG_R2); // nnnnn
}
else
{
code |= insEncodeReg_Rn(id->idReg3()); // nnnnn
}

dst += emitOutputCall(ig, dst, id, code);
sz = id->idIsLargeCall() ? sizeof(instrDescCGCA) : sizeof(instrDesc);
break;
Expand Down Expand Up @@ -13375,7 +13378,15 @@ void emitter::emitDispInsHelp(
case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn
// The size of a branch target is always EA_PTRSIZE
assert(insOptsNone(id->idInsOpt()));
emitDispReg(id->idReg3(), EA_PTRSIZE, false);

if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD())
{
emitDispReg(REG_R2, EA_PTRSIZE, false);
}
else
{
emitDispReg(id->idReg3(), EA_PTRSIZE, false);
}
break;

case IF_LS_1A: // LS_1A XX...V..iiiiiiii iiiiiiiiiiittttt Rt PC imm(1MB)
Expand Down
Loading