diff --git a/src/coreclr/inc/cfi.h b/src/coreclr/inc/cfi.h index a0f4c246a4b0b7..d86cacfc25164a 100644 --- a/src/coreclr/inc/cfi.h +++ b/src/coreclr/inc/cfi.h @@ -18,7 +18,7 @@ struct CFI_CODE { unsigned char CodeOffset;// Offset from the start of code the frame covers. unsigned char CfiOpCode; - short DwarfReg; // Dwarf register number. 0~32 for x64. + short DwarfReg; // Dwarf register number. int Offset; CFI_CODE(unsigned char codeOffset, unsigned char cfiOpcode, short dwarfReg, int offset) diff --git a/src/coreclr/jit/unwind.cpp b/src/coreclr/jit/unwind.cpp index 4521c5cbd0c5b8..29f7d4162b928a 100644 --- a/src/coreclr/jit/unwind.cpp +++ b/src/coreclr/jit/unwind.cpp @@ -165,7 +165,7 @@ void Compiler::unwindPushPopCFI(regNumber reg) } //------------------------------------------------------------------------ -// Compiler::unwindPush2Pop2CFI: Record push/save of 2 registers simultaneously. +// Compiler::unwindPush2Pop2CFI: Record push/save of 2 registers simultaneously. // // Arguments: // reg1 - The first register being pushed/saved. @@ -173,9 +173,32 @@ void Compiler::unwindPushPopCFI(regNumber reg) // void Compiler::unwindPush2Pop2CFI(regNumber reg1, regNumber reg2) { - // ToDo: This is a placeholder till OS has unwind support for push2/pop2. - unwindPushPopCFI(reg1); - unwindPushPopCFI(reg2); + assert(GetEmitter()->emitGeneratingPrologOrFuncletProlog()); + + FuncInfoDsc* func = funCurrentFunc(); + UNATIVE_OFFSET cbProlog = unwindGetCurrentOffset(func); + + regMaskTP relOffsetMask = RBM_CALLEE_SAVED +#if defined(UNIX_AMD64_ABI) && ETW_EBP_FRAMED + // In case of ETW_EBP_FRAMED defined the REG_FPBASE (RBP) + // is excluded from the callee-save register list. + // Make sure the register gets PUSH unwind info in this case, + // since it is pushed as a frame register. + | RBM_FPBASE +#endif + ; + + createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, 2 * REGSIZE_BYTES); + + if (relOffsetMask & genRegMask(reg1)) + { + createCfiCode(func, cbProlog, CFI_REL_OFFSET, mapRegNumToDwarfReg(reg1), REGSIZE_BYTES); + } + + if (relOffsetMask & genRegMask(reg2)) + { + createCfiCode(func, cbProlog, CFI_REL_OFFSET, mapRegNumToDwarfReg(reg2), 0); + } } typedef jitstd::vector CFICodeVector; diff --git a/src/coreclr/jit/unwindamd64.cpp b/src/coreclr/jit/unwindamd64.cpp index 92519f02b91284..7da24d7f28be9c 100644 --- a/src/coreclr/jit/unwindamd64.cpp +++ b/src/coreclr/jit/unwindamd64.cpp @@ -72,52 +72,52 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) dwarfReg = 15; break; case REG_R16: - dwarfReg = 16; + dwarfReg = 130; break; case REG_R17: - dwarfReg = 17; + dwarfReg = 131; break; case REG_R18: - dwarfReg = 18; + dwarfReg = 132; break; case REG_R19: - dwarfReg = 19; + dwarfReg = 133; break; case REG_R20: - dwarfReg = 20; + dwarfReg = 134; break; case REG_R21: - dwarfReg = 21; + dwarfReg = 135; break; case REG_R22: - dwarfReg = 22; + dwarfReg = 136; break; case REG_R23: - dwarfReg = 23; + dwarfReg = 137; break; case REG_R24: - dwarfReg = 24; + dwarfReg = 138; break; case REG_R25: - dwarfReg = 25; + dwarfReg = 139; break; case REG_R26: - dwarfReg = 26; + dwarfReg = 140; break; case REG_R27: - dwarfReg = 27; + dwarfReg = 141; break; case REG_R28: - dwarfReg = 28; + dwarfReg = 142; break; case REG_R29: - dwarfReg = 29; + dwarfReg = 143; break; case REG_R30: - dwarfReg = 30; + dwarfReg = 144; break; case REG_R31: - dwarfReg = 31; + dwarfReg = 145; break; default: noway_assert(!"unexpected REG_NUM"); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs index 4a8b2076872590..bb860f9fd71ce5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs @@ -80,7 +80,7 @@ private static byte[] CfiCodeToInstructions(DwarfCie cie, byte[] blobData) { case CFI_OPCODE.CFI_DEF_CFA_REGISTER: cfiCode[cfiCodeOffset++] = DW_CFA_def_cfa_register; - cfiCode[cfiCodeOffset++] = (byte)dwarfReg; + cfiCodeOffset += DwarfHelper.WriteULEB128(cfiCode.AsSpan(cfiCodeOffset), (uint)dwarfReg); break; case CFI_OPCODE.CFI_REL_OFFSET: @@ -112,7 +112,7 @@ private static byte[] CfiCodeToInstructions(DwarfCie cie, byte[] blobData) case CFI_OPCODE.CFI_DEF_CFA: cfiCode[cfiCodeOffset++] = DW_CFA_def_cfa; - cfiCode[cfiCodeOffset++] = (byte)dwarfReg; + cfiCodeOffset += DwarfHelper.WriteULEB128(cfiCode.AsSpan(cfiCodeOffset), (uint)dwarfReg); cfaOffset = cfiOffset; cfiCodeOffset += DwarfHelper.WriteULEB128(cfiCode.AsSpan(cfiCodeOffset), (uint)cfaOffset); break;