Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/prerequisites-for-building.md2
-rw-r--r--THIRD-PARTY-NOTICES59
-rw-r--r--src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets1
-rw-r--r--src/Native/Runtime/CMakeLists.txt27
-rw-r--r--src/Native/Runtime/startup.cpp4
-rw-r--r--src/Native/Runtime/unix/PalRedhawkUnix.cpp4
-rw-r--r--src/Native/Runtime/unix/UnixContext.cpp68
-rw-r--r--src/Native/Runtime/unix/config.h.in4
-rw-r--r--src/Native/Runtime/unix/configure.cmake33
-rw-r--r--src/Native/libunwind/include/__libunwind_config.h20
-rw-r--r--src/Native/libunwind/include/libunwind.h22
-rw-r--r--src/Native/libunwind/src/CompactUnwinder.hpp130
-rw-r--r--src/Native/libunwind/src/DwarfInstructions.hpp42
-rw-r--r--src/Native/libunwind/src/Registers.hpp262
-rw-r--r--src/Native/libunwind/src/UnwindCursor.hpp19
-rw-r--r--src/Native/libunwind/src/config.h5
-rw-r--r--src/Native/libunwind/src/libunwind.cpp15
17 files changed, 472 insertions, 245 deletions
diff --git a/Documentation/prerequisites-for-building.md b/Documentation/prerequisites-for-building.md
index 7d4cd8154..a22000607 100644
--- a/Documentation/prerequisites-for-building.md
+++ b/Documentation/prerequisites-for-building.md
@@ -13,7 +13,7 @@ PowerShell also needs to be available from the PATH environment variable (it's t
Install basic dependency packages:
```
-sudo apt-get install cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev libunwind8 libunwind8-dev liblttng-ust liblttng-ust-dev uuid uuid-dev
+sudo apt-get install cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev liblttng-ust liblttng-ust-dev uuid uuid-dev
```
# Mac OSX (10.10+)
diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES
new file mode 100644
index 000000000..41b07973f
--- /dev/null
+++ b/THIRD-PARTY-NOTICES
@@ -0,0 +1,59 @@
+.NET Core uses third-party libraries or other resources that may be
+distributed under licenses different than the .NET Core software.
+
+Attributions and licence notices for test cases originally authored by
+third parties can be found in the respective test directories.
+
+In the event that we accidentally failed to list a required notice, please
+bring it to our attention. Post an issue or email us:
+
+ dotnet@microsoft.com
+
+The attached notices are provided for information only.
+
+License notice for The LLVM Compiler Infrastructure
+---------------------------------------------------
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index cc4a4c2ce..82ca49944 100644
--- a/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -59,7 +59,6 @@ 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/CMakeLists.txt b/src/Native/Runtime/CMakeLists.txt
index fe2786573..59afa5b37 100644
--- a/src/Native/Runtime/CMakeLists.txt
+++ b/src/Native/Runtime/CMakeLists.txt
@@ -73,6 +73,9 @@ if(WIN32)
list(APPEND COMMON_RUNTIME_SOURCES
windows/PalRedhawkCommon.cpp
windows/PalRedhawkMinWin.cpp
+ )
+
+ list(APPEND FULL_RUNTIME_SOURCES
windows/CoffNativeCodeManager.cpp
)
@@ -88,14 +91,32 @@ if(WIN32)
else()
include_directories(unix)
+ include_directories(../libunwind/include)
+
+ # Disable building _Unwind_XXX style APIs of libunwind, since we don't use them.
+ add_definitions(-D_LIBUNWIND_DISABLE_ZERO_COST_APIS=1)
+
+ # Compile unwinding only for the current compilation target architecture
+ add_definitions(-D_LIBUNWIND_IS_NATIVE_ONLY)
list(APPEND COMMON_RUNTIME_SOURCES
- unix/HardwareExceptions.cpp
unix/PalRedhawkUnix.cpp
+ )
+
+ list(APPEND FULL_RUNTIME_SOURCES
+ unix/HardwareExceptions.cpp
unix/UnixContext.cpp
unix/UnixNativeCodeManager.cpp
+ ../libunwind/src/Unwind-EHABI.cpp
+ ../libunwind/src/libunwind.cpp
)
+ if(CLR_CMAKE_PLATFORM_DARWIN)
+ list(APPEND FULL_RUNTIME_SOURCES
+ ../libunwind/src/Unwind_AppleExtras.cpp
+ )
+ endif()
+
if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
set(ARCH_SOURCES_DIR amd64)
set(ASM_SUFFIX S)
@@ -107,6 +128,10 @@ else()
set(ASM_SUFFIX S)
endif()
+ list(APPEND RUNTIME_SOURCES_ARCH_ASM
+ ../libunwind/src/UnwindRegistersRestore.S
+ ../libunwind/src/UnwindRegistersSave.S
+ )
endif()
list(APPEND RUNTIME_SOURCES_ARCH_ASM
diff --git a/src/Native/Runtime/startup.cpp b/src/Native/Runtime/startup.cpp
index ba6844111..8a7b0c56c 100644
--- a/src/Native/Runtime/startup.cpp
+++ b/src/Native/Runtime/startup.cpp
@@ -70,13 +70,13 @@ bool InitDLL(HANDLE hPalInstance)
if (!RestrictedCallouts::Initialize())
return false;
-#ifndef APP_LOCAL_RUNTIME
+#if !defined(APP_LOCAL_RUNTIME) && !defined(USE_PORTABLE_HELPERS)
#ifndef PLATFORM_UNIX
PalAddVectoredExceptionHandler(1, RhpVectoredExceptionHandler);
#else
PalSetHardwareExceptionHandler(RhpHardwareExceptionHandler);
#endif
-#endif
+#endif // !APP_LOCAL_RUNTIME && !USE_PORTABLE_HELPERS
//
// init per-instance state
diff --git a/src/Native/Runtime/unix/PalRedhawkUnix.cpp b/src/Native/Runtime/unix/PalRedhawkUnix.cpp
index 894f11360..c471b80f7 100644
--- a/src/Native/Runtime/unix/PalRedhawkUnix.cpp
+++ b/src/Native/Runtime/unix/PalRedhawkUnix.cpp
@@ -443,12 +443,12 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalInit()
{
return false;
}
-
+#ifndef USE_PORTABLE_HELPERS
if (!InitializeHardwareExceptionHandling())
{
return false;
}
-
+#endif // !USE_PORTABLE_HELPERS
int status = pthread_key_create(&g_threadKey, TlsObjectDestructor);
if (status != 0)
{
diff --git a/src/Native/Runtime/unix/UnixContext.cpp b/src/Native/Runtime/unix/UnixContext.cpp
index 493a27e54..02caacf8f 100644
--- a/src/Native/Runtime/unix/UnixContext.cpp
+++ b/src/Native/Runtime/unix/UnixContext.cpp
@@ -11,10 +11,6 @@
#include "regdisplay.h"
#include "config.h"
-#if !HAVE_LIBUNWIND_H
-#error Don't know how to unwind on this platform
-#endif
-
#include <libunwind.h>
#if HAVE_UCONTEXT_T
@@ -201,56 +197,6 @@
#endif // __APPLE__
-#if UNWIND_CONTEXT_IS_UCONTEXT_T
-
-#if defined(_AMD64_)
-#define ASSIGN_UNWIND_REGS \
- ASSIGN_REG(Rip, IP) \
- ASSIGN_REG(Rsp, SP) \
- ASSIGN_REG_PTR(Rbp, Rbp) \
- ASSIGN_REG_PTR(Rbx, Rbx) \
- ASSIGN_REG_PTR(R12, R12) \
- ASSIGN_REG_PTR(R13, R13) \
- ASSIGN_REG_PTR(R14, R14) \
- ASSIGN_REG_PTR(R15, R15)
-#elif defined(_ARM64_)
-#define ASSIGN_UNWIND_REGS \
- ASSIGN_REG(Pc, IP)
- // ASSIGN_REG(Sp, SP) \
- // ASSIGN_REG_PTR(Fp, FP) \
- // ASSIGN_REG_PTR(Lr, LR) \
- // ASSIGN_REG_PTR(X19, X19) \
- // ASSIGN_REG_PTR(X20, X20) \
- // ASSIGN_REG_PTR(X21, X21) \
- // ASSIGN_REG_PTR(X22, X22) \
- // ASSIGN_REG_PTR(X23, X23) \
- // ASSIGN_REG_PTR(X24, X24) \
- // ASSIGN_REG_PTR(X25, X25) \
- // ASSIGN_REG_PTR(X26, X26) \
- // ASSIGN_REG_PTR(X27, X27) \
- // ASSIGN_REG_PTR(X28, X28)
-#else
-#error unsupported architecture
-#endif
-
-// Convert REGDISPLAY to unw_context_t
-static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unwContext)
-{
-#define ASSIGN_REG(regName1, regName2) \
- MCREG_##regName1(unwContext->uc_mcontext) = regDisplay->regName2;
-
-#define ASSIGN_REG_PTR(regName1, regName2) \
- if (regDisplay->p##regName2 != NULL) \
- MCREG_##regName1(unwContext->uc_mcontext) = *(regDisplay->p##regName2);
-
- ASSIGN_UNWIND_REGS
-
-#undef ASSIGN_REG
-#undef ASSIGN_REG_PTR
-}
-
-#else // UNWIND_CONTEXT_IS_UCONTEXT_T
-
// Update unw_context_t from REGDISPLAY
static void RegDisplayToUnwindContext(REGDISPLAY* regDisplay, unw_context_t *unwContext)
{
@@ -309,20 +255,17 @@ static void RegDisplayToUnwindCursor(REGDISPLAY* regDisplay, unw_cursor_t *curso
#undef ASSIGN_REG_PTR
#endif // _AMD64_
}
-#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)
{
int st;
-#if !UNWIND_CONTEXT_IS_UCONTEXT_T
st = unw_getcontext(unwContext);
if (st < 0)
{
return false;
}
-#endif
RegDisplayToUnwindContext(regDisplay, unwContext);
@@ -332,10 +275,8 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs
return false;
}
-#if !UNWIND_CONTEXT_IS_UCONTEXT_T
// Set the unwind context to the specified windows context
RegDisplayToUnwindCursor(regDisplay, cursor);
-#endif
return true;
}
@@ -343,7 +284,6 @@ bool InitializeUnwindContextAndCursor(REGDISPLAY* regDisplay, unw_cursor_t* curs
// 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)
unw_save_loc_t saveLoc;
unw_get_save_loc(cursor, reg, &saveLoc);
if (saveLoc.type == UNW_SLT_MEMORY)
@@ -353,10 +293,6 @@ static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, i
if (unwContext == NULL || (pLoc < (PTR_UIntNative)unwContext) || ((PTR_UIntNative)(unwContext + 1) <= pLoc))
*contextPointer = (PTR_UIntNative)saveLoc.u.addr;
}
-#else
- // Returning NULL indicates that we don't have context pointers available
- *contextPointer = NULL;
-#endif
}
#if defined(_AMD64_)
@@ -600,7 +536,6 @@ bool VirtualUnwind(REGDISPLAY* pRegisterSet)
return false;
}
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_ARM64_) || defined(_ARM_)
// FreeBSD, NetBSD and OSX appear to do two different things when unwinding
// 1: If it reaches where it cannot unwind anymore, say a
// managed frame. It wil return 0, but also update the $pc
@@ -610,7 +545,6 @@ bool VirtualUnwind(REGDISPLAY* pRegisterSet)
// So we bank the original PC here, so we can compare it after
// the step
uintptr_t curPc = pRegisterSet->GetIP();
-#endif
int st = unw_step(&cursor);
if (st < 0)
@@ -621,13 +555,11 @@ bool VirtualUnwind(REGDISPLAY* pRegisterSet)
// Update the REGDISPLAY to reflect the unwind
UnwindCursorToRegDisplay(&cursor, &unwContext, pRegisterSet);
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_ARM64_) || defined(_ARM_)
if (st == 0 && pRegisterSet->GetIP() == curPc)
{
// TODO: is this correct for CoreRT? Should we return false instead?
pRegisterSet->SetIP(0);
}
-#endif
return true;
}
diff --git a/src/Native/Runtime/unix/config.h.in b/src/Native/Runtime/unix/config.h.in
index 15cd31176..085ceaa3a 100644
--- a/src/Native/Runtime/unix/config.h.in
+++ b/src/Native/Runtime/unix/config.h.in
@@ -4,7 +4,6 @@
#cmakedefine01 HAVE_SYS_VMPARAM_H
#cmakedefine01 HAVE_MACH_VM_TYPES_H
#cmakedefine01 HAVE_MACH_VM_PARAM_H
-#cmakedefine01 HAVE_LIBUNWIND_H
#cmakedefine01 HAVE_PTHREAD_ATTR_GET_NP
#cmakedefine01 HAVE_PTHREAD_GETATTR_NP
@@ -15,14 +14,11 @@
#cmakedefine01 HAVE_SYSCTL
#cmakedefine01 HAVE_SYSCONF
-#cmakedefine HAVE_UNW_GET_SAVE_LOC
-
#cmakedefine01 HAVE_GREGSET_T
#cmakedefine01 HAVE___GREGSET_T
#cmakedefine01 HAVE_SIGINFO_T
#cmakedefine01 HAVE_UCONTEXT_T
-#cmakedefine01 UNWIND_CONTEXT_IS_UCONTEXT_T
#cmakedefine01 HAVE__SC_PHYS_PAGES
#cmakedefine01 HAVE__SC_AVPHYS_PAGES
diff --git a/src/Native/Runtime/unix/configure.cmake b/src/Native/Runtime/unix/configure.cmake
index ed7fc8764..d58e1219e 100644
--- a/src/Native/Runtime/unix/configure.cmake
+++ b/src/Native/Runtime/unix/configure.cmake
@@ -18,7 +18,6 @@ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
check_include_files(sys/vmparam.h HAVE_SYS_VMPARAM_H)
check_include_files(mach/vm_types.h HAVE_MACH_VM_TYPES_H)
check_include_files(mach/vm_param.h HAVE_MACH_VM_PARAM_H)
-check_include_files(libunwind.h HAVE_LIBUNWIND_H)
check_library_exists(pthread pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP)
check_library_exists(pthread pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP)
@@ -29,20 +28,6 @@ check_function_exists(clock_nanosleep HAVE_CLOCK_NANOSLEEP)
check_function_exists(sysctl HAVE_SYSCTL)
check_function_exists(sysconf HAVE_SYSCONF)
-set(CMAKE_REQUIRED_LIBRARIES unwind unwind-generic)
-check_cxx_source_compiles("
-#include <libunwind.h>
-
-int main(int argc, char **argv) {
- unw_cursor_t cursor;
- unw_save_loc_t saveLoc;
- int reg = UNW_REG_IP;
- unw_get_save_loc(&cursor, reg, &saveLoc);
-
- return 0;
-}" HAVE_UNW_GET_SAVE_LOC)
-set(CMAKE_REQUIRED_LIBRARIES)
-
check_struct_has_member ("ucontext_t" uc_mcontext.gregs[0] ucontext.h HAVE_GREGSET_T)
check_struct_has_member ("ucontext_t" uc_mcontext.__gregs[0] ucontext.h HAVE___GREGSET_T)
@@ -53,19 +38,6 @@ set(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_EXTRA_INCLUDE_FILES ucontext.h)
check_type_size(ucontext_t UCONTEXT_T)
-check_cxx_source_compiles("
-#include <libunwind.h>
-#include <ucontext.h>
-
-int main(int argc, char **argv)
-{
- unw_context_t libUnwindContext;
- ucontext_t uContext;
-
- libUnwindContext = uContext;
- return 0;
-}" UNWIND_CONTEXT_IS_UCONTEXT_T)
-
check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES)
check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES)
@@ -133,9 +105,4 @@ int main()
exit(ret);
}" HAVE_MACH_ABSOLUTE_TIME)
-if(NOT HAVE_LIBUNWIND_H)
- unset(HAVE_LIBUNWIND_H CACHE)
- message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8 and libunwind8-dev (or the appropriate packages for your platform)")
-endif()
-
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
diff --git a/src/Native/libunwind/include/__libunwind_config.h b/src/Native/libunwind/include/__libunwind_config.h
index a9d9958be..17a1a192d 100644
--- a/src/Native/libunwind/include/__libunwind_config.h
+++ b/src/Native/libunwind/include/__libunwind_config.h
@@ -20,13 +20,13 @@
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
# if defined(__i386__)
# define _LIBUNWIND_TARGET_I386 1
-# define _LIBUNWIND_CONTEXT_SIZE 8
-# define _LIBUNWIND_CURSOR_SIZE 19
+# define _LIBUNWIND_CONTEXT_SIZE 25
+# define _LIBUNWIND_CURSOR_SIZE 32
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 9
# elif defined(__x86_64__)
# define _LIBUNWIND_TARGET_X86_64 1
-# define _LIBUNWIND_CONTEXT_SIZE 21
-# define _LIBUNWIND_CURSOR_SIZE 33
+# define _LIBUNWIND_CONTEXT_SIZE 38
+# define _LIBUNWIND_CURSOR_SIZE 50
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 17
# elif defined(__ppc__)
# define _LIBUNWIND_TARGET_PPC 1
@@ -35,17 +35,17 @@
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 113
# elif defined(__aarch64__)
# define _LIBUNWIND_TARGET_AARCH64 1
-# define _LIBUNWIND_CONTEXT_SIZE 66
-# define _LIBUNWIND_CURSOR_SIZE 78
+# define _LIBUNWIND_CONTEXT_SIZE 100
+# define _LIBUNWIND_CURSOR_SIZE 112
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 96
# elif defined(__arm__)
# define _LIBUNWIND_TARGET_ARM 1
# if defined(__ARM_WMMX)
-# define _LIBUNWIND_CONTEXT_SIZE 60
-# define _LIBUNWIND_CURSOR_SIZE 67
+# define _LIBUNWIND_CONTEXT_SIZE 76
+# define _LIBUNWIND_CURSOR_SIZE 83
# else
-# define _LIBUNWIND_CONTEXT_SIZE 42
-# define _LIBUNWIND_CURSOR_SIZE 49
+# define _LIBUNWIND_CONTEXT_SIZE 58
+# define _LIBUNWIND_CURSOR_SIZE 65
# endif
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 96
# elif defined(__or1k__)
diff --git a/src/Native/libunwind/include/libunwind.h b/src/Native/libunwind/include/libunwind.h
index 9d72d48d2..59187798d 100644
--- a/src/Native/libunwind/include/libunwind.h
+++ b/src/Native/libunwind/include/libunwind.h
@@ -95,6 +95,26 @@ struct unw_proc_info_t {
};
typedef struct unw_proc_info_t unw_proc_info_t;
+enum unw_save_loc_type_t
+{
+ UNW_SLT_NONE, /* register is not saved ("not an l-value") */
+ UNW_SLT_MEMORY, /* register has been saved in memory */
+ UNW_SLT_REG /* register has been saved in (another) register */
+};
+typedef enum unw_save_loc_type_t unw_save_loc_type_t;
+
+struct unw_save_loc_t
+{
+ unw_save_loc_type_t type;
+ union
+ {
+ unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */
+ unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */
+ }
+ u;
+};
+typedef struct unw_save_loc_t unw_save_loc_t;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -119,7 +139,7 @@ extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL;
extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
-//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
+extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
extern unw_addr_space_t unw_local_addr_space;
diff --git a/src/Native/libunwind/src/CompactUnwinder.hpp b/src/Native/libunwind/src/CompactUnwinder.hpp
index 1be1b0be1..84ae42477 100644
--- a/src/Native/libunwind/src/CompactUnwinder.hpp
+++ b/src/Native/libunwind/src/CompactUnwinder.hpp
@@ -88,19 +88,19 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingEBPFrame(
// no register saved in this slot
break;
case UNWIND_X86_REG_EBX:
- registers.setEBX(addressSpace.get32(savedRegisters));
+ registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_ECX:
- registers.setECX(addressSpace.get32(savedRegisters));
+ registers.setECX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_EDX:
- registers.setEDX(addressSpace.get32(savedRegisters));
+ registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_EDI:
- registers.setEDI(addressSpace.get32(savedRegisters));
+ registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_ESI:
- registers.setESI(addressSpace.get32(savedRegisters));
+ registers.setESI(addressSpace.get32(savedRegisters), savedRegisters);
break;
default:
(void)functionStart;
@@ -205,22 +205,22 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingFrameless(
for (uint32_t i = 0; i < regCount; ++i) {
switch (registersSaved[i]) {
case UNWIND_X86_REG_EBX:
- registers.setEBX(addressSpace.get32(savedRegisters));
+ registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_ECX:
- registers.setECX(addressSpace.get32(savedRegisters));
+ registers.setECX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_EDX:
- registers.setEDX(addressSpace.get32(savedRegisters));
+ registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_EDI:
- registers.setEDI(addressSpace.get32(savedRegisters));
+ registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_ESI:
- registers.setESI(addressSpace.get32(savedRegisters));
+ registers.setESI(addressSpace.get32(savedRegisters), savedRegisters);
break;
case UNWIND_X86_REG_EBP:
- registers.setEBP(addressSpace.get32(savedRegisters));
+ registers.setEBP(addressSpace.get32(savedRegisters), savedRegisters);
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
@@ -240,11 +240,11 @@ void CompactUnwinder_x86<A>::frameUnwind(A &addressSpace,
Registers_x86 &registers) {
typename A::pint_t bp = registers.getEBP();
// ebp points to old ebp
- registers.setEBP(addressSpace.get32(bp));
+ registers.setEBP(addressSpace.get32(bp), bp);
// old esp is ebp less saved ebp and return address
- registers.setSP((uint32_t)bp + 8);
+ registers.setSP((uint32_t)bp + 8, 0);
// pop return address into eip
- registers.setIP(addressSpace.get32(bp + 4));
+ registers.setIP(addressSpace.get32(bp + 4), bp + 4);
}
template <typename A>
@@ -252,9 +252,9 @@ void CompactUnwinder_x86<A>::framelessUnwind(
A &addressSpace, typename A::pint_t returnAddressLocation,
Registers_x86 &registers) {
// return address is on stack after last saved register
- registers.setIP(addressSpace.get32(returnAddressLocation));
+ registers.setIP(addressSpace.get32(returnAddressLocation), returnAddressLocation);
// old esp is before return address
- registers.setSP((uint32_t)returnAddressLocation + 4);
+ registers.setSP((uint32_t)returnAddressLocation + 4, 0);
}
#endif // _LIBUNWIND_TARGET_I386
@@ -319,19 +319,19 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame(
// no register saved in this slot
break;
case UNWIND_X86_64_REG_RBX:
- registers.setRBX(addressSpace.get64(savedRegisters));
+ registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R12:
- registers.setR12(addressSpace.get64(savedRegisters));
+ registers.setR12(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R13:
- registers.setR13(addressSpace.get64(savedRegisters));
+ registers.setR13(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R14:
- registers.setR14(addressSpace.get64(savedRegisters));
+ registers.setR14(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R15:
- registers.setR15(addressSpace.get64(savedRegisters));
+ registers.setR15(addressSpace.get64(savedRegisters), savedRegisters);
break;
default:
(void)functionStart;
@@ -436,22 +436,22 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless(
for (uint32_t i = 0; i < regCount; ++i) {
switch (registersSaved[i]) {
case UNWIND_X86_64_REG_RBX:
- registers.setRBX(addressSpace.get64(savedRegisters));
+ registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R12:
- registers.setR12(addressSpace.get64(savedRegisters));
+ registers.setR12(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R13:
- registers.setR13(addressSpace.get64(savedRegisters));
+ registers.setR13(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R14:
- registers.setR14(addressSpace.get64(savedRegisters));
+ registers.setR14(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_R15:
- registers.setR15(addressSpace.get64(savedRegisters));
+ registers.setR15(addressSpace.get64(savedRegisters), savedRegisters);
break;
case UNWIND_X86_64_REG_RBP:
- registers.setRBP(addressSpace.get64(savedRegisters));
+ registers.setRBP(addressSpace.get64(savedRegisters), savedRegisters);
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
@@ -471,11 +471,11 @@ void CompactUnwinder_x86_64<A>::frameUnwind(A &addressSpace,
Registers_x86_64 &registers) {
uint64_t rbp = registers.getRBP();
// ebp points to old ebp
- registers.setRBP(addressSpace.get64(rbp));
+ registers.setRBP(addressSpace.get64(rbp), rbp);
// old esp is ebp less saved ebp and return address
- registers.setSP(rbp + 16);
+ registers.setSP(rbp + 16, 0);
// pop return address into eip
- registers.setIP(addressSpace.get64(rbp + 8));
+ registers.setIP(addressSpace.get64(rbp + 8), rbp + 8);
}
template <typename A>
@@ -483,9 +483,9 @@ void CompactUnwinder_x86_64<A>::framelessUnwind(A &addressSpace,
uint64_t returnAddressLocation,
Registers_x86_64 &registers) {
// return address is on stack after last saved register
- registers.setIP(addressSpace.get64(returnAddressLocation));
+ registers.setIP(addressSpace.get64(returnAddressLocation), returnAddressLocation);
// old esp is before return address
- registers.setSP(returnAddressLocation + 8);
+ registers.setSP(returnAddressLocation + 8, 0);
}
#endif // _LIBUNWIND_TARGET_X86_64
@@ -539,74 +539,74 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrameless(
uint64_t savedRegisterLoc = registers.getSP() + stackSize;
if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
- registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
- registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
- registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
- registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
- registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
registers.setFloatRegister(UNW_ARM64_D8,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
registers.setFloatRegister(UNW_ARM64_D9,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
registers.setFloatRegister(UNW_ARM64_D10,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
registers.setFloatRegister(UNW_ARM64_D11,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
registers.setFloatRegister(UNW_ARM64_D12,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
registers.setFloatRegister(UNW_ARM64_D13,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
registers.setFloatRegister(UNW_ARM64_D14,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
registers.setFloatRegister(UNW_ARM64_D15,
- addressSpace.getDouble(savedRegisterLoc));
+ addressSpace.getDouble(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
// subtract stack size off of sp
- registers.setSP(savedRegisterLoc);
+ registers.setSP(savedRegisterLoc, 0);
// set pc to be value in lr
- registers.setIP(registers.getRegister(UNW_ARM64_LR));
+ registers.setIP(registers.getRegister(UNW_ARM64_LR), 0);
return UNW_STEP_SUCCESS;
}
@@ -618,33 +618,33 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
uint64_t savedRegisterLoc = registers.getFP() - 8;
if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
- registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
- registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
- registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
- registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
- registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
- registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc));
+ registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc);
savedRegisterLoc -= 8;
}
@@ -683,11 +683,11 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
uint64_t fp = registers.getFP();
// fp points to old fp
- registers.setFP(addressSpace.get64(fp));
+ registers.setFP(addressSpace.get64(fp), fp);
// old sp is fp less saved fp and lr
- registers.setSP(fp + 16);
+ registers.setSP(fp + 16, 0);
// pop return address into pc
- registers.setIP(addressSpace.get64(fp + 8));
+ registers.setIP(addressSpace.get64(fp + 8), fp + 8);
return UNW_STEP_SUCCESS;
}
diff --git a/src/Native/libunwind/src/DwarfInstructions.hpp b/src/Native/libunwind/src/DwarfInstructions.hpp
index 9494bb840..e001359d6 100644
--- a/src/Native/libunwind/src/DwarfInstructions.hpp
+++ b/src/Native/libunwind/src/DwarfInstructions.hpp
@@ -57,7 +57,8 @@ private:
const R &registers,
pint_t initialStackValue);
static pint_t getSavedRegister(A &addressSpace, const R &registers,
- pint_t cfa, const RegisterLocation &savedReg);
+ pint_t cfa, const RegisterLocation &savedReg,
+ pint_t& location);
static double getSavedFloatRegister(A &addressSpace, const R &registers,
pint_t cfa, const RegisterLocation &savedReg);
static v128 getSavedVectorRegister(A &addressSpace, const R &registers,
@@ -80,21 +81,24 @@ private:
template <typename A, typename R>
typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
A &addressSpace, const R &registers, pint_t cfa,
- const RegisterLocation &savedReg) {
+ const RegisterLocation &savedReg,
+ typename A::pint_t& location) {
switch (savedReg.location) {
case CFI_Parser<A>::kRegisterInCFA:
- return addressSpace.getP(cfa + (pint_t)savedReg.value);
+ location = cfa + (pint_t)savedReg.value;
+ return addressSpace.getP(location);
case CFI_Parser<A>::kRegisterAtExpression:
- return addressSpace.getP(
- evaluateExpression((pint_t)savedReg.value, addressSpace,
- registers, cfa));
+ location = evaluateExpression((pint_t)savedReg.value, addressSpace,
+ registers, cfa);
+ return addressSpace.getP(location);
case CFI_Parser<A>::kRegisterIsExpression:
+ location = 0;
return evaluateExpression((pint_t)savedReg.value, addressSpace,
registers, cfa);
-
case CFI_Parser<A>::kRegisterInRegister:
+ location = 0;
return registers.getRegister((int)savedReg.value);
case CFI_Parser<A>::kRegisterUnused:
@@ -183,13 +187,21 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
newRegisters.setVectorRegister(
i, getSavedVectorRegister(addressSpace, registers, cfa,
prolog.savedRegisters[i]));
- else if (i == (int)cieInfo.returnAddressRegister)
+ else if (i == (int)cieInfo.returnAddressRegister) {
+ pint_t dummyLocation;
returnAddress = getSavedRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]);
- else if (registers.validRegister(i))
- newRegisters.setRegister(
- i, getSavedRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]));
+ prolog.savedRegisters[i],
+ dummyLocation);
+ }
+ else if (registers.validRegister(i)) {
+ pint_t value;
+ pint_t location;
+ value = getSavedRegister(addressSpace, registers, cfa,
+ prolog.savedRegisters[i],
+ location);
+
+ newRegisters.setRegister(i, value, location);
+ }
else
return UNW_EBADREG;
}
@@ -197,11 +209,11 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
// By definition, the CFA is the stack pointer at the call site, so
// restoring SP means setting it to CFA.
- newRegisters.setSP(cfa);
+ newRegisters.setSP(cfa, 0);
// Return address is address after call site instruction, so setting IP to
// that does simualates a return.
- newRegisters.setIP(returnAddress);
+ newRegisters.setIP(returnAddress, 0);
// Simulate the step by replacing the register set with the new ones.
registers = newRegisters;
diff --git a/src/Native/libunwind/src/Registers.hpp b/src/Native/libunwind/src/Registers.hpp
index 8066b808c..cca90092f 100644
--- a/src/Native/libunwind/src/Registers.hpp
+++ b/src/Native/libunwind/src/Registers.hpp
@@ -35,7 +35,8 @@ public:
bool validRegister(int num) const;
uint32_t getRegister(int num) const;
- void setRegister(int num, uint32_t value);
+ void setRegister(int num, uint32_t value, uint32_t location);
+ uint32_t getRegisterLocation(int num) const;
bool validFloatRegister(int) const { return false; }
double getFloatRegister(int num) const;
void setFloatRegister(int num, double value);
@@ -47,21 +48,21 @@ public:
static int lastDwarfRegNum() { return 8; }
uint32_t getSP() const { return _registers.__esp; }
- void setSP(uint32_t value) { _registers.__esp = value; }
+ void setSP(uint32_t value, uint32_t location) { _registers.__esp = value; _registerLocations.__esp = location; }
uint32_t getIP() const { return _registers.__eip; }
- void setIP(uint32_t value) { _registers.__eip = value; }
+ void setIP(uint32_t value, uint32_t location) { _registers.__eip = value; _registerLocations.__eip = location; }
uint32_t getEBP() const { return _registers.__ebp; }
- void setEBP(uint32_t value) { _registers.__ebp = value; }
+ void setEBP(uint32_t value, uint32_t location) { _registers.__ebp = value; _registerLocations.__ebp = location; }
uint32_t getEBX() const { return _registers.__ebx; }
- void setEBX(uint32_t value) { _registers.__ebx = value; }
+ void setEBX(uint32_t value, uint32_t location) { _registers.__ebx = value; _registerLocations.__ebx = location; }
uint32_t getECX() const { return _registers.__ecx; }
- void setECX(uint32_t value) { _registers.__ecx = value; }
+ void setECX(uint32_t value, uint32_t location) { _registers.__ecx = value; _registerLocations.__ecx = location; }
uint32_t getEDX() const { return _registers.__edx; }
- void setEDX(uint32_t value) { _registers.__edx = value; }
+ void setEDX(uint32_t value, uint32_t location) { _registers.__edx = value; _registerLocations.__edx = location; }
uint32_t getESI() const { return _registers.__esi; }
- void setESI(uint32_t value) { _registers.__esi = value; }
+ void setESI(uint32_t value, uint32_t location) { _registers.__esi = value; _registerLocations.__esi = location; }
uint32_t getEDI() const { return _registers.__edi; }
- void setEDI(uint32_t value) { _registers.__edi = value; }
+ void setEDI(uint32_t value, uint32_t location) { _registers.__edi = value; _registerLocations.__edi = location; }
private:
struct GPRs {
@@ -82,18 +83,32 @@ private:
unsigned int __fs;
unsigned int __gs;
};
+ struct GPRLocations {
+ unsigned int __eax;
+ unsigned int __ebx;
+ unsigned int __ecx;
+ unsigned int __edx;
+ unsigned int __edi;
+ unsigned int __esi;
+ unsigned int __ebp;
+ unsigned int __esp;
+ unsigned int __eip;
+ };
GPRs _registers;
+ GPRLocations _registerLocations;
};
inline Registers_x86::Registers_x86(const void *registers) {
static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
"x86 registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
}
inline Registers_x86::Registers_x86() {
memset(&_registers, 0, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
}
inline bool Registers_x86::validRegister(int regNum) const {
@@ -134,42 +149,78 @@ inline uint32_t Registers_x86::getRegister(int regNum) const {
_LIBUNWIND_ABORT("unsupported x86 register");
}
-inline void Registers_x86::setRegister(int regNum, uint32_t value) {
+inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t location) {
switch (regNum) {
case UNW_REG_IP:
_registers.__eip = value;
+ _registerLocations.__eip = location;
return;
case UNW_REG_SP:
_registers.__esp = value;
+ _registerLocations.__esp = location;
return;
case UNW_X86_EAX:
_registers.__eax = value;
+ _registerLocations.__eax = location;
return;
case UNW_X86_ECX:
_registers.__ecx = value;
+ _registerLocations.__ecx = location;
return;
case UNW_X86_EDX:
_registers.__edx = value;
+ _registerLocations.__edx = location;
return;
case UNW_X86_EBX:
_registers.__ebx = value;
+ _registerLocations.__ebx = location;
return;
case UNW_X86_EBP:
_registers.__ebp = value;
+ _registerLocations.__ebp = location;
return;
case UNW_X86_ESP:
_registers.__esp = value;
+ _registerLocations.__esp = location;
return;
case UNW_X86_ESI:
_registers.__esi = value;
+ _registerLocations.__esi = location;
return;
case UNW_X86_EDI:
_registers.__edi = value;
+ _registerLocations.__edi = location;
return;
}
_LIBUNWIND_ABORT("unsupported x86 register");
}
+inline uint32_t Registers_x86::getRegisterLocation(int regNum) const {
+ switch (regNum) {
+ case UNW_REG_IP:
+ return _registerLocations.__eip;
+ case UNW_REG_SP:
+ return _registerLocations.__esp;
+ case UNW_X86_EAX:
+ return _registerLocations.__eax;
+ case UNW_X86_ECX:
+ return _registerLocations.__ecx;
+ case UNW_X86_EDX:
+ return _registerLocations.__edx;
+ case UNW_X86_EBX:
+ return _registerLocations.__ebx;
+ case UNW_X86_EBP:
+ return _registerLocations.__ebp;
+ case UNW_X86_ESP:
+ return _registerLocations.__esp;
+ case UNW_X86_ESI:
+ return _registerLocations.__esi;
+ case UNW_X86_EDI:
+ return _registerLocations.__edi;
+ }
+ _LIBUNWIND_ABORT("unsupported x86 register");
+}
+
inline const char *Registers_x86::getRegisterName(int regNum) {
switch (regNum) {
case UNW_REG_IP:
@@ -225,7 +276,8 @@ public:
bool validRegister(int num) const;
uint64_t getRegister(int num) const;
- void setRegister(int num, uint64_t value);
+ void setRegister(int num, uint64_t value, uint64_t location);
+ uint64_t getRegisterLocation(int num) const;
bool validFloatRegister(int) const { return false; }
double getFloatRegister(int num) const;
void setFloatRegister(int num, double value);
@@ -237,21 +289,21 @@ public:
static int lastDwarfRegNum() { return 16; }
uint64_t getSP() const { return _registers.__rsp; }
- void setSP(uint64_t value) { _registers.__rsp = value; }
+ void setSP(uint64_t value, uint64_t location) { _registers.__rsp = value; _registerLocations.__rsp = location;}
uint64_t getIP() const { return _registers.__rip; }
- void setIP(uint64_t value) { _registers.__rip = value; }
+ void setIP(uint64_t value, uint64_t location) { _registers.__rip = value; _registerLocations.__rip = location; }
uint64_t getRBP() const { return _registers.__rbp; }
- void setRBP(uint64_t value) { _registers.__rbp = value; }
+ void setRBP(uint64_t value, uint64_t location) { _registers.__rbp = value; _registerLocations.__rbp = location; }
uint64_t getRBX() const { return _registers.__rbx; }
- void setRBX(uint64_t value) { _registers.__rbx = value; }
+ void setRBX(uint64_t value, uint64_t location) { _registers.__rbx = value; _registerLocations.__rbx = location; }
uint64_t getR12() const { return _registers.__r12; }
- void setR12(uint64_t value) { _registers.__r12 = value; }
+ void setR12(uint64_t value, uint64_t location) { _registers.__r12 = value; _registerLocations.__r12 = location; }
uint64_t getR13() const { return _registers.__r13; }
- void setR13(uint64_t value) { _registers.__r13 = value; }
+ void setR13(uint64_t value, uint64_t location) { _registers.__r13 = value; _registerLocations.__r13 = location; }
uint64_t getR14() const { return _registers.__r14; }
- void setR14(uint64_t value) { _registers.__r14 = value; }
+ void setR14(uint64_t value, uint64_t location) { _registers.__r14 = value; _registerLocations.__r14 = location; }
uint64_t getR15() const { return _registers.__r15; }
- void setR15(uint64_t value) { _registers.__r15 = value; }
+ void setR15(uint64_t value, uint64_t location) { _registers.__r15 = value; _registerLocations.__r15 = location; }
private:
struct GPRs {
@@ -277,17 +329,39 @@ private:
uint64_t __fs;
uint64_t __gs;
};
+ struct GPRLocations {
+ uint64_t __rax;
+ uint64_t __rbx;
+ uint64_t __rcx;
+ uint64_t __rdx;
+ uint64_t __rdi;
+ uint64_t __rsi;
+ uint64_t __rbp;
+ uint64_t __rsp;
+ uint64_t __r8;
+ uint64_t __r9;
+ uint64_t __r10;
+ uint64_t __r11;
+ uint64_t __r12;
+ uint64_t __r13;
+ uint64_t __r14;
+ uint64_t __r15;
+ uint64_t __rip;
+ };
GPRs _registers;
+ GPRLocations _registerLocations;
};
inline Registers_x86_64::Registers_x86_64(const void *registers) {
static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
"x86_64 registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
}
inline Registers_x86_64::Registers_x86_64() {
memset(&_registers, 0, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
}
inline bool Registers_x86_64::validRegister(int regNum) const {
@@ -344,61 +418,121 @@ inline uint64_t Registers_x86_64::getRegister(int regNum) const {
_LIBUNWIND_ABORT("unsupported x86_64 register");
}
-inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
+inline uint64_t Registers_x86_64::getRegisterLocation(int regNum) const {
+ switch (regNum) {
+ case UNW_REG_IP:
+ return _registerLocations.__rip;
+ case UNW_REG_SP:
+ return _registerLocations.__rsp;
+ case UNW_X86_64_RAX:
+ return _registerLocations.__rax;
+ case UNW_X86_64_RDX:
+ return _registerLocations.__rdx;
+ case UNW_X86_64_RCX:
+ return _registerLocations.__rcx;
+ case UNW_X86_64_RBX:
+ return _registerLocations.__rbx;
+ case UNW_X86_64_RSI:
+ return _registerLocations.__rsi;
+ case UNW_X86_64_RDI:
+ return _registerLocations.__rdi;
+ case UNW_X86_64_RBP:
+ return _registerLocations.__rbp;
+ case UNW_X86_64_RSP:
+ return _registerLocations.__rsp;
+ case UNW_X86_64_R8:
+ return _registerLocations.__r8;
+ case UNW_X86_64_R9:
+ return _registerLocations.__r9;
+ case UNW_X86_64_R10:
+ return _registerLocations.__r10;
+ case UNW_X86_64_R11:
+ return _registerLocations.__r11;
+ case UNW_X86_64_R12:
+ return _registerLocations.__r12;
+ case UNW_X86_64_R13:
+ return _registerLocations.__r13;
+ case UNW_X86_64_R14:
+ return _registerLocations.__r14;
+ case UNW_X86_64_R15:
+ return _registerLocations.__r15;
+ }
+ _LIBUNWIND_ABORT("unsupported x86_64 register");
+}
+
+inline void Registers_x86_64::setRegister(int regNum, uint64_t value, uint64_t location) {
switch (regNum) {
case UNW_REG_IP:
_registers.__rip = value;
+ _registerLocations.__rip = location;
return;
case UNW_REG_SP:
_registers.__rsp = value;
+ _registerLocations.__rsp = location;
return;
case UNW_X86_64_RAX:
_registers.__rax = value;
+ _registerLocations.__rax = location;
return;
case UNW_X86_64_RDX:
_registers.__rdx = value;
+ _registerLocations.__rdx = location;
return;
case UNW_X86_64_RCX:
_registers.__rcx = value;
+ _registerLocations.__rcx = location;
return;
case UNW_X86_64_RBX:
_registers.__rbx = value;
+ _registerLocations.__rbx = location;
return;
case UNW_X86_64_RSI:
_registers.__rsi = value;
+ _registerLocations.__rsi = location;
return;
case UNW_X86_64_RDI:
_registers.__rdi = value;
+ _registerLocations.__rdi = location;
return;
case UNW_X86_64_RBP:
_registers.__rbp = value;
+ _registerLocations.__rbp = location;
return;
case UNW_X86_64_RSP:
_registers.__rsp = value;
+ _registerLocations.__rsp = location;
return;
case UNW_X86_64_R8:
_registers.__r8 = value;
+ _registerLocations.__r8 = location;
return;
case UNW_X86_64_R9:
_registers.__r9 = value;
+ _registerLocations.__r9 = location;
return;
case UNW_X86_64_R10:
_registers.__r10 = value;
+ _registerLocations.__r10 = location;
return;
case UNW_X86_64_R11:
_registers.__r11 = value;
+ _registerLocations.__r11 = location;
return;
case UNW_X86_64_R12:
_registers.__r12 = value;
+ _registerLocations.__r12 = location;
return;
case UNW_X86_64_R13:
_registers.__r13 = value;
+ _registerLocations.__r13 = location;
return;
case UNW_X86_64_R14:
_registers.__r14 = value;
+ _registerLocations.__r14 = location;
return;
case UNW_X86_64_R15:
_registers.__r15 = value;
+ _registerLocations.__r15 = location;
return;
}
_LIBUNWIND_ABORT("unsupported x86_64 register");
@@ -1041,7 +1175,8 @@ public:
bool validRegister(int num) const;
uint64_t getRegister(int num) const;
- void setRegister(int num, uint64_t value);
+ void setRegister(int num, uint64_t value, uint64_t location);
+ uint64_t getRegisterLocation(int num) const;
bool validFloatRegister(int num) const;
double getFloatRegister(int num) const;
void setFloatRegister(int num, double value);
@@ -1053,11 +1188,11 @@ public:
static int lastDwarfRegNum() { return 95; }
uint64_t getSP() const { return _registers.__sp; }
- void setSP(uint64_t value) { _registers.__sp = value; }
+ void setSP(uint64_t value, uint64_t location) { _registers.__sp = value; _registerLocations.__sp = location; }
uint64_t getIP() const { return _registers.__pc; }
- void setIP(uint64_t value) { _registers.__pc = value; }
+ void setIP(uint64_t value, uint64_t location) { _registers.__pc = value; _registerLocations.__pc = location; }
uint64_t getFP() const { return _registers.__fp; }
- void setFP(uint64_t value) { _registers.__fp = value; }
+ void setFP(uint64_t value, uint64_t location) { _registers.__fp = value; _registerLocations.__fp = location; }
private:
struct GPRs {
@@ -1069,8 +1204,18 @@ private:
uint64_t padding; // 16-byte align
};
- GPRs _registers;
- double _vectorHalfRegisters[32];
+ struct GPRLocations {
+ uint64_t __x[29]; // x0-x28
+ uint64_t __fp; // Frame pointer x29
+ uint64_t __lr; // Link register x30
+ uint64_t __sp; // Stack pointer x31
+ uint64_t __pc; // Program counter
+ uint64_t padding; // 16-byte align
+ };
+
+ GPRs _registers;
+ GPRLocations _registerLocations;
+ double _vectorHalfRegisters[32];
// Currently only the lower double in 128-bit vectore registers
// is perserved during unwinding. We could define new register
// numbers (> 96) which mean whole vector registers, then this
@@ -1081,6 +1226,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) {
static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
"arm64 registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
static_assert(sizeof(GPRs) == 0x110,
"expected VFP registers to be at offset 272");
memcpy(_vectorHalfRegisters,
@@ -1090,6 +1236,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) {
inline Registers_arm64::Registers_arm64() {
memset(&_registers, 0, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
}
@@ -1117,17 +1264,33 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const {
_LIBUNWIND_ABORT("unsupported arm64 register");
}
-inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
- if (regNum == UNW_REG_IP)
+inline void Registers_arm64::setRegister(int regNum, uint64_t value, uint64_t location) {
+ if (regNum == UNW_REG_IP) {
_registers.__pc = value;
- else if (regNum == UNW_REG_SP)
+ _registerLocations.__pc = location;
+ }
+ else if (regNum == UNW_REG_SP) {
_registers.__sp = value;
- else if ((regNum >= 0) && (regNum < 32))
+ _registerLocations.__sp = location;
+ }
+ else if ((regNum >= 0) && (regNum < 32)) {
_registers.__x[regNum] = value;
+ _registerLocations.__x[regNum] = location;
+ }
else
_LIBUNWIND_ABORT("unsupported arm64 register");
}
+inline uint64_t Registers_arm64::getRegisterLocation(int regNum) const {
+ if (regNum == UNW_REG_IP)
+ return _registerLocations.__pc;
+ if (regNum == UNW_REG_SP)
+ return _registerLocations.__sp;
+ if ((regNum >= 0) && (regNum < 32))
+ return _registerLocations.__x[regNum];
+ _LIBUNWIND_ABORT("unsupported arm64 register");
+}
+
inline const char *Registers_arm64::getRegisterName(int regNum) {
switch (regNum) {
case UNW_REG_IP:
@@ -1311,7 +1474,8 @@ public:
bool validRegister(int num) const;
uint32_t getRegister(int num);
- void setRegister(int num, uint32_t value);
+ void setRegister(int num, uint32_t value, uint32_t location);
+ uint32_t getRegisterLocation(int num) const;
bool validFloatRegister(int num) const;
unw_fpreg_t getFloatRegister(int num);
void setFloatRegister(int num, unw_fpreg_t value);
@@ -1325,9 +1489,9 @@ public:
}
uint32_t getSP() const { return _registers.__sp; }
- void setSP(uint32_t value) { _registers.__sp = value; }
+ void setSP(uint32_t value, uint32_t location) { _registers.__sp = value; _registerLocations.__sp = location; }
uint32_t getIP() const { return _registers.__pc; }
- void setIP(uint32_t value) { _registers.__pc = value; }
+ void setIP(uint32_t value, uint32_t location) { _registers.__pc = value; _registerLocations.__pc = location; }
void saveVFPAsX() {
assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
@@ -1359,6 +1523,13 @@ private:
uint32_t __pc; // Program counter r15
};
+ struct GPRLocations {
+ uint32_t __r[13]; // r0-r12
+ uint32_t __sp; // Stack pointer r13
+ uint32_t __lr; // Link register r14
+ uint32_t __pc; // Program counter r15
+ };
+
static void saveVFPWithFSTMD(unw_fpreg_t*);
static void saveVFPWithFSTMX(unw_fpreg_t*);
static void saveVFPv3(unw_fpreg_t*);
@@ -1375,6 +1546,7 @@ private:
// ARM registers
GPRs _registers;
+ GPRLocations _registerLocations;
// We save floating point registers lazily because we can't know ahead of
// time which ones are used. See EHABI #4.7.
@@ -1412,6 +1584,7 @@ inline Registers_arm::Registers_arm(const void *registers)
"arm registers do not fit into unw_context_t");
// See unw_getcontext() note about data.
memcpy(&_registers, registers, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
#if defined(__ARM_WMMX)
@@ -1427,6 +1600,7 @@ inline Registers_arm::Registers_arm()
_saved_vfp_d0_d15(false),
_saved_vfp_d16_d31(false) {
memset(&_registers, 0, sizeof(_registers));
+ memset(&_registerLocations, 0, sizeof(_registerLocations));
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
#if defined(__ARM_WMMX)
@@ -1483,24 +1657,28 @@ inline uint32_t Registers_arm::getRegister(int regNum) {
_LIBUNWIND_ABORT("unsupported arm register");
}
-inline void Registers_arm::setRegister(int regNum, uint32_t value) {
+inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t location) {
if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
_registers.__sp = value;
+ _registerLocations.__sp = location;
return;
}
if (regNum == UNW_ARM_LR) {
_registers.__lr = value;
+ _registerLocations.__lr = location;
return;
}
if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
_registers.__pc = value;
+ _registerLocations.__pc = location;
return;
}
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
_registers.__r[regNum] = value;
+ _registerLocations.__r[regNum] = location;
return;
}
@@ -1518,6 +1696,22 @@ inline void Registers_arm::setRegister(int regNum, uint32_t value) {
_LIBUNWIND_ABORT("unsupported arm register");
}
+inline uint32_t Registers_arm::getRegisterLocation(int regNum) const {
+ if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
+ return _registerLocations.__sp;
+
+ if (regNum == UNW_ARM_LR)
+ return _registerLocations.__lr;
+
+ if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
+ return _registerLocations.__pc;
+
+ if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
+ return _registerLocations.__r[regNum];
+
+ _LIBUNWIND_ABORT("unsupported arm register");
+}
+
inline const char *Registers_arm::getRegisterName(int regNum) {
switch (regNum) {
case UNW_REG_IP:
diff --git a/src/Native/libunwind/src/UnwindCursor.hpp b/src/Native/libunwind/src/UnwindCursor.hpp
index 4ed5a6ec0..7a1149eaf 100644
--- a/src/Native/libunwind/src/UnwindCursor.hpp
+++ b/src/Native/libunwind/src/UnwindCursor.hpp
@@ -384,9 +384,12 @@ public:
virtual ~AbstractUnwindCursor() {}
virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); }
virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); }
- virtual void setReg(int, unw_word_t) {
+ virtual void setReg(int, unw_word_t, unw_word_t) {
_LIBUNWIND_ABORT("setReg not implemented");
}
+ virtual unw_word_t getRegLocation(int) {
+ _LIBUNWIND_ABORT("getRegLocation not implemented");
+ }
virtual bool validFloatReg(int) {
_LIBUNWIND_ABORT("validFloatReg not implemented");
}
@@ -429,7 +432,8 @@ public:
virtual ~UnwindCursor() {}
virtual bool validReg(int);
virtual unw_word_t getReg(int);
- virtual void setReg(int, unw_word_t);
+ virtual void setReg(int, unw_word_t, unw_word_t);
+ virtual unw_word_t getRegLocation(int);
virtual bool validFloatReg(int);
virtual unw_fpreg_t getFloatReg(int);
virtual void setFloatReg(int, unw_fpreg_t);
@@ -634,8 +638,13 @@ unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
}
template <typename A, typename R>
-void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
- _registers.setRegister(regNum, (typename A::pint_t)value);
+void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value, unw_word_t location) {
+ _registers.setRegister(regNum, (typename A::pint_t)value, (typename A::pint_t)location);
+}
+
+template <typename A, typename R>
+unw_word_t UnwindCursor<A, R>::getRegLocation(int regNum) {
+ return _registers.getRegisterLocation(regNum);
}
template <typename A, typename R>
@@ -1349,7 +1358,7 @@ int UnwindCursor<A, R>::step() {
if (_unwindInfoMissing)
return UNW_STEP_END;
if (_info.gp)
- setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp);
+ setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp, 0);
}
return result;
diff --git a/src/Native/libunwind/src/config.h b/src/Native/libunwind/src/config.h
index 4e4dd997a..bba0f9c9f 100644
--- a/src/Native/libunwind/src/config.h
+++ b/src/Native/libunwind/src/config.h
@@ -68,11 +68,12 @@
#define _LIBUNWIND_SUPPORT_FRAME_APIS 0
#endif
-#if defined(__i386__) || defined(__x86_64__) || \
+#if !_LIBUNWIND_DISABLE_ZERO_COST_APIS && ( \
+ defined(__i386__) || defined(__x86_64__) || \
defined(__ppc__) || defined(__ppc64__) || \
(!defined(__APPLE__) && defined(__arm__)) || \
(defined(__arm64__) || defined(__aarch64__)) || \
- (defined(__APPLE__) && defined(__mips__))
+ (defined(__APPLE__) && defined(__mips__)))
#define _LIBUNWIND_BUILD_ZERO_COST_APIS 1
#else
#define _LIBUNWIND_BUILD_ZERO_COST_APIS 0
diff --git a/src/Native/libunwind/src/libunwind.cpp b/src/Native/libunwind/src/libunwind.cpp
index bbb829eed..c9e3ba15a 100644
--- a/src/Native/libunwind/src/libunwind.cpp
+++ b/src/Native/libunwind/src/libunwind.cpp
@@ -177,7 +177,7 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
typedef LocalAddressSpace::pint_t pint_t;
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validReg(regNum)) {
- co->setReg(regNum, (pint_t)value);
+ co->setReg(regNum, (pint_t)value, 0);
// specical case altering IP to re-find info (being called by personality
// function)
if (regNum == UNW_REG_IP)
@@ -221,6 +221,19 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
return UNW_EBADREG;
}
+/// Get location of specified register at cursor position in stack frame.
+_LIBUNWIND_EXPORT int unw_get_save_loc(unw_cursor_t* cursor, int regNum,
+ unw_save_loc_t* location)
+{
+ AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
+ if (co->validReg(regNum)) {
+ // We only support memory locations, not register locations
+ location->u.addr = co->getRegLocation(regNum);
+ location->type = (location->u.addr == 0) ? UNW_SLT_NONE : UNW_SLT_MEMORY;
+ return UNW_ESUCCESS;
+ }
+ return UNW_EBADREG;
+}
/// Move cursor to next frame.
_LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {