diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-09-20 04:12:29 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-09-20 06:16:56 +0300 |
commit | 94d8b4ce86268353fcdbaa116be2b9a43a7ec2a9 (patch) | |
tree | 4c956e970d3d85df307c6f08c09bc3b29cfda12b | |
parent | 34ed9fa54bfba29424f181b852f67d0552852b93 (diff) |
Link with libunwind on Linux
-rw-r--r-- | src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets | 1 | ||||
-rw-r--r-- | src/Native/Runtime/unix/UnixContext.cpp | 142 |
2 files changed, 61 insertions, 82 deletions
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 82ca49944..cc4a4c2ce 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -59,6 +59,7 @@ See the LICENSE file in the project root for more information. <LinkerArg Include="-ldl" /> <LinkerArg Include="-lm" /> <LinkerArg Include="-lrt" Condition="'$(TargetOS)' != 'OSX'" /> + <LinkerArg Include="-lunwind-x86_64" Condition="'$(TargetOS)' != 'OSX'" /> </ItemGroup> <MakeDir Directories="$([System.IO.Path]::GetDirectoryName($(NativeBinary)))" /> diff --git a/src/Native/Runtime/unix/UnixContext.cpp b/src/Native/Runtime/unix/UnixContext.cpp index ac47ad1c2..4812a1ec7 100644 --- a/src/Native/Runtime/unix/UnixContext.cpp +++ b/src/Native/Runtime/unix/UnixContext.cpp @@ -24,12 +24,6 @@ #include "UnixContext.h" #ifdef __APPLE__ -// TODO: remove this define and all related #ifdefs after we can link shared libunwind -// during the build. -#define CAN_LINK_SHARED_LIBUNWIND -#endif // __APPLE__ - -#ifdef __APPLE__ #define MCREG_Rip(mc) ((mc)->__ss.__rip) #define MCREG_Rsp(mc) ((mc)->__ss.__rsp) @@ -221,7 +215,7 @@ ASSIGN_REG_PTR(R15, R15) #elif defined(_ARM64_) #define ASSIGN_UNWIND_REGS \ - ASSIGN_REG(Pc, IP) + ASSIGN_REG(Pc, IP) // ASSIGN_REG(Sp, SP) \ // ASSIGN_REG_PTR(Fp, FP) \ // ASSIGN_REG_PTR(Lr, LR) \ @@ -260,7 +254,7 @@ static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unw // Update unw_context_t from REGDISPLAY static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unwContext) { -#if defined(_ARM_) +#if defined(_ARM_) // Assuming that unw_set_reg() on cursor will point the cursor to the // supposed stack frame is dangerous for libunwind-arm in Linux. // It is because libunwind's unw_cursor_t has other data structure @@ -289,12 +283,11 @@ static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unw #undef ASSIGN_REG #undef ASSIGN_REG_PTR #endif // _ARM_ -} +} // Update unw_cursor_t from REGDISPLAY static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *cursor) { -#ifdef CAN_LINK_SHARED_LIBUNWIND #if defined(_AMD64_) #define ASSIGN_REG(regName1, regName2) \ unw_set_reg(cursor, regName1, regDisplay->regName2); @@ -315,17 +308,13 @@ static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *curso #undef ASSIGN_REG #undef ASSIGN_REG_PTR #endif // _AMD64_ -#endif // CAN_LINK_SHARED_LIBUNWIND } #endif // UNWIND_CONTEXT_IS_UCONTEXT_T // Initialize unw_cursor_t and unw_context_t from REGDISPLAY bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* cursor, unw_context_t* unwContext) { -#ifndef CAN_LINK_SHARED_LIBUNWIND - return false; -#else // CAN_LINK_SHARED_LIBUNWIND - int st; + int st; #if !UNWIND_CONTEXT_IS_UCONTEXT_T st = unw_getcontext(unwContext); @@ -349,19 +338,18 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs #endif return true; -#endif // CAN_LINK_SHARED_LIBUNWIND } -// Update context pointer for a register from the unw_cursor_t. +// Update context pointer for a register from the unw_cursor_t. static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, int reg, PTR_UIntNative *contextPointer) { -#if defined(HAVE_UNW_GET_SAVE_LOC) && defined(CAN_LINK_SHARED_LIBUNWIND) +#if defined(HAVE_UNW_GET_SAVE_LOC) unw_save_loc_t saveLoc; unw_get_save_loc(cursor, reg, &saveLoc); if (saveLoc.type == UNW_SLT_MEMORY) { PTR_UIntNative pLoc = (PTR_UIntNative)saveLoc.u.addr; - // Filter out fake save locations that point to unwContext + // Filter out fake save locations that point to unwContext if (unwContext == NULL || (pLoc < (PTR_UIntNative)unwContext) || ((PTR_UIntNative)(unwContext + 1) <= pLoc)) *contextPointer = (PTR_UIntNative)saveLoc.u.addr; } @@ -373,34 +361,34 @@ static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, i #if defined(_AMD64_) #define GET_CONTEXT_POINTERS \ - GET_CONTEXT_POINTER(UNW_X86_64_RBP, Rbp) \ - GET_CONTEXT_POINTER(UNW_X86_64_RBX, Rbx) \ - GET_CONTEXT_POINTER(UNW_X86_64_R12, R12) \ - GET_CONTEXT_POINTER(UNW_X86_64_R13, R13) \ - GET_CONTEXT_POINTER(UNW_X86_64_R14, R14) \ - GET_CONTEXT_POINTER(UNW_X86_64_R15, R15) + GET_CONTEXT_POINTER(UNW_X86_64_RBP, Rbp) \ + GET_CONTEXT_POINTER(UNW_X86_64_RBX, Rbx) \ + GET_CONTEXT_POINTER(UNW_X86_64_R12, R12) \ + GET_CONTEXT_POINTER(UNW_X86_64_R13, R13) \ + GET_CONTEXT_POINTER(UNW_X86_64_R14, R14) \ + GET_CONTEXT_POINTER(UNW_X86_64_R15, R15) #elif defined(_ARM_) #define GET_CONTEXT_POINTERS \ - GET_CONTEXT_POINTER(UNW_ARM_R4, R4) \ - GET_CONTEXT_POINTER(UNW_ARM_R5, R5) \ - GET_CONTEXT_POINTER(UNW_ARM_R6, R6) \ - GET_CONTEXT_POINTER(UNW_ARM_R7, R7) \ - GET_CONTEXT_POINTER(UNW_ARM_R8, R8) \ - GET_CONTEXT_POINTER(UNW_ARM_R9, R9) \ - GET_CONTEXT_POINTER(UNW_ARM_R10, R10) \ - GET_CONTEXT_POINTER(UNW_ARM_R11, R11) + GET_CONTEXT_POINTER(UNW_ARM_R4, R4) \ + GET_CONTEXT_POINTER(UNW_ARM_R5, R5) \ + GET_CONTEXT_POINTER(UNW_ARM_R6, R6) \ + GET_CONTEXT_POINTER(UNW_ARM_R7, R7) \ + GET_CONTEXT_POINTER(UNW_ARM_R8, R8) \ + GET_CONTEXT_POINTER(UNW_ARM_R9, R9) \ + GET_CONTEXT_POINTER(UNW_ARM_R10, R10) \ + GET_CONTEXT_POINTER(UNW_ARM_R11, R11) #elif defined(_ARM64_) #define GET_CONTEXT_POINTERS \ - GET_CONTEXT_POINTER(UNW_AARCH64_X19, 19) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X20, 20) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X21, 21) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X22, 22) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X23, 23) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X24, 24) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X25, 25) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X26, 26) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X27, 27) \ - GET_CONTEXT_POINTER(UNW_AARCH64_X28, 28) + GET_CONTEXT_POINTER(UNW_AARCH64_X19, 19) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X20, 20) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X21, 21) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X22, 22) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X23, 23) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X24, 24) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X25, 25) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X26, 26) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X27, 27) \ + GET_CONTEXT_POINTER(UNW_AARCH64_X28, 28) #else #error unsupported architecture #endif @@ -409,13 +397,11 @@ static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, i void UnwindCursorToRegDisplay(unw_cursor_t *cursor, unw_context_t *unwContext, REGDISPLAY *regDisplay) { #define GET_CONTEXT_POINTER(unwReg, rdReg) GetContextPointer(cursor, unwContext, unwReg, ®Display->p##rdReg); - GET_CONTEXT_POINTERS + GET_CONTEXT_POINTERS #undef GET_CONTEXT_POINTER -#ifdef CAN_LINK_SHARED_LIBUNWIND unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) ®Display->IP); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) ®Display->SP); -#endif // CAN_LINK_SHARED_LIBUNWIND #if defined(_ARM_) || defined(_ARM64_) regDisplay->IP |= 1; @@ -424,45 +410,45 @@ void UnwindCursorToRegDisplay(unw_cursor_t *cursor, unw_context_t *unwContext, R #if defined(_AMD64_) #define ASSIGN_CONTROL_REGS \ - ASSIGN_REG(Rip, IP) \ - ASSIGN_REG(Rsp, Rsp) + ASSIGN_REG(Rip, IP) \ + ASSIGN_REG(Rsp, Rsp) #define ASSIGN_INTEGER_REGS \ - ASSIGN_REG(Rbx, Rbx) \ - ASSIGN_REG(Rbp, Rbp) \ - ASSIGN_REG(R12, R12) \ - ASSIGN_REG(R13, R13) \ - ASSIGN_REG(R14, R14) \ - ASSIGN_REG(R15, R15) + ASSIGN_REG(Rbx, Rbx) \ + ASSIGN_REG(Rbp, Rbp) \ + ASSIGN_REG(R12, R12) \ + ASSIGN_REG(R13, R13) \ + ASSIGN_REG(R14, R14) \ + ASSIGN_REG(R15, R15) #define ASSIGN_TWO_ARGUMENT_REGS(arg0Reg, arg1Reg) \ - MCREG_Rdi(nativeContext->uc_mcontext) = arg0Reg; \ - MCREG_Rsi(nativeContext->uc_mcontext) = arg1Reg; + MCREG_Rdi(nativeContext->uc_mcontext) = arg0Reg; \ + MCREG_Rsi(nativeContext->uc_mcontext) = arg1Reg; #elif defined(_ARM_) #define ASSIGN_CONTROL_REGS \ - ASSIGN_REG(Pc, IP) \ - ASSIGN_REG(Sp, SP) \ - ASSIGN_REG(Lr, LR) + ASSIGN_REG(Pc, IP) \ + ASSIGN_REG(Sp, SP) \ + ASSIGN_REG(Lr, LR) #define ASSIGN_INTEGER_REGS \ - ASSIGN_REG(R4, R4) \ - ASSIGN_REG(R5, R5) \ - ASSIGN_REG(R6, R6) \ - ASSIGN_REG(R7, R7) \ - ASSIGN_REG(R8, R8) \ - ASSIGN_REG(R9, R9) \ - ASSIGN_REG(R10, R10) \ - ASSIGN_REG(R11, R11) + ASSIGN_REG(R4, R4) \ + ASSIGN_REG(R5, R5) \ + ASSIGN_REG(R6, R6) \ + ASSIGN_REG(R7, R7) \ + ASSIGN_REG(R8, R8) \ + ASSIGN_REG(R9, R9) \ + ASSIGN_REG(R10, R10) \ + ASSIGN_REG(R11, R11) #define ASSIGN_TWO_ARGUMENT_REGS(arg0Reg, arg1Reg) \ - MCREG_R0(nativeContext->uc_mcontext) = arg0Reg; \ - MCREG_R1(nativeContext->uc_mcontext) = arg1Reg; + MCREG_R0(nativeContext->uc_mcontext) = arg0Reg; \ + MCREG_R1(nativeContext->uc_mcontext) = arg1Reg; #elif defined(_ARM64_) #define ASSIGN_CONTROL_REGS \ - ASSIGN_REG(Pc, IP) + ASSIGN_REG(Pc, IP) // ASSIGN_REG(Sp, SP) \ // ASSIGN_REG(Fp, FP) \ // ASSIGN_REG(Lr, LR) \ @@ -480,8 +466,8 @@ void UnwindCursorToRegDisplay(unw_cursor_t *cursor, unw_context_t *unwContext, R // ASSIGN_REG(X28, X28) #define ASSIGN_TWO_ARGUMENT_REGS - // MCREG_X0(nativeContext->uc_mcontext) = arg0Reg; \ - // MCREG_X1(nativeContext->uc_mcontext) = arg1Reg; + // MCREG_X0(nativeContext->uc_mcontext) = arg0Reg; \ + // MCREG_X1(nativeContext->uc_mcontext) = arg1Reg; #else #error unsupported architecture @@ -490,7 +476,7 @@ void UnwindCursorToRegDisplay(unw_cursor_t *cursor, unw_context_t *unwContext, R // Convert Unix native context to PAL_LIMITED_CONTEXT void NativeContextToPalContext(const void* context, PAL_LIMITED_CONTEXT* palContext) { - ucontext_t *nativeContext = (ucontext_t*)context; + ucontext_t *nativeContext = (ucontext_t*)context; #define ASSIGN_REG(regNative, regPal) palContext->regPal = MCREG_##regNative(nativeContext->uc_mcontext); ASSIGN_CONTROL_REGS ASSIGN_INTEGER_REGS @@ -500,7 +486,7 @@ void NativeContextToPalContext(const void* context, PAL_LIMITED_CONTEXT* palCont // Redirect Unix native context to the PAL_LIMITED_CONTEXT and also set the first two argument registers void RedirectNativeContext(void* context, const PAL_LIMITED_CONTEXT* palContext, UIntNative arg0Reg, UIntNative arg1Reg) { - ucontext_t *nativeContext = (ucontext_t*)context; + ucontext_t *nativeContext = (ucontext_t*)context; #define ASSIGN_REG(regNative, regPal) MCREG_##regNative(nativeContext->uc_mcontext) = palContext->regPal; ASSIGN_CONTROL_REGS @@ -572,9 +558,6 @@ uint64_t GetPC(void* context) // Find LSDA and start address for a function at address controlPC bool FindProcInfo(UIntNative controlPC, UIntNative* startAddress, UIntNative* lsda) { -#ifndef CAN_LINK_SHARED_LIBUNWIND - return false; -#else // CAN_LINK_SHARED_LIBUNWIND unw_context_t unwContext; unw_cursor_t cursor; REGDISPLAY regDisplay; @@ -600,15 +583,11 @@ bool FindProcInfo(UIntNative controlPC, UIntNative* startAddress, UIntNative* ls *startAddress = procInfo.start_ip; return true; -#endif // CAN_LINK_SHARED_LIBUNWIND } // Virtually unwind stack to the caller of the context specified by the REGDISPLAY bool VirtualUnwind(REGDISPLAY* pRegisterSet) { -#ifndef CAN_LINK_SHARED_LIBUNWIND - return false; -#else // CAN_LINK_SHARED_LIBUNWIND unw_context_t unwContext; unw_cursor_t cursor; @@ -647,5 +626,4 @@ bool VirtualUnwind(REGDISPLAY* pRegisterSet) #endif return true; -#endif // CAN_LINK_SHARED_LIBUNWIND } |