Fix unix unwind info
authorSergey Andreenko <seandree@microsoft.com>
Thu, 8 Dec 2016 22:42:56 +0000 (14:42 -0800)
committerSergey Andreenko <seandree@microsoft.com>
Thu, 8 Dec 2016 23:59:26 +0000 (15:59 -0800)
Windows uses offset from stack pointer, when unix has to use offset from
caninical frame address,

Commit migrated from https://github.com/dotnet/coreclr/commit/26880afb0a4d8aaa7dd40d864b77b98602b6c981

src/coreclr/src/jit/unwindamd64.cpp

index 89abdff..14eba8c 100644 (file)
@@ -481,6 +481,13 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
 }
 
 #ifdef UNIX_AMD64_ABI
+//------------------------------------------------------------------------
+// Compiler::unwindSetFrameRegCFI: Record a cfi info for a frame register set.
+//
+// Arguments:
+//    reg    - The register being set as the frame register.
+//    offset - The offset from the current stack pointer that the frame pointer will point at.
+//
 void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset)
 {
     assert(compGeneratingProlog);
@@ -492,7 +499,13 @@ void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset)
     createCfiCode(func, cbProlog, CFI_DEF_CFA_REGISTER, mapRegNumToDwarfReg(reg));
     if (offset != 0)
     {
-        createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, offset);
+        // before: cfa = rsp + old_cfa_offset;
+        //         rbp = rsp + offset;
+        // after: cfa should be based on rbp, but points to the old address:
+        //         rsp + old_cfa_offset == rbp + old_cfa_offset + adjust;
+        // adjust = -offset;
+        int adjust = -(int)offset;
+        createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, adjust);
     }
 }
 #endif // UNIX_AMD64_ABI