summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.cpp336
-rw-r--r--lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.h83
-rw-r--r--lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp320
-rw-r--r--lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.h22
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp73
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLibUnwind.h66
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/include/libunwind.h509
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/include/mach-o/compact_unwind_encoding.h212
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/include/unwind.h213
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp455
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp108
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyInstructions.hpp147
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp411
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/CompactUnwinder.hpp1019
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp1627
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/DwarfParser.hpp869
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/FileAbstraction.hpp135
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/InternalMacros.h89
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/Registers.hpp456
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/Registers.s261
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp80
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp984
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/RemoteRegisterMap.hpp405
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/RemoteUnwindProfile.h85
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/Unwind-sjlj.c466
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp1313
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1-gcc-ext.c282
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1.c443
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/dwarf2.h245
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/libunwind_priv.h35
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx428
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/unw_getcontext.s229
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp43
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h1
37 files changed, 0 insertions, 12462 deletions
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
index 4509eb7f150..57db2ad0405 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
@@ -23,8 +23,6 @@
#include "lldb/Breakpoint/WatchpointLocation.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Target/Unwind.h"
-#include "LibUnwindRegisterContext.h"
-#include "UnwindLibUnwind.h"
#include "UnwindMacOSXFrameBackchain.h"
using namespace lldb;
diff --git a/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.cpp b/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.cpp
deleted file mode 100644
index 96bba7e9b99..00000000000
--- a/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-//===-- LibUnwindRegisterContext.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LibUnwindRegisterContext.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Target/Thread.h"
-// Project includes
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// LibUnwindRegisterContext constructor
-//----------------------------------------------------------------------
-LibUnwindRegisterContext::LibUnwindRegisterContext
-(
- Thread &thread,
- StackFrame *frame,
- const lldb_private::unw_cursor_t& unwind_cursor
-) :
- RegisterContext (thread, frame),
- m_unwind_cursor (unwind_cursor),
- m_unwind_cursor_is_valid (true)
-{
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-LibUnwindRegisterContext::~LibUnwindRegisterContext()
-{
-}
-
-void
-LibUnwindRegisterContext::Invalidate ()
-{
- m_unwind_cursor_is_valid = false;
-}
-
-size_t
-LibUnwindRegisterContext::GetRegisterCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterCount();
-}
-
-const lldb::RegisterInfo *
-LibUnwindRegisterContext::GetRegisterInfoAtIndex (uint32_t reg)
-{
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
-}
-
-size_t
-LibUnwindRegisterContext::GetRegisterSetCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterSetCount();
-}
-
-
-
-const lldb::RegisterSet *
-LibUnwindRegisterContext::GetRegisterSet (uint32_t reg_set)
-{
- return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
-}
-
-
-
-bool
-LibUnwindRegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
-{
- if (m_unwind_cursor_is_valid == false)
- return false;
-
- // Read the register
- unw_word_t reg_value;
- if (unw_get_reg (&m_unwind_cursor, reg, &reg_value) != UNW_ESUCCESS)
- return false;
-
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- switch (reg_info->encoding)
- {
- case eEncodingUint:
- switch (reg_info->byte_size)
- {
- case 1:
- case 2:
- case 4:
- value = (uint32_t)reg_value;
- return true;
-
- case 8:
- value = (uint64_t)reg_value;
- return true;
- }
- break;
-
- case eEncodingSint:
- switch (reg_info->byte_size)
- {
- case 1:
- case 2:
- case 4:
- value = (int32_t)reg_value;
- return true;
-
- case 8:
- value = (int64_t)reg_value;
- return true;
- }
- break;
-
- case eEncodingIEEE754:
- if (reg_info->byte_size > sizeof(unw_word_t))
- return false;
-
- switch (reg_info->byte_size)
- {
- case sizeof (float):
- if (sizeof (float) == sizeof(uint32_t))
- {
- value = (uint32_t)reg_value;
- return true;
- }
- else if (sizeof (float) == sizeof(uint64_t))
- {
- value = (uint64_t)reg_value;
- return true;
- }
- break;
-
- case sizeof (double):
- if (sizeof (double) == sizeof(uint32_t))
- {
- value = (uint32_t)reg_value;
- return true;
- }
- else if (sizeof (double) == sizeof(uint64_t))
- {
- value = (uint64_t)reg_value;
- return true;
- }
- break;
-
- case sizeof (long double):
- if (sizeof (long double) == sizeof(uint32_t))
- {
- value = (uint32_t)reg_value;
- return true;
- }
- else if (sizeof (long double) == sizeof(uint64_t))
- {
- value = (uint64_t)reg_value;
- return true;
- }
- break;
- }
- break;
-
- default:
- break;
- }
- return false;
-}
-
-
-bool
-LibUnwindRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
-{
- Scalar reg_value;
-
- if (ReadRegisterValue (reg, reg_value))
- {
- if (reg_value.GetData(data))
- {
- // "reg_value" is local and now "data" points to the data within
- // "reg_value", so we must make a copy that will live within "data"
- DataBufferSP data_sp (new DataBufferHeap (data.GetDataStart(), data.GetByteSize()));
- data.SetData (data_sp, 0, data.GetByteSize());
- return true;
- }
- }
- return false;
-}
-
-
-bool
-LibUnwindRegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- if (reg_info == NULL)
- return false;
- unw_word_t reg_value = 0;
- switch (value.GetType())
- {
- case Scalar::e_void:
- return false;
-
- case Scalar::e_sint: reg_value = value.SInt(); break;
- case Scalar::e_uint: reg_value = value.UInt(); break;
- case Scalar::e_slong: reg_value = value.SLong(); break;
- case Scalar::e_ulong: reg_value = value.ULong(); break;
- case Scalar::e_slonglong: reg_value = value.SLongLong(); break;
- case Scalar::e_ulonglong: reg_value = value.ULongLong(); break;
- case Scalar::e_float:
- if (sizeof (float) == sizeof (unsigned int))
- reg_value = value.UInt();
- else if (sizeof (float) == sizeof (unsigned long))
- reg_value = value.ULong();
- else if (sizeof (float) == sizeof (unsigned long long))
- reg_value = value.ULongLong();
- else
- return false;
- break;
-
- case Scalar::e_double:
- if (sizeof (double) == sizeof (unsigned int))
- reg_value = value.UInt();
- else if (sizeof (double) == sizeof (unsigned long))
- reg_value = value.ULong();
- else if (sizeof (double) == sizeof (unsigned long long))
- reg_value = value.ULongLong();
- else
- return false;
- break;
-
- case Scalar::e_long_double:
- if (sizeof (long double) == sizeof (unsigned int))
- reg_value = value.UInt();
- else if (sizeof (long double) == sizeof (unsigned long))
- reg_value = value.ULong();
- else if (sizeof (long double) == sizeof (unsigned long long))
- reg_value = value.ULongLong();
- else
- return false;
- break;
- }
-
- return unw_set_reg (&m_unwind_cursor, reg, reg_value) == UNW_ESUCCESS;
-}
-
-
-bool
-LibUnwindRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-
- if (reg_info == NULL)
- return false;
- if (reg_info->byte_size > sizeof (unw_word_t))
- return false;
-
- Scalar value;
- uint32_t offset = data_offset;
-
- switch (reg_info->encoding)
- {
- case eEncodingUint:
- if (reg_info->byte_size <= 4)
- value = data.GetMaxU32 (&offset, reg_info->byte_size);
- else if (reg_info->byte_size <= 8)
- value = data.GetMaxU64 (&offset, reg_info->byte_size);
- else
- return false;
- break;
-
- case eEncodingSint:
- if (reg_info->byte_size <= 4)
- value = (int32_t)data.GetMaxU32 (&offset, reg_info->byte_size);
- else if (reg_info->byte_size <= 8)
- value = data.GetMaxS64 (&offset, reg_info->byte_size);
- else
- return false;
- break;
-
- case eEncodingIEEE754:
- switch (reg_info->byte_size)
- {
- case sizeof (float):
- value = data.GetFloat (&offset);
- break;
-
- case sizeof (double):
- value = data.GetDouble (&offset);
- break;
-
- case sizeof (long double):
- value = data.GetLongDouble (&offset);
- break;
- default:
- return false;
- }
-
- default:
- return false;
- }
- return WriteRegisterValue (reg, value);
-}
-
-
-bool
-LibUnwindRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- // libunwind frames can't handle this it doesn't always have all register
- // values. This call should only be called on frame zero anyway so there
- // shouldn't be any problem
- return false;
-}
-
-bool
-LibUnwindRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- // Since this class doesn't respond to "ReadAllRegisterValues()", it must
- // not have been the one that saved all the register values. So we just let
- // the thread's register context (the register context for frame zero) do
- // the writing.
- return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
-}
-
-
-uint32_t
-LibUnwindRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
-{
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
-}
-
diff --git a/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.h b/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.h
deleted file mode 100644
index bd7d8bd3bea..00000000000
--- a/lldb/source/Plugins/Process/Utility/LibUnwindRegisterContext.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- LibUnwindRegisterContext.h ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_LibUnwindRegisterContext_h_
-#define lldb_LibUnwindRegisterContext_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
-
-#include "libunwind/include/libunwind.h"
-
-class LibUnwindRegisterContext : public lldb_private::RegisterContext
-{
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- LibUnwindRegisterContext (lldb_private::Thread &thread,
- lldb_private::StackFrame *frame,
- const lldb_private::unw_cursor_t &unwind_cursor);
-
- virtual
- ~LibUnwindRegisterContext ();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- virtual void
- Invalidate ();
-
- virtual size_t
- GetRegisterCount ();
-
- virtual const lldb::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
-
- virtual size_t
- GetRegisterSetCount ();
-
- virtual const lldb::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
-
- virtual bool
- ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value);
-
- virtual bool
- ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data);
-
- virtual bool
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
-
- virtual bool
- WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value);
-
- virtual bool
- WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset);
-
- virtual bool
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
-
- virtual uint32_t
- ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
-
-private:
- lldb_private::unw_cursor_t m_unwind_cursor;
- bool m_unwind_cursor_is_valid;
- //------------------------------------------------------------------
- // For LibUnwindRegisterContext only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (LibUnwindRegisterContext);
-};
-
-#endif // lldb_LibUnwindRegisterContext_h_
diff --git a/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp b/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp
deleted file mode 100644
index 7f6f1759bdb..00000000000
--- a/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-//===-- MacOSXLibunwindCallbacks.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_MacOSXLibunwindCallbacks_cpp_
-#define liblldb_MacOSXLibunwindCallbacks_cpp_
-#if defined(__cplusplus)
-
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/FileSpec.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-
-#include "lldb/lldb-enumerations.h"
-#include "llvm-c/EnhancedDisassembly.h"
-
-#include "libunwind/include/libunwind.h"
-
-using namespace lldb;
-
-namespace lldb_private {
-
-/* Don't implement (libunwind does not use)
- find_proc_info
- put_unwind_info
- get_dyn_info_list_addr
- access_mem
- resume
-*/
-/*
- Should implement (not needed yet)
- access_fpreg
- access_vecreg
- proc_is_sigtramp
- proc_is_inferior_function_call
- access_reg_inf_func_call
-*/
-
-static int
-access_reg (lldb_private::unw_addr_space_t as, lldb_private::unw_regnum_t regnum, lldb_private::unw_word_t *valp, int write, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *th = (Thread *) arg;
- /* FIXME Only support reading for now. */
- if (write == 1)
- return -1;
- if (th->GetRegisterContext()->GetRegisterInfoAtIndex(regnum) == NULL)
- return -1;
- DataExtractor de;
- if (!th->GetRegisterContext()->ReadRegisterBytes (regnum, de))
- return -1;
- memcpy (valp, de.GetDataStart(), de.GetByteSize());
- return UNW_ESUCCESS;
-}
-
-static int
-get_proc_name (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t ip, char *bufp, size_t buf_len, lldb_private::unw_word_t *offp, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *thread = (Thread *) arg;
- Target &target = thread->GetProcess().GetTarget();
- Address addr;
- if (!target.GetSectionLoadList().ResolveLoadAddress(ip, addr))
- return -1;
-
- SymbolContext sc;
- if (!target.GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextFunction, sc))
- return -1;
- if (!sc.symbol)
- return -1;
- strlcpy (bufp, sc.symbol->GetMangled().GetMangledName().AsCString(""), buf_len);
- if (offp)
- *offp = addr.GetLoadAddress(&target) - sc.symbol->GetValue().GetLoadAddress(&target);
- return UNW_ESUCCESS;
-}
-
-static int
-find_image_info (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t load_addr, lldb_private::unw_word_t *mh,
- lldb_private::unw_word_t *text_start, lldb_private::unw_word_t *text_end,
- lldb_private::unw_word_t *eh_frame, lldb_private::unw_word_t *eh_frame_len,
- lldb_private::unw_word_t *compact_unwind_start, lldb_private::unw_word_t *compact_unwind_len, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *thread = (Thread *) arg;
- Target &target = thread->GetProcess().GetTarget();
- Address addr;
- if (!target.GetSectionLoadList().ResolveLoadAddress(load_addr, addr))
- return -1;
-
- SymbolContext sc;
- if (!target.GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextModule, sc))
- return -1;
-
- SectionList *sl = sc.module_sp->GetObjectFile()->GetSectionList();
- static ConstString g_segment_name_TEXT("__TEXT");
- SectionSP text_segment_sp(sl->FindSectionByName(g_segment_name_TEXT));
- if (!text_segment_sp)
- return -1;
-
- *mh = text_segment_sp->GetLoadBaseAddress (&target);
- *text_start = text_segment_sp->GetLoadBaseAddress (&target);
- *text_end = *text_start + text_segment_sp->GetByteSize();
-
- static ConstString g_section_name_eh_frame ("__eh_frame");
- SectionSP eh_frame_section_sp = text_segment_sp->GetChildren().FindSectionByName(g_section_name_eh_frame);
- if (eh_frame_section_sp.get()) {
- *eh_frame = eh_frame_section_sp->GetLoadBaseAddress (&target);
- *eh_frame_len = eh_frame_section_sp->GetByteSize();
- } else {
- *eh_frame = 0;
- *eh_frame_len = 0;
- }
-
- static ConstString g_section_name_unwind_info ("__unwind_info");
- SectionSP unwind_info_section_sp = text_segment_sp->GetChildren().FindSectionByName(g_section_name_unwind_info);
- if (unwind_info_section_sp.get()) {
- *compact_unwind_start = unwind_info_section_sp->GetLoadBaseAddress (&target);
- *compact_unwind_len = unwind_info_section_sp->GetByteSize();
- } else {
- *compact_unwind_start = 0;
- *compact_unwind_len = 0;
- }
- return UNW_ESUCCESS;
-}
-
-static int
-get_proc_bounds (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t ip, lldb_private::unw_word_t *low, lldb_private::unw_word_t *high, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *thread = (Thread *) arg;
- Target &target = thread->GetProcess().GetTarget();
- Address addr;
- if (!target.GetSectionLoadList().ResolveLoadAddress(ip, addr))
- return -1;
- SymbolContext sc;
- if (!target.GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextFunction | eSymbolContextSymbol, sc))
- return -1;
- if (sc.function)
- {
- lldb::addr_t start, len;
- start = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(&target);
- len = sc.function->GetAddressRange().GetByteSize();
- if (start == LLDB_INVALID_ADDRESS || len == LLDB_INVALID_ADDRESS)
- return -1;
- *low = start;
- *high = start + len;
- return UNW_ESUCCESS;
- }
- if (sc.symbol)
- {
- lldb::addr_t start, len;
- start = sc.symbol->GetAddressRangeRef().GetBaseAddress().GetLoadAddress(&target);
- len = sc.symbol->GetAddressRangeRef().GetByteSize();
- if (start == LLDB_INVALID_ADDRESS)
- return -1;
- *low = start;
- if (len != LLDB_INVALID_ADDRESS)
- *high = start + len;
- else
- *high = 0;
- return UNW_ESUCCESS;
- }
- return -1;
-}
-
-static int
-access_raw (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t addr, lldb_private::unw_word_t extent, uint8_t *valp, int write, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *th = (Thread *) arg;
- /* FIXME Only support reading for now. */
- if (write == 1)
- return -1;
-
- Error error;
- if (th->GetProcess().ReadMemory (addr, valp, extent, error) != extent)
- return -1;
- return UNW_ESUCCESS;
-}
-
-
-static int
-reg_info
-(
- lldb_private::unw_addr_space_t as,
- lldb_private::unw_regnum_t regnum,
- lldb_private::unw_regtype_t *type,
- char *buf,
- size_t buflen,
- void *arg
-)
-{
- if (arg == 0)
- return -1;
- Thread *th = (Thread *) arg;
- RegisterContext *regc = th->GetRegisterContext();
- if (regnum > regc->GetRegisterCount())
- {
- *type = UNW_NOT_A_REG;
- return UNW_ESUCCESS;
- }
-
- const char *name = regc->GetRegisterName (regnum);
- if (name == NULL)
- {
- *type = UNW_NOT_A_REG;
- return UNW_ESUCCESS;
- }
- strlcpy (buf, name, buflen);
-
- const lldb::RegisterInfo *reginfo = regc->GetRegisterInfoAtIndex (regnum);
- if (reginfo == NULL || reginfo->encoding == eEncodingInvalid)
- {
- *type = UNW_NOT_A_REG;
- return UNW_ESUCCESS;
- }
- if (reginfo->encoding == eEncodingUint || reginfo->encoding == eEncodingSint)
- *type = UNW_INTEGER_REG;
- if (reginfo->encoding == eEncodingIEEE754)
- *type = UNW_FLOATING_POINT_REG;
- if (reginfo->encoding == eEncodingVector)
- *type = UNW_VECTOR_REG;
-
- return UNW_ESUCCESS;
-}
-
-
-static int
-read_byte_for_edis (uint8_t *buf, uint64_t addr, void *arg)
-{
- if (arg == 0)
- return -1;
- Thread *th = (Thread *) arg;
- DataBufferHeap onebyte(1, 0);
- Error error;
- if (th->GetProcess().ReadMemory (addr, onebyte.GetBytes(), onebyte.GetByteSize(), error) != 1)
- return -1;
- *buf = onebyte.GetBytes()[0];
- return UNW_ESUCCESS;
-}
-
-static int
-instruction_length (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t addr, int *length, void *arg)
-{
- EDDisassemblerRef disasm;
- EDInstRef cur_insn;
-
- if (arg == 0)
- return -1;
- Thread *thread = (Thread *) arg;
- Target &target = thread->GetProcess().GetTarget();
-
- const ArchSpec::CPU arch_cpu = target.GetArchitecture ().GetGenericCPUType();
-
- if (arch_cpu == ArchSpec::eCPU_i386)
- {
- if (EDGetDisassembler (&disasm, "i386-apple-darwin", kEDAssemblySyntaxX86ATT) != 0)
- return -1;
- }
- else if (arch_cpu == ArchSpec::eCPU_x86_64)
- {
- if (EDGetDisassembler (&disasm, "x86_64-apple-darwin", kEDAssemblySyntaxX86ATT) != 0)
- return -1;
- }
- else
- {
- return -1;
- }
-
- if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr, arg) != 1)
- return -1;
- *length = EDInstByteSize (cur_insn);
- EDReleaseInst (cur_insn);
- return UNW_ESUCCESS;
-}
-
-lldb_private::unw_accessors_t
-get_macosx_libunwind_callbacks () {
- lldb_private::unw_accessors_t ap;
- bzero (&ap, sizeof (lldb_private::unw_accessors_t));
- ap.find_proc_info = NULL;
- ap.put_unwind_info = NULL;
- ap.get_dyn_info_list_addr = NULL;
- ap.find_image_info = find_image_info;
- ap.access_mem = NULL;
- ap.access_reg = access_reg;
- ap.access_fpreg = NULL;
- ap.access_vecreg = NULL;
- ap.resume = NULL;
- ap.get_proc_name = get_proc_name;
- ap.get_proc_bounds = get_proc_bounds;
- ap.access_raw = access_raw;
- ap.reg_info = reg_info;
- ap.proc_is_sigtramp = NULL;
- ap.proc_is_inferior_function_call = NULL;
- ap.access_reg_inf_func_call = NULL;
- ap.instruction_length = instruction_length;
- return ap;
-}
-
-
-} // namespace lldb_private
-
-#endif // #if defined(__cplusplus)
-#endif // #ifndef liblldb_MacOSXLibunwindCallbacks_cpp_
diff --git a/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.h b/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.h
deleted file mode 100644
index 78bd27b2ad3..00000000000
--- a/lldb/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- MacOSXLibunwindCallbacks.h ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_MacOSXLibunwindCallbacks_h_
-#define liblldb_MacOSXLibunwindCallbacks_h_
-#if defined(__cplusplus)
-
-namespace lldb_private {
-
-unw_accessors_t get_macosx_libunwind_callbacks ();
-
-} // namespace lldb_utility
-
-#endif // #if defined(__cplusplus)
-#endif // #ifndef liblldb_MacOSXLibunwindCallbacks_h_
-
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
deleted file mode 100644
index bbc58a21cc0..00000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- UnwindLibUnwind.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Target/Thread.h"
-#include "UnwindLibUnwind.h"
-#include "LibUnwindRegisterContext.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-UnwindLibUnwind::UnwindLibUnwind (Thread &thread, unw_addr_space_t addr_space) :
- Unwind (thread),
- m_addr_space (addr_space),
- m_cursors()
-{
- m_pc_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- m_sp_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
-}
-
-uint32_t
-UnwindLibUnwind::GetFrameCount()
-{
- if (m_cursors.empty())
- {
- unw_cursor_t cursor;
- unw_init_remote (&cursor, m_addr_space, &m_thread);
-
- m_cursors.push_back (cursor);
-
- while (1)
- {
- int stepresult = unw_step (&cursor);
- if (stepresult > 0)
- m_cursors.push_back (cursor);
- else
- break;
- }
- }
- return m_cursors.size();
-}
-
-bool
-UnwindLibUnwind::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
-{
- const uint32_t frame_count = GetFrameCount();
- if (idx < frame_count)
- {
- int pc_err = unw_get_reg (&m_cursors[idx], m_pc_regnum, &pc);
- int sp_err = unw_get_reg (&m_cursors[idx], m_sp_regnum, &cfa);
- return pc_err == UNW_ESUCCESS && sp_err == UNW_ESUCCESS;
- }
- return false;
-}
-
-RegisterContext *
-UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame)
-{
- uint32_t idx = frame->GetUnwindFrameIndex ();
- const uint32_t frame_count = GetFrameCount();
- if (idx < frame_count)
- return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]);
- return NULL;
-}
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.h b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.h
deleted file mode 100644
index 8b3489b80e1..00000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- UnwindLibUnwind.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_UnwindLibUnwind_h_
-#define lldb_UnwindLibUnwind_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-
-// Other libraries and framework includes
-#include "libunwind/include/libunwind.h"
-
-// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/Unwind.h"
-
-class UnwindLibUnwind : public lldb_private::Unwind
-{
-public:
- UnwindLibUnwind (lldb_private::Thread &thread,
- lldb_private::unw_addr_space_t addr_space);
-
- virtual
- ~UnwindLibUnwind()
- {
- }
-
- virtual void
- Clear()
- {
- m_cursors.clear();
- }
-
- virtual uint32_t
- GetFrameCount();
-
- bool
- GetFrameInfoAtIndex (uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc);
-
- lldb_private::RegisterContext *
- CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
-
- lldb_private::Thread &
- GetThread();
-
-private:
- lldb_private::unw_addr_space_t m_addr_space;
- std::vector<lldb_private::unw_cursor_t> m_cursors;
- uint32_t m_pc_regnum;
- uint32_t m_sp_regnum;
- //------------------------------------------------------------------
- // For UnwindLibUnwind only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (UnwindLibUnwind);
-};
-
-#endif // lldb_UnwindLibUnwind_h_
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/include/libunwind.h b/lldb/source/Plugins/Process/Utility/libunwind/include/libunwind.h
deleted file mode 100644
index df7025653ea..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/include/libunwind.h
+++ /dev/null
@@ -1,509 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- libunwind.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// C interface to libuwind
-//
-// Source compatible with Level 1 Base ABI documented at:
-// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef __LIBUNWIND__
-#define __LIBUNWIND__
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <mach/mach_types.h>
-#include <Availability.h>
-
-namespace lldb_private {
-
-#pragma mark Error codes
-
-enum {
- UNW_ESUCCESS = 0, /* no error */
- UNW_EUNSPEC = -6540, /* unspecified (general) error */
- UNW_ENOMEM = -6541, /* out of memory */
- UNW_EBADREG = -6542, /* bad register number */
- UNW_EREADONLYREG = -6543, /* attempt to write read-only register */
- UNW_ESTOPUNWIND = -6544, /* stop unwinding */
- UNW_EINVALIDIP = -6545, /* invalid IP */
- UNW_EBADFRAME = -6546, /* bad frame */
- UNW_EINVAL = -6547, /* unsupported operation or bad value */
- UNW_EBADVERSION = -6548, /* unwind info has unsupported version */
- UNW_ENOINFO = -6549, /* no unwind info found */
- UNW_EREGUNAVAILABLE = -6550 /* contents of requested reg are not available */
-};
-
-#pragma mark General data structures
-
-struct unw_context_t { uint64_t data[128]; };
-typedef struct unw_context_t unw_context_t;
-
-struct unw_cursor_t { uint64_t data[140]; };
-typedef struct unw_cursor_t unw_cursor_t;
-
-enum unw_as_type { UNW_LOCAL, UNW_REMOTE };
-struct unw_addr_space
-{
- enum unw_as_type type;
- uint8_t data[1];
-};
-typedef struct unw_addr_space* unw_addr_space_t;
-
-typedef int unw_regnum_t;
-typedef uint64_t unw_word_t;
-typedef double unw_fpreg_t;
-
-enum unw_vecreg_format {
- UNW_VECREG_SIGNED,
- UNW_VECREG_UNSIGNED,
- UNW_VECREG_FLOAT
-};
-
-typedef struct
-{
- union {
- double doubles[8];
- float floats [16];
-
- uint64_t dwords [8];
- uint32_t words [16];
- uint16_t hwords [32];
- uint8_t bytes [64];
- } data;
- uint16_t unit_size; // bits
- uint16_t num_units;
- uint8_t format;
-} unw_vecreg_t;
-
-struct unw_proc_info_t
-{
- unw_word_t start_ip; /* start address of function */
- unw_word_t end_ip; /* address after end of function */
- unw_word_t lsda; /* address of language specific data area, or zero if not used */
- unw_word_t handler; /* personality routine, or zero if not used */
- unw_word_t gp; /* not used */
- unw_word_t flags; /* not used */
- uint32_t format; /* compact unwind encoding, or zero if none */
- uint32_t unwind_info_size; /* size of dwarf unwind info, or zero if none */
- unw_word_t unwind_info; /* address of dwarf unwind info, or zero if none */
- unw_word_t extra; /* mach_header of mach-o image containing function */
-};
-typedef struct unw_proc_info_t unw_proc_info_t;
-
-#pragma mark Local API
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int unw_getcontext(unw_context_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_init_local(unw_cursor_t*, unw_context_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_step(unw_cursor_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_get_reg(unw_cursor_t*, unw_regnum_t, unw_word_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_get_fpreg(unw_cursor_t*, unw_regnum_t, unw_fpreg_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_set_reg(unw_cursor_t*, unw_regnum_t, unw_word_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_set_fpreg(unw_cursor_t*, unw_regnum_t, unw_fpreg_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_resume(unw_cursor_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-
-extern const char* unw_regname(unw_cursor_t*, unw_regnum_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_get_proc_info(unw_cursor_t*, unw_proc_info_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_is_fpreg(unw_cursor_t*, unw_regnum_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_is_signal_frame(unw_cursor_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_get_proc_name(unw_cursor_t*, char*, size_t, unw_word_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
-
-
-#pragma mark Remote data structures
-
-typedef enum {
- UNW_NOT_A_REG = 0,
- UNW_INTEGER_REG,
- UNW_FLOATING_POINT_REG,
- UNW_VECTOR_REG,
- UNW_OTHER_REG
-} unw_regtype_t;
-
-typedef enum {
- UNW_TARGET_UNSPECIFIED = 0,
- UNW_TARGET_I386,
- UNW_TARGET_X86_64,
- UNW_TARGET_PPC,
- UNW_TARGET_ARM
-} unw_targettype_t;
-
-typedef enum {
- UNW_LOG_LEVEL_NONE = 0x00000000,
- UNW_LOG_LEVEL_INFO = 0x00000001,
- UNW_LOG_LEVEL_API = 0x00000002,
- UNW_LOG_LEVEL_VERBOSE = 0x00000004,
- UNW_LOG_LEVEL_TIMINGS = 0x00000008,
- UNW_LOG_LEVEL_DEBUG = 0x00000010,
- UNW_LOG_LEVEL_ALL = 0x0FFFFFFF
-} unw_log_level_t;
-
-typedef enum {
- UNW_CACHE_NONE = 0,
- UNW_CACHE_GLOBAL,
- UNW_CACHE_PER_THREAD
-} unw_caching_policy_t;
-
-typedef struct {
- int (*find_proc_info)(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int need_unwind_info, void *arg);
- int (*put_unwind_info)(unw_addr_space_t as, unw_proc_info_t *pip, void *arg);
- int (*get_dyn_info_list_addr)(unw_addr_space_t as, unw_word_t *dilap, void *arg);
-
- // Reads or writes a memory object the size of a target pointer.
- // Byte-swaps if necessary.
- int (*access_mem)(unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, int write, void *arg);
-
- // Register contents sent as-is (i.e. not byte-swapped).
- // Register numbers are the driver program's numbering scheme as
- // determined by the reg_info callbacks; libunwind will interrogate
- // the driver program to figure out which numbers it uses to refer to
- // which registers.
- int (*access_reg)(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write, void *arg);
- int (*access_fpreg)(unw_addr_space_t as, unw_regnum_t regnum, unw_fpreg_t *valp, int write, void *arg);
- int (*resume)(unw_addr_space_t as, unw_cursor_t *cp, void *arg);
- int (*get_proc_name)(unw_addr_space_t as, unw_word_t addr, char *bufp, size_t buf_len, unw_word_t *offp, void *arg);
-
-
- // Added to find the start of the image (executable, bundle, dylib, etc)
- // for a given address.
- // as - The address space to use
- // ip - The address libunwind wants to know about
- // mh - The Mach-O header address for this image
- // text_start - The start of __TEXT segment (all its sections)
- // text_end - The end address of __TEXT segment (all its sections)
- // eh_frame - The start of __TEXT,__eh_frame
- // eh_frame_len - The length of __TEXT,__eh_frame
- // compact_unwind_start - The start of __TEXT,__unwind_info
- // compact_unwind_len - The length of __TEXT,__unwind_info
- // arg - The driver-provided generic argument
- // All addresses are the in-memory, slid, addresses.
- // If eh_frame or unwind_info are missing, addr and len is returned as 0.
- int (*find_image_info)(unw_addr_space_t as, unw_word_t ip, unw_word_t *mh,
- unw_word_t *text_start, unw_word_t *text_end,
- unw_word_t *eh_frame, unw_word_t *eh_frame_len,
- unw_word_t *compact_unwind_start,
- unw_word_t *compact_unwind_len, void *arg);
-
- // Added to get the start and end address of a function without needing
- // all of the information (and potential allocation) that the
- // find_proc_info() call entails.
- // as - The address space to use
- // ip - The address libunwind wants to know about
- // low - The start address of the function at 'ip'
- // high - The first address past the function at 'ip'
- // arg - The driver-provided generic argument
- // If HIGH is unknown, it should be set to 0. All addresses
- // are the in-memory, slid, addresses.
- int (*get_proc_bounds)(unw_addr_space_t as, unw_word_t ip,
- unw_word_t *low, unw_word_t *high, void *arg);
-
- // Added to support accessing non-word-size memory objects across
- // platforms. No byte swapping should be done.
- // as - The address space to use
- // addr - The starting address to access
- // extent - The extent of the region to access, in bytes
- // valp - The local region to be written from / read into
- // write - non-zero if the data is to be written into the target
- // rather than read
- // arg - The driver-provided generic argument (see unw_init_remote)
- int (*access_raw)(unw_addr_space_t as, unw_word_t addr, unw_word_t extent,
- uint8_t *valp, int write, void *arg);
-
- // Added to support identifying registers.
- // libunwind will interrogate the driver program via this callback to
- // identify what register numbers it is using; the register names are
- // used to correlate that the driver program's register numbers with
- // libunwind's internal register numbers. The driver program should
- // use its own register numbers when requesting registers with
- // unw_get_reg() and libunwind will provide the driver program's
- // register numbers to the access_reg callback function.
- // as - The address space to use
- // regnum - The register number
- // type - Write the register type to this address
- // For a non-existent register, return UNW_ESUCCESS but
- // write UNW_NOT_A_REG to type
- // buf - If non-NULL, the register name is written to this address
- // buf_len - The size of the buffer provided for the register name
- // arg - The driver-provided generic argument (see unw_init_remote)
- int (*reg_info)(unw_addr_space_t as, unw_regnum_t regnum,
- unw_regtype_t* type, char *bufp, size_t buf_len, void *arg);
-
- // Added to read a vector register's value from the remote machine.
- // as - The address space to use
- // regnum - The register number
- // valp - The local region to be written from / read into
- // write - non-zero if the data is to be written into the target
- // rather than read
- // arg - The driver-specified generic argument
- int (*access_vecreg)(unw_addr_space_t as, unw_regnum_t regnum,
- unw_vecreg_t* valp, int write, void *arg);
-
- // Added to identify if an unwind cursor is pointing to _sigtramp().
- // After a _sigtramp we have an entire register set available and we should
- // return any of the registers requested.
- // as - The address space to use
- // ip - The address of the function libunwind is examining
- // arg - The driver-provided generic argument
- // This function returns non-zero if ip is in _sigtramp.
- int (*proc_is_sigtramp) (unw_addr_space_t as, unw_word_t ip, void *arg);
-
- // Added to identify if an unwind cursor is pointing to a debugger's
- // inferior function call dummy frame.
- // The driver program will need to provide the full register set (via the
- // standard access_reg callback) for the function that was executing
- // when the inferior function call was made; it will use these register
- // values and not try to unwind out of the inferior function call dummy
- // frame.
- // After a inf func call we have an entire register set available and
- // we should return any of the registers requested.
- // as - The address space to use
- // ip - The address of the function libunwind is examining
- // sp - The stack pointer value of the frame
- // arg - The driver-provided generic argument (see unw_init_remote)
- // This function returns non-zero if ip/sp is an inferior function call
- // dummy frame.
- int (*proc_is_inferior_function_call) (unw_addr_space_t as, unw_word_t ip,
- unw_word_t sp, void *arg);
-
- // Added to retrieve a register value from a above a debugger's inferior
- // function call dummy frame. Similar to _sigtramp but the debugger will
- // have the register context squirreled away in its own memory (or possibly
- // saved on the stack somewhere).
- // May be NULL if the program being unwound will not have a debugger
- // calling functions mid-execution.
- // as - The address space to use
- // ip - The pc value for the dummy frame
- // sp - The stack pointer for the dummy frame
- // regnum - The register number in the driver program's register
- // numbering scheme.
- // valp - Pointer to a word of memory to be read/written
- // write - Non-zero if libunwind is writing a new value to the reg,
- // else it is reading the contents of that register.
- // arg - The driver-provided generic argument (see unw_init_remote)
- int (*access_reg_inf_func_call)(unw_addr_space_t as, unw_word_t ip,
- unw_word_t sp, unw_regnum_t regnum,
- unw_word_t *valp, int write, void *arg);
-
- // Added to iterate over unknown assembly instructions when analyzing a
- // function prologue. Needed for ISAs with variable length instructions
- // (i386, x86_64) or multiple instruction sizes (arm, thumb).
- // Returns zero if the instruction length was successfully measured.
- // as - The address space to use
- // addr - The address of the instruction being measured
- // length - Set to the length of the instruction
- // arg - The driver-provided generic argument (see unw_init_remote)
- int (*instruction_length)(unw_addr_space_t as, unw_word_t addr,
- int *length, void *arg);
-
-} unw_accessors_t;
-
-extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t, void*) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern unw_accessors_t* unw_get_accessors(unw_addr_space_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern unw_addr_space_t unw_create_addr_space(unw_accessors_t*, unw_targettype_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern void unw_flush_caches(unw_addr_space_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern int unw_set_caching_policy(unw_addr_space_t, unw_caching_policy_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern void unw_destroy_addr_space(unw_addr_space_t asp) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-extern void unw_set_logging_level(unw_addr_space_t, FILE *, unw_log_level_t) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-
-// Should be called when remote unwinding if a bundle in the remote process
-// is unloaded
-extern void unw_image_was_unloaded(unw_addr_space_t, unw_word_t mh) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-
-// Try to discern where the function's prologue instructions end
-// start - start address of the function, required
-// end - first address beyond the function, or zero if unknown
-// endofprologue - set to the address after the last prologue instruction if successful
-extern int unw_end_of_prologue_setup(unw_cursor_t*, unw_word_t start, unw_word_t end, unw_word_t *endofprologue) __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
-
-/*
- * Dynamic unwinding API
- * NOT IMPLEMENTED on Mac OS X
- * extern void _U_dyn_register(unw_dyn_info_t*);
- * extern void _U_dyn_cancel(unw_dyn_info_t*);
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#pragma mark Register numbers
-
-// architecture independent register numbers
-enum {
- UNW_REG_IP = -1, // instruction pointer
- UNW_REG_SP = -2 // stack pointer
-};
-
-
-// 32-bit x86 registers
-enum {
- UNW_X86_EAX = 0,
- UNW_X86_ECX = 1,
- UNW_X86_EDX = 2,
- UNW_X86_EBX = 3,
- UNW_X86_EBP = 4,
- UNW_X86_ESP = 5,
- UNW_X86_ESI = 6,
- UNW_X86_EDI = 7
-};
-
-
-// 64-bit x86_64 registers
-enum {
- UNW_X86_64_RAX = 0,
- UNW_X86_64_RDX = 1,
- UNW_X86_64_RCX = 2,
- UNW_X86_64_RBX = 3,
- UNW_X86_64_RSI = 4,
- UNW_X86_64_RDI = 5,
- UNW_X86_64_RBP = 6,
- UNW_X86_64_RSP = 7,
- UNW_X86_64_R8 = 8,
- UNW_X86_64_R9 = 9,
- UNW_X86_64_R10 = 10,
- UNW_X86_64_R11 = 11,
- UNW_X86_64_R12 = 12,
- UNW_X86_64_R13 = 13,
- UNW_X86_64_R14 = 14,
- UNW_X86_64_R15 = 15
-};
-
-
-// 32-bit ppc register numbers
-enum {
- UNW_PPC_R0 = 0,
- UNW_PPC_R1 = 1,
- UNW_PPC_R2 = 2,
- UNW_PPC_R3 = 3,
- UNW_PPC_R4 = 4,
- UNW_PPC_R5 = 5,
- UNW_PPC_R6 = 6,
- UNW_PPC_R7 = 7,
- UNW_PPC_R8 = 8,
- UNW_PPC_R9 = 9,
- UNW_PPC_R10 = 10,
- UNW_PPC_R11 = 11,
- UNW_PPC_R12 = 12,
- UNW_PPC_R13 = 13,
- UNW_PPC_R14 = 14,
- UNW_PPC_R15 = 15,
- UNW_PPC_R16 = 16,
- UNW_PPC_R17 = 17,
- UNW_PPC_R18 = 18,
- UNW_PPC_R19 = 19,
- UNW_PPC_R20 = 20,
- UNW_PPC_R21 = 21,
- UNW_PPC_R22 = 22,
- UNW_PPC_R23 = 23,
- UNW_PPC_R24 = 24,
- UNW_PPC_R25 = 25,
- UNW_PPC_R26 = 26,
- UNW_PPC_R27 = 27,
- UNW_PPC_R28 = 28,
- UNW_PPC_R29 = 29,
- UNW_PPC_R30 = 30,
- UNW_PPC_R31 = 31,
- UNW_PPC_F0 = 32,
- UNW_PPC_F1 = 33,
- UNW_PPC_F2 = 34,
- UNW_PPC_F3 = 35,
- UNW_PPC_F4 = 36,
- UNW_PPC_F5 = 37,
- UNW_PPC_F6 = 38,
- UNW_PPC_F7 = 39,
- UNW_PPC_F8 = 40,
- UNW_PPC_F9 = 41,
- UNW_PPC_F10 = 42,
- UNW_PPC_F11 = 43,
- UNW_PPC_F12 = 44,
- UNW_PPC_F13 = 45,
- UNW_PPC_F14 = 46,
- UNW_PPC_F15 = 47,
- UNW_PPC_F16 = 48,
- UNW_PPC_F17 = 49,
- UNW_PPC_F18 = 50,
- UNW_PPC_F19 = 51,
- UNW_PPC_F20 = 52,
- UNW_PPC_F21 = 53,
- UNW_PPC_F22 = 54,
- UNW_PPC_F23 = 55,
- UNW_PPC_F24 = 56,
- UNW_PPC_F25 = 57,
- UNW_PPC_F26 = 58,
- UNW_PPC_F27 = 59,
- UNW_PPC_F28 = 60,
- UNW_PPC_F29 = 61,
- UNW_PPC_F30 = 62,
- UNW_PPC_F31 = 63,
- UNW_PPC_MQ = 64,
- UNW_PPC_LR = 65,
- UNW_PPC_CTR = 66,
- UNW_PPC_AP = 67,
- UNW_PPC_CR0 = 68,
- UNW_PPC_CR1 = 69,
- UNW_PPC_CR2 = 70,
- UNW_PPC_CR3 = 71,
- UNW_PPC_CR4 = 72,
- UNW_PPC_CR5 = 73,
- UNW_PPC_CR6 = 74,
- UNW_PPC_CR7 = 75,
- UNW_PPC_XER = 76,
- UNW_PPC_V0 = 77,
- UNW_PPC_V1 = 78,
- UNW_PPC_V2 = 79,
- UNW_PPC_V3 = 80,
- UNW_PPC_V4 = 81,
- UNW_PPC_V5 = 82,
- UNW_PPC_V6 = 83,
- UNW_PPC_V7 = 84,
- UNW_PPC_V8 = 85,
- UNW_PPC_V9 = 86,
- UNW_PPC_V10 = 87,
- UNW_PPC_V11 = 88,
- UNW_PPC_V12 = 89,
- UNW_PPC_V13 = 90,
- UNW_PPC_V14 = 91,
- UNW_PPC_V15 = 92,
- UNW_PPC_V16 = 93,
- UNW_PPC_V17 = 94,
- UNW_PPC_V18 = 95,
- UNW_PPC_V19 = 96,
- UNW_PPC_V20 = 97,
- UNW_PPC_V21 = 98,
- UNW_PPC_V22 = 99,
- UNW_PPC_V23 = 100,
- UNW_PPC_V24 = 101,
- UNW_PPC_V25 = 102,
- UNW_PPC_V26 = 103,
- UNW_PPC_V27 = 104,
- UNW_PPC_V28 = 105,
- UNW_PPC_V29 = 106,
- UNW_PPC_V30 = 107,
- UNW_PPC_V31 = 108,
- UNW_PPC_VRSAVE = 109,
- UNW_PPC_VSCR = 110,
- UNW_PPC_SPE_ACC = 111,
- UNW_PPC_SPEFSCR = 112
-
-};
-
-
-} // namespace lldb_private
-
-
-#endif
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/include/mach-o/compact_unwind_encoding.h b/lldb/source/Plugins/Process/Utility/libunwind/include/mach-o/compact_unwind_encoding.h
deleted file mode 100644
index bee2ad578d6..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/include/mach-o/compact_unwind_encoding.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- compact_unwind_encoding.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef __COMPACT_UNWIND_ENCODING__
-#define __COMPACT_UNWIND_ENCODING__
-
-#include <stdint.h>
-
-namespace lldb_private {
-
-//
-// Each final linked mach-o image has an optional __TEXT, __unwind_info section.
-// This section is much smaller and faster to use than the __eh_frame section.
-//
-
-
-
-//
-// Compilers usually emit standard Dwarf FDEs. The linker recognizes standard FDEs and
-// synthesizes a matching compact_unwind_encoding_t and adds it to the __unwind_info table.
-// It is also possible for the compiler to emit __unwind_info entries for functions that
-// have different unwind requirements at different ranges in the function.
-//
-typedef uint32_t compact_unwind_encoding_t;
-
-
-
-//
-// The __unwind_info section is laid out for an efficient two level lookup.
-// The header of the section contains a coarse index that maps function address
-// to the page (4096 byte block) containing the unwind info for that function.
-//
-
-#define UNWIND_SECTION_VERSION 1
-struct unwind_info_section_header
-{
- uint32_t version; // UNWIND_SECTION_VERSION
- uint32_t commonEncodingsArraySectionOffset;
- uint32_t commonEncodingsArrayCount;
- uint32_t personalityArraySectionOffset;
- uint32_t personalityArrayCount;
- uint32_t indexSectionOffset;
- uint32_t indexCount;
- // compact_unwind_encoding_t[]
- // uintptr_t personalities[]
- // unwind_info_section_header_index_entry[]
- // unwind_info_section_header_lsda_index_entry[]
-};
-
-struct unwind_info_section_header_index_entry
-{
- uint32_t functionOffset;
- uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page
- uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range
-};
-
-struct unwind_info_section_header_lsda_index_entry
-{
- uint32_t functionOffset;
- uint32_t lsdaOffset;
-};
-
-//
-// There are two kinds of second level index pages: regular and compressed.
-// A compressed page can hold up to 1021 entries, but it cannot be used
-// if too many different encoding types are used. The regular page holds
-// 511 entries.
-//
-
-struct unwind_info_regular_second_level_entry
-{
- uint32_t functionOffset;
- compact_unwind_encoding_t encoding;
-};
-
-#define UNWIND_SECOND_LEVEL_REGULAR 2
-struct unwind_info_regular_second_level_page_header
-{
- uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR
- uint16_t entryPageOffset;
- uint16_t entryCount;
- // entry array
-};
-
-#define UNWIND_SECOND_LEVEL_COMPRESSED 3
-struct unwind_info_compressed_second_level_page_header
-{
- uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
- uint16_t entryPageOffset;
- uint16_t entryCount;
- uint16_t encodingsPageOffset;
- uint16_t encodingsCount;
- // 32-bit entry array
- // encodings array
-};
-
-#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
-#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF)
-
-
-
-// architecture independent bits
-enum {
- UNWIND_IS_NOT_FUNCTION_START = 0x80000000,
- UNWIND_HAS_LSDA = 0x40000000,
- UNWIND_PERSONALITY_MASK = 0x30000000,
-};
-
-
-// x86_64
-//
-// 1-bit: start
-// 1-bit: has lsda
-// 2-bit: personality index
-//
-// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=dwarf
-// rbp based:
-// 15-bits (5*3-bits per reg) register permutation
-// 8-bits for stack offset
-// frameless:
-// 8-bits stack size
-// 3-bits stack adjust
-// 3-bits register count
-// 10-bits register permutation
-//
-enum {
- UNWIND_X86_64_MODE_MASK = 0x0F000000,
- UNWIND_X86_64_MODE_COMPATIBILITY = 0x00000000,
- UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
- UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
- UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
- UNWIND_X86_64_MODE_DWARF = 0x04000000,
-
- UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
- UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
-
- UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
- UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
- UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
- UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
-
- UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
-};
-
-enum {
- UNWIND_X86_64_REG_NONE = 0,
- UNWIND_X86_64_REG_RBX = 1,
- UNWIND_X86_64_REG_R12 = 2,
- UNWIND_X86_64_REG_R13 = 3,
- UNWIND_X86_64_REG_R14 = 4,
- UNWIND_X86_64_REG_R15 = 5,
- UNWIND_X86_64_REG_RBP = 6,
-};
-
-
-// x86
-//
-// 1-bit: start
-// 1-bit: has lsda
-// 2-bit: personality index
-//
-// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=dwarf
-// ebp based:
-// 15-bits (5*3-bits per reg) register permutation
-// 8-bits for stack offset
-// frameless:
-// 8-bits stack size
-// 3-bits stack adjust
-// 3-bits register count
-// 10-bits register permutation
-//
-enum {
- UNWIND_X86_MODE_MASK = 0x0F000000,
- UNWIND_X86_MODE_COMPATIBILITY = 0x00000000,
- UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
- UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
- UNWIND_X86_MODE_STACK_IND = 0x03000000,
- UNWIND_X86_MODE_DWARF = 0x04000000,
-
- UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
- UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
-
- UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
- UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
- UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
- UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
-
- UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
-};
-
-enum {
- UNWIND_X86_REG_NONE = 0,
- UNWIND_X86_REG_EBX = 1,
- UNWIND_X86_REG_ECX = 2,
- UNWIND_X86_REG_EDX = 3,
- UNWIND_X86_REG_EDI = 4,
- UNWIND_X86_REG_ESI = 5,
- UNWIND_X86_REG_EBP = 6,
-};
-
-}; // namespace lldb_private
-
-#endif
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/include/unwind.h b/lldb/source/Plugins/Process/Utility/libunwind/include/unwind.h
deleted file mode 100644
index 80b9d2881c2..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/include/unwind.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- unwind.h ------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// C interface to libuwind
-//
-// Source compatible with Level 1 Base ABI documented at:
-// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef __UNWIND_H__
-#define __UNWIND_H__
-
-#include <stdint.h>
-#include <stddef.h>
-#include <Availability.h>
-
-namespace lldb_private {
-
-typedef enum {
- _URC_NO_REASON = 0,
- _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
- _URC_FATAL_PHASE2_ERROR = 2,
- _URC_FATAL_PHASE1_ERROR = 3,
- _URC_NORMAL_STOP = 4,
- _URC_END_OF_STACK = 5,
- _URC_HANDLER_FOUND = 6,
- _URC_INSTALL_CONTEXT = 7,
- _URC_CONTINUE_UNWIND = 8
-} _Unwind_Reason_Code;
-
-typedef enum {
- _UA_SEARCH_PHASE = 1,
- _UA_CLEANUP_PHASE = 2,
- _UA_HANDLER_FRAME = 4,
- _UA_FORCE_UNWIND = 8,
- _UA_END_OF_STACK = 16 // gcc extension to C++ ABI
-} _Unwind_Action;
-
-
-struct _Unwind_Context; // opaque
-struct _Unwind_Exception; // forward declaration
-
-struct _Unwind_Exception {
- uint64_t exception_class;
- void (*exception_cleanup)(_Unwind_Reason_Code reason, struct _Unwind_Exception* exc);
- uintptr_t private_1; // non-zero means forced unwind
- uintptr_t private_2; // holds sp that phase1 found for phase2 to use
-};
-
-
-typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
- (int version,
- _Unwind_Action actions,
- uint64_t exceptionClass,
- struct _Unwind_Exception* exceptionObject,
- struct _Unwind_Context* context,
- void* stop_parameter );
-
-
-typedef _Unwind_Reason_Code (*__personality_routine)
- (int version,
- _Unwind_Action actions,
- uint64_t exceptionClass,
- struct _Unwind_Exception* exceptionObject,
- struct _Unwind_Context* context);
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//
-// The following are the base functions documented by the C++ ABI
-//
-#if __arm__
- extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception* exception_object);
- extern void _Unwind_SjLj_Resume(struct _Unwind_Exception* exception_object);
-#else
- extern _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception* exception_object);
- extern void _Unwind_Resume(struct _Unwind_Exception* exception_object);
-#endif
-extern void _Unwind_DeleteException(struct _Unwind_Exception* exception_object);
-extern uintptr_t _Unwind_GetGR(struct _Unwind_Context* context, int index);
-extern void _Unwind_SetGR(struct _Unwind_Context* context, int index, uintptr_t new_value);
-extern uintptr_t _Unwind_GetIP(struct _Unwind_Context* context);
-extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t new_value);
-extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context* context);
-extern uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context* context);
-#if __arm__
- extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception* exception_object, _Unwind_Stop_Fn stop, void* stop_parameter );
-#else
- extern _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception* exception_object, _Unwind_Stop_Fn stop, void* stop_parameter );
-#endif
-
-#if __arm__
- typedef struct _Unwind_FunctionContext* _Unwind_FunctionContext_t;
- extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc);
- extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
-#endif
-
-//
-// The following are semi-suppoted extensions to the C++ ABI
-//
-
-
-//
-// called by __cxa_rethrow().
-//
-#if __arm__
- extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception* exception_object);
-#else
- extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception* exception_object);
-#endif
-
-
-//
-// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the
-// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack
-// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON.
-//
-typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context*, void*);
-extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
-
-
-//
-// _Unwind_GetCFA is a gcc extension that can be called from within a personality
-// handler to get the CFA (stack pointer before call) of current frame.
-//
-extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context*);
-
-
-//
-// _Unwind_GetIPInfo is a gcc extension that can be called from within a personality
-// handler. Similar to _Unwind_GetIP() but also returns in *ipBefore a non-zero
-// value if the instruction pointer is at or before the instruction causing
-// the unwind. Normally, in a function call, the IP returned is the return address
-// which is after the call instruction and may be past the end of the function
-// containing the call instruction.
-//
-extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context* context, int* ipBefore);
-
-
-//
-// __register_frame() is used with dynamically generated code to register the FDE
-// for a generated (JIT) code. The FDE must use pc-rel addressing to point to its
-// function and optional LSDA. __register_frame() has existed in all versions of
-// Mac OS X, but in 10.4 and 10.5 it was buggy and did not actually register the
-// FDE with the unwinder. In 10.6 and later it does register properly.
-//
-extern void __register_frame(const void* fde);
-extern void __deregister_frame(const void* fde);
-
-
-//
-// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
-// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind info"
-// which the runtime uses in preference to dwarf unwind info. This function
-// will only work if the target function has an FDE but no compact unwind info.
-//
-struct dwarf_eh_bases
-{
- uintptr_t tbase;
- uintptr_t dbase;
- uintptr_t func;
-};
-extern const void* _Unwind_Find_FDE(const void* pc, struct dwarf_eh_bases*);
-
-
-//
-// This function attempts to find the start (address of first instruction) of
-// a function given an address inside the function. It only works if the function
-// has an FDE (dwarf unwind info).
-// This function is unimplemented on Mac OS X 10.6 and later. Instead, use
-// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result.
-extern void* _Unwind_FindEnclosingFunction(void* pc);
-
-
-// Mac OS X does not support text-rel and data-rel addressing so these functions are unimplemented
-extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context* context) __attribute__((unavailable));
-extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context* context) __attribute__((unavailable));
-
-
-
-// Mac OS X 10.4 and 10.5 had implementations of these functions in libgcc_s.dylib,
-// but they never worked. These functions are no longer available.
-extern void __register_frame_info_bases(const void* fde, void* ob, void* tb, void* db) __attribute__((unavailable));
-extern void __register_frame_info(const void* fde, void* ob) __attribute__((unavailable));
-extern void __register_frame_info_table_bases(const void* fde, void* ob,void* tb, void* db) __attribute__((unavailable));
-extern void __register_frame_info_table(const void* fde, void* ob) __attribute__((unavailable));
-extern void __register_frame_table(const void* fde) __attribute__((unavailable));
-extern void* __deregister_frame_info(const void* fde) __attribute__((unavailable));
-extern void* __deregister_frame_info_bases(const void* fde) __attribute__((unavailable));
-
-
-#ifdef __cplusplus
-}
-#endif
-
-}; // namespace lldb_private
-
-#endif // __UNWIND_H__
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp
deleted file mode 100644
index 6a7734e9a55..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- AddressSpace.hpp ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// C++ interface to lower levels of libuwind
-//
-
-#ifndef __ADDRESSSPACE_HPP__
-#define __ADDRESSSPACE_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <mach-o/loader.h>
-#include <mach-o/getsect.h>
-#if !defined (SUPPORT_REMOTE_UNWINDING)
-#include <mach-o/dyld_priv.h>
-#endif
-#include <mach/i386/thread_status.h>
-#include <Availability.h>
-
-#include "FileAbstraction.hpp"
-#include "libunwind.h"
-#include "InternalMacros.h"
-#include "dwarf2.h"
-#include "RemoteProcInfo.hpp"
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-bool _dyld_find_unwind_sections(void* addr, void* info)
-{
- assert("unwinding with a non-remote process not supported.");
- return false;
-}
-#endif // SUPPORT_REMOTE_UNWINDING
-
-namespace lldb_private {
-
-///
-/// LocalAddressSpace is used as a template parameter to UnwindCursor when unwinding a thread
-/// in the same process. It compiles away and making local unwinds very fast.
-///
-class LocalAddressSpace
-{
-public:
-
- #if __LP64__
- typedef uint64_t pint_t;
- typedef int64_t sint_t;
- #else
- typedef uint32_t pint_t;
- typedef int32_t sint_t;
- #endif
- int getBytes(pint_t addr, pint_t extent, uint8_t* buf) { memcpy(buf, (void*)addr, extent); return 1; }
- uint8_t get8(pint_t addr) { return *((uint8_t*)addr); }
- uint16_t get16(pint_t addr) { return *((uint16_t*)addr); }
- uint32_t get32(pint_t addr) { return *((uint32_t*)addr); }
- uint64_t get64(pint_t addr) { return *((uint64_t*)addr); }
- double getDouble(pint_t addr) { return *((double*)addr); }
- v128 getVector(pint_t addr) { return *((v128*)addr); }
-
- uint8_t get8(pint_t addr, int& err) { return *((uint8_t*)addr); err = 0; }
- uint16_t get16(pint_t addr, int& err) { return *((uint16_t*)addr); err = 0; }
- uint32_t get32(pint_t addr, int& err) { return *((uint32_t*)addr); err = 0; }
- uint64_t get64(pint_t addr, int& err) { return *((uint64_t*)addr); err = 0; }
- double getDouble(pint_t addr, int& err) { return *((double*)addr); err = 0; }
- v128 getVector(pint_t addr, int& err) { return *((v128*)addr); err = 0; }
-
- uintptr_t getP(pint_t addr);
- uintptr_t getP(pint_t addr, int &err);
- static uint64_t getULEB128(pint_t& addr, pint_t end);
- static int64_t getSLEB128(pint_t& addr, pint_t end);
-
- pint_t getEncodedP(pint_t& addr, pint_t end, uint8_t encoding);
- bool findFunctionName(pint_t addr, char* buf, size_t bufLen, unw_word_t* offset);
- bool findUnwindSections(pint_t addr, pint_t& mh, pint_t& dwarfStart, pint_t& dwarfLen, pint_t& compactStart);
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
- RemoteProcInfo* getRemoteProcInfo () { return NULL; }
- unw_accessors_t* accessors() { return NULL; }
- unw_addr_space_t wrap() { return NULL; }
-#endif
-};
-
-LocalAddressSpace sThisAddress;
-
-inline uintptr_t LocalAddressSpace::getP(pint_t addr)
-{
-#if __LP64__
- return get64(addr);
-#else
- return get32(addr);
-#endif
-}
-
-inline uintptr_t LocalAddressSpace::getP(pint_t addr, int &err)
-{
-#if __LP64__
- return get64(addr);
-#else
- return get32(addr);
-#endif
- err = 0;
-}
-
-/* Read a ULEB128 into a 64-bit word. */
-inline uint64_t
-LocalAddressSpace::getULEB128(pint_t& addr, pint_t end)
-{
- const uint8_t* p = (uint8_t*)addr;
- const uint8_t* pend = (uint8_t*)end;
- uint64_t result = 0;
- int bit = 0;
- do {
- uint64_t b;
-
- if ( p == pend )
- ABORT("truncated uleb128 expression");
-
- b = *p & 0x7f;
-
- if (bit >= 64 || b << bit >> bit != b) {
- ABORT("malformed uleb128 expression");
- }
- else {
- result |= b << bit;
- bit += 7;
- }
- } while ( *p++ >= 0x80 );
- addr = (pint_t)p;
- return result;
-}
-
-/* Read a SLEB128 into a 64-bit word. */
-inline int64_t
-LocalAddressSpace::getSLEB128(pint_t& addr, pint_t end)
-{
- const uint8_t* p = (uint8_t*)addr;
- int64_t result = 0;
- int bit = 0;
- uint8_t byte;
- do {
- byte = *p++;
- result |= ((byte & 0x7f) << bit);
- bit += 7;
- } while (byte & 0x80);
- // sign extend negative numbers
- if ( (byte & 0x40) != 0 )
- result |= (-1LL) << bit;
- addr = (pint_t)p;
- return result;
-}
-
-LocalAddressSpace::pint_t
-LocalAddressSpace::getEncodedP(pint_t& addr, pint_t end, uint8_t encoding)
-{
- pint_t startAddr = addr;
- const uint8_t* p = (uint8_t*)addr;
- pint_t result;
-
- // first get value
- switch (encoding & 0x0F) {
- case DW_EH_PE_ptr:
- result = getP(addr);
- p += sizeof(pint_t);
- addr = (pint_t)p;
- break;
- case DW_EH_PE_uleb128:
- result = getULEB128(addr, end);
- break;
- case DW_EH_PE_udata2:
- result = get16(addr);
- p += 2;
- addr = (pint_t)p;
- break;
- case DW_EH_PE_udata4:
- result = get32(addr);
- p += 4;
- addr = (pint_t)p;
- break;
- case DW_EH_PE_udata8:
- result = get64(addr);
- p += 8;
- addr = (pint_t)p;
- break;
- case DW_EH_PE_sleb128:
- result = getSLEB128(addr, end);
- break;
- case DW_EH_PE_sdata2:
- result = (int16_t)get16(addr);
- p += 2;
- addr = (pint_t)p;
- break;
- case DW_EH_PE_sdata4:
- result = (int32_t)get32(addr);
- p += 4;
- addr = (pint_t)p;
- break;
- case DW_EH_PE_sdata8:
- result = get64(addr);
- p += 8;
- addr = (pint_t)p;
- break;
- default:
- ABORT("unknown pointer encoding");
- }
-
- // then add relative offset
- switch ( encoding & 0x70 ) {
- case DW_EH_PE_absptr:
- // do nothing
- break;
- case DW_EH_PE_pcrel:
- result += startAddr;
- break;
- case DW_EH_PE_textrel:
- ABORT("DW_EH_PE_textrel pointer encoding not supported");
- break;
- case DW_EH_PE_datarel:
- ABORT("DW_EH_PE_datarel pointer encoding not supported");
- break;
- case DW_EH_PE_funcrel:
- ABORT("DW_EH_PE_funcrel pointer encoding not supported");
- break;
- case DW_EH_PE_aligned:
- ABORT("DW_EH_PE_aligned pointer encoding not supported");
- break;
- default:
- ABORT("unknown pointer encoding");
- break;
- }
-
- if ( encoding & DW_EH_PE_indirect )
- result = getP(result);
-
- return result;
-}
-
-
-inline bool LocalAddressSpace::findUnwindSections(pint_t addr, pint_t& mh, pint_t& dwarfStart, pint_t& dwarfLen, pint_t& compactStart)
-{
-#if !defined (SUPPORT_REMOTE_UNWINDING)
- dyld_unwind_sections info;
- if ( _dyld_find_unwind_sections((void*)addr, &info) ) {
- mh = (pint_t)info.mh;
- dwarfStart = (pint_t)info.dwarf_section;
- dwarfLen = (pint_t)info.dwarf_section_length;
- compactStart = (pint_t)info.compact_unwind_section;
- return true;
- }
-#else
- assert("unwinding with a non-remote process not supported.");
-#endif
- return false;
-}
-
-
-inline bool LocalAddressSpace::findFunctionName(pint_t addr, char* buf, size_t bufLen, unw_word_t* offset)
-{
- dl_info dyldInfo;
- if ( dladdr((void*)addr, &dyldInfo) ) {
- if ( dyldInfo.dli_sname != NULL ) {
- strlcpy(buf, dyldInfo.dli_sname, bufLen);
- *offset = (addr - (pint_t)dyldInfo.dli_saddr);
- return true;
- }
- }
- return false;
-}
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-///
-/// OtherAddressSpace is used as a template parameter to UnwindCursor when unwinding a thread
-/// in the another process. The other process can be a different endianness and a different
-/// pointer size and is handled by the P template parameter.
-///
-template <typename P>
-class OtherAddressSpace
-{
-public:
- OtherAddressSpace (unw_addr_space_t remote_addr_space, void* arg) : fAddrSpace ((unw_addr_space_remote *)remote_addr_space), fArg(arg)
- {
- if (fAddrSpace->type != UNW_REMOTE)
- ABORT("OtherAddressSpace ctor called with non-remote address space.");
- fRemoteProcInfo = fAddrSpace->ras;
- }
-
- typedef typename P::uint_t pint_t;
- typedef typename P::int_t sint_t;
-
- int getBytes(pint_t addr, pint_t extent, uint8_t* buf) { return fRemoteProcInfo->getBytes (addr, extent, buf, fArg); }
- uint8_t get8(pint_t addr) { return fRemoteProcInfo->get8(addr, fArg); }
- uint16_t get16(pint_t addr) { return fRemoteProcInfo->get16(addr, fArg); }
- uint32_t get32(pint_t addr) { return fRemoteProcInfo->get32(addr, fArg); }
- uint64_t get64(pint_t addr) { return fRemoteProcInfo->get64(addr, fArg); }
- pint_t getP(pint_t addr) { return fRemoteProcInfo->getP(addr, fArg); }
-
- uint8_t get8(pint_t addr, int& err) { return fRemoteProcInfo->get8(addr, err, fArg); }
- uint16_t get16(pint_t addr, int& err) { return fRemoteProcInfo->get16(addr, err, fArg); }
- uint32_t get32(pint_t addr, int& err) { return fRemoteProcInfo->get32(addr, err, fArg); }
- uint64_t get64(pint_t addr, int& err) { return fRemoteProcInfo->get64(addr, err, fArg); }
- pint_t getP(pint_t addr, int &err) { return fRemoteProcInfo->getP(addr, err, fArg); }
-
- uint64_t getULEB128(pint_t& addr, pint_t end) { return fRemoteProcInfo->getULEB128 (addr, end, fArg); }
- int64_t getSLEB128(pint_t& addr, pint_t end) { return fRemoteProcInfo->getSLEB128 (addr, end, fArg); }
- pint_t getEncodedP(pint_t& addr, pint_t end, uint8_t encoding);
- double getDouble(pint_t addr);
- v128 getVector(pint_t addr);
- bool findFunctionName(pint_t addr, char* buf, size_t bufLen, unw_word_t* offset);
- bool findFunctionExtent(pint_t addr, unw_word_t* begin, unw_word_t* end);
- bool findUnwindSections(pint_t addr, pint_t& mh, pint_t& eh_frame_start, pint_t& eh_frame_len, pint_t& compactStart);
- RemoteProcInfo* getRemoteProcInfo () { return fRemoteProcInfo; }
- unw_accessors_t* accessors() { return fRemoteProcInfo->getAccessors(); }
- unw_addr_space_t wrap() { return (unw_addr_space_t) fAddrSpace; }
-private:
- void* localCopy(pint_t addr);
- unw_addr_space_remote *fAddrSpace;
- RemoteProcInfo* fRemoteProcInfo;
- void* fArg;
-};
-
-template <typename P>
-typename OtherAddressSpace<P>::pint_t OtherAddressSpace<P>::getEncodedP(pint_t& addr, pint_t end, uint8_t encoding)
-{
- pint_t startAddr = addr;
- pint_t p = addr;
- pint_t result;
-
- // first get value
- switch (encoding & 0x0F) {
- case DW_EH_PE_ptr:
- result = fRemoteProcInfo->getP(addr, fArg);
- p += sizeof(pint_t);
- addr = p;
- break;
- case DW_EH_PE_uleb128:
- result = fRemoteProcInfo->getULEB128(addr, end, fArg);
- break;
- case DW_EH_PE_udata2:
- result = fRemoteProcInfo->get16(addr, fArg);
- p += 2;
- addr = p;
- break;
- case DW_EH_PE_udata4:
- result = fRemoteProcInfo->get32(addr, fArg);
- p += 4;
- addr = p;
- break;
- case DW_EH_PE_udata8:
- result = fRemoteProcInfo->get64(addr, fArg);
- p += 8;
- addr = p;
- break;
- case DW_EH_PE_sleb128:
- result = fRemoteProcInfo->getSLEB128(addr, end, fArg);
- break;
- case DW_EH_PE_sdata2:
- result = (int16_t)fRemoteProcInfo->get16(addr, fArg);
- p += 2;
- addr = p;
- break;
- case DW_EH_PE_sdata4:
- result = (int32_t)fRemoteProcInfo->get32(addr, fArg);
- p += 4;
- addr = p;
- break;
- case DW_EH_PE_sdata8:
- result = fRemoteProcInfo->get64(addr, fArg);
- p += 8;
- addr = p;
- break;
- default:
- ABORT("unknown pointer encoding");
- }
-
- // then add relative offset
- switch ( encoding & 0x70 ) {
- case DW_EH_PE_absptr:
- // do nothing
- break;
- case DW_EH_PE_pcrel:
- result += startAddr;
- break;
- case DW_EH_PE_textrel:
- ABORT("DW_EH_PE_textrel pointer encoding not supported");
- break;
- case DW_EH_PE_datarel:
- ABORT("DW_EH_PE_datarel pointer encoding not supported");
- break;
- case DW_EH_PE_funcrel:
- ABORT("DW_EH_PE_funcrel pointer encoding not supported");
- break;
- case DW_EH_PE_aligned:
- ABORT("DW_EH_PE_aligned pointer encoding not supported");
- break;
- default:
- ABORT("unknown pointer encoding");
- break;
- }
-
- if ( encoding & DW_EH_PE_indirect )
- result = fRemoteProcInfo->getP(result, fArg);
-
- return result;
-}
-
-template <typename P>
-double OtherAddressSpace<P>::getDouble(pint_t addr)
-{
- return fRemoteProcInfo->getDouble(addr, fArg);
-}
-
-template <typename P>
-v128 OtherAddressSpace<P>::getVector(pint_t addr)
-{
- return fRemoteProcInfo->getVector(addr, fArg);
-}
-
-template <typename P>
-bool OtherAddressSpace<P>::findUnwindSections(pint_t addr, pint_t& mh, pint_t& eh_frame_start, pint_t& eh_frame_len, pint_t& compactStart)
-{
- compactStart = 0;
- uint64_t t_mh, t_text_start, t_text_end, t_eh_frame_start, t_eh_frame_len, t_compact_start;
- if (fRemoteProcInfo->getImageAddresses (addr, t_mh, t_text_start, t_text_end, t_eh_frame_start, t_eh_frame_len, t_compact_start, fArg))
- {
- mh = t_mh;
- eh_frame_start = t_eh_frame_start;
- eh_frame_len = t_eh_frame_len;
- compactStart = t_compact_start;
- return true;
- }
- return false;
-}
-
-template <typename P>
-bool OtherAddressSpace<P>::findFunctionName(pint_t addr, char* buf, size_t bufLen, unw_word_t* offset)
-{
- return fRemoteProcInfo->findFunctionName (addr, buf, bufLen, offset, fArg);
-}
-
-#endif // SUPPORT_REMOTE_UNWINDING
-
-
-} // namespace lldb_private
-
-
-
-#endif // __ADDRESSSPACE_HPP__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp
deleted file mode 100644
index f7b8790579f..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- ArchDefaultUnwinder.hpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Unwind a stack frame using nothing but the default conventions on
-// this architecture.
-
-#ifndef __ARCH_DEFAULT_UNWINDER_HPP
-#define __ARCH_DEFAULT_UNWINDER_HPP
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "RemoteRegisterMap.hpp"
-#include "RemoteProcInfo.hpp"
-
-namespace lldb_private
-{
-
-// As a last ditch attempt to unwind a stack frame, unwind by the
-// architecture's typical conventions. We try compact unwind, eh frame CFI,
-// and then assembly profiling if we have function bounds -- but if we're
-// looking at an address with no function bounds or unwind info, make a best
-// guess at how to get out.
-
-// In practice, this is usually hit when we try to step out of start() in a
-// stripped application binary, we've jumped to 0x0, or we're in jitted code
-// in the heap.
-
-template <typename A, typename R>
-int stepByArchitectureDefault_x86 (A& addressSpace, R& registers,
- uint64_t pc, int wordsize) {
- R newRegisters(registers);
- RemoteRegisterMap *rmap = addressSpace.getRemoteProcInfo()->getRegisterMap();
- int frame_reg = rmap->unwind_regno_for_frame_pointer();
- int stack_reg = rmap->unwind_regno_for_stack_pointer();
- int err;
-
- /* If the pc is 0x0 either we call'ed 0 (went thorugh a null function
- pointer) or this is a thread in the middle of being created that has
- no stack at all.
- For the call-0x0 case, we know how to unwind that - the pc is at
- the stack pointer.
-
- Otherwise follow the usual convention of trusting that RBP/EBP has the
- start of the stack frame and we can find the caller's pc based on
- that. */
-
- uint64_t newpc, newframeptr;
- newpc = 0;
- newframeptr = -1;
- if (pc == 0) {
- uint64_t oldsp = registers.getRegister(stack_reg);
- err = 0;
- if (oldsp != 0) {
- newpc = addressSpace.getP(registers.getRegister(stack_reg), err);
- if (err != 0)
- return UNW_EUNSPEC;
- newRegisters.setIP (newpc);
- newRegisters.setRegister (stack_reg, registers.getRegister(stack_reg) +
- wordsize);
- }
- }
- else {
- newpc = addressSpace.getP(registers.getRegister(frame_reg) +
- wordsize, err);
- if (err != 0)
- return UNW_EUNSPEC;
-
- newRegisters.setIP (newpc);
- newframeptr = addressSpace.getP(registers.getRegister(frame_reg),
- err);
- if (err != 0)
- return UNW_EUNSPEC;
-
- newRegisters.setRegister (frame_reg, newframeptr);
- newRegisters.setRegister (stack_reg, registers.getRegister(frame_reg) +
- (wordsize * 2));
- }
- registers = newRegisters;
- if (newpc == 0 || newframeptr == 0)
- return UNW_STEP_END;
- return UNW_STEP_SUCCESS;
-}
-
-template <typename A>
-int stepByArchitectureDefault (A& addressSpace, Registers_x86_64 &registers,
- uint64_t pc) {
- return stepByArchitectureDefault_x86 (addressSpace, registers, pc, 8);
-}
-
-template <typename A>
-int stepByArchitectureDefault (A& addressSpace, Registers_x86& registers,
- uint64_t pc) {
- return stepByArchitectureDefault_x86 (addressSpace, registers, pc, 4);
-}
-
-}; // namespace lldb_private
-
-#endif // SUPPORT_REMOTE_UNWINDING
-#endif // __ARCH_DEFAULT_UNWINDER_HPP
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyInstructions.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyInstructions.hpp
deleted file mode 100644
index 1e695d5e4f0..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyInstructions.hpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- AssemblyInstructions.hpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __ASSEMBLY_INSTRUCTIONS_HPP
-#define __ASSEMBLY_INSTRUCTIONS_HPP
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include <limits.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <map>
-
-#include "libunwind.h"
-#include "AssemblyParser.hpp"
-#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "RemoteUnwindProfile.h"
-
-namespace lldb_private
-{
-
-// A debug function to dump the contents of an RemoteUnwindProfile to
-// stdout in a human readable form.
-
-template <typename A, typename R>
-void printProfile (A& addressSpace, uint64_t pc, RemoteUnwindProfile* profile, R& registers) {
- RemoteProcInfo *procinfo = addressSpace.getRemoteProcInfo();
- RemoteRegisterMap *regmap = procinfo->getRegisterMap();
-
- procinfo->logDebug ("Print profile: given pc of 0x%llx, profile has range 0x%llx - 0x%llx", pc, profile->fStart, profile->fEnd);
- procinfo->logDebug ("CFA locations:");
- std::map<uint64_t, RemoteUnwindProfile::CFALocation>::iterator i;
- for (i = profile->cfa.begin(); i != profile->cfa.end(); ++i) {
- procinfo->logDebug (" as of 0x%llx cfa is based off of reg %d (%s) offset %d", i->first, i->second.regno, regmap->unwind_regno_to_name(i->second.regno), i->second.offset);
- }
- procinfo->logDebug ("Caller's saved IP is at %d bytes offset from the cfa", (int)profile->returnAddress.value);
- procinfo->logDebug ("Register saves:");
- std::map<uint64_t, std::vector<RemoteUnwindProfile::SavedReg> >::iterator j;
- for (j = profile->saved_registers.begin(); j != profile->saved_registers.end(); ++j) {
- char *tbuf1, *tbuf2, *tbuf3;
- asprintf (&tbuf1, " at pc 0x%llx there are %d registers saved ", j->first, (int) j->second.size());
- std::vector<RemoteUnwindProfile::SavedReg>::iterator k;
- for (k = j->second.begin(); k != j->second.end(); ++k) {
- if (k->location == RemoteUnwindProfile::kRegisterOffsetFromCFA) {
- asprintf (&tbuf2, "[reg %d (%s) is %d bytes from cfa] ", k->regno, regmap->unwind_regno_to_name(k->regno), (int) k->value);
- int newlen = strlen (tbuf1) + strlen (tbuf2) + 1;
- tbuf3 = (char *) malloc (newlen);
- strcpy (tbuf3, tbuf1);
- strcat (tbuf3, tbuf2);
- free (tbuf1);
- free (tbuf2);
- tbuf1 = tbuf3;
- }
- if (k->location == RemoteUnwindProfile::kRegisterIsCFA) {
- asprintf (&tbuf2, "[reg %d (%s) is the same as the cfa] ", k->regno, regmap->unwind_regno_to_name(k->regno));
- int newlen = strlen (tbuf1) + strlen (tbuf2) + 1;
- tbuf3 = (char *) malloc (newlen);
- strcpy (tbuf3, tbuf1);
- strcat (tbuf3, tbuf2);
- free (tbuf1);
- free (tbuf2);
- tbuf1 = tbuf3;
- }
- }
- procinfo->logDebug ("%s", tbuf1);
- free (tbuf1);
- }
-}
-
-template <typename A, typename R>
-int stepWithAssembly (A& addressSpace, uint64_t pc, RemoteUnwindProfile* profile, R& registers) {
- R newRegisters(registers);
- RemoteProcInfo *procinfo = addressSpace.getRemoteProcInfo();
- if (pc > profile->fEnd)
- ABORT("stepWithAssembly called with pc not in RemoteUnwindProfile's bounds");
-
- if (procinfo && (procinfo->getDebugLoggingLevel() & UNW_LOG_LEVEL_DEBUG))
- printProfile (addressSpace, pc, profile, registers);
-
- std::map<uint64_t, RemoteUnwindProfile::CFALocation>::iterator i = profile->cfa.lower_bound (pc);
- if (i == profile->cfa.begin() && i == profile->cfa.end())
- return UNW_EINVAL;
- if (i == profile->cfa.end()) {
- --i;
- } else {
- if (i != profile->cfa.begin() && i->first != pc)
- --i;
- }
-
- uint64_t cfa = registers.getRegister (i->second.regno) + i->second.offset;
-
- std::map<uint64_t, std::vector<RemoteUnwindProfile::SavedReg> >::iterator j;
-
- for (j = profile->saved_registers.begin(); j != profile->saved_registers.end() && j->first <= pc; ++j) {
- std::vector<RemoteUnwindProfile::SavedReg>::iterator k = j->second.begin();
- for (; k != j->second.end(); ++k) {
- RemoteUnwindProfile::SavedReg sr = *k;
- if (sr.type == RemoteUnwindProfile::kGeneralPurposeRegister) {
- uint64_t result;
- int err = 0;
- switch (sr.location) {
- case RemoteUnwindProfile::kRegisterOffsetFromCFA:
- result = addressSpace.getP(cfa + sr.value, err);
- break;
- case RemoteUnwindProfile::kRegisterIsCFA:
- result = cfa;
- break;
- default:
- ABORT("Unknown saved register location in stepWithAssembly.");
- }
- // If we failed to read remote memory, stop unwinding.
- if (err)
- return UNW_STEP_END;
- newRegisters.setRegister (sr.regno, result);
- }
- }
- }
- newRegisters.setSP(cfa);
- uint64_t ip = addressSpace.getP(cfa + profile->returnAddress.value);
- if (ip == 0)
- return UNW_STEP_END;
- newRegisters.setIP(ip);
- registers = newRegisters;
- return UNW_STEP_SUCCESS;
-}
-
-}; // namespace lldb_private
-
-#endif // SUPPORT_REMOTE_UNWINDING
-#endif //ASSEMBLY_INSTRUCTIONS_HPP
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp
deleted file mode 100644
index 50d0c938ebc..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/AssemblyParser.hpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- AssemblyParser.hpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Disassemble the prologue instructions in functions, create a profile
-// of stack movements and register saves performed therein.
-
-#ifndef __ASSEMBLY_PARSER_HPP
-#define __ASSEMBLY_PARSER_HPP
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#include <limits.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <map>
-#include <vector>
-
-#include "libunwind.h"
-#include "RemoteProcInfo.hpp"
-#include "Registers.hpp"
-#include "FileAbstraction.hpp"
-#include "AddressSpace.hpp"
-#include "RemoteUnwindProfile.h"
-
-namespace lldb_private
-{
-
-// Analyze the instructions in an x86_64/i386 function prologue, fill out an RemoteUnwindProfile.
-
-class AssemblyParse_x86 {
-public:
- enum { kMaxInstructionByteSize = 32 };
-
- AssemblyParse_x86 (RemoteProcInfo& procinfo, unw_accessors_t *acc, unw_addr_space_t as, void *arg) : fArg(arg), fRemoteProcInfo(procinfo), fAccessors(acc), fAs(as) {
- fRegisterMap = fRemoteProcInfo.getRegisterMap();
- if (fRemoteProcInfo.getTargetArch() == UNW_TARGET_X86_64) {
- fStackPointerRegnum = UNW_X86_64_RSP;
- fFramePointerRegnum = UNW_X86_64_RBP;
- fWordSize = 8;
- } else {
- fStackPointerRegnum = UNW_X86_ESP;
- fFramePointerRegnum = UNW_X86_EBP;
- fWordSize = 4;
- }
- }
-
- uint32_t extract_4_LE (uint8_t *b) {
- uint32_t v = 0;
- for (int i = 3; i >= 0; i--)
- v = (v << 8) | b[i];
- return v;
- }
-
- bool push_rbp_pattern_p ();
- bool push_0_pattern_p ();
- bool mov_rsp_rbp_pattern_p ();
- bool sub_rsp_pattern_p (int *amount);
- bool push_reg_p (int *regno);
- bool mov_reg_to_local_stack_frame_p (int *regno, int *rbp_offset);
- bool ret_pattern_p ();
- bool profileFunction (uint64_t start, uint64_t end, RemoteUnwindProfile& profile);
-
-private:
-
- void *fArg;
- uint8_t fCurInsnByteBuf[kMaxInstructionByteSize];
- int fCurInsnSize;
- RemoteProcInfo& fRemoteProcInfo;
- RemoteRegisterMap *fRegisterMap;
- unw_accessors_t *fAccessors;
- unw_addr_space_t fAs;
- int fWordSize;
- int fStackPointerRegnum;
- int fFramePointerRegnum;
-};
-
-// Macro to detect if this is a REX mode prefix byte.
-#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
-
-// The high bit which should be added to the source register number (the "R" bit)
-#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
-
-// The high bit which should be added to the destination register number (the "B" bit)
-#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
-
-// pushq %rbp [0x55]
-bool AssemblyParse_x86::push_rbp_pattern_p () {
- uint8_t *p = fCurInsnByteBuf;
- if (*p == 0x55)
- return true;
- return false;
-}
-
-// pushq $0 ; the first instruction in start() [0x6a 0x00]
-bool AssemblyParse_x86::push_0_pattern_p ()
-{
- uint8_t *p = fCurInsnByteBuf;
- if (*p == 0x6a && *(p + 1) == 0x0)
- return true;
- return false;
-}
-
-// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
-// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
-bool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
- uint8_t *p = fCurInsnByteBuf;
- if (fWordSize == 8 && *p == 0x48)
- p++;
- if (*(p) == 0x8b && *(p + 1) == 0xec)
- return true;
- if (*(p) == 0x89 && *(p + 1) == 0xe5)
- return true;
- return false;
-}
-
-// subq $0x20, %rsp
-bool AssemblyParse_x86::sub_rsp_pattern_p (int *amount) {
- uint8_t *p = fCurInsnByteBuf;
- if (fWordSize == 8 && *p == 0x48)
- p++;
- // 8-bit immediate operand
- if (*p == 0x83 && *(p + 1) == 0xec) {
- *amount = (int8_t) *(p + 2);
- return true;
- }
- // 32-bit immediate operand
- if (*p == 0x81 && *(p + 1) == 0xec) {
- *amount = (int32_t) extract_4_LE (p + 2);
- return true;
- }
- // Not handled: [0x83 0xc4] for imm8 with neg values
- // [0x81 0xc4] for imm32 with neg values
- return false;
-}
-
-// pushq %rbx
-// pushl $ebx
-bool AssemblyParse_x86::push_reg_p (int *regno) {
- uint8_t *p = fCurInsnByteBuf;
- int regno_prefix_bit = 0;
- // If we have a rex prefix byte, check to see if a B bit is set
- if (fWordSize == 8 && *p == 0x41) {
- regno_prefix_bit = 1 << 3;
- p++;
- }
- if (*p >= 0x50 && *p <= 0x57) {
- int r = (*p - 0x50) | regno_prefix_bit;
- if (fRegisterMap->machine_regno_to_unwind_regno (r, *regno) == true) {
- return true;
- }
- }
- return false;
-}
-
-// Look for an instruction sequence storing a nonvolatile register
-// on to the stack frame.
-
-// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
-// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4]
-bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int *regno, int *rbp_offset) {
- uint8_t *p = fCurInsnByteBuf;
- int src_reg_prefix_bit = 0;
- int target_reg_prefix_bit = 0;
-
- if (fWordSize == 8 && REX_W_PREFIX_P (*p)) {
- src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
- target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
- if (target_reg_prefix_bit == 1) {
- // rbp/ebp don't need a prefix bit - we know this isn't the
- // reg we care about.
- return false;
- }
- p++;
- }
-
- if (*p == 0x89) {
- /* Mask off the 3-5 bits which indicate the destination register
- if this is a ModR/M byte. */
- int opcode_destreg_masked_out = *(p + 1) & (~0x38);
-
- /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
- and three bits between them, e.g. 01nnn101
- We're looking for a destination of ebp-disp8 or ebp-disp32. */
- int immsize;
- if (opcode_destreg_masked_out == 0x45)
- immsize = 2;
- else if (opcode_destreg_masked_out == 0x85)
- immsize = 4;
- else
- return false;
-
- int offset = 0;
- if (immsize == 2)
- offset = (int8_t) *(p + 2);
- if (immsize == 4)
- offset = (uint32_t) extract_4_LE (p + 2);
- if (offset > 0)
- return false;
-
- int savedreg = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
- if (fRegisterMap->machine_regno_to_unwind_regno (savedreg, *regno) == true) {
- *rbp_offset = offset > 0 ? offset : -offset;
- return true;
- }
- }
- return false;
-}
-
-// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
-bool AssemblyParse_x86::ret_pattern_p () {
- uint8_t *p = fCurInsnByteBuf;
- if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
- return true;
- return false;
-}
-
-bool AssemblyParse_x86::profileFunction (uint64_t start, uint64_t end, RemoteUnwindProfile& profile) {
- if (start == -1 || end == 0)
- return false;
-
- profile.fStart = start;
- profile.fEnd = end;
- profile.fRegSizes[RemoteUnwindProfile::kGeneralPurposeRegister] = fWordSize;
- profile.fRegSizes[RemoteUnwindProfile::kFloatingPointRegister] = 8;
- profile.fRegSizes[RemoteUnwindProfile::kVectorRegister] = 16;
-
- // On function entry, the CFA is rsp+fWordSize
-
- RemoteUnwindProfile::CFALocation initial_cfaloc;
- initial_cfaloc.regno = fStackPointerRegnum;
- initial_cfaloc.offset = fWordSize;
- profile.cfa[start] = initial_cfaloc;
-
- // The return address is at CFA - fWordSize
- // CFA doesn't change value during the lifetime of the function (hence "C")
- // so the returnAddress is the same for the duration of the function.
-
- profile.returnAddress.regno = 0;
- profile.returnAddress.location = RemoteUnwindProfile::kRegisterOffsetFromCFA;
- profile.returnAddress.value = -fWordSize;
- profile.returnAddress.adj = 0;
- profile.returnAddress.type = RemoteUnwindProfile::kGeneralPurposeRegister;
-
- // The caller's rsp has the same value as the CFA at all points during
- // this function's lifetime.
-
- RemoteUnwindProfile::SavedReg rsp_loc;
- rsp_loc.regno = fStackPointerRegnum;
- rsp_loc.location = RemoteUnwindProfile::kRegisterIsCFA;
- rsp_loc.value = 0;
- rsp_loc.adj = 0;
- rsp_loc.type = RemoteUnwindProfile::kGeneralPurposeRegister;
- profile.saved_registers[start].push_back(rsp_loc);
- profile.fRegistersSaved[fStackPointerRegnum] = 1;
-
- int non_prologue_insn_count = 0;
- int insn_count = 0;
- uint64_t cur_addr = start;
- uint64_t first_insn_past_prologue = start;
- int push_rbp_seen = 0;
- int current_cfa_register = fStackPointerRegnum;
- int sp_adjustments = 0;
-
- while (cur_addr < end && non_prologue_insn_count < 10)
- {
- int offset, regno;
- uint64_t next_addr;
- insn_count++;
- int is_prologue_insn = 0;
-
- if (fAccessors->instruction_length (fAs, cur_addr, &fCurInsnSize, fArg) != 0) {
- /* An error parsing the instruction; stop scanning. */
- break;
- }
- assert (fCurInsnSize <= kMaxInstructionByteSize);
- if (fRemoteProcInfo.getBytes (cur_addr, fCurInsnSize, fCurInsnByteBuf, fArg) == 0)
- return false;
- next_addr = cur_addr + fCurInsnSize;
-
- // start () opens with a 'push $0x0' which is in the saved ip slot on the stack -
- // so we know to stop backtracing here. We need to ignore this instruction.
- if (push_0_pattern_p () && push_rbp_seen == 0 && insn_count == 1)
- {
- cur_addr = next_addr;
- first_insn_past_prologue = next_addr;
- continue;
- }
-
- if (push_rbp_pattern_p () && push_rbp_seen == 0)
- {
- if (current_cfa_register == fStackPointerRegnum) {
- sp_adjustments -= fWordSize;
- RemoteUnwindProfile::CFALocation cfaloc;
- cfaloc.regno = fStackPointerRegnum;
- cfaloc.offset = abs (sp_adjustments - fWordSize);
- profile.cfa[next_addr] = cfaloc;
- }
-
- RemoteUnwindProfile::SavedReg sreg;
- sreg.regno = fFramePointerRegnum;
- sreg.location = RemoteUnwindProfile::kRegisterOffsetFromCFA;
- sreg.value = sp_adjustments - fWordSize;
- sreg.adj = 0;
- sreg.type = RemoteUnwindProfile::kGeneralPurposeRegister;
- profile.saved_registers[next_addr].push_back(sreg);
-
- push_rbp_seen = 1;
- profile.fRegistersSaved[fFramePointerRegnum] = 1;
- is_prologue_insn = 1;
- goto next_iteration;
- }
- if (mov_rsp_rbp_pattern_p ()) {
- RemoteUnwindProfile::CFALocation cfaloc;
- cfaloc.regno = fFramePointerRegnum;
- cfaloc.offset = abs (sp_adjustments - fWordSize);
- profile.cfa[next_addr] = cfaloc;
- current_cfa_register = fFramePointerRegnum;
- is_prologue_insn = 1;
- goto next_iteration;
- }
- if (ret_pattern_p ()) {
- break;
- }
- if (sub_rsp_pattern_p (&offset)) {
- sp_adjustments -= offset;
- if (current_cfa_register == fStackPointerRegnum) {
- RemoteUnwindProfile::CFALocation cfaloc;
- cfaloc.regno = fStackPointerRegnum;
- cfaloc.offset = abs (sp_adjustments - fWordSize);
- profile.cfa[next_addr] = cfaloc;
- }
- is_prologue_insn = 1;
- }
- if (push_reg_p (&regno)) {
- sp_adjustments -= fWordSize;
- if (current_cfa_register == fStackPointerRegnum) {
- RemoteUnwindProfile::CFALocation cfaloc;
- cfaloc.regno = fStackPointerRegnum;
- cfaloc.offset = abs (sp_adjustments - fWordSize);
- profile.cfa[next_addr] = cfaloc;
- is_prologue_insn = 1;
- }
- if (fRegisterMap->nonvolatile_reg_p (regno) && profile.fRegistersSaved[regno] == 0) {
- RemoteUnwindProfile::SavedReg sreg;
- sreg.regno = regno;
- sreg.location = RemoteUnwindProfile::kRegisterOffsetFromCFA;
- sreg.value = sp_adjustments - fWordSize;
- sreg.adj = 0;
- sreg.type = RemoteUnwindProfile::kGeneralPurposeRegister;
- profile.saved_registers[next_addr].push_back(sreg);
- profile.fRegistersSaved[regno] = 1;
- is_prologue_insn = 1;
- }
- }
- if (mov_reg_to_local_stack_frame_p (&regno, &offset)
- && fRegisterMap->nonvolatile_reg_p (regno)
- && profile.fRegistersSaved[regno] == 0) {
- RemoteUnwindProfile::SavedReg sreg;
- sreg.regno = regno;
- sreg.location = RemoteUnwindProfile::kRegisterOffsetFromCFA;
- sreg.value = offset - fWordSize;
- sreg.adj = 0;
- sreg.type = RemoteUnwindProfile::kGeneralPurposeRegister;
- profile.saved_registers[next_addr].push_back(sreg);
- profile.fRegistersSaved[regno] = 1;
- is_prologue_insn = 1;
- }
-next_iteration:
- if (is_prologue_insn) {
- first_insn_past_prologue = next_addr;
- non_prologue_insn_count = 0;
- }
- cur_addr = next_addr;
- non_prologue_insn_count++;
- }
- profile.fFirstInsnPastPrologue = first_insn_past_prologue;
- return true;
-}
-
-
-
-
-bool AssemblyParse (RemoteProcInfo *procinfo, unw_accessors_t *acc, unw_addr_space_t as, uint64_t start, uint64_t end, RemoteUnwindProfile &profile, void *arg) {
- if (procinfo->getTargetArch() == UNW_TARGET_X86_64 || procinfo->getTargetArch() == UNW_TARGET_I386) {
- AssemblyParse_x86 parser(*procinfo, acc, as, arg);
- return parser.profileFunction (start, end, profile);
- } else {
- ABORT("Only x86_64 and i386 assembly parsing supported at this time");
- return false;
- }
-}
-
-}; // namespace lldb_private
-
-#endif // SUPPORT_REMOTE_UNWINDING
-#endif //ASSEMBLY_PARSER_HPP
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/CompactUnwinder.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/CompactUnwinder.hpp
deleted file mode 100644
index dda2308ada6..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/CompactUnwinder.hpp
+++ /dev/null
@@ -1,1019 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- CompactUnwinder.hpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// C++ interface to lower levels of libuwind
-//
-
-#ifndef __COMPACT_UNWINDER_HPP__
-#define __COMPACT_UNWINDER_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <libunwind.h>
-#include <mach-o/compact_unwind_encoding.h>
-
-#include "AddressSpace.hpp"
-#include "Registers.hpp"
-
-
-
-#define EXTRACT_BITS(value, mask) \
- ( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
-
-#define SUPPORT_OLD_BINARIES 0
-
-namespace lldb_private {
-
-
-
-///
-/// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka unwind) by
-/// modifying a Registers_x86 register set
-///
-template <typename A>
-class CompactUnwinder_x86
-{
-public:
-
- static int stepWithCompactEncoding(compact_unwind_encoding_t info, uint32_t functionStart, A& addressSpace, Registers_x86& registers);
-
-private:
- typename A::pint_t pint_t;
-
- static void frameUnwind(A& addressSpace, Registers_x86& registers);
- static void framelessUnwind(A& addressSpace, typename A::pint_t returnAddressLocation, Registers_x86& registers);
- static int stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A& addressSpace, Registers_x86& registers);
- static int stepWithCompactEncodingFrameless(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A& addressSpace, Registers_x86& registers, bool indirectStackSize);
-#if SUPPORT_OLD_BINARIES
- static int stepWithCompactEncodingCompat(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A& addressSpace, Registers_x86& registers);
-#endif
-};
-
-
-
-template <typename A>
-int CompactUnwinder_x86<A>::stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A& addressSpace, Registers_x86& registers)
-{
- //fprintf(stderr, "stepWithCompactEncoding(0x%08X)\n", compactEncoding);
- switch ( compactEncoding & UNWIND_X86_MODE_MASK ) {
-#if SUPPORT_OLD_BINARIES
- case UNWIND_X86_MODE_COMPATIBILITY:
- return stepWithCompactEncodingCompat(compactEncoding, functionStart, addressSpace, registers);
-#endif
- case UNWIND_X86_MODE_EBP_FRAME:
- return stepWithCompactEncodingEBPFrame(compactEncoding, functionStart, addressSpace, registers);
- case UNWIND_X86_MODE_STACK_IMMD:
- return stepWithCompactEncodingFrameless(compactEncoding, functionStart, addressSpace, registers, false);
- case UNWIND_X86_MODE_STACK_IND:
- return stepWithCompactEncodingFrameless(compactEncoding, functionStart, addressSpace, registers, true);
- }
- ABORT("invalid compact unwind encoding");
-}
-
-
-template <typename A>
-int CompactUnwinder_x86<A>::stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, uint32_t functionStart,
- A& addressSpace, Registers_x86& registers)
-{
- uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_OFFSET);
- uint32_t savedRegistersLocations = EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_REGISTERS);
-
- uint64_t savedRegisters = registers.getEBP() - 4*savedRegistersOffset;
- for (int i=0; i < 5; ++i) {
- switch (savedRegistersLocations & 0x7) {
- case UNWIND_X86_REG_NONE:
- // no register saved in this slot
- break;
- case UNWIND_X86_REG_EBX:
- registers.setEBX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_ECX:
- registers.setECX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_EDX:
- registers.setEDX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_EDI:
- registers.setEDI(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_ESI:
- registers.setESI(addressSpace.get32(savedRegisters));
- break;
- default:
- DEBUG_MESSAGE("bad register for EBP frame, encoding=%08X for function starting at 0x%X\n", compactEncoding, functionStart);
- ABORT("invalid compact unwind encoding");
- }
- savedRegisters += 4;
- savedRegistersLocations = (savedRegistersLocations >> 3);
- }
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-}
-
-
-template <typename A>
-int CompactUnwinder_x86<A>::stepWithCompactEncodingFrameless(compact_unwind_encoding_t encoding, uint32_t functionStart,
- A& addressSpace, Registers_x86& registers, bool indirectStackSize)
-{
- uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
- uint32_t stackAdjust = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST);
- uint32_t regCount = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
- uint32_t permutation = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
- uint32_t stackSize = stackSizeEncoded*4;
- if ( indirectStackSize ) {
- // stack size is encoded in subl $xxx,%esp instruction
- uint32_t subl = addressSpace.get32(functionStart+stackSizeEncoded);
- stackSize = subl + 4*stackAdjust;
- }
- // decompress permutation
- int permunreg[6];
- switch ( regCount ) {
- case 6:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- permunreg[5] = 0;
- break;
- case 5:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- break;
- case 4:
- permunreg[0] = permutation/60;
- permutation -= (permunreg[0]*60);
- permunreg[1] = permutation/12;
- permutation -= (permunreg[1]*12);
- permunreg[2] = permutation/3;
- permutation -= (permunreg[2]*3);
- permunreg[3] = permutation;
- break;
- case 3:
- permunreg[0] = permutation/20;
- permutation -= (permunreg[0]*20);
- permunreg[1] = permutation/4;
- permutation -= (permunreg[1]*4);
- permunreg[2] = permutation;
- break;
- case 2:
- permunreg[0] = permutation/5;
- permutation -= (permunreg[0]*5);
- permunreg[1] = permutation;
- break;
- case 1:
- permunreg[0] = permutation;
- break;
- }
- // re-number registers back to standard numbers
- int registersSaved[6];
- bool used[7] = { false, false, false, false, false, false, false };
- for (uint32_t i=0; i < regCount; ++i) {
- int renum = 0;
- for (int u=1; u < 7; ++u) {
- if ( !used[u] ) {
- if ( renum == permunreg[i] ) {
- registersSaved[i] = u;
- used[u] = true;
- break;
- }
- ++renum;
- }
- }
- }
- uint64_t savedRegisters = registers.getSP() + stackSize - 4 - 4*regCount;
- for (uint32_t i=0; i < regCount; ++i) {
- switch ( registersSaved[i] ) {
- case UNWIND_X86_REG_EBX:
- registers.setEBX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_ECX:
- registers.setECX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_EDX:
- registers.setEDX(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_EDI:
- registers.setEDI(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_ESI:
- registers.setESI(addressSpace.get32(savedRegisters));
- break;
- case UNWIND_X86_REG_EBP:
- registers.setEBP(addressSpace.get32(savedRegisters));
- break;
- default:
- DEBUG_MESSAGE("bad register for frameless, encoding=%08X for function starting at 0x%X\n", encoding, functionStart);
- ABORT("invalid compact unwind encoding");
- }
- savedRegisters += 4;
- }
- framelessUnwind(addressSpace, savedRegisters, registers);
- return UNW_STEP_SUCCESS;
-}
-
-
-#if SUPPORT_OLD_BINARIES
-template <typename A>
-int CompactUnwinder_x86<A>::stepWithCompactEncodingCompat(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A& addressSpace, Registers_x86& registers)
-{
- //fprintf(stderr, "stepWithCompactEncoding(0x%08X)\n", compactEncoding);
- typename A::pint_t savedRegisters;
- uint32_t stackValue = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_SIZE);
- uint32_t stackSize;
- uint32_t stackAdjust;
- switch (compactEncoding & UNWIND_X86_CASE_MASK ) {
- case UNWIND_X86_UNWIND_INFO_UNSPECIFIED:
- return UNW_ENOINFO;
-
- case UNWIND_X86_EBP_FRAME_NO_REGS:
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_EBX:
- savedRegisters = registers.getEBP() - 4;
- registers.setEBX(addressSpace.get32(savedRegisters));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_ESI:
- savedRegisters = registers.getEBP() - 4;
- registers.setESI(addressSpace.get32(savedRegisters));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_EDI:
- savedRegisters = registers.getEBP() - 4;
- registers.setEDI(addressSpace.get32(savedRegisters));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_EBX_ESI:
- savedRegisters = registers.getEBP() - 8;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_ESI_EDI:
- savedRegisters = registers.getEBP() - 8;
- registers.setESI(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_EBX_ESI_EDI:
- savedRegisters = registers.getEBP() - 12;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- registers.setEDI(addressSpace.get32(savedRegisters+8));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_EBP_FRAME_EBX_EDI:
- savedRegisters = registers.getEBP() - 8;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_NO_REGS:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*0;
- framelessUnwind(addressSpace, savedRegisters+4*0, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_EBX:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setEBX(addressSpace.get32(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_ESI:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setESI(addressSpace.get32(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_EDI:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setEDI(addressSpace.get32(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_EBX_ESI:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*2;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- framelessUnwind(addressSpace, savedRegisters+4*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_ESI_EDI:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*2;
- registers.setESI(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- framelessUnwind(addressSpace, savedRegisters+4*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_ESI_EDI_EBP:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*3;
- registers.setESI(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- registers.setEBP(addressSpace.get32(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+4*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_EBX_ESI_EDI:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*3;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- registers.setEDI(addressSpace.get32(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+4*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IMM_STK_EBX_ESI_EDI_EBP:
- stackSize = stackValue * 4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*4;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- registers.setEDI(addressSpace.get32(savedRegisters+8));
- registers.setEBP(addressSpace.get32(savedRegisters+12));
- framelessUnwind(addressSpace, savedRegisters+4*4, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_NO_REGS:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*0;
- framelessUnwind(addressSpace, savedRegisters+4*0, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_EBX:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setEBX(addressSpace.get32(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_ESI:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setESI(addressSpace.get32(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_EDI:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*1;
- registers.setEDI(addressSpace.get32(savedRegisters));
- return UNW_STEP_SUCCESS;
- framelessUnwind(addressSpace, savedRegisters+4*1, registers);
-
- case UNWIND_X86_IND_STK_EBX_ESI:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*2;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- framelessUnwind(addressSpace, savedRegisters+4*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_ESI_EDI:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*2;
- registers.setESI(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- framelessUnwind(addressSpace, savedRegisters+4*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_ESI_EDI_EBP:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*3;
- registers.setESI(addressSpace.get32(savedRegisters));
- registers.setEDI(addressSpace.get32(savedRegisters+4));
- registers.setEBP(addressSpace.get32(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+4*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_EBX_ESI_EDI:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*3;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- registers.setEDI(addressSpace.get32(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+4*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_IND_STK_EBX_ESI_EDI_EBP:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_STACK_ADJUST);
- stackSize += stackAdjust*4;
- savedRegisters = registers.getSP() + stackSize - 4 - 4*4;
- registers.setEBX(addressSpace.get32(savedRegisters));
- registers.setESI(addressSpace.get32(savedRegisters+4));
- registers.setEDI(addressSpace.get32(savedRegisters+8));
- registers.setEBP(addressSpace.get32(savedRegisters+12));
- framelessUnwind(addressSpace, savedRegisters+4*4, registers);
- return UNW_STEP_SUCCESS;
-
- default:
- DEBUG_MESSAGE("unknown compact unwind encoding %08X for function starting at 0x%X\n",
- compactEncoding & UNWIND_X86_CASE_MASK, functionStart);
- ABORT("unknown compact unwind encoding");
- }
- return UNW_EINVAL;
-}
-#endif // SUPPORT_OLD_BINARIES
-
-
-
-template <typename A>
-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));
- // old esp is ebp less saved ebp and return address
- registers.setSP(bp+8);
- // pop return address into eip
- registers.setIP(addressSpace.get32(bp+4));
-}
-
-template <typename A>
-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));
- // old esp is before return address
- registers.setSP(returnAddressLocation+4);
-}
-
-
-
-
-
-///
-/// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka unwind) by
-/// modifying a Registers_x86_64 register set
-///
-template <typename A>
-class CompactUnwinder_x86_64
-{
-public:
-
- static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers);
-
-private:
- typename A::pint_t pint_t;
-
- static void frameUnwind(A& addressSpace, Registers_x86_64& registers);
- static void framelessUnwind(A& addressSpace, uint64_t returnAddressLocation, Registers_x86_64& registers);
- static int stepWithCompactEncodingRBPFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers);
- static int stepWithCompactEncodingFrameless(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers, bool indirectStackSize);
-#if SUPPORT_OLD_BINARIES
- static int stepWithCompactEncodingCompat(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers);
-#endif
-};
-
-
-template <typename A>
-int CompactUnwinder_x86_64<A>::stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers)
-{
- //fprintf(stderr, "stepWithCompactEncoding(0x%08X)\n", compactEncoding);
- switch ( compactEncoding & UNWIND_X86_64_MODE_MASK ) {
-#if SUPPORT_OLD_BINARIES
- case UNWIND_X86_64_MODE_COMPATIBILITY:
- return stepWithCompactEncodingCompat(compactEncoding, functionStart, addressSpace, registers);
-#endif
- case UNWIND_X86_64_MODE_RBP_FRAME:
- return stepWithCompactEncodingRBPFrame(compactEncoding, functionStart, addressSpace, registers);
- case UNWIND_X86_64_MODE_STACK_IMMD:
- return stepWithCompactEncodingFrameless(compactEncoding, functionStart, addressSpace, registers, false);
- case UNWIND_X86_64_MODE_STACK_IND:
- return stepWithCompactEncodingFrameless(compactEncoding, functionStart, addressSpace, registers, true);
- }
- ABORT("invalid compact unwind encoding");
-}
-
-
-template <typename A>
-int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart,
- A& addressSpace, Registers_x86_64& registers)
-{
- uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
- uint32_t savedRegistersLocations = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
-
- uint64_t savedRegisters = registers.getRBP() - 8*savedRegistersOffset;
- for (int i=0; i < 5; ++i) {
- int readerr = 0;
- switch (savedRegistersLocations & 0x7) {
- case UNWIND_X86_64_REG_NONE:
- // no register saved in this slot
- break;
- case UNWIND_X86_64_REG_RBX:
- registers.setRBX(addressSpace.get64(savedRegisters, readerr));
- break;
- case UNWIND_X86_64_REG_R12:
- registers.setR12(addressSpace.get64(savedRegisters, readerr));
- break;
- case UNWIND_X86_64_REG_R13:
- registers.setR13(addressSpace.get64(savedRegisters, readerr));
- break;
- case UNWIND_X86_64_REG_R14:
- registers.setR14(addressSpace.get64(savedRegisters, readerr));
- break;
- case UNWIND_X86_64_REG_R15:
- registers.setR15(addressSpace.get64(savedRegisters, readerr));
- break;
- default:
- DEBUG_MESSAGE("bad register for RBP frame, encoding=%08X for function starting at 0x%llX\n", compactEncoding, functionStart);
- ABORT("invalid compact unwind encoding");
- }
- // Error reading memory while doing a remote unwind?
- if (readerr)
- return UNW_STEP_END;
-
- savedRegisters += 8;
- savedRegistersLocations = (savedRegistersLocations >> 3);
- }
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-}
-
-
-template <typename A>
-int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless(compact_unwind_encoding_t encoding, uint64_t functionStart,
- A& addressSpace, Registers_x86_64& registers, bool indirectStackSize)
-{
- uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
- uint32_t stackAdjust = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
- uint32_t regCount = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
- uint32_t permutation = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
- uint32_t stackSize = stackSizeEncoded*8;
- if ( indirectStackSize ) {
- // stack size is encoded in subl $xxx,%esp instruction
- uint32_t subl = addressSpace.get32(functionStart+stackSizeEncoded);
- stackSize = subl + 8*stackAdjust;
- }
- // decompress permutation
- int permunreg[6];
- switch ( regCount ) {
- case 6:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- permunreg[5] = 0;
- break;
- case 5:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- break;
- case 4:
- permunreg[0] = permutation/60;
- permutation -= (permunreg[0]*60);
- permunreg[1] = permutation/12;
- permutation -= (permunreg[1]*12);
- permunreg[2] = permutation/3;
- permutation -= (permunreg[2]*3);
- permunreg[3] = permutation;
- break;
- case 3:
- permunreg[0] = permutation/20;
- permutation -= (permunreg[0]*20);
- permunreg[1] = permutation/4;
- permutation -= (permunreg[1]*4);
- permunreg[2] = permutation;
- break;
- case 2:
- permunreg[0] = permutation/5;
- permutation -= (permunreg[0]*5);
- permunreg[1] = permutation;
- break;
- case 1:
- permunreg[0] = permutation;
- break;
- }
- // re-number registers back to standard numbers
- int registersSaved[6];
- bool used[7] = { false, false, false, false, false, false, false };
- for (uint32_t i=0; i < regCount; ++i) {
- int renum = 0;
- for (int u=1; u < 7; ++u) {
- if ( !used[u] ) {
- if ( renum == permunreg[i] ) {
- registersSaved[i] = u;
- used[u] = true;
- break;
- }
- ++renum;
- }
- }
- }
- uint64_t savedRegisters = registers.getSP() + stackSize - 8 - 8*regCount;
- for (uint32_t i=0; i < regCount; ++i) {
- switch ( registersSaved[i] ) {
- case UNWIND_X86_64_REG_RBX:
- registers.setRBX(addressSpace.get64(savedRegisters));
- break;
- case UNWIND_X86_64_REG_R12:
- registers.setR12(addressSpace.get64(savedRegisters));
- break;
- case UNWIND_X86_64_REG_R13:
- registers.setR13(addressSpace.get64(savedRegisters));
- break;
- case UNWIND_X86_64_REG_R14:
- registers.setR14(addressSpace.get64(savedRegisters));
- break;
- case UNWIND_X86_64_REG_R15:
- registers.setR15(addressSpace.get64(savedRegisters));
- break;
- case UNWIND_X86_64_REG_RBP:
- registers.setRBP(addressSpace.get64(savedRegisters));
- break;
- default:
- DEBUG_MESSAGE("bad register for frameless, encoding=%08X for function starting at 0x%llX\n", encoding, functionStart);
- ABORT("invalid compact unwind encoding");
- }
- savedRegisters += 8;
- }
- framelessUnwind(addressSpace, savedRegisters, registers);
- return UNW_STEP_SUCCESS;
-}
-
-#if SUPPORT_OLD_BINARIES
-template <typename A>
-int CompactUnwinder_x86_64<A>::stepWithCompactEncodingCompat(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A& addressSpace, Registers_x86_64& registers)
-{
- uint64_t savedRegisters;
- uint32_t stackValue = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_SIZE);
- uint64_t stackSize;
- uint32_t stackAdjust;
-
- switch (compactEncoding & UNWIND_X86_64_CASE_MASK ) {
- case UNWIND_X86_64_UNWIND_INFO_UNSPECIFIED:
- return UNW_ENOINFO;
-
- case UNWIND_X86_64_RBP_FRAME_NO_REGS:
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_RBP_FRAME_RBX:
- savedRegisters = registers.getRBP() - 8*1;
- registers.setRBX(addressSpace.get64(savedRegisters));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_RBP_FRAME_RBX_R12:
- savedRegisters = registers.getRBP() - 8*2;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_RBP_FRAME_RBX_R12_R13:
- savedRegisters = registers.getRBP() - 8*3;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_RBP_FRAME_RBX_R12_R13_R14:
- savedRegisters = registers.getRBP() - 8*4;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_RBP_FRAME_RBX_R12_R13_R14_R15:
- savedRegisters = registers.getRBP() - 8*5;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- registers.setR15(addressSpace.get64(savedRegisters+32));
- frameUnwind(addressSpace, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_NO_REGS:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*0;
- framelessUnwind(addressSpace, savedRegisters+8*0, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*1;
- registers.setRBX(addressSpace.get64(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+8*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_R12:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*2;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+8*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_RBP:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*2;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+8*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_R12_R13:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*3;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- framelessUnwind(addressSpace, savedRegisters+8*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_R12_R13_R14:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*4;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- framelessUnwind(addressSpace, savedRegisters+8*4, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_R12_R13_R14_R15:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*5;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- registers.setR15(addressSpace.get64(savedRegisters+32));
- framelessUnwind(addressSpace, savedRegisters+8*5, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_RBP_R12_R13_R14_R15:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*6;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- registers.setR14(addressSpace.get64(savedRegisters+32));
- registers.setR15(addressSpace.get64(savedRegisters+40));
- framelessUnwind(addressSpace, savedRegisters+8*6, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_RBP_R12:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*3;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- framelessUnwind(addressSpace, savedRegisters+8*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_RBP_R12_R13:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*4;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- framelessUnwind(addressSpace, savedRegisters+8*4, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IMM_STK_RBX_RBP_R12_R13_R14:
- stackSize = stackValue * 8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*5;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- registers.setR14(addressSpace.get64(savedRegisters+32));
- framelessUnwind(addressSpace, savedRegisters+8*5, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_NO_REGS:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*0;
- framelessUnwind(addressSpace, savedRegisters+8*0, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*1;
- registers.setRBX(addressSpace.get64(savedRegisters));
- framelessUnwind(addressSpace, savedRegisters+8*1, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_R12:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*2;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+8*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_RBP:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*2;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- framelessUnwind(addressSpace, savedRegisters+8*2, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_R12_R13:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*3;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- framelessUnwind(addressSpace, savedRegisters+8*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_R12_R13_R14:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*4;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- framelessUnwind(addressSpace, savedRegisters+8*4, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_R12_R13_R14_R15:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*5;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setR12(addressSpace.get64(savedRegisters+8));
- registers.setR13(addressSpace.get64(savedRegisters+16));
- registers.setR14(addressSpace.get64(savedRegisters+24));
- registers.setR15(addressSpace.get64(savedRegisters+32));
- framelessUnwind(addressSpace, savedRegisters+8*5, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_RBP_R12_R13_R14_R15:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*6;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- registers.setR14(addressSpace.get64(savedRegisters+32));
- registers.setR15(addressSpace.get64(savedRegisters+40));
- framelessUnwind(addressSpace, savedRegisters+8*6, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_RBP_R12:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*3;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- framelessUnwind(addressSpace, savedRegisters+8*3, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_RBP_R12_R13:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*4;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- framelessUnwind(addressSpace, savedRegisters+8*4, registers);
- return UNW_STEP_SUCCESS;
-
- case UNWIND_X86_64_IND_STK_RBX_RBP_R12_R13_R14:
- stackSize = addressSpace.get32(functionStart+stackValue);
- stackAdjust = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_STACK_ADJUST);
- stackSize += stackAdjust*8;
- savedRegisters = registers.getSP() + stackSize - 8 - 8*5;
- registers.setRBX(addressSpace.get64(savedRegisters));
- registers.setRBP(addressSpace.get64(savedRegisters+8));
- registers.setR12(addressSpace.get64(savedRegisters+16));
- registers.setR13(addressSpace.get64(savedRegisters+24));
- registers.setR14(addressSpace.get64(savedRegisters+32));
- framelessUnwind(addressSpace, savedRegisters+8*5, registers);
- return UNW_STEP_SUCCESS;
-
- default:
- DEBUG_MESSAGE("unknown compact unwind encoding %08X for function starting at 0x%llX\n",
- compactEncoding & UNWIND_X86_64_CASE_MASK, functionStart);
- ABORT("unknown compact unwind encoding");
- }
- return UNW_EINVAL;
-}
-#endif // SUPPORT_OLD_BINARIES
-
-
-template <typename A>
-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));
- // old esp is ebp less saved ebp and return address
- registers.setSP(rbp+16);
- // pop return address into eip
- registers.setIP(addressSpace.get64(rbp+8));
-}
-
-template <typename A>
-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));
- // old esp is before return address
- registers.setSP(returnAddressLocation+8);
-}
-
-
-}; // namespace lldb_private
-
-
-
-#endif // __COMPACT_UNWINDER_HPP__
-
-
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp
deleted file mode 100644
index 8b835b8cd29..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp
+++ /dev/null
@@ -1,1627 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- DwarfInstructions.hpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// processor specific parsing of dwarf unwind instructions
-//
-
-#ifndef __DWARF_INSTRUCTIONS_HPP__
-#define __DWARF_INSTRUCTIONS_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <vector>
-
-#include <libunwind.h>
-#include <mach-o/compact_unwind_encoding.h>
-
-#include "dwarf2.h"
-#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "DwarfParser.hpp"
-#include "InternalMacros.h"
-//#include "CompactUnwinder.hpp"
-
-#define EXTRACT_BITS(value, mask) \
- ( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
-
-#define CFI_INVALID_ADDRESS ((pint_t)(-1))
-
-namespace lldb_private {
-
-///
-/// Used by linker when parsing __eh_frame section
-///
-template <typename A>
-struct CFI_Reference {
- typedef typename A::pint_t pint_t;
- uint8_t encodingOfTargetAddress;
- uint32_t offsetInCFI;
- pint_t targetAddress;
-};
-template <typename A>
-struct CFI_Atom_Info {
- typedef typename A::pint_t pint_t;
- pint_t address;
- uint32_t size;
- bool isCIE;
- union {
- struct {
- CFI_Reference<A> function;
- CFI_Reference<A> cie;
- CFI_Reference<A> lsda;
- uint32_t compactUnwindInfo;
- } fdeInfo;
- struct {
- CFI_Reference<A> personality;
- } cieInfo;
- } u;
-};
-
-typedef void (*WarnFunc)(void* ref, uint64_t funcAddr, const char* msg);
-
-///
-/// DwarfInstructions maps abtract dwarf unwind instructions to a particular architecture
-///
-template <typename A, typename R>
-class DwarfInstructions
-{
-public:
- typedef typename A::pint_t pint_t;
- typedef typename A::sint_t sint_t;
-
- static const char* parseCFIs(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength,
- CFI_Atom_Info<A>* infos, uint32_t infosCount, void* ref, WarnFunc warn);
-
-
- static compact_unwind_encoding_t createCompactEncodingFromFDE(A& addressSpace, pint_t fdeStart,
- pint_t* lsda, pint_t* personality,
- char warningBuffer[1024]);
-
- static int stepWithDwarf(A& addressSpace, pint_t pc, pint_t fdeStart, R& registers);
-
-private:
-
- enum {
- DW_X86_64_RET_ADDR = 16
- };
-
- enum {
- DW_X86_RET_ADDR = 8
- };
-
- static pint_t evaluateExpression(pint_t expression, A& addressSpace, const R& registers, pint_t initialStackValue);
- static pint_t getSavedRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg);
- static double getSavedFloatRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg);
- static v128 getSavedVectorRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg);
-
- // x86 specific variants
- static int lastRestoreReg(const Registers_x86&);
- static bool isReturnAddressRegister(int regNum, const Registers_x86&);
- static pint_t getCFA(A& addressSpace, const typename CFI_Parser<A>::PrologInfo& prolog, const Registers_x86&);
-
- static uint32_t getEBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool& failure);
- static compact_unwind_encoding_t encodeToUseDwarf(const Registers_x86&);
- static compact_unwind_encoding_t createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
- const Registers_x86&, const typename CFI_Parser<A>::PrologInfo& prolog,
- char warningBuffer[1024]);
-
- // x86_64 specific variants
- static int lastRestoreReg(const Registers_x86_64&);
- static bool isReturnAddressRegister(int regNum, const Registers_x86_64&);
- static pint_t getCFA(A& addressSpace, const typename CFI_Parser<A>::PrologInfo& prolog, const Registers_x86_64&);
-
- static uint32_t getRBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool& failure);
- static compact_unwind_encoding_t encodeToUseDwarf(const Registers_x86_64&);
- static compact_unwind_encoding_t createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
- const Registers_x86_64&, const typename CFI_Parser<A>::PrologInfo& prolog,
- char warningBuffer[1024]);
-};
-
-
-
-
-template <typename A, typename R>
-const char* DwarfInstructions<A,R>::parseCFIs(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength,
- CFI_Atom_Info<A>* infos, uint32_t infosCount, void* ref, WarnFunc warn)
-{
- typename CFI_Parser<A>::CIE_Info cieInfo;
- CFI_Atom_Info<A>* entry = infos;
- CFI_Atom_Info<A>* end = &infos[infosCount];
- const pint_t ehSectionEnd = ehSectionStart + sectionLength;
- for (pint_t p=ehSectionStart; p < ehSectionEnd; ) {
- pint_t currentCFI = p;
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return NULL; // end marker
- if ( entry >= end )
- return "too little space allocated for parseCFIs";
- pint_t nextCFI = p + cfiLength;
- uint32_t id = addressSpace.get32(p);
- if ( id == 0 ) {
- // is CIE
- const char* err = CFI_Parser<A>::parseCIE(addressSpace, currentCFI, &cieInfo);
- if ( err != NULL )
- return err;
- entry->address = currentCFI;
- entry->size = nextCFI - currentCFI;
- entry->isCIE = true;
- entry->u.cieInfo.personality.targetAddress = cieInfo.personality;
- entry->u.cieInfo.personality.offsetInCFI = cieInfo.personalityOffsetInCIE;
- entry->u.cieInfo.personality.encodingOfTargetAddress = cieInfo.personalityEncoding;
- ++entry;
- }
- else {
- // is FDE
- entry->address = currentCFI;
- entry->size = nextCFI - currentCFI;
- entry->isCIE = false;
- entry->u.fdeInfo.function.targetAddress = CFI_INVALID_ADDRESS;
- entry->u.fdeInfo.cie.targetAddress = CFI_INVALID_ADDRESS;
- entry->u.fdeInfo.lsda.targetAddress = CFI_INVALID_ADDRESS;
- uint32_t ciePointer = addressSpace.get32(p);
- pint_t cieStart = p-ciePointer;
- // validate pointer to CIE is within section
- if ( (cieStart < ehSectionStart) || (cieStart > ehSectionEnd) )
- return "FDE points to CIE outside __eh_frame section";
- // optimize usual case where cie is same for all FDEs
- if ( cieStart != cieInfo.cieStart ) {
- const char* err = CFI_Parser<A>::parseCIE(addressSpace, cieStart, &cieInfo);
- if ( err != NULL )
- return err;
- }
- entry->u.fdeInfo.cie.targetAddress = cieStart;
- entry->u.fdeInfo.cie.offsetInCFI = p-currentCFI;
- entry->u.fdeInfo.cie.encodingOfTargetAddress = DW_EH_PE_sdata4 | DW_EH_PE_pcrel;
- p += 4;
- // parse pc begin and range
- pint_t offsetOfFunctionAddress = p-currentCFI;
- pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding);
- pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding & 0x0F);
- //fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- // test if pc is within the function this FDE covers
- entry->u.fdeInfo.function.targetAddress = pcStart;
- entry->u.fdeInfo.function.offsetInCFI = offsetOfFunctionAddress;
- entry->u.fdeInfo.function.encodingOfTargetAddress = cieInfo.pointerEncoding;
- // check for augmentation length
- if ( cieInfo.fdesHaveAugmentationData ) {
- uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
- pint_t endOfAug = p + augLen;
- if ( cieInfo.lsdaEncoding != 0 ) {
- // peek at value (without indirection). Zero means no lsda
- pint_t lsdaStart = p;
- if ( addressSpace.getEncodedP(p, nextCFI, cieInfo.lsdaEncoding & 0x0F) != 0 ) {
- // reset pointer and re-parse lsda address
- p = lsdaStart;
- pint_t offsetOfLSDAAddress = p-currentCFI;
- entry->u.fdeInfo.lsda.targetAddress = addressSpace.getEncodedP(p, nextCFI, cieInfo.lsdaEncoding);
- entry->u.fdeInfo.lsda.offsetInCFI = offsetOfLSDAAddress;
- entry->u.fdeInfo.lsda.encodingOfTargetAddress = cieInfo.lsdaEncoding;
- }
- }
- p = endOfAug;
- }
- // compute compact unwind encoding
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- fdeInfo.fdeStart = currentCFI;
- fdeInfo.fdeLength = nextCFI - currentCFI;
- fdeInfo.fdeInstructions = p;
- fdeInfo.pcStart = pcStart;
- fdeInfo.pcEnd = pcStart + pcRange;
- fdeInfo.lsda = entry->u.fdeInfo.lsda.targetAddress;
- typename CFI_Parser<A>::PrologInfo prolog;
- R dummy; // for proper selection of architecture specific functions
- if ( CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, CFI_INVALID_ADDRESS, &prolog) ) {
- char warningBuffer[1024];
- entry->u.fdeInfo.compactUnwindInfo = createCompactEncodingFromProlog(addressSpace, fdeInfo.pcStart, dummy, prolog, warningBuffer);
- if ( fdeInfo.lsda != CFI_INVALID_ADDRESS )
- entry->u.fdeInfo.compactUnwindInfo |= UNWIND_HAS_LSDA;
- if ( warningBuffer[0] != '\0' )
- warn(ref, fdeInfo.pcStart, warningBuffer);
- }
- else {
- warn(ref, CFI_INVALID_ADDRESS, "dwarf unwind instructions could not be parsed");
- entry->u.fdeInfo.compactUnwindInfo = encodeToUseDwarf(dummy);
- }
- ++entry;
- }
- p = nextCFI;
- }
- if ( entry != end )
- return "wrong entry count for parseCFIs";
- return NULL; // success
-}
-
-
-
-
-template <typename A, typename R>
-compact_unwind_encoding_t DwarfInstructions<A,R>::createCompactEncodingFromFDE(A& addressSpace, pint_t fdeStart,
- pint_t* lsda, pint_t* personality,
- char warningBuffer[1024])
-{
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- typename CFI_Parser<A>::CIE_Info cieInfo;
- R dummy; // for proper selection of architecture specific functions
- if ( CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo) == NULL ) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if ( CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, CFI_INVALID_ADDRESS, &prolog) ) {
- *lsda = fdeInfo.lsda;
- *personality = cieInfo.personality;
- compact_unwind_encoding_t encoding;
- encoding = createCompactEncodingFromProlog(addressSpace, fdeInfo.pcStart, dummy, prolog, warningBuffer);
- if ( fdeInfo.lsda != 0 )
- encoding |= UNWIND_HAS_LSDA;
- return encoding;
- }
- else {
- strcpy(warningBuffer, "dwarf unwind instructions could not be parsed");
- return encodeToUseDwarf(dummy);
- }
- }
- else {
- strcpy(warningBuffer, "dwarf FDE could not be parsed");
- return encodeToUseDwarf(dummy);
- }
-}
-
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A,R>::getSavedRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg)
-{
- switch ( savedReg.location ) {
- case CFI_Parser<A>::kRegisterInCFA:
- return addressSpace.getP(cfa + savedReg.value);
-
- case CFI_Parser<A>::kRegisterAtExpression:
- return addressSpace.getP(evaluateExpression(savedReg.value, addressSpace, registers, cfa));
-
- case CFI_Parser<A>::kRegisterIsExpression:
- return evaluateExpression(savedReg.value, addressSpace, registers, cfa);
-
- case CFI_Parser<A>::kRegisterInRegister:
- return registers.getRegister(savedReg.value);
-
- case CFI_Parser<A>::kRegisterUnused:
- case CFI_Parser<A>::kRegisterOffsetFromCFA:
- // FIX ME
- break;
- }
- ABORT("unsupported restore location for register");
-}
-
-template <typename A, typename R>
-double DwarfInstructions<A,R>::getSavedFloatRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg)
-{
- switch ( savedReg.location ) {
- case CFI_Parser<A>::kRegisterInCFA:
- return addressSpace.getDouble(cfa + savedReg.value);
-
- case CFI_Parser<A>::kRegisterAtExpression:
- return addressSpace.getDouble(evaluateExpression(savedReg.value, addressSpace, registers, cfa));
-
- case CFI_Parser<A>::kRegisterIsExpression:
- case CFI_Parser<A>::kRegisterUnused:
- case CFI_Parser<A>::kRegisterOffsetFromCFA:
- case CFI_Parser<A>::kRegisterInRegister:
- // FIX ME
- break;
- }
- ABORT("unsupported restore location for float register");
-}
-
-template <typename A, typename R>
-v128 DwarfInstructions<A,R>::getSavedVectorRegister(A& addressSpace, const R& registers, pint_t cfa,
- const typename CFI_Parser<A>::RegisterLocation& savedReg)
-{
- switch ( savedReg.location ) {
- case CFI_Parser<A>::kRegisterInCFA:
- return addressSpace.getVector(cfa + savedReg.value);
-
- case CFI_Parser<A>::kRegisterAtExpression:
- return addressSpace.getVector(evaluateExpression(savedReg.value, addressSpace, registers, cfa));
-
- case CFI_Parser<A>::kRegisterIsExpression:
- case CFI_Parser<A>::kRegisterUnused:
- case CFI_Parser<A>::kRegisterOffsetFromCFA:
- case CFI_Parser<A>::kRegisterInRegister:
- // FIX ME
- break;
- }
- ABORT("unsupported restore location for vector register");
-}
-
-
-template <typename A, typename R>
-int DwarfInstructions<A,R>::stepWithDwarf(A& addressSpace, pint_t pc, pint_t fdeStart, R& registers)
-{
- //fprintf(stderr, "stepWithDwarf(pc=0x%0llX, fdeStart=0x%0llX)\n", (uint64_t)pc, (uint64_t)fdeStart);
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- typename CFI_Parser<A>::CIE_Info cieInfo;
- if ( CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo) == NULL ) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if ( CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, &prolog) ) {
- R newRegisters = registers;
-
- // get pointer to cfa (architecture specific)
- pint_t cfa = getCFA(addressSpace, prolog, registers);
-
- // restore registers that dwarf says were saved
- pint_t returnAddress = 0;
- for (int i=0; i <= lastRestoreReg(newRegisters); ++i) {
- if ( prolog.savedRegisters[i].location != CFI_Parser<A>::kRegisterUnused ) {
- if ( registers.validFloatRegister(i) )
- newRegisters.setFloatRegister(i, getSavedFloatRegister(addressSpace, registers, cfa, prolog.savedRegisters[i]));
- else if ( registers.validVectorRegister(i) )
- newRegisters.setVectorRegister(i, getSavedVectorRegister(addressSpace, registers, cfa, prolog.savedRegisters[i]));
- else if ( isReturnAddressRegister(i, registers) )
- returnAddress = getSavedRegister(addressSpace, registers, cfa, prolog.savedRegisters[i]);
- else if ( registers.validRegister(i) )
- newRegisters.setRegister(i, getSavedRegister(addressSpace, registers, cfa, prolog.savedRegisters[i]));
- else
- return UNW_EBADREG;
- }
- }
-
- // by definition the CFA is the stack pointer at the call site, so restoring SP means setting it to CFA
- newRegisters.setSP(cfa);
-
- // return address is address after call site instruction, so setting IP to that does a return
- newRegisters.setIP(returnAddress);
-
- // do the actual step by replacing the register set with the new ones
- registers = newRegisters;
-
- return UNW_STEP_SUCCESS;
- }
- }
- return UNW_EBADFRAME;
-}
-
-
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A,R>::evaluateExpression(pint_t expression, A& addressSpace,
- const R& registers, pint_t initialStackValue)
-{
- const bool log = false;
- pint_t p = expression;
- pint_t expressionEnd = expression+20; // just need something until length is read
- uint64_t length = addressSpace.getULEB128(p, expressionEnd);
- expressionEnd = p + length;
- if (log) fprintf(stderr, "evaluateExpression(): length=%llu\n", length);
- pint_t stack[100];
- pint_t* sp = stack;
- *(++sp) = initialStackValue;
-
- while ( p < expressionEnd ) {
- if (log) {
- for(pint_t* t = sp; t > stack; --t) {
- fprintf(stderr, "sp[] = 0x%llX\n", (uint64_t)(*t));
- }
- }
- uint8_t opcode = addressSpace.get8(p++);
- sint_t svalue;
- pint_t value;
- uint32_t reg;
- switch (opcode) {
- case DW_OP_addr:
- // push immediate address sized value
- value = addressSpace.getP(p);
- p += sizeof(pint_t);
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_deref:
- // pop stack, dereference, push result
- value = *sp--;
- *(++sp) = addressSpace.getP(value);
- if (log) fprintf(stderr, "dereference 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_const1u:
- // push immediate 1 byte value
- value = addressSpace.get8(p);
- p += 1;
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_const1s:
- // push immediate 1 byte signed value
- svalue = (int8_t)addressSpace.get8(p);
- p += 1;
- *(++sp) = svalue;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)svalue);
- break;
-
- case DW_OP_const2u:
- // push immediate 2 byte value
- value = addressSpace.get16(p);
- p += 2;
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_const2s:
- // push immediate 2 byte signed value
- svalue = (int16_t)addressSpace.get16(p);
- p += 2;
- *(++sp) = svalue;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)svalue);
- break;
-
- case DW_OP_const4u:
- // push immediate 4 byte value
- value = addressSpace.get32(p);
- p += 4;
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_const4s:
- // push immediate 4 byte signed value
- svalue = (int32_t)addressSpace.get32(p);
- p += 4;
- *(++sp) = svalue;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)svalue);
- break;
-
- case DW_OP_const8u:
- // push immediate 8 byte value
- value = addressSpace.get64(p);
- p += 8;
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_const8s:
- // push immediate 8 byte signed value
- value = (int32_t)addressSpace.get64(p);
- p += 8;
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_constu:
- // push immediate ULEB128 value
- value = addressSpace.getULEB128(p, expressionEnd);
- *(++sp) = value;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_consts:
- // push immediate SLEB128 value
- svalue = addressSpace.getSLEB128(p, expressionEnd);
- *(++sp) = svalue;
- if (log) fprintf(stderr, "push 0x%llX\n", (uint64_t)svalue);
- break;
-
- case DW_OP_dup:
- // push top of stack
- value = *sp;
- *(++sp) = value;
- if (log) fprintf(stderr, "duplicate top of stack\n");
- break;
-
- case DW_OP_drop:
- // pop
- --sp;
- if (log) fprintf(stderr, "pop top of stack\n");
- break;
-
- case DW_OP_over:
- // dup second
- value = sp[-1];
- *(++sp) = value;
- if (log) fprintf(stderr, "duplicate second in stack\n");
- break;
-
- case DW_OP_pick:
- // pick from
- reg = addressSpace.get8(p);
- p += 1;
- value = sp[-reg];
- *(++sp) = value;
- if (log) fprintf(stderr, "duplicate %d in stack\n", reg);
- break;
-
- case DW_OP_swap:
- // swap top two
- value = sp[0];
- sp[0] = sp[-1];
- sp[-1] = value;
- if (log) fprintf(stderr, "swap top of stack\n");
- break;
-
- case DW_OP_rot:
- // rotate top three
- value = sp[0];
- sp[0] = sp[-1];
- sp[-1] = sp[-2];
- sp[-2] = value;
- if (log) fprintf(stderr, "rotate top three of stack\n");
- break;
-
- case DW_OP_xderef:
- // pop stack, dereference, push result
- value = *sp--;
- *sp = *((uint64_t*)value);
- if (log) fprintf(stderr, "x-dereference 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_abs:
- svalue = *sp;
- if ( svalue < 0 )
- *sp = -svalue;
- if (log) fprintf(stderr, "abs\n");
- break;
-
- case DW_OP_and:
- value = *sp--;
- *sp &= value;
- if (log) fprintf(stderr, "and\n");
- break;
-
- case DW_OP_div:
- svalue = *sp--;
- *sp = *sp / svalue;
- if (log) fprintf(stderr, "div\n");
- break;
-
- case DW_OP_minus:
- svalue = *sp--;
- *sp = *sp - svalue;
- if (log) fprintf(stderr, "minus\n");
- break;
-
- case DW_OP_mod:
- svalue = *sp--;
- *sp = *sp % svalue;
- if (log) fprintf(stderr, "module\n");
- break;
-
- case DW_OP_mul:
- svalue = *sp--;
- *sp = *sp * svalue;
- if (log) fprintf(stderr, "mul\n");
- break;
-
- case DW_OP_neg:
- *sp = 0 - *sp;
- if (log) fprintf(stderr, "neg\n");
- break;
-
- case DW_OP_not:
- svalue = *sp;
- *sp = ~svalue;
- if (log) fprintf(stderr, "not\n");
- break;
-
- case DW_OP_or:
- value = *sp--;
- *sp |= value;
- if (log) fprintf(stderr, "or\n");
- break;
-
- case DW_OP_plus:
- value = *sp--;
- *sp += value;
- if (log) fprintf(stderr, "plus\n");
- break;
-
- case DW_OP_plus_uconst:
- // pop stack, add uelb128 constant, push result
- *sp += addressSpace.getULEB128(p, expressionEnd);
- if (log) fprintf(stderr, "add constant\n");
- break;
-
- case DW_OP_shl:
- value = *sp--;
- *sp = *sp << value;
- if (log) fprintf(stderr, "shift left\n");
- break;
-
- case DW_OP_shr:
- value = *sp--;
- *sp = *sp >> value;
- if (log) fprintf(stderr, "shift left\n");
- break;
-
- case DW_OP_shra:
- value = *sp--;
- svalue = *sp;
- *sp = svalue >> value;
- if (log) fprintf(stderr, "shift left arithmetric\n");
- break;
-
- case DW_OP_xor:
- value = *sp--;
- *sp ^= value;
- if (log) fprintf(stderr, "xor\n");
- break;
-
- case DW_OP_skip:
- svalue = (int16_t)addressSpace.get16(p);
- p += 2;
- p += svalue;
- if (log) fprintf(stderr, "skip %lld\n", (uint64_t)svalue);
- break;
-
- case DW_OP_bra:
- svalue = (int16_t)addressSpace.get16(p);
- p += 2;
- if ( *sp-- )
- p += svalue;
- if (log) fprintf(stderr, "bra %lld\n", (uint64_t)svalue);
- break;
-
- case DW_OP_eq:
- value = *sp--;
- *sp = (*sp == value);
- if (log) fprintf(stderr, "eq\n");
- break;
-
- case DW_OP_ge:
- value = *sp--;
- *sp = (*sp >= value);
- if (log) fprintf(stderr, "ge\n");
- break;
-
- case DW_OP_gt:
- value = *sp--;
- *sp = (*sp > value);
- if (log) fprintf(stderr, "gt\n");
- break;
-
- case DW_OP_le:
- value = *sp--;
- *sp = (*sp <= value);
- if (log) fprintf(stderr, "le\n");
- break;
-
- case DW_OP_lt:
- value = *sp--;
- *sp = (*sp < value);
- if (log) fprintf(stderr, "lt\n");
- break;
-
- case DW_OP_ne:
- value = *sp--;
- *sp = (*sp != value);
- if (log) fprintf(stderr, "ne\n");
- break;
-
- case DW_OP_lit0:
- case DW_OP_lit1:
- case DW_OP_lit2:
- case DW_OP_lit3:
- case DW_OP_lit4:
- case DW_OP_lit5:
- case DW_OP_lit6:
- case DW_OP_lit7:
- case DW_OP_lit8:
- case DW_OP_lit9:
- case DW_OP_lit10:
- case DW_OP_lit11:
- case DW_OP_lit12:
- case DW_OP_lit13:
- case DW_OP_lit14:
- case DW_OP_lit15:
- case DW_OP_lit16:
- case DW_OP_lit17:
- case DW_OP_lit18:
- case DW_OP_lit19:
- case DW_OP_lit20:
- case DW_OP_lit21:
- case DW_OP_lit22:
- case DW_OP_lit23:
- case DW_OP_lit24:
- case DW_OP_lit25:
- case DW_OP_lit26:
- case DW_OP_lit27:
- case DW_OP_lit28:
- case DW_OP_lit29:
- case DW_OP_lit30:
- case DW_OP_lit31:
- value = opcode - DW_OP_lit0;
- *(++sp) = value;
- if (log) fprintf(stderr, "push literal 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_reg0:
- case DW_OP_reg1:
- case DW_OP_reg2:
- case DW_OP_reg3:
- case DW_OP_reg4:
- case DW_OP_reg5:
- case DW_OP_reg6:
- case DW_OP_reg7:
- case DW_OP_reg8:
- case DW_OP_reg9:
- case DW_OP_reg10:
- case DW_OP_reg11:
- case DW_OP_reg12:
- case DW_OP_reg13:
- case DW_OP_reg14:
- case DW_OP_reg15:
- case DW_OP_reg16:
- case DW_OP_reg17:
- case DW_OP_reg18:
- case DW_OP_reg19:
- case DW_OP_reg20:
- case DW_OP_reg21:
- case DW_OP_reg22:
- case DW_OP_reg23:
- case DW_OP_reg24:
- case DW_OP_reg25:
- case DW_OP_reg26:
- case DW_OP_reg27:
- case DW_OP_reg28:
- case DW_OP_reg29:
- case DW_OP_reg30:
- case DW_OP_reg31:
- reg = opcode - DW_OP_reg0;
- *(++sp) = registers.getRegister(reg);
- if (log) fprintf(stderr, "push reg %d\n", reg);
- break;
-
- case DW_OP_regx:
- reg = addressSpace.getULEB128(p, expressionEnd);
- *(++sp) = registers.getRegister(reg);
- if (log) fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t)svalue);
- break;
-
- case DW_OP_breg0:
- case DW_OP_breg1:
- case DW_OP_breg2:
- case DW_OP_breg3:
- case DW_OP_breg4:
- case DW_OP_breg5:
- case DW_OP_breg6:
- case DW_OP_breg7:
- case DW_OP_breg8:
- case DW_OP_breg9:
- case DW_OP_breg10:
- case DW_OP_breg11:
- case DW_OP_breg12:
- case DW_OP_breg13:
- case DW_OP_breg14:
- case DW_OP_breg15:
- case DW_OP_breg16:
- case DW_OP_breg17:
- case DW_OP_breg18:
- case DW_OP_breg19:
- case DW_OP_breg20:
- case DW_OP_breg21:
- case DW_OP_breg22:
- case DW_OP_breg23:
- case DW_OP_breg24:
- case DW_OP_breg25:
- case DW_OP_breg26:
- case DW_OP_breg27:
- case DW_OP_breg28:
- case DW_OP_breg29:
- case DW_OP_breg30:
- case DW_OP_breg31:
- reg = opcode - DW_OP_breg0;
- svalue = addressSpace.getSLEB128(p, expressionEnd);
- *(++sp) = registers.getRegister(reg) + svalue;
- if (log) fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t)svalue);
- break;
-
- case DW_OP_bregx:
- reg = addressSpace.getULEB128(p, expressionEnd);
- svalue = addressSpace.getSLEB128(p, expressionEnd);
- *(++sp) = registers.getRegister(reg) + svalue;
- if (log) fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t)svalue);
- break;
-
- case DW_OP_fbreg:
- ABORT("DW_OP_fbreg not implemented");
- break;
-
- case DW_OP_piece:
- ABORT("DW_OP_piece not implemented");
- break;
-
- case DW_OP_deref_size:
- // pop stack, dereference, push result
- value = *sp--;
- switch ( addressSpace.get8(p++) ) {
- case 1:
- value = addressSpace.get8(value);
- break;
- case 2:
- value = addressSpace.get16(value);
- break;
- case 4:
- value = addressSpace.get32(value);
- break;
- case 8:
- value = addressSpace.get64(value);
- break;
- default:
- ABORT("DW_OP_deref_size with bad size");
- }
- *(++sp) = value;
- if (log) fprintf(stderr, "sized dereference 0x%llX\n", (uint64_t)value);
- break;
-
- case DW_OP_xderef_size:
- case DW_OP_nop:
- case DW_OP_push_object_addres:
- case DW_OP_call2:
- case DW_OP_call4:
- case DW_OP_call_ref:
- default:
- ABORT("dwarf opcode not implemented");
- }
-
- }
- if (log) fprintf(stderr, "expression evaluates to 0x%llX\n", (uint64_t)*sp);
- return *sp;
-}
-
-
-
-//
-// x86_64 specific functions
-//
-
-template <typename A, typename R>
-int DwarfInstructions<A,R>::lastRestoreReg(const Registers_x86_64&)
-{
- COMPILE_TIME_ASSERT( (int)CFI_Parser<A>::kMaxRegisterNumber > (int)DW_X86_64_RET_ADDR );
- return DW_X86_64_RET_ADDR;
-}
-
-template <typename A, typename R>
-bool DwarfInstructions<A,R>::isReturnAddressRegister(int regNum, const Registers_x86_64&)
-{
- return (regNum == DW_X86_64_RET_ADDR);
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A,R>::getCFA(A& addressSpace, const typename CFI_Parser<A>::PrologInfo& prolog,
- const Registers_x86_64& registers)
-{
- if ( prolog.cfaRegister != 0 )
- return registers.getRegister(prolog.cfaRegister) + prolog.cfaRegisterOffset;
- else if ( prolog.cfaExpression != 0 )
- return evaluateExpression(prolog.cfaExpression, addressSpace, registers, 0);
- else
- ABORT("getCFA(): unknown location for x86_64 cfa");
-}
-
-
-
-template <typename A, typename R>
-compact_unwind_encoding_t DwarfInstructions<A,R>::encodeToUseDwarf(const Registers_x86_64&)
-{
- return UNWIND_X86_64_MODE_DWARF;
-}
-
-template <typename A, typename R>
-compact_unwind_encoding_t DwarfInstructions<A,R>::encodeToUseDwarf(const Registers_x86&)
-{
- return UNWIND_X86_MODE_DWARF;
-}
-
-
-
-template <typename A, typename R>
-uint32_t DwarfInstructions<A,R>::getRBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool& failure)
-{
- if ( (regOffsetFromBaseOffset < 0) || (regOffsetFromBaseOffset > 32) ) {
- failure = true;
- return 0;
- }
- unsigned int slotIndex = regOffsetFromBaseOffset/8;
-
- switch ( reg ) {
- case UNW_X86_64_RBX:
- return UNWIND_X86_64_REG_RBX << (slotIndex*3);
- case UNW_X86_64_R12:
- return UNWIND_X86_64_REG_R12 << (slotIndex*3);
- case UNW_X86_64_R13:
- return UNWIND_X86_64_REG_R13 << (slotIndex*3);
- case UNW_X86_64_R14:
- return UNWIND_X86_64_REG_R14 << (slotIndex*3);
- case UNW_X86_64_R15:
- return UNWIND_X86_64_REG_R15 << (slotIndex*3);
- }
-
- // invalid register
- failure = true;
- return 0;
-}
-
-
-
-template <typename A, typename R>
-compact_unwind_encoding_t DwarfInstructions<A,R>::createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
- const Registers_x86_64& r, const typename CFI_Parser<A>::PrologInfo& prolog,
- char warningBuffer[1024])
-{
- warningBuffer[0] = '\0';
-
- // don't create compact unwind info for unsupported dwarf kinds
- if ( prolog.registerSavedMoreThanOnce ) {
- strcpy(warningBuffer, "register saved more than once (might be shrink wrap)");
- return UNWIND_X86_64_MODE_DWARF;
- }
- if ( prolog.cfaOffsetWasNegative ) {
- strcpy(warningBuffer, "cfa had negative offset (dwarf might contain epilog)");
- return UNWIND_X86_64_MODE_DWARF;
- }
- if ( prolog.spExtraArgSize != 0 ) {
- strcpy(warningBuffer, "dwarf uses DW_CFA_GNU_args_size");
- return UNWIND_X86_64_MODE_DWARF;
- }
-
- // figure out which kind of frame this function uses
- bool standardRBPframe = (
- (prolog.cfaRegister == UNW_X86_64_RBP)
- && (prolog.cfaRegisterOffset == 16)
- && (prolog.savedRegisters[UNW_X86_64_RBP].location == CFI_Parser<A>::kRegisterInCFA)
- && (prolog.savedRegisters[UNW_X86_64_RBP].value == -16) );
- bool standardRSPframe = (prolog.cfaRegister == UNW_X86_64_RSP);
- if ( !standardRBPframe && !standardRSPframe ) {
- // no compact encoding for this
- strcpy(warningBuffer, "does not use RBP or RSP based frame");
- return UNWIND_X86_64_MODE_DWARF;
- }
-
- // scan which registers are saved
- int saveRegisterCount = 0;
- bool rbxSaved = false;
- bool r12Saved = false;
- bool r13Saved = false;
- bool r14Saved = false;
- bool r15Saved = false;
- bool rbpSaved = false;
- for (int i=0; i < 64; ++i) {
- if ( prolog.savedRegisters[i].location != CFI_Parser<A>::kRegisterUnused ) {
- if ( prolog.savedRegisters[i].location != CFI_Parser<A>::kRegisterInCFA ) {
- sprintf(warningBuffer, "register %d saved somewhere other that in frame", i);
- return UNWIND_X86_64_MODE_DWARF;
- }
- switch (i) {
- case UNW_X86_64_RBX:
- rbxSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_64_R12:
- r12Saved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_64_R13:
- r13Saved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_64_R14:
- r14Saved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_64_R15:
- r15Saved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_64_RBP:
- rbpSaved = true;
- ++saveRegisterCount;
- break;
- case DW_X86_64_RET_ADDR:
- break;
- default:
- sprintf(warningBuffer, "non-standard register %d being saved in prolog", i);
- return UNWIND_X86_64_MODE_DWARF;
- }
- }
- }
- const int64_t cfaOffsetRBX = prolog.savedRegisters[UNW_X86_64_RBX].value;
- const int64_t cfaOffsetR12 = prolog.savedRegisters[UNW_X86_64_R12].value;
- const int64_t cfaOffsetR13 = prolog.savedRegisters[UNW_X86_64_R13].value;
- const int64_t cfaOffsetR14 = prolog.savedRegisters[UNW_X86_64_R14].value;
- const int64_t cfaOffsetR15 = prolog.savedRegisters[UNW_X86_64_R15].value;
- const int64_t cfaOffsetRBP = prolog.savedRegisters[UNW_X86_64_RBP].value;
-
- // encode standard RBP frames
- compact_unwind_encoding_t encoding = 0;
- if ( standardRBPframe ) {
- // | |
- // +--------------+ <- CFA
- // | ret addr |
- // +--------------+
- // | rbp |
- // +--------------+ <- rbp
- // ~ ~
- // +--------------+
- // | saved reg3 |
- // +--------------+ <- CFA - offset+16
- // | saved reg2 |
- // +--------------+ <- CFA - offset+8
- // | saved reg1 |
- // +--------------+ <- CFA - offset
- // | |
- // +--------------+
- // | |
- // <- rsp
- //
- encoding = UNWIND_X86_64_MODE_RBP_FRAME;
-
- // find save location of farthest register from rbp
- int furthestCfaOffset = 0;
- if ( rbxSaved & (cfaOffsetRBX < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetRBX;
- if ( r12Saved & (cfaOffsetR12 < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetR12;
- if ( r13Saved & (cfaOffsetR13 < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetR13;
- if ( r14Saved & (cfaOffsetR14 < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetR14;
- if ( r15Saved & (cfaOffsetR15 < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetR15;
-
- if ( furthestCfaOffset == 0 ) {
- // no registers saved, nothing more to encode
- return encoding;
- }
-
- // add stack offset to encoding
- int rbpOffset = furthestCfaOffset + 16;
- int encodedOffset = rbpOffset/(-8);
- if ( encodedOffset > 255 ) {
- strcpy(warningBuffer, "offset of saved registers too far to encode");
- return UNWIND_X86_64_MODE_DWARF;
- }
- encoding |= (encodedOffset << __builtin_ctz(UNWIND_X86_64_RBP_FRAME_OFFSET));
-
- // add register saved from each stack location
- bool encodingFailure = false;
- if ( rbxSaved )
- encoding |= getRBPEncodedRegister(UNW_X86_64_RBX, cfaOffsetRBX - furthestCfaOffset, encodingFailure);
- if ( r12Saved )
- encoding |= getRBPEncodedRegister(UNW_X86_64_R12, cfaOffsetR12 - furthestCfaOffset, encodingFailure);
- if ( r13Saved )
- encoding |= getRBPEncodedRegister(UNW_X86_64_R13, cfaOffsetR13 - furthestCfaOffset, encodingFailure);
- if ( r14Saved )
- encoding |= getRBPEncodedRegister(UNW_X86_64_R14, cfaOffsetR14 - furthestCfaOffset, encodingFailure);
- if ( r15Saved )
- encoding |= getRBPEncodedRegister(UNW_X86_64_R15, cfaOffsetR15 - furthestCfaOffset, encodingFailure);
-
- if ( encodingFailure ){
- strcpy(warningBuffer, "saved registers not contiguous");
- return UNWIND_X86_64_MODE_DWARF;
- }
-
- return encoding;
- }
- else {
- // | |
- // +--------------+ <- CFA
- // | ret addr |
- // +--------------+
- // | saved reg1 |
- // +--------------+ <- CFA - 16
- // | saved reg2 |
- // +--------------+ <- CFA - 24
- // | saved reg3 |
- // +--------------+ <- CFA - 32
- // | saved reg4 |
- // +--------------+ <- CFA - 40
- // | saved reg5 |
- // +--------------+ <- CFA - 48
- // | saved reg6 |
- // +--------------+ <- CFA - 56
- // | |
- // <- esp
- //
-
- // for RSP based frames we need to encode stack size in unwind info
- encoding = UNWIND_X86_64_MODE_STACK_IMMD;
- uint64_t stackValue = prolog.cfaRegisterOffset / 8;
- uint32_t stackAdjust = 0;
- bool immedStackSize = true;
- const uint32_t stackMaxImmedValue = EXTRACT_BITS(0xFFFFFFFF,UNWIND_X86_64_FRAMELESS_STACK_SIZE);
- if ( stackValue > stackMaxImmedValue ) {
- // stack size is too big to fit as an immediate value, so encode offset of subq instruction in function
- pint_t functionContentAdjustStackIns = funcAddr + prolog.codeOffsetAtStackDecrement - 4;
- uint32_t stackDecrementInCode = addressSpace.get32(functionContentAdjustStackIns);
- stackAdjust = (prolog.cfaRegisterOffset - stackDecrementInCode)/8;
- stackValue = functionContentAdjustStackIns - funcAddr;
- immedStackSize = false;
- if ( stackAdjust > 7 ) {
- strcpy(warningBuffer, "stack subq instruction is too different from dwarf stack size");
- return UNWIND_X86_64_MODE_DWARF;
- }
- encoding = UNWIND_X86_64_MODE_STACK_IND;
- }
-
-
- // validate that saved registers are all within 6 slots abutting return address
- int registers[6];
- for (int i=0; i < 6;++i)
- registers[i] = 0;
- if ( r15Saved ) {
- if ( cfaOffsetR15 < -56 ) {
- strcpy(warningBuffer, "r15 is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetR15+56)/8] = UNWIND_X86_64_REG_R15;
- }
- if ( r14Saved ) {
- if ( cfaOffsetR14 < -56 ) {
- strcpy(warningBuffer, "r14 is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetR14+56)/8] = UNWIND_X86_64_REG_R14;
- }
- if ( r13Saved ) {
- if ( cfaOffsetR13 < -56 ) {
- strcpy(warningBuffer, "r13 is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetR13+56)/8] = UNWIND_X86_64_REG_R13;
- }
- if ( r12Saved ) {
- if ( cfaOffsetR12 < -56 ) {
- strcpy(warningBuffer, "r12 is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetR12+56)/8] = UNWIND_X86_64_REG_R12;
- }
- if ( rbxSaved ) {
- if ( cfaOffsetRBX < -56 ) {
- strcpy(warningBuffer, "rbx is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetRBX+56)/8] = UNWIND_X86_64_REG_RBX;
- }
- if ( rbpSaved ) {
- if ( cfaOffsetRBP < -56 ) {
- strcpy(warningBuffer, "rbp is saved too far from return address");
- return UNWIND_X86_64_MODE_DWARF;
- }
- registers[(cfaOffsetRBP+56)/8] = UNWIND_X86_64_REG_RBP;
- }
-
- // validate that saved registers are contiguous and abut return address on stack
- for (int i=0; i < saveRegisterCount; ++i) {
- if ( registers[5-i] == 0 ) {
- strcpy(warningBuffer, "registers not save contiguously in stack");
- return UNWIND_X86_64_MODE_DWARF;
- }
- }
-
- // encode register permutation
- // the 10-bits are encoded differently depending on the number of registers saved
- int renumregs[6];
- for (int i=6-saveRegisterCount; i < 6; ++i) {
- int countless = 0;
- for (int j=6-saveRegisterCount; j < i; ++j) {
- if ( registers[j] < registers[i] )
- ++countless;
- }
- renumregs[i] = registers[i] - countless -1;
- }
- uint32_t permutationEncoding = 0;
- switch ( saveRegisterCount ) {
- case 6:
- permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] + 6*renumregs[2] + 2*renumregs[3] + renumregs[4]);
- break;
- case 5:
- permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] + 6*renumregs[3] + 2*renumregs[4] + renumregs[5]);
- break;
- case 4:
- permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] + 3*renumregs[4] + renumregs[5]);
- break;
- case 3:
- permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] + renumregs[5]);
- break;
- case 2:
- permutationEncoding |= (5*renumregs[4] + renumregs[5]);
- break;
- case 1:
- permutationEncoding |= (renumregs[5]);
- break;
- }
-
- encoding |= (stackValue << __builtin_ctz(UNWIND_X86_64_FRAMELESS_STACK_SIZE));
- encoding |= (stackAdjust << __builtin_ctz(UNWIND_X86_64_FRAMELESS_STACK_ADJUST));
- encoding |= (saveRegisterCount << __builtin_ctz(UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT));
- encoding |= (permutationEncoding << __builtin_ctz(UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION));
- return encoding;
- }
-}
-
-
-
-
-//
-// x86 specific functions
-//
-template <typename A, typename R>
-int DwarfInstructions<A,R>::lastRestoreReg(const Registers_x86&)
-{
- COMPILE_TIME_ASSERT( (int)CFI_Parser<A>::kMaxRegisterNumber > (int)DW_X86_RET_ADDR );
- return DW_X86_RET_ADDR;
-}
-
-template <typename A, typename R>
-bool DwarfInstructions<A,R>::isReturnAddressRegister(int regNum, const Registers_x86&)
-{
- return (regNum == DW_X86_RET_ADDR);
-}
-
-template <typename A, typename R>
-typename A::pint_t DwarfInstructions<A,R>::getCFA(A& addressSpace, const typename CFI_Parser<A>::PrologInfo& prolog,
- const Registers_x86& registers)
-{
- if ( prolog.cfaRegister != 0 )
- return registers.getRegister(prolog.cfaRegister) + prolog.cfaRegisterOffset;
- else if ( prolog.cfaExpression != 0 )
- return evaluateExpression(prolog.cfaExpression, addressSpace, registers, 0);
- else
- ABORT("getCFA(): unknown location for x86 cfa");
-}
-
-
-
-
-
-template <typename A, typename R>
-uint32_t DwarfInstructions<A,R>::getEBPEncodedRegister(uint32_t reg, int32_t regOffsetFromBaseOffset, bool& failure)
-{
- if ( (regOffsetFromBaseOffset < 0) || (regOffsetFromBaseOffset > 16) ) {
- failure = true;
- return 0;
- }
- unsigned int slotIndex = regOffsetFromBaseOffset/4;
-
- switch ( reg ) {
- case UNW_X86_EBX:
- return UNWIND_X86_REG_EBX << (slotIndex*3);
- case UNW_X86_ECX:
- return UNWIND_X86_REG_ECX << (slotIndex*3);
- case UNW_X86_EDX:
- return UNWIND_X86_REG_EDX << (slotIndex*3);
- case UNW_X86_EDI:
- return UNWIND_X86_REG_EDI << (slotIndex*3);
- case UNW_X86_ESI:
- return UNWIND_X86_REG_ESI << (slotIndex*3);
- }
-
- // invalid register
- failure = true;
- return 0;
-}
-
-template <typename A, typename R>
-compact_unwind_encoding_t DwarfInstructions<A,R>::createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr,
- const Registers_x86& r, const typename CFI_Parser<A>::PrologInfo& prolog,
- char warningBuffer[1024])
-{
- warningBuffer[0] = '\0';
-
- // don't create compact unwind info for unsupported dwarf kinds
- if ( prolog.registerSavedMoreThanOnce ) {
- strcpy(warningBuffer, "register saved more than once (might be shrink wrap)");
- return UNWIND_X86_MODE_DWARF;
- }
- if ( prolog.spExtraArgSize != 0 ) {
- strcpy(warningBuffer, "dwarf uses DW_CFA_GNU_args_size");
- return UNWIND_X86_MODE_DWARF;
- }
-
- // figure out which kind of frame this function uses
- bool standardEBPframe = (
- (prolog.cfaRegister == UNW_X86_EBP)
- && (prolog.cfaRegisterOffset == 8)
- && (prolog.savedRegisters[UNW_X86_EBP].location == CFI_Parser<A>::kRegisterInCFA)
- && (prolog.savedRegisters[UNW_X86_EBP].value == -8) );
- bool standardESPframe = (prolog.cfaRegister == UNW_X86_ESP);
- if ( !standardEBPframe && !standardESPframe ) {
- // no compact encoding for this
- strcpy(warningBuffer, "does not use EBP or ESP based frame");
- return UNWIND_X86_MODE_DWARF;
- }
-
- // scan which registers are saved
- int saveRegisterCount = 0;
- bool ebxSaved = false;
- bool ecxSaved = false;
- bool edxSaved = false;
- bool esiSaved = false;
- bool ediSaved = false;
- bool ebpSaved = false;
- for (int i=0; i < 64; ++i) {
- if ( prolog.savedRegisters[i].location != CFI_Parser<A>::kRegisterUnused ) {
- if ( prolog.savedRegisters[i].location != CFI_Parser<A>::kRegisterInCFA ) {
- sprintf(warningBuffer, "register %d saved somewhere other that in frame", i);
- return UNWIND_X86_MODE_DWARF;
- }
- switch (i) {
- case UNW_X86_EBX:
- ebxSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_ECX:
- ecxSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_EDX:
- edxSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_ESI:
- esiSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_EDI:
- ediSaved = true;
- ++saveRegisterCount;
- break;
- case UNW_X86_EBP:
- ebpSaved = true;
- ++saveRegisterCount;
- break;
- case DW_X86_RET_ADDR:
- break;
- default:
- sprintf(warningBuffer, "non-standard register %d being saved in prolog", i);
- return UNWIND_X86_MODE_DWARF;
- }
- }
- }
- const int32_t cfaOffsetEBX = prolog.savedRegisters[UNW_X86_EBX].value;
- const int32_t cfaOffsetECX = prolog.savedRegisters[UNW_X86_ECX].value;
- const int32_t cfaOffsetEDX = prolog.savedRegisters[UNW_X86_EDX].value;
- const int32_t cfaOffsetEDI = prolog.savedRegisters[UNW_X86_EDI].value;
- const int32_t cfaOffsetESI = prolog.savedRegisters[UNW_X86_ESI].value;
- const int32_t cfaOffsetEBP = prolog.savedRegisters[UNW_X86_EBP].value;
-
- // encode standard RBP frames
- compact_unwind_encoding_t encoding = 0;
- if ( standardEBPframe ) {
- // | |
- // +--------------+ <- CFA
- // | ret addr |
- // +--------------+
- // | ebp |
- // +--------------+ <- ebp
- // ~ ~
- // +--------------+
- // | saved reg3 |
- // +--------------+ <- CFA - offset+8
- // | saved reg2 |
- // +--------------+ <- CFA - offset+e
- // | saved reg1 |
- // +--------------+ <- CFA - offset
- // | |
- // +--------------+
- // | |
- // <- esp
- //
- encoding = UNWIND_X86_MODE_EBP_FRAME;
-
- // find save location of farthest register from ebp
- int furthestCfaOffset = 0;
- if ( ebxSaved & (cfaOffsetEBX < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetEBX;
- if ( ecxSaved & (cfaOffsetECX < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetECX;
- if ( edxSaved & (cfaOffsetEDX < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetEDX;
- if ( ediSaved & (cfaOffsetEDI < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetEDI;
- if ( esiSaved & (cfaOffsetESI < furthestCfaOffset) )
- furthestCfaOffset = cfaOffsetESI;
-
- if ( furthestCfaOffset == 0 ) {
- // no registers saved, nothing more to encode
- return encoding;
- }
-
- // add stack offset to encoding
- int ebpOffset = furthestCfaOffset + 8;
- int encodedOffset = ebpOffset/(-4);
- if ( encodedOffset > 255 ) {
- strcpy(warningBuffer, "offset of saved registers too far to encode");
- return UNWIND_X86_MODE_DWARF;
- }
- encoding |= (encodedOffset << __builtin_ctz(UNWIND_X86_EBP_FRAME_OFFSET));
-
- // add register saved from each stack location
- bool encodingFailure = false;
- if ( ebxSaved )
- encoding |= getEBPEncodedRegister(UNW_X86_EBX, cfaOffsetEBX - furthestCfaOffset, encodingFailure);
- if ( ecxSaved )
- encoding |= getEBPEncodedRegister(UNW_X86_ECX, cfaOffsetECX - furthestCfaOffset, encodingFailure);
- if ( edxSaved )
- encoding |= getEBPEncodedRegister(UNW_X86_EDX, cfaOffsetEDX - furthestCfaOffset, encodingFailure);
- if ( ediSaved )
- encoding |= getEBPEncodedRegister(UNW_X86_EDI, cfaOffsetEDI - furthestCfaOffset, encodingFailure);
- if ( esiSaved )
- encoding |= getEBPEncodedRegister(UNW_X86_ESI, cfaOffsetESI - furthestCfaOffset, encodingFailure);
-
- if ( encodingFailure ){
- strcpy(warningBuffer, "saved registers not contiguous");
- return UNWIND_X86_MODE_DWARF;
- }
-
- return encoding;
- }
- else {
- // | |
- // +--------------+ <- CFA
- // | ret addr |
- // +--------------+
- // | saved reg1 |
- // +--------------+ <- CFA - 8
- // | saved reg2 |
- // +--------------+ <- CFA - 12
- // | saved reg3 |
- // +--------------+ <- CFA - 16
- // | saved reg4 |
- // +--------------+ <- CFA - 20
- // | saved reg5 |
- // +--------------+ <- CFA - 24
- // | saved reg6 |
- // +--------------+ <- CFA - 28
- // | |
- // <- esp
- //
-
- // for ESP based frames we need to encode stack size in unwind info
- encoding = UNWIND_X86_MODE_STACK_IMMD;
- uint64_t stackValue = prolog.cfaRegisterOffset / 4;
- uint32_t stackAdjust = 0;
- bool immedStackSize = true;
- const uint32_t stackMaxImmedValue = EXTRACT_BITS(0xFFFFFFFF,UNWIND_X86_FRAMELESS_STACK_SIZE);
- if ( stackValue > stackMaxImmedValue ) {
- // stack size is too big to fit as an immediate value, so encode offset of subq instruction in function
- pint_t functionContentAdjustStackIns = funcAddr + prolog.codeOffsetAtStackDecrement - 4;
- uint32_t stackDecrementInCode = addressSpace.get32(functionContentAdjustStackIns);
- stackAdjust = (prolog.cfaRegisterOffset - stackDecrementInCode)/4;
- stackValue = functionContentAdjustStackIns - funcAddr;
- immedStackSize = false;
- if ( stackAdjust > 7 ) {
- strcpy(warningBuffer, "stack subq instruction is too different from dwarf stack size");
- return UNWIND_X86_MODE_DWARF;
- }
- encoding = UNWIND_X86_MODE_STACK_IND;
- }
-
-
- // validate that saved registers are all within 6 slots abutting return address
- int registers[6];
- for (int i=0; i < 6;++i)
- registers[i] = 0;
- if ( ebxSaved ) {
- if ( cfaOffsetEBX < -28 ) {
- strcpy(warningBuffer, "ebx is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetEBX+28)/4] = UNWIND_X86_REG_EBX;
- }
- if ( ecxSaved ) {
- if ( cfaOffsetECX < -28 ) {
- strcpy(warningBuffer, "ecx is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetECX+28)/4] = UNWIND_X86_REG_ECX;
- }
- if ( edxSaved ) {
- if ( cfaOffsetEDX < -28 ) {
- strcpy(warningBuffer, "edx is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetEDX+28)/4] = UNWIND_X86_REG_EDX;
- }
- if ( ediSaved ) {
- if ( cfaOffsetEDI < -28 ) {
- strcpy(warningBuffer, "edi is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetEDI+28)/4] = UNWIND_X86_REG_EDI;
- }
- if ( esiSaved ) {
- if ( cfaOffsetESI < -28 ) {
- strcpy(warningBuffer, "esi is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetESI+28)/4] = UNWIND_X86_REG_ESI;
- }
- if ( ebpSaved ) {
- if ( cfaOffsetEBP < -28 ) {
- strcpy(warningBuffer, "ebp is saved too far from return address");
- return UNWIND_X86_MODE_DWARF;
- }
- registers[(cfaOffsetEBP+28)/4] = UNWIND_X86_REG_EBP;
- }
-
- // validate that saved registers are contiguous and abut return address on stack
- for (int i=0; i < saveRegisterCount; ++i) {
- if ( registers[5-i] == 0 ) {
- strcpy(warningBuffer, "registers not save contiguously in stack");
- return UNWIND_X86_MODE_DWARF;
- }
- }
-
- // encode register permutation
- // the 10-bits are encoded differently depending on the number of registers saved
- int renumregs[6];
- for (int i=6-saveRegisterCount; i < 6; ++i) {
- int countless = 0;
- for (int j=6-saveRegisterCount; j < i; ++j) {
- if ( registers[j] < registers[i] )
- ++countless;
- }
- renumregs[i] = registers[i] - countless -1;
- }
- uint32_t permutationEncoding = 0;
- switch ( saveRegisterCount ) {
- case 6:
- permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] + 6*renumregs[2] + 2*renumregs[3] + renumregs[4]);
- break;
- case 5:
- permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] + 6*renumregs[3] + 2*renumregs[4] + renumregs[5]);
- break;
- case 4:
- permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] + 3*renumregs[4] + renumregs[5]);
- break;
- case 3:
- permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] + renumregs[5]);
- break;
- case 2:
- permutationEncoding |= (5*renumregs[4] + renumregs[5]);
- break;
- case 1:
- permutationEncoding |= (renumregs[5]);
- break;
- }
-
- encoding |= (stackValue << __builtin_ctz(UNWIND_X86_FRAMELESS_STACK_SIZE));
- encoding |= (stackAdjust << __builtin_ctz(UNWIND_X86_FRAMELESS_STACK_ADJUST));
- encoding |= (saveRegisterCount << __builtin_ctz(UNWIND_X86_FRAMELESS_STACK_REG_COUNT));
- encoding |= (permutationEncoding << __builtin_ctz(UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION));
- return encoding;
- }
-}
-
-
-
-
-
-} // namespace lldb_private
-
-
-#endif // __DWARF_INSTRUCTIONS_HPP__
-
-
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfParser.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfParser.hpp
deleted file mode 100644
index df6db3047b8..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/DwarfParser.hpp
+++ /dev/null
@@ -1,869 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- DwarfParser.hpp -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// processor specific parsing of dwarf unwind instructions
-//
-
-#ifndef __DWARF_PARSER_HPP__
-#define __DWARF_PARSER_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <vector>
-
-#include "libunwind.h"
-#include "dwarf2.h"
-
-#include "AddressSpace.hpp"
-#include "RemoteUnwindProfile.h"
-
-namespace lldb_private {
-
-
-///
-/// CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
-/// See Dwarf Spec for details:
-/// http://www.linux-foundation.org/spec/booksets/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
-///
-template <typename A>
-class CFI_Parser
-{
-public:
- typedef typename A::pint_t pint_t;
-
- ///
- /// Information encoded in a CIE (Common Information Entry)
- ///
- struct CIE_Info {
- pint_t cieStart;
- pint_t cieLength;
- pint_t cieInstructions;
- uint8_t pointerEncoding;
- uint8_t lsdaEncoding;
- uint8_t personalityEncoding;
- uint8_t personalityOffsetInCIE;
- pint_t personality;
- int codeAlignFactor;
- int dataAlignFactor;
- bool isSignalFrame;
- bool fdesHaveAugmentationData;
- };
-
- ///
- /// Information about an FDE (Frame Description Entry)
- ///
- struct FDE_Info {
- pint_t fdeStart;
- pint_t fdeLength;
- pint_t fdeInstructions;
- pint_t pcStart;
- pint_t pcEnd;
- pint_t lsda;
- };
-
- ///
- /// Used by linker when parsing __eh_frame section
- ///
- struct FDE_Reference {
- pint_t address;
- uint32_t offsetInFDE;
- uint8_t encodingOfAddress;
- };
- struct FDE_Atom_Info {
- pint_t fdeAddress;
- FDE_Reference function;
- FDE_Reference cie;
- FDE_Reference lsda;
- };
- struct CIE_Atom_Info {
- pint_t cieAddress;
- FDE_Reference personality;
- };
-
-
- ///
- /// Information about a frame layout and registers saved determined
- /// by "running" the dwarf FDE "instructions"
- ///
- enum { kMaxRegisterNumber = 120 };
- enum RegisterSavedWhere { kRegisterUnused, kRegisterInCFA, kRegisterOffsetFromCFA,
- kRegisterInRegister, kRegisterAtExpression, kRegisterIsExpression } ;
- struct RegisterLocation {
- RegisterSavedWhere location;
- int64_t value;
- };
- struct PrologInfo {
- uint32_t cfaRegister;
- int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
- int64_t cfaExpression; // CFA = expression
- bool registersInOtherRegisters;
- bool registerSavedMoreThanOnce;
- bool cfaOffsetWasNegative;
- uint32_t spExtraArgSize;
- uint32_t codeOffsetAtStackDecrement;
-
- RegisterLocation savedRegisters[kMaxRegisterNumber]; // from where to restore registers
- };
-
- struct PrologInfoStackEntry {
- PrologInfoStackEntry(PrologInfoStackEntry* n, const PrologInfo& i)
- : next(n), info(i) {}
- PrologInfoStackEntry* next;
- PrologInfo info;
- };
-
- static bool findFDE(A& addressSpace, pint_t pc, pint_t ehSectionStart, uint32_t sectionLength, pint_t fdeHint, FDE_Info* fdeInfo, CIE_Info* cieInfo);
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
- static bool functionFuncBoundsViaFDE(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength, std::vector<FuncBounds> &funcbounds);
-#endif
-
- static const char* decodeFDE(A& addressSpace, pint_t fdeStart, FDE_Info* fdeInfo, CIE_Info* cieInfo);
- static bool parseFDEInstructions(A& addressSpace, const FDE_Info& fdeInfo, const CIE_Info& cieInfo, pint_t upToPC, PrologInfo* results);
- static const char* getCFIs(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength,
- std::vector<FDE_Atom_Info>& fdes, std::vector<CIE_Atom_Info>& cies);
- static uint32_t getCFICount(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength);
-
- static const char* parseCIE(A& addressSpace, pint_t cie, CIE_Info* cieInfo);
-
-private:
- static bool parseInstructions(A& addressSpace, pint_t instructions, pint_t instructionsEnd, const CIE_Info& cieInfo,
- pint_t pcoffset, PrologInfoStackEntry*& rememberStack, PrologInfo* results);
-
-};
-
-
-///
-/// Parse a FDE into a CIE_Info and an FDE_Info
-///
-template <typename A>
-const char* CFI_Parser<A>::decodeFDE(A& addressSpace, pint_t fdeStart, FDE_Info* fdeInfo, CIE_Info* cieInfo)
-{
- pint_t p = fdeStart;
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return "FDE has zero length"; // end marker
- uint32_t ciePointer = addressSpace.get32(p);
- if ( ciePointer == 0 )
- return "FDE is really a CIE"; // this is a CIE not an FDE
- pint_t nextCFI = p + cfiLength;
- pint_t cieStart = p-ciePointer;
- const char* err = parseCIE(addressSpace, cieStart, cieInfo);
- if (err != NULL)
- return err;
- p += 4;
- // parse pc begin and range
- pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
- pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F);
- // parse rest of info
- fdeInfo->lsda = 0;
- // check for augmentation length
- if ( cieInfo->fdesHaveAugmentationData ) {
- uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
- pint_t endOfAug = p + augLen;
- if ( cieInfo->lsdaEncoding != 0 ) {
- // peek at value (without indirection). Zero means no lsda
- pint_t lsdaStart = p;
- if ( addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0 ) {
- // reset pointer and re-parse lsda address
- p = lsdaStart;
- fdeInfo->lsda = addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
- }
- }
- p = endOfAug;
- }
- fdeInfo->fdeStart = fdeStart;
- fdeInfo->fdeLength = nextCFI - fdeStart;
- fdeInfo->fdeInstructions = p;
- fdeInfo->pcStart = pcStart;
- fdeInfo->pcEnd = pcStart+pcRange;
- return NULL; // success
-}
-
-
-///
-/// Scan an eh_frame section to find an FDE for a pc
-///
-template <typename A>
-bool CFI_Parser<A>::findFDE(A& addressSpace, pint_t pc, pint_t ehSectionStart, uint32_t sectionLength, pint_t fdeHint, FDE_Info* fdeInfo, CIE_Info* cieInfo)
-{
- //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
- pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;
- const pint_t ehSectionEnd = p + sectionLength;
- while ( p < ehSectionEnd ) {
- pint_t currentCFI = p;
- //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p);
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return false; // end marker
- uint32_t id = addressSpace.get32(p);
- if ( id == 0 ) {
- // skip over CIEs
- p += cfiLength;
- }
- else {
- // process FDE to see if it covers pc
- pint_t nextCFI = p + cfiLength;
- uint32_t ciePointer = addressSpace.get32(p);
- pint_t cieStart = p-ciePointer;
- // validate pointer to CIE is within section
- if ( (ehSectionStart <= cieStart) && (cieStart < ehSectionEnd) ) {
- if ( parseCIE(addressSpace, cieStart, cieInfo) == NULL ) {
- p += 4;
- // parse pc begin and range
- pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
- pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F);
- //fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- // test if pc is within the function this FDE covers
- if ( (pcStart < pc) && (pc <= pcStart+pcRange) ) {
- // parse rest of info
- fdeInfo->lsda = 0;
- // check for augmentation length
- if ( cieInfo->fdesHaveAugmentationData ) {
- uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
- pint_t endOfAug = p + augLen;
- if ( cieInfo->lsdaEncoding != 0 ) {
- // peek at value (without indirection). Zero means no lsda
- pint_t lsdaStart = p;
- if ( addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0 ) {
- // reset pointer and re-parse lsda address
- p = lsdaStart;
- fdeInfo->lsda = addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
- }
- }
- p = endOfAug;
- }
- fdeInfo->fdeStart = currentCFI;
- fdeInfo->fdeLength = nextCFI - currentCFI;
- fdeInfo->fdeInstructions = p;
- fdeInfo->pcStart = pcStart;
- fdeInfo->pcEnd = pcStart+pcRange;
- //fprintf(stderr, "findFDE(pc=0x%llX) found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- return true;
- }
- else {
- //fprintf(stderr, "findFDE(pc=0x%llX) not found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- // pc is not in begin/range, skip this FDE
- }
- }
- else {
- // malformed CIE, now augmentation describing pc range encoding
- //fprintf(stderr, "malformed CIE\n");
- }
- }
- else {
- // malformed FDE. CIE is bad
- //fprintf(stderr, "malformed FDE, cieStart=0x%llX, ehSectionStart=0x%llX, ehSectionEnd=0x%llX\n",
- // (uint64_t)cieStart, (uint64_t)ehSectionStart, (uint64_t)ehSectionEnd);
- }
- p = nextCFI;
- }
- }
- //fprintf(stderr, "findFDE(pc=0x%llX) not found\n",(uint64_t)pc);
- return false;
-}
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-/// Scan an eh_frame section to find all the function start addresses
-/// This is only made for working with libunwind-remote. It copies
-/// the eh_frame section into local memory and steps through it quickly
-/// to find the start addresses of the CFIs.
-///
-template <typename A>
-bool CFI_Parser<A>::functionFuncBoundsViaFDE(A& addressSpace, pint_t ehSectionStart,
- uint32_t sectionLength, std::vector<FuncBounds> &funcbounds)
-{
- //fprintf(stderr, "functionFuncBoundsViaFDE(0x%llX)\n", (long long)pc);
- pint_t p = ehSectionStart;
- const pint_t ehSectionEnd = p + sectionLength;
- pint_t lastCieSeen = (pint_t) -1;
- CIE_Info cieInfo;
- while ( p < ehSectionEnd ) {
- //fprintf(stderr, "functionFuncBoundsViaFDE() CFI at 0x%llX\n", (long long)p);
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return false; // end marker
- uint32_t id = addressSpace.get32(p);
- if ( id == 0 ) {
- // skip over CIEs
- p += cfiLength;
- }
- else {
- // process FDE to see if it covers pc
- pint_t nextCFI = p + cfiLength;
- uint32_t ciePointer = addressSpace.get32(p);
- pint_t cieStart = p-ciePointer;
- // validate pointer to CIE is within section
- if ( (ehSectionStart <= cieStart) && (cieStart < ehSectionEnd) ) {
- const char *errmsg;
- // don't re-parse the cie if this fde is pointing to one we already parsed
- if (cieStart == lastCieSeen) {
- errmsg = NULL;
- }
- else {
- errmsg = parseCIE(addressSpace, cieStart, &cieInfo);
- if (errmsg == NULL)
- lastCieSeen = cieStart;
- }
- if ( errmsg == NULL ) {
- p += 4;
- // parse pc begin and range
- pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding);
- pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding & 0x0F);
- //fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- funcbounds.push_back(FuncBounds(pcStart, pcStart + pcRange));
- }
- else {
- // malformed CIE, now augmentation describing pc range encoding
- //fprintf(stderr, "malformed CIE\n");
- return false;
- }
- }
- else {
- // malformed FDE. CIE is bad
- //fprintf(stderr, "malformed FDE, cieStart=0x%llX, ehSectionStart=0x%llX, ehSectionEnd=0x%llX\n",
- // (uint64_t)cieStart, (uint64_t)ehSectionStart, (uint64_t)ehSectionEnd);
- return false;
- }
- p = nextCFI;
- }
- }
- return true;
-}
-#endif // SUPPORT_REMOTE_UNWINDING
-
-
-
-///
-/// Extract info from a CIE
-///
-template <typename A>
-const char* CFI_Parser<A>::parseCIE(A& addressSpace, pint_t cie, CIE_Info* cieInfo)
-{
- //fprintf(stderr, "parseCIE(0x%llX)\n", (long long)cie);
- cieInfo->pointerEncoding = 0;
- cieInfo->lsdaEncoding = 0;
- cieInfo->personalityEncoding = 0;
- cieInfo->personalityOffsetInCIE = 0;
- cieInfo->personality = 0;
- cieInfo->codeAlignFactor = 0;
- cieInfo->dataAlignFactor = 0;
- cieInfo->isSignalFrame = false;
- cieInfo->fdesHaveAugmentationData = false;
- cieInfo->cieStart = cie;
- pint_t p = cie;
- uint64_t cieLength = addressSpace.get32(p);
- p += 4;
- pint_t cieContentEnd = p + cieLength;
- if ( cieLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cieLength = addressSpace.get64(p);
- p += 8;
- cieContentEnd = p + cieLength;
- }
- if ( cieLength == 0 )
- return NULL;
- // CIE ID is always 0
- if ( addressSpace.get32(p) != 0 )
- return "CIE ID is not zero";
- p += 4;
- // Version is always 1 or 3
- uint8_t version = addressSpace.get8(p);
- if ( (version != 1) && (version != 3) )
- return "CIE version is not 1 or 3";
- ++p;
- // save start of augmentation string and find end
- pint_t strStart = p;
- while ( addressSpace.get8(p) != 0 )
- ++p;
- ++p;
- // parse code aligment factor
- cieInfo->codeAlignFactor = addressSpace.getULEB128(p, cieContentEnd);
- // parse data alignment factor
- cieInfo->dataAlignFactor = addressSpace.getSLEB128(p, cieContentEnd);
- // parse return address register
- addressSpace.getULEB128(p, cieContentEnd);
- // parse augmentation data based on augmentation string
- const char* result = NULL;
- if ( addressSpace.get8(strStart) == 'z' ) {
- // parse augmentation data length
- addressSpace.getULEB128(p, cieContentEnd);
- for (pint_t s=strStart; addressSpace.get8(s) != '\0'; ++s) {
- switch ( addressSpace.get8(s) ) {
- case 'z':
- cieInfo->fdesHaveAugmentationData = true;
- break;
- case 'P':
- cieInfo->personalityEncoding = addressSpace.get8(p);
- ++p;
- cieInfo->personalityOffsetInCIE = p-cie;
- cieInfo->personality = addressSpace.getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding);
- break;
- case 'L':
- cieInfo->lsdaEncoding = addressSpace.get8(p);
- ++p;
- break;
- case 'R':
- cieInfo->pointerEncoding = addressSpace.get8(p);
- ++p;
- break;
- case 'S':
- cieInfo->isSignalFrame = true;
- break;
- default:
- // ignore unknown letters
- break;
- }
- }
- }
- cieInfo->cieLength = cieContentEnd - cieInfo->cieStart;
- cieInfo->cieInstructions = p;
- return result;
-}
-
-
-template <typename A>
-uint32_t CFI_Parser<A>::getCFICount(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength)
-{
- uint32_t count = 0;
- const pint_t ehSectionEnd = ehSectionStart + sectionLength;
- for (pint_t p=ehSectionStart; p < ehSectionEnd; ) {
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return count; // end marker
- ++count;
- p += cfiLength;
- }
- return count;
-}
-
-
-
-template <typename A>
-const char* CFI_Parser<A>::getCFIs(A& addressSpace, pint_t ehSectionStart, uint32_t sectionLength,
- std::vector<FDE_Atom_Info>& fdes, std::vector<CIE_Atom_Info>& cies)
-{
- const pint_t ehSectionEnd = ehSectionStart + sectionLength;
- for (pint_t p=ehSectionStart; p < ehSectionEnd; ) {
- pint_t currentCFI = p;
- uint64_t cfiLength = addressSpace.get32(p);
- p += 4;
- if ( cfiLength == 0xffffffff ) {
- // 0xffffffff means length is really next 8 bytes
- cfiLength = addressSpace.get64(p);
- p += 8;
- }
- if ( cfiLength == 0 )
- return NULL; // end marker
- uint32_t id = addressSpace.get32(p);
- if ( id == 0 ) {
- // is CIE
- CIE_Info cieInfo;
- const char* err = parseCIE(addressSpace, currentCFI, &cieInfo);
- if ( err != NULL )
- return err;
- CIE_Atom_Info entry;
- entry.cieAddress = currentCFI;
- entry.personality.address = cieInfo.personality;
- entry.personality.offsetInFDE = cieInfo.personalityOffsetInCIE;
- entry.personality.encodingOfAddress = cieInfo.personalityEncoding;
- cies.push_back(entry);
- p += cfiLength;
- }
- else {
- // is FDE
- FDE_Atom_Info entry;
- entry.fdeAddress = currentCFI;
- entry.function.address = 0;
- entry.cie.address = 0;
- entry.lsda.address = 0;
- pint_t nextCFI = p + cfiLength;
- uint32_t ciePointer = addressSpace.get32(p);
- pint_t cieStart = p-ciePointer;
- // validate pointer to CIE is within section
- if ( (cieStart < ehSectionStart) || (cieStart > ehSectionEnd) )
- return "FDE points to CIE outside __eh_frame section";
- CIE_Info cieInfo;
- const char* err = parseCIE(addressSpace, cieStart, &cieInfo);
- if ( err != NULL )
- return err;
- entry.cie.address = cieStart;
- entry.cie.offsetInFDE = p-currentCFI;
- entry.cie.encodingOfAddress = DW_EH_PE_sdata4 | DW_EH_PE_pcrel;
- p += 4;
- // parse pc begin and range
- pint_t offsetOfFunctionAddress = p-currentCFI;
- pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding);
- pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding & 0x0F);
- //fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange));
- // test if pc is within the function this FDE covers
- entry.function.address = pcStart;
- entry.function.offsetInFDE = offsetOfFunctionAddress;
- entry.function.encodingOfAddress = cieInfo.pointerEncoding;
- // skip over augmentation length
- if ( cieInfo.fdesHaveAugmentationData ) {
- uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
- pint_t endOfAug = p + augLen;
- if ( (cieInfo.lsdaEncoding != 0) && (addressSpace.getP(p) != 0) ) {
- pint_t offsetOfLSDAAddress = p-currentCFI;
- entry.lsda.address = addressSpace.getEncodedP(p, nextCFI, cieInfo.lsdaEncoding);
- entry.lsda.offsetInFDE = offsetOfLSDAAddress;
- entry.lsda.encodingOfAddress = cieInfo.lsdaEncoding;
- }
- p = endOfAug;
- }
- fdes.push_back(entry);
- p = nextCFI;
- }
- }
- return NULL; // success
-}
-
-
-
-///
-/// "run" the dwarf instructions and create the abstact PrologInfo for an FDE
-///
-template <typename A>
-bool CFI_Parser<A>::parseFDEInstructions(A& addressSpace, const FDE_Info& fdeInfo, const CIE_Info& cieInfo, pint_t upToPC, PrologInfo* results)
-{
- // clear results
- bzero(results, sizeof(PrologInfo));
- PrologInfoStackEntry* rememberStack = NULL;
-
- // parse CIE then FDE instructions
- return parseInstructions(addressSpace, cieInfo.cieInstructions, cieInfo.cieStart+cieInfo.cieLength,
- cieInfo, (pint_t)(-1), rememberStack, results)
- && parseInstructions(addressSpace, fdeInfo.fdeInstructions, fdeInfo.fdeStart+fdeInfo.fdeLength,
- cieInfo, upToPC-fdeInfo.pcStart, rememberStack, results);
-}
-
-
-///
-/// "run" the dwarf instructions
-///
-template <typename A>
-bool CFI_Parser<A>::parseInstructions(A& addressSpace, pint_t instructions, pint_t instructionsEnd, const CIE_Info& cieInfo,
- pint_t pcoffset, PrologInfoStackEntry*& rememberStack, PrologInfo* results)
-{
- const bool logDwarf = false;
- pint_t p = instructions;
- uint32_t codeOffset = 0;
- PrologInfo initialState = *results;
-
- // see Dwarf Spec, section 6.4.2 for details on unwind opcodes
- while ( (p < instructionsEnd) && (codeOffset < pcoffset) ) {
- uint64_t reg;
- uint64_t reg2;
- int64_t offset;
- uint64_t length;
- uint8_t opcode = addressSpace.get8(p);
- uint8_t operand;
- PrologInfoStackEntry* entry;
- ++p;
- switch (opcode) {
- case DW_CFA_nop:
- if ( logDwarf ) fprintf(stderr, "DW_CFA_nop\n");
- break;
- case DW_CFA_set_loc:
- codeOffset = addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);
- if ( logDwarf ) fprintf(stderr, "DW_CFA_set_loc\n");
- break;
- case DW_CFA_advance_loc1:
- codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
- p += 1;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_advance_loc1: new offset=%u\n", codeOffset);
- break;
- case DW_CFA_advance_loc2:
- codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
- p += 2;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_advance_loc2: new offset=%u\n", codeOffset);
- break;
- case DW_CFA_advance_loc4:
- codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
- p += 4;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_advance_loc4: new offset=%u\n", codeOffset);
- break;
- case DW_CFA_offset_extended:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- offset = addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_offset_extended dwarf unwind, reg too big\n");
- return false;
- }
- if ( results->savedRegisters[reg].location != kRegisterUnused )
- results->registerSavedMoreThanOnce = true;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_offset_extended(reg=%lld, offset=%lld)\n", reg, offset);
- break;
- case DW_CFA_restore_extended:
- reg = addressSpace.getULEB128(p, instructionsEnd);;
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_restore_extended dwarf unwind, reg too big\n");
- return false;
- }
- results->savedRegisters[reg] = initialState.savedRegisters[reg];
- if ( logDwarf ) fprintf(stderr, "DW_CFA_restore_extended(reg=%lld)\n", reg);
- break;
- case DW_CFA_undefined:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_undefined dwarf unwind, reg too big\n");
- return false;
- }
- results->savedRegisters[reg].location = kRegisterUnused;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_undefined(reg=%lld)\n", reg);
- break;
- case DW_CFA_same_value:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_same_value dwarf unwind, reg too big\n");
- return false;
- }
- if ( logDwarf ) fprintf(stderr, "DW_CFA_same_value(reg=%lld)\n", reg);
- break;
- case DW_CFA_register:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- reg2 = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_register dwarf unwind, reg too big\n");
- return false;
- }
- if ( reg2 > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_register dwarf unwind, reg2 too big\n");
- return false;
- }
- results->savedRegisters[reg].location = kRegisterInRegister;
- results->savedRegisters[reg].value = reg2;
- results->registersInOtherRegisters = true;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_register(reg=%lld, reg2=%lld)\n", reg, reg2);
- break;
- case DW_CFA_remember_state:
- // avoid operator new, because that would be an upward dependency
- entry = (PrologInfoStackEntry*)malloc(sizeof(PrologInfoStackEntry));
- if ( entry != NULL ) {
- entry->next = rememberStack;
- entry->info = *results;
- rememberStack = entry;
- }
- else {
- return false;
- }
- if ( logDwarf ) fprintf(stderr, "DW_CFA_remember_state\n");
- break;
- case DW_CFA_restore_state:
- if ( rememberStack != NULL ) {
- PrologInfoStackEntry* top = rememberStack;
- *results = top->info;
- rememberStack = top->next;
- free((char*)top);
- }
- else {
- return false;
- }
- if ( logDwarf ) fprintf(stderr, "DW_CFA_restore_state\n");
- break;
- case DW_CFA_def_cfa:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- offset = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_def_cfa dwarf unwind, reg too big\n");
- return false;
- }
- results->cfaRegister = reg;
- results->cfaRegisterOffset = offset;
- if ( offset > 0x80000000 )
- results->cfaOffsetWasNegative = true;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa(reg=%lld, offset=%lld)\n", reg, offset);
- break;
- case DW_CFA_def_cfa_register:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_def_cfa_register dwarf unwind, reg too big\n");
- return false;
- }
- results->cfaRegister = reg;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa_register(%lld)\n", reg);
- break;
- case DW_CFA_def_cfa_offset:
- results->cfaRegisterOffset = addressSpace.getULEB128(p, instructionsEnd);
- results->codeOffsetAtStackDecrement = codeOffset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa_offset(%d)\n", results->cfaRegisterOffset);
- break;
- case DW_CFA_def_cfa_expression:
- results->cfaRegister = 0;
- results->cfaExpression = p;
- length = addressSpace.getULEB128(p, instructionsEnd);
- p += length;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa_expression(expression=0x%llX, length=%llu)\n",
- results->cfaExpression, length);
- break;
- case DW_CFA_expression:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_expression dwarf unwind, reg too big\n");
- return false;
- }
- results->savedRegisters[reg].location = kRegisterAtExpression;
- results->savedRegisters[reg].value = p;
- length = addressSpace.getULEB128(p, instructionsEnd);
- p += length;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_expression(reg=%lld, expression=0x%llX, length=%llu)\n",
- reg, results->savedRegisters[reg].value, length);
- break;
- case DW_CFA_offset_extended_sf:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_offset_extended_sf dwarf unwind, reg too big\n");
- return false;
- }
- offset = addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- if ( results->savedRegisters[reg].location != kRegisterUnused )
- results->registerSavedMoreThanOnce = true;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_offset_extended_sf(reg=%lld, offset=%lld)\n", reg, offset);
- break;
- case DW_CFA_def_cfa_sf:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- offset = addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_def_cfa_sf dwarf unwind, reg too big\n");
- return false;
- }
- results->cfaRegister = reg;
- results->cfaRegisterOffset = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa_sf(reg=%lld, offset=%lld)\n", reg, offset);
- break;
- case DW_CFA_def_cfa_offset_sf:
- results->cfaRegisterOffset = addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- results->codeOffsetAtStackDecrement = codeOffset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_def_cfa_offset_sf(%d)\n", results->cfaRegisterOffset);
- break;
- case DW_CFA_val_offset:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- offset = addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
- results->savedRegisters[reg].value = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_val_offset(reg=%lld, offset=%lld\n", reg, offset);
- break;
- case DW_CFA_val_offset_sf:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_val_offset_sf dwarf unwind, reg too big\n");
- return false;
- }
- offset = addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
- results->savedRegisters[reg].value = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_val_offset_sf(reg=%lld, offset=%lld\n", reg, offset);
- break;
- case DW_CFA_val_expression:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_val_expression dwarf unwind, reg too big\n");
- return false;
- }
- results->savedRegisters[reg].location = kRegisterIsExpression;
- results->savedRegisters[reg].value = p;
- length = addressSpace.getULEB128(p, instructionsEnd);
- p += length;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_val_expression(reg=%lld, expression=0x%llX, length=%lld)\n",
- reg, results->savedRegisters[reg].value, length);
- break;
- case DW_CFA_GNU_args_size:
- offset = addressSpace.getULEB128(p, instructionsEnd);
- results->spExtraArgSize = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_GNU_args_size(%lld)\n", offset);
- break;
- case DW_CFA_GNU_negative_offset_extended:
- reg = addressSpace.getULEB128(p, instructionsEnd);
- if ( reg > kMaxRegisterNumber ) {
- fprintf(stderr, "malformed DW_CFA_GNU_negative_offset_extended dwarf unwind, reg too big\n");
- return false;
- }
- offset = addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- if ( results->savedRegisters[reg].location != kRegisterUnused )
- results->registerSavedMoreThanOnce = true;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = -offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_GNU_negative_offset_extended(%lld)\n", offset);
- break;
- default:
- operand = opcode & 0x3F;
- switch ( opcode & 0xC0 ) {
- case DW_CFA_offset:
- reg = operand;
- offset = addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- if ( results->savedRegisters[reg].location != kRegisterUnused )
- results->registerSavedMoreThanOnce = true;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_offset(reg=%d, offset=%lld)\n", operand, offset);
- break;
- case DW_CFA_advance_loc:
- codeOffset += operand * cieInfo.codeAlignFactor;
- if ( logDwarf ) fprintf(stderr, "DW_CFA_advance_loc: new offset=%u\n", codeOffset);
- break;
- case DW_CFA_restore:
- // <rdar://problem/7503075> Python crashes when handling an exception thrown by an obj-c object
- // libffi uses DW_CFA_restore in the middle of some custom dward, so it is not a good epilog flag
- //return true; // gcc-4.5 starts the epilog with this
- reg = operand;
- results->savedRegisters[reg] = initialState.savedRegisters[reg];
- if ( logDwarf ) fprintf(stderr, "DW_CFA_restore(reg=%lld)\n", reg);
- break;
- default:
- if ( logDwarf ) fprintf(stderr, "unknown CFA opcode 0x%02X\n", opcode);
- return false;
- }
- }
- }
-
- return true;
-}
-
-
-} // namespace lldb_private
-
-
-#endif // __DWARF_PARSER_HPP__
-
-
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/FileAbstraction.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/FileAbstraction.hpp
deleted file mode 100644
index a4af02051a5..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/FileAbstraction.hpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- FileAbstraction.hpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __FILE_ABSTRACTION__
-#define __FILE_ABSTRACTION__
-
-
-#include <stdint.h>
-#include <string.h>
-#include <libkern/OSByteOrder.h>
-
-#ifdef __OPTIMIZE__
-#define INLINE __attribute__((always_inline))
-#else
-#define INLINE
-#endif
-
-//
-// This abstraction layer is for use with file formats that have 64-bit/32-bit and Big-Endian/Little-Endian variants
-//
-// For example: to make a utility that handles 32-bit little enidan files use: Pointer32<LittleEndian>
-//
-//
-// get16() read a 16-bit number from an E endian struct
-// set16() write a 16-bit number to an E endian struct
-// get32() read a 32-bit number from an E endian struct
-// set32() write a 32-bit number to an E endian struct
-// get64() read a 64-bit number from an E endian struct
-// set64() write a 64-bit number to an E endian struct
-//
-// getBits() read a bit field from an E endian struct (bitCount=number of bits in field, firstBit=bit index of field)
-// setBits() write a bit field to an E endian struct (bitCount=number of bits in field, firstBit=bit index of field)
-//
-// getBitsRaw() read a bit field from a struct with native endianness
-// setBitsRaw() write a bit field from a struct with native endianness
-//
-
-class BigEndian
-{
-public:
- static uint16_t get16(const uint16_t& from) INLINE { return OSReadBigInt16(&from, 0); }
- static void set16(uint16_t& into, uint16_t value) INLINE { OSWriteBigInt16(&into, 0, value); }
-
- static uint32_t get32(const uint32_t& from) INLINE { return OSReadBigInt32(&from, 0); }
- static void set32(uint32_t& into, uint32_t value) INLINE { OSWriteBigInt32(&into, 0, value); }
-
- static uint64_t get64(const uint64_t& from) INLINE { return OSReadBigInt64(&from, 0); }
- static void set64(uint64_t& into, uint64_t value) INLINE { OSWriteBigInt64(&into, 0, value); }
-
- static uint32_t getBits(const uint32_t& from,
- uint8_t firstBit, uint8_t bitCount) INLINE { return getBitsRaw(get32(from), firstBit, bitCount); }
- static void setBits(uint32_t& into, uint32_t value,
- uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); }
-
- static uint32_t getBitsRaw(const uint32_t& from,
- uint8_t firstBit, uint8_t bitCount) INLINE { return ((from >> (32-firstBit-bitCount)) & ((1<<bitCount)-1)); }
- static void setBitsRaw(uint32_t& into, uint32_t value,
- uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = into;
- const uint32_t mask = ((1<<bitCount)-1);
- temp &= ~(mask << (32-firstBit-bitCount));
- temp |= ((value & mask) << (32-firstBit-bitCount));
- into = temp; }
- enum { little_endian = 0 };
-};
-
-
-class LittleEndian
-{
-public:
- static uint16_t get16(const uint16_t& from) INLINE { return OSReadLittleInt16(&from, 0); }
- static void set16(uint16_t& into, uint16_t value) INLINE { OSWriteLittleInt16(&into, 0, value); }
-
- static uint32_t get32(const uint32_t& from) INLINE { return OSReadLittleInt32(&from, 0); }
- static void set32(uint32_t& into, uint32_t value) INLINE { OSWriteLittleInt32(&into, 0, value); }
-
- static uint64_t get64(const uint64_t& from) INLINE { return OSReadLittleInt64(&from, 0); }
- static void set64(uint64_t& into, uint64_t value) INLINE { OSWriteLittleInt64(&into, 0, value); }
-
- static uint32_t getBits(const uint32_t& from,
- uint8_t firstBit, uint8_t bitCount) INLINE { return getBitsRaw(get32(from), firstBit, bitCount); }
- static void setBits(uint32_t& into, uint32_t value,
- uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); }
-
- static uint32_t getBitsRaw(const uint32_t& from,
- uint8_t firstBit, uint8_t bitCount) INLINE { return ((from >> firstBit) & ((1<<bitCount)-1)); }
- static void setBitsRaw(uint32_t& into, uint32_t value,
- uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = into;
- const uint32_t mask = ((1<<bitCount)-1);
- temp &= ~(mask << firstBit);
- temp |= ((value & mask) << firstBit);
- into = temp; }
- enum { little_endian = 1 };
-};
-
-
-template <typename _E>
-class Pointer32
-{
-public:
- typedef uint32_t uint_t;
- typedef int32_t int_t;
- typedef _E E;
-
- static uint64_t getP(const uint_t& from) INLINE { return _E::get32(from); }
- static void setP(uint_t& into, uint64_t value) INLINE { _E::set32(into, value); }
-};
-
-
-template <typename _E>
-class Pointer64
-{
-public:
- typedef uint64_t uint_t;
- typedef int64_t int_t;
- typedef _E E;
-
- static uint64_t getP(const uint_t& from) INLINE { return _E::get64(from); }
- static void setP(uint_t& into, uint64_t value) INLINE { _E::set64(into, value); }
-};
-
-
-
-
-
-
-#endif // __FILE_ABSTRACTION__
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/InternalMacros.h b/lldb/source/Plugins/Process/Utility/libunwind/src/InternalMacros.h
deleted file mode 100644
index 40483900d38..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/InternalMacros.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- InternalMacros.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef INTERNAL_MACROS_H
-#define INTERNAL_MACROS_H
-
-#include <assert.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- extern void __assert_rtn(const char *, const char *, int, const char *) __attribute__((noreturn));
-#ifdef __cplusplus
-}
-#endif
-
-#define UNW_STEP_SUCCESS 1
-#define UNW_STEP_END 0
-
-
-struct v128 { unsigned int vec[4]; };
-
-
-#define EXPORT __attribute__((visibility("default")))
-
-#define COMPILE_TIME_ASSERT( expr ) \
- extern int compile_time_assert_failed[ ( expr ) ? 1 : -1 ] __attribute__( ( unused ) );
-
-#define ABORT(msg) __assert_rtn(__func__, __FILE__, __LINE__, msg)
-
-#if NDEBUG
- #define DEBUG_MESSAGE(msg, ...)
- #define DEBUG_PRINT_API(msg, ...)
- #define DEBUG_PRINT_UNWINDING_TEST 0
- #define DEBUG_PRINT_UNWINDING(msg, ...)
- #define DEBUG_LOG_NON_ZERO(x) x;
- #define INITIALIZE_DEBUG_PRINT_API
- #define INITIALIZE_DEBUG_PRINT_UNWINDING
-#else
- #define DEBUG_MESSAGE(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
- #ifdef __cplusplus
- extern "C" {
- #endif
- extern bool logAPIs();
- extern bool logUnwinding();
- #ifdef __cplusplus
- }
- #endif
- #define DEBUG_LOG_NON_ZERO(x) { int _err = x; if ( _err != 0 ) fprintf(stderr, "libuwind: " #x "=%d in %s", _err, __FUNCTION__); }
- #define DEBUG_PRINT_API(msg, ...) do { if ( logAPIs() ) fprintf(stderr, msg, __VA_ARGS__); } while(0)
- #define DEBUG_PRINT_UNWINDING(msg, ...) do { if ( logUnwinding() ) fprintf(stderr, msg, __VA_ARGS__); } while(0)
- #define DEBUG_PRINT_UNWINDING_TEST logUnwinding()
- #define INITIALIZE_DEBUG_PRINT_API bool logAPIs() { static bool log = (getenv("LIBUNWIND_PRINT_APIS") != NULL); return log; }
- #define INITIALIZE_DEBUG_PRINT_UNWINDING bool logUnwinding() { static bool log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL); return log; }
-#endif
-
-
-// note hack for <rdar://problem/6175741>
-// Once libgcc_s.dylib vectors to libSystem, then we can remove the $ld$hide$os10.6$ lines
-#if __ppc__
- #define NOT_HERE_BEFORE_10_6(sym) \
- extern const char sym##_tmp3 __asm("$ld$hide$os10.3$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
- extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
- extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
- #define NEVER_HERE(sym) \
- extern const char sym##_tmp3 __asm("$ld$hide$os10.3$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp3 = 0; \
- extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
- extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
- extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
-#else
- #define NOT_HERE_BEFORE_10_6(sym) \
- extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
- extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
- #define NEVER_HERE(sym) \
- extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
- extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
- extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
-#endif
-
-
-
-#endif // INTERNAL_MACROS_H
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.hpp
deleted file mode 100644
index 89bd1ce4156..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.hpp
+++ /dev/null
@@ -1,456 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- Registers.hpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// C++ interface to lower levels of libuwind
-//
-
-#ifndef __REGISTERS_HPP__
-#define __REGISTERS_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <mach-o/loader.h>
-#include <mach-o/getsect.h>
-#include <mach/i386/thread_status.h>
-
-#include "libunwind.h"
-#include "InternalMacros.h"
-
-namespace lldb_private {
-
-
-///
-/// Registers_x86 holds the register state of a thread in a 32-bit intel process.
-///
-class Registers_x86
-{
-public:
- Registers_x86();
- Registers_x86(const void* registers);
-
- bool validRegister(int num) const;
- uint32_t getRegister(int num) const;
- void setRegister(int num, uint32_t value);
- bool validFloatRegister(int num) const { return false; }
- double getFloatRegister(int num) const;
- void setFloatRegister(int num, double value);
- bool validVectorRegister(int num) const { return false; }
- v128 getVectorRegister(int num) const;
- void setVectorRegister(int num, v128 value);
- const char* getRegisterName(int num);
- void jumpto() {}
-
- uint32_t getSP() const { return fRegisters.__esp; }
- void setSP(uint32_t value) { fRegisters.__esp = value; }
- uint32_t getIP() const { return fRegisters.__eip; }
- void setIP(uint32_t value) { fRegisters.__eip = value; }
- uint32_t getEBP() const { return fRegisters.__ebp; }
- void setEBP(uint32_t value) { fRegisters.__ebp = value; }
- uint32_t getEBX() const { return fRegisters.__ebx; }
- void setEBX(uint32_t value) { fRegisters.__ebx = value; }
- uint32_t getECX() const { return fRegisters.__ecx; }
- void setECX(uint32_t value) { fRegisters.__ecx = value; }
- uint32_t getEDX() const { return fRegisters.__edx; }
- void setEDX(uint32_t value) { fRegisters.__edx = value; }
- uint32_t getESI() const { return fRegisters.__esi; }
- void setESI(uint32_t value) { fRegisters.__esi = value; }
- uint32_t getEDI() const { return fRegisters.__edi; }
- void setEDI(uint32_t value) { fRegisters.__edi = value; }
-
-private:
- i386_thread_state_t fRegisters;
-};
-
-inline Registers_x86::Registers_x86(const void* registers)
-{
- COMPILE_TIME_ASSERT( sizeof(Registers_x86) < sizeof(unw_context_t) );
- fRegisters = *((i386_thread_state_t*)registers);
-}
-
-inline Registers_x86::Registers_x86()
-{
- bzero(&fRegisters, sizeof(fRegisters));
-}
-
-
-inline bool Registers_x86::validRegister(int regNum) const
-{
- if ( regNum == UNW_REG_IP )
- return true;
- if ( regNum == UNW_REG_SP )
- return true;
- if ( regNum < 0 )
- return false;
- if ( regNum > 7 )
- return false;
- return true;
-}
-
-inline uint32_t Registers_x86::getRegister(int regNum) const
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- return fRegisters.__eip;
- case UNW_REG_SP:
- return fRegisters.__esp;
- case UNW_X86_EAX:
- return fRegisters.__eax;
- case UNW_X86_ECX:
- return fRegisters.__ecx;
- case UNW_X86_EDX:
- return fRegisters.__edx;
- case UNW_X86_EBX:
- return fRegisters.__ebx;
- case UNW_X86_EBP:
- return fRegisters.__ebp;
- case UNW_X86_ESP:
- return fRegisters.__esp;
- case UNW_X86_ESI:
- return fRegisters.__esi;
- case UNW_X86_EDI:
- return fRegisters.__edi;
- }
- ABORT("unsupported x86 register");
-}
-
-inline void Registers_x86::setRegister(int regNum, uint32_t value)
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- fRegisters.__eip = value;
- return;
- case UNW_REG_SP:
- fRegisters.__esp = value;
- return;
- case UNW_X86_EAX:
- fRegisters.__eax = value;
- return;
- case UNW_X86_ECX:
- fRegisters.__ecx = value;
- return;
- case UNW_X86_EDX:
- fRegisters.__edx = value;
- return;
- case UNW_X86_EBX:
- fRegisters.__ebx = value;
- return;
- case UNW_X86_EBP:
- fRegisters.__ebp = value;
- return;
- case UNW_X86_ESP:
- fRegisters.__esp = value;
- return;
- case UNW_X86_ESI:
- fRegisters.__esi = value;
- return;
- case UNW_X86_EDI:
- fRegisters.__edi = value;
- return;
- }
- ABORT("unsupported x86 register");
-}
-
-inline const char* Registers_x86::getRegisterName(int regNum)
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- return "ip";
- case UNW_REG_SP:
- return "esp";
- case UNW_X86_EAX:
- return "eax";
- case UNW_X86_ECX:
- return "ecx";
- case UNW_X86_EDX:
- return "edx";
- case UNW_X86_EBX:
- return "ebx";
- case UNW_X86_EBP:
- return "ebp";
- case UNW_X86_ESP:
- return "esp";
- case UNW_X86_ESI:
- return "esi";
- case UNW_X86_EDI:
- return "edi";
- default:
- return "unknown register";
- }
-}
-
-inline double Registers_x86::getFloatRegister(int num) const
-{
- ABORT("no x86 float registers");
-}
-
-inline void Registers_x86::setFloatRegister(int num, double value)
-{
- ABORT("no x86 float registers");
-}
-
-inline v128 Registers_x86::getVectorRegister(int num) const
-{
- ABORT("no x86 vector registers");
-}
-
-inline void Registers_x86::setVectorRegister(int num, v128 value)
-{
- ABORT("no x86 vector registers");
-}
-
-
-
-
-///
-/// Registers_x86_64 holds the register state of a thread in a 64-bit intel process.
-///
-class Registers_x86_64
-{
-public:
- Registers_x86_64();
- Registers_x86_64(const void* registers);
-
- bool validRegister(int num) const;
- uint64_t getRegister(int num) const;
- void setRegister(int num, uint64_t value);
- bool validFloatRegister(int num) const{ return false; }
- double getFloatRegister(int num) const;
- void setFloatRegister(int num, double value);
- bool validVectorRegister(int num) const { return false; }
- v128 getVectorRegister(int num) const;
- void setVectorRegister(int num, v128 value);
- const char* getRegisterName(int num);
- void jumpto() {}
- uint64_t getSP() const { return fRegisters.__rsp; }
- void setSP(uint64_t value) { fRegisters.__rsp = value; }
- uint64_t getIP() const { return fRegisters.__rip; }
- void setIP(uint64_t value) { fRegisters.__rip = value; }
- uint64_t getRBP() const { return fRegisters.__rbp; }
- void setRBP(uint64_t value) { fRegisters.__rbp = value; }
- uint64_t getRBX() const { return fRegisters.__rbx; }
- void setRBX(uint64_t value) { fRegisters.__rbx = value; }
- uint64_t getR12() const { return fRegisters.__r12; }
- void setR12(uint64_t value) { fRegisters.__r12 = value; }
- uint64_t getR13() const { return fRegisters.__r13; }
- void setR13(uint64_t value) { fRegisters.__r13 = value; }
- uint64_t getR14() const { return fRegisters.__r14; }
- void setR14(uint64_t value) { fRegisters.__r14 = value; }
- uint64_t getR15() const { return fRegisters.__r15; }
- void setR15(uint64_t value) { fRegisters.__r15 = value; }
-private:
- x86_thread_state64_t fRegisters;
-};
-
-inline Registers_x86_64::Registers_x86_64(const void* registers)
-{
- COMPILE_TIME_ASSERT( sizeof(Registers_x86_64) < sizeof(unw_context_t) );
- fRegisters = *((x86_thread_state64_t*)registers);
-}
-
-inline Registers_x86_64::Registers_x86_64()
-{
- bzero(&fRegisters, sizeof(fRegisters));
-}
-
-
-inline bool Registers_x86_64::validRegister(int regNum) const
-{
- if ( regNum == UNW_REG_IP )
- return true;
- if ( regNum == UNW_REG_SP )
- return true;
- if ( regNum < 0 )
- return false;
- if ( regNum > 15 )
- return false;
- return true;
-}
-
-inline uint64_t Registers_x86_64::getRegister(int regNum) const
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- return fRegisters.__rip;
- case UNW_REG_SP:
- return fRegisters.__rsp;
- case UNW_X86_64_RAX:
- return fRegisters.__rax;
- case UNW_X86_64_RDX:
- return fRegisters.__rdx;
- case UNW_X86_64_RCX:
- return fRegisters.__rcx;
- case UNW_X86_64_RBX:
- return fRegisters.__rbx;
- case UNW_X86_64_RSI:
- return fRegisters.__rsi;
- case UNW_X86_64_RDI:
- return fRegisters.__rdi;
- case UNW_X86_64_RBP:
- return fRegisters.__rbp;
- case UNW_X86_64_RSP:
- return fRegisters.__rsp;
- case UNW_X86_64_R8:
- return fRegisters.__r8;
- case UNW_X86_64_R9:
- return fRegisters.__r9;
- case UNW_X86_64_R10:
- return fRegisters.__r10;
- case UNW_X86_64_R11:
- return fRegisters.__r11;
- case UNW_X86_64_R12:
- return fRegisters.__r12;
- case UNW_X86_64_R13:
- return fRegisters.__r13;
- case UNW_X86_64_R14:
- return fRegisters.__r14;
- case UNW_X86_64_R15:
- return fRegisters.__r15;
- }
- ABORT("unsupported x86_64 register");
-}
-
-inline void Registers_x86_64::setRegister(int regNum, uint64_t value)
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- fRegisters.__rip = value;
- return;
- case UNW_REG_SP:
- fRegisters.__rsp = value;
- return;
- case UNW_X86_64_RAX:
- fRegisters.__rax = value;
- return;
- case UNW_X86_64_RDX:
- fRegisters.__rdx = value;
- return;
- case UNW_X86_64_RCX:
- fRegisters.__rcx = value;
- return;
- case UNW_X86_64_RBX:
- fRegisters.__rbx = value;
- return;
- case UNW_X86_64_RSI:
- fRegisters.__rsi = value;
- return;
- case UNW_X86_64_RDI:
- fRegisters.__rdi = value;
- return;
- case UNW_X86_64_RBP:
- fRegisters.__rbp = value;
- return;
- case UNW_X86_64_RSP:
- fRegisters.__rsp = value;
- return;
- case UNW_X86_64_R8:
- fRegisters.__r8 = value;
- return;
- case UNW_X86_64_R9:
- fRegisters.__r9 = value;
- return;
- case UNW_X86_64_R10:
- fRegisters.__r10 = value;
- return;
- case UNW_X86_64_R11:
- fRegisters.__r11 = value;
- return;
- case UNW_X86_64_R12:
- fRegisters.__r12 = value;
- return;
- case UNW_X86_64_R13:
- fRegisters.__r13 = value;
- return;
- case UNW_X86_64_R14:
- fRegisters.__r14 = value;
- return;
- case UNW_X86_64_R15:
- fRegisters.__r15 = value;
- return;
- }
- ABORT("unsupported x86_64 register");
-}
-
-inline const char* Registers_x86_64::getRegisterName(int regNum)
-{
- switch ( regNum ) {
- case UNW_REG_IP:
- return "rip";
- case UNW_REG_SP:
- return "rsp";
- case UNW_X86_64_RAX:
- return "rax";
- case UNW_X86_64_RDX:
- return "rdx";
- case UNW_X86_64_RCX:
- return "rcx";
- case UNW_X86_64_RBX:
- return "rbx";
- case UNW_X86_64_RSI:
- return "rsi";
- case UNW_X86_64_RDI:
- return "rdi";
- case UNW_X86_64_RBP:
- return "rbp";
- case UNW_X86_64_RSP:
- return "rsp";
- case UNW_X86_64_R8:
- return "r8";
- case UNW_X86_64_R9:
- return "r9";
- case UNW_X86_64_R10:
- return "r10";
- case UNW_X86_64_R11:
- return "r11";
- case UNW_X86_64_R12:
- return "r12";
- case UNW_X86_64_R13:
- return "r13";
- case UNW_X86_64_R14:
- return "r14";
- case UNW_X86_64_R15:
- return "r15";
- default:
- return "unknown register";
- }
-}
-
-double Registers_x86_64::getFloatRegister(int num) const
-{
- ABORT("no x86_64 float registers");
-}
-
-void Registers_x86_64::setFloatRegister(int num, double value)
-{
- ABORT("no x86_64 float registers");
-}
-
-inline v128 Registers_x86_64::getVectorRegister(int num) const
-{
- ABORT("no x86_64 vector registers");
-}
-
-inline void Registers_x86_64::setVectorRegister(int num, v128 value)
-{
- ABORT("no x86_64 vector registers");
-}
-
-
-} // namespace lldb_private
-
-
-
-#endif // __REGISTERS_HPP__
-
-
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.s b/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.s
deleted file mode 100644
index 45dae3bcbfc..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/Registers.s
+++ /dev/null
@@ -1,261 +0,0 @@
-
-
-#if __i386__
- .text
- .globl __ZN12lldb_private13Registers_x866jumptoEv
- .private_extern __ZN12lldb_private13Registers_x866jumptoEv
-__ZN12lldb_private13Registers_x866jumptoEv:
-#
-# void lldb_private::Registers_x86::jumpto()
-#
-# On entry:
-# + +
-# +-----------------------+
-# + thread_state pointer +
-# +-----------------------+
-# + return address +
-# +-----------------------+ <-- SP
-# + +
- movl 4(%esp), %eax
- # set up eax and ret on new stack location
- movl 28(%eax), %edx # edx holds new stack pointer
- subl $8,%edx
- movl %edx, 28(%eax)
- movl 0(%eax), %ebx
- movl %ebx, 0(%edx)
- movl 40(%eax), %ebx
- movl %ebx, 4(%edx)
- # we now have ret and eax pushed onto where new stack will be
- # restore all registers
- movl 4(%eax), %ebx
- movl 8(%eax), %ecx
- movl 12(%eax), %edx
- movl 16(%eax), %edi
- movl 20(%eax), %esi
- movl 24(%eax), %ebp
- movl 28(%eax), %esp
- # skip ss
- # skip eflags
- pop %eax # eax was already pushed on new stack
- ret # eip was already pushed on new stack
- # skip cs
- # skip ds
- # skip es
- # skip fs
- # skip gs
-
-#elif __x86_64__
-
- .text
- .globl __ZN12lldb_private16Registers_x86_646jumptoEv
- .private_extern __ZN12lldb_private16Registers_x86_646jumptoEv
-__ZN12lldb_private16Registers_x86_646jumptoEv:
-#
-# void lldb_private::Registers_x86_64::jumpto()
-#
-# On entry, thread_state pointer is in rdi
-
- movq 56(%rdi), %rax # rax holds new stack pointer
- subq $16, %rax
- movq %rax, 56(%rdi)
- movq 32(%rdi), %rbx # store new rdi on new stack
- movq %rbx, 0(%rax)
- movq 128(%rdi), %rbx # store new rip on new stack
- movq %rbx, 8(%rax)
- # restore all registers
- movq 0(%rdi), %rax
- movq 8(%rdi), %rbx
- movq 16(%rdi), %rcx
- movq 24(%rdi), %rdx
- # restore rdi later
- movq 40(%rdi), %rsi
- movq 48(%rdi), %rbp
- # restore rsp later
- movq 64(%rdi), %r8
- movq 72(%rdi), %r9
- movq 80(%rdi), %r10
- movq 88(%rdi), %r11
- movq 96(%rdi), %r12
- movq 104(%rdi), %r13
- movq 112(%rdi), %r14
- movq 120(%rdi), %r15
- # skip rflags
- # skip cs
- # skip fs
- # skip gs
- movq 56(%rdi), %rsp # cut back rsp to new location
- pop %rdi # rdi was saved here earlier
- ret # rip was saved here
-
-
-#elif __ppc__
-
- .text
- .globl __ZN12lldb_private13Registers_ppc6jumptoEv
- .private_extern __ZN12lldb_private13Registers_ppc6jumptoEv
-__ZN12lldb_private13Registers_ppc6jumptoEv:
-;
-; void lldb_private::Registers_ppc::jumpto()
-;
-; On entry:
-; thread_state pointer is in r3
-;
-
- ; restore integral registerrs
- ; skip r0 for now
- ; skip r1 for now
- lwz r2, 16(r3)
- ; skip r3 for now
- ; skip r4 for now
- ; skip r5 for now
- lwz r6, 32(r3)
- lwz r7, 36(r3)
- lwz r8, 40(r3)
- lwz r9, 44(r3)
- lwz r10, 48(r3)
- lwz r11, 52(r3)
- lwz r12, 56(r3)
- lwz r13, 60(r3)
- lwz r14, 64(r3)
- lwz r15, 68(r3)
- lwz r16, 72(r3)
- lwz r17, 76(r3)
- lwz r18, 80(r3)
- lwz r19, 84(r3)
- lwz r20, 88(r3)
- lwz r21, 92(r3)
- lwz r22, 96(r3)
- lwz r23,100(r3)
- lwz r24,104(r3)
- lwz r25,108(r3)
- lwz r26,112(r3)
- lwz r27,116(r3)
- lwz r28,120(r3)
- lwz r29,124(r3)
- lwz r30,128(r3)
- lwz r31,132(r3)
-
- ; restore float registers
- lfd f0, 160(r3)
- lfd f1, 168(r3)
- lfd f2, 176(r3)
- lfd f3, 184(r3)
- lfd f4, 192(r3)
- lfd f5, 200(r3)
- lfd f6, 208(r3)
- lfd f7, 216(r3)
- lfd f8, 224(r3)
- lfd f9, 232(r3)
- lfd f10,240(r3)
- lfd f11,248(r3)
- lfd f12,256(r3)
- lfd f13,264(r3)
- lfd f14,272(r3)
- lfd f15,280(r3)
- lfd f16,288(r3)
- lfd f17,296(r3)
- lfd f18,304(r3)
- lfd f19,312(r3)
- lfd f20,320(r3)
- lfd f21,328(r3)
- lfd f22,336(r3)
- lfd f23,344(r3)
- lfd f24,352(r3)
- lfd f25,360(r3)
- lfd f26,368(r3)
- lfd f27,376(r3)
- lfd f28,384(r3)
- lfd f29,392(r3)
- lfd f30,400(r3)
- lfd f31,408(r3)
-
- ; restore vector registers if any are in use
- lwz r5,156(r3) ; test VRsave
- cmpwi r5,0
- beq Lnovec
-
- subi r4,r1,16
- rlwinm r4,r4,0,0,27 ; mask low 4-bits
- ; r4 is now a 16-byte aligned pointer into the red zone
- ; the fVectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
-
-
-#define LOAD_VECTOR_UNALIGNEDl(_index) \
- andis. r0,r5,(1<<(15-_index)) @\
- beq Ldone ## _index @\
- lwz r0, 424+_index*16(r3) @\
- stw r0, 0(r4) @\
- lwz r0, 424+_index*16+4(r3) @\
- stw r0, 4(r4) @\
- lwz r0, 424+_index*16+8(r3) @\
- stw r0, 8(r4) @\
- lwz r0, 424+_index*16+12(r3)@\
- stw r0, 12(r4) @\
- lvx v ## _index,0,r4 @\
-Ldone ## _index:
-
-#define LOAD_VECTOR_UNALIGNEDh(_index) \
- andi. r0,r5,(1<<(31-_index)) @\
- beq Ldone ## _index @\
- lwz r0, 424+_index*16(r3) @\
- stw r0, 0(r4) @\
- lwz r0, 424+_index*16+4(r3) @\
- stw r0, 4(r4) @\
- lwz r0, 424+_index*16+8(r3) @\
- stw r0, 8(r4) @\
- lwz r0, 424+_index*16+12(r3)@\
- stw r0, 12(r4) @\
- lvx v ## _index,0,r4 @\
- Ldone ## _index:
-
-
- LOAD_VECTOR_UNALIGNEDl(0)
- LOAD_VECTOR_UNALIGNEDl(1)
- LOAD_VECTOR_UNALIGNEDl(2)
- LOAD_VECTOR_UNALIGNEDl(3)
- LOAD_VECTOR_UNALIGNEDl(4)
- LOAD_VECTOR_UNALIGNEDl(5)
- LOAD_VECTOR_UNALIGNEDl(6)
- LOAD_VECTOR_UNALIGNEDl(7)
- LOAD_VECTOR_UNALIGNEDl(8)
- LOAD_VECTOR_UNALIGNEDl(9)
- LOAD_VECTOR_UNALIGNEDl(10)
- LOAD_VECTOR_UNALIGNEDl(11)
- LOAD_VECTOR_UNALIGNEDl(12)
- LOAD_VECTOR_UNALIGNEDl(13)
- LOAD_VECTOR_UNALIGNEDl(14)
- LOAD_VECTOR_UNALIGNEDl(15)
- LOAD_VECTOR_UNALIGNEDh(16)
- LOAD_VECTOR_UNALIGNEDh(17)
- LOAD_VECTOR_UNALIGNEDh(18)
- LOAD_VECTOR_UNALIGNEDh(19)
- LOAD_VECTOR_UNALIGNEDh(20)
- LOAD_VECTOR_UNALIGNEDh(21)
- LOAD_VECTOR_UNALIGNEDh(22)
- LOAD_VECTOR_UNALIGNEDh(23)
- LOAD_VECTOR_UNALIGNEDh(24)
- LOAD_VECTOR_UNALIGNEDh(25)
- LOAD_VECTOR_UNALIGNEDh(26)
- LOAD_VECTOR_UNALIGNEDh(27)
- LOAD_VECTOR_UNALIGNEDh(28)
- LOAD_VECTOR_UNALIGNEDh(29)
- LOAD_VECTOR_UNALIGNEDh(30)
- LOAD_VECTOR_UNALIGNEDh(31)
-
-Lnovec:
- lwz r0, 136(r3) ; __cr
- mtocrf 255,r0
- lwz r0, 148(r3) ; __ctr
- mtctr r0
- lwz r0, 0(r3) ; __ssr0
- mtctr r0
- lwz r0, 8(r3) ; do r0 now
- lwz r5,28(r3) ; do r5 now
- lwz r4,24(r3) ; do r4 now
- lwz r1,12(r3) ; do sp now
- lwz r3,20(r3) ; do r3 last
- bctr
-
-
-#endif
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp
deleted file mode 100644
index b7e833eb871..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- RemoteDebuggerDummyUnwinder.hpp -------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Code to unwind past a debugger's dummy frame inserted when it does an
-// inferior function call.
-// In this case we'll need to get the saved register context from the debugger -
-// it may be in the debugger's local memory or it may be saved in a nonstandard
-// location in the inferior process' memory.
-
-#ifndef __REMOTE_DEBUGGER_DUMMY_UNWINDER_HPP__
-#define __REMOTE_DEBUGGER_DUMMY_UNWINDER_HPP__
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#include "libunwind.h"
-#include "Registers.hpp"
-#include "AddressSpace.hpp"
-#include "RemoteRegisterMap.hpp"
-#include "RemoteProcInfo.hpp"
-
-namespace lldb_private
-{
-
-template <typename A>
-int stepOutOfDebuggerDummyFrame (A& addressSpace, Registers_x86_64& registers,
- RemoteProcInfo *procinfo, uint64_t ip,
- uint64_t sp, void* arg)
-{
- Registers_x86_64 newRegisters(registers);
- RemoteRegisterMap *rmap = addressSpace.getRemoteProcInfo()->getRegisterMap();
- unw_word_t regv;
- for (int i = UNW_X86_64_RAX; i <= UNW_X86_64_R15; i++) {
- int driver_regnum;
- if (!rmap->unwind_regno_to_caller_regno (i, driver_regnum))
- continue;
- if (addressSpace.accessors()->access_reg_inf_func_call (procinfo->wrap(), ip, sp, driver_regnum, &regv, 0, arg))
- newRegisters.setRegister(i, regv);
- }
- if (!addressSpace.accessors()->access_reg_inf_func_call (procinfo->wrap(), ip, sp, rmap->caller_regno_for_ip(), &regv, 0, arg))
- return UNW_EUNSPEC;
- newRegisters.setIP (regv);
- registers = newRegisters;
- return UNW_STEP_SUCCESS;
-}
-
-template <typename A>
-int stepOutOfDebuggerDummyFrame (A& addressSpace, Registers_x86& registers,
- RemoteProcInfo *procinfo, uint64_t ip,
- uint64_t sp, void* arg)
-{
- Registers_x86 newRegisters(registers);
- RemoteRegisterMap *rmap = addressSpace.getRemoteProcInfo()->getRegisterMap();
- unw_word_t regv;
- for (int i = UNW_X86_EAX; i <= UNW_X86_EDI; i++) {
- int driver_regnum;
- if (!rmap->unwind_regno_to_caller_regno (i, driver_regnum))
- continue;
- if (addressSpace.accessors()->access_reg_inf_func_call (procinfo->wrap(), ip, sp, driver_regnum, &regv, 0, arg))
- newRegisters.setRegister(i, regv);
- }
- if (!addressSpace.accessors()->access_reg_inf_func_call (procinfo->wrap(), ip, sp, rmap->caller_regno_for_ip(), &regv, 0, arg))
- return UNW_EUNSPEC;
- newRegisters.setIP (regv);
- registers = newRegisters;
- return UNW_STEP_SUCCESS;
-}
-
-}; // namespace lldb_private
-
-#endif // SUPPORT_REMOTE_UNWINDING
-
-#endif // __REMOTE_DEBUGGER_DUMMY_UNWINDER_HPP__
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp
deleted file mode 100644
index ee9901c6211..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp
+++ /dev/null
@@ -1,984 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- RemoteProcInfo.hpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file defines the primary object created when unw_create_addr_space()
-// is called. This object tracks the list of known images in memory
-// (dylibs, bundles, etc), it maintains a link to a RemoteRegisterMap for this
-// architecture, it caches the remote process memory in a local store and all
-// read/writes are filtered through its accessors which will use the memory
-// caches. It maintains a logging level set by the driver program and puts
-// timing/debug messages out on a FILE* provided to it.
-
-// RemoteProcInfo is not specific to any particular unwind so it does not
-// maintain an "arg" argument (an opaque pointer that the driver program uses
-// to track the process/thread being unwound).
-
-#ifndef __REMOTE_PROC_INFO_HPP__
-#define __REMOTE_PROC_INFO_HPP__
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <stdarg.h>
-#include <sys/time.h>
-#include <mach-o/loader.h>
-#include <mach-o/getsect.h>
-#include <mach/i386/thread_status.h>
-#include <Availability.h>
-
-#include <map>
-#include <vector>
-#include <algorithm>
-
-#include "FileAbstraction.hpp"
-#include "libunwind.h"
-#include "InternalMacros.h"
-#include "dwarf2.h"
-#include "RemoteUnwindProfile.h"
-#include "Registers.hpp"
-#include "RemoteRegisterMap.hpp"
-
-namespace lldb_private
-{
-class RemoteProcInfo;
-
-///
-/// unw_addr_space_remote is the concrete instance that a unw_addr_space_t points to when examining
-/// a remote process.
-///
-struct unw_addr_space_remote
-{
- enum unw_as_type type; // should always be UNW_REMOTE
- RemoteProcInfo* ras;
-};
-
-class RemoteMemoryBlob
-{
-public:
- typedef void (*free_callback_with_arg)(void *, void*);
- typedef void (*free_callback)(void *);
-
- /* This object is constructed with a callback to free the memory;
- that callback takes a pointer to the memory region and optionally
- takes an additional argument -- the "void* arg" passed around for
- remote unwinds, in case the driver program allocated this e.g. with
- mach_vm_read, and needs the token to vm_deallocate it. */
-
- RemoteMemoryBlob (uint8_t *buf, free_callback_with_arg to_free,
- uint64_t startaddr, uint64_t len, uint64_t mh, void *arg) :
- fBuf(buf), fToFree(NULL), fToFreeWithArg(to_free),
- fStartAddr(startaddr), fLen(len), fMachHeader(mh),
- fArg(arg) { }
- RemoteMemoryBlob (uint8_t *buf, free_callback to_free, uint64_t startaddr,
- uint64_t len, uint64_t mh, void *arg) :
- fBuf(buf), fToFree(to_free), fToFreeWithArg(NULL),
- fStartAddr(startaddr), fLen(len), fMachHeader(mh),
- fArg(NULL) { }
-
- // the following is to create a dummy RMB object for lower_bound's use in
- // searching.
- RemoteMemoryBlob (uint64_t startaddr) : fBuf(NULL), fToFree(NULL),
- fToFreeWithArg(NULL), fStartAddr(startaddr), fLen(0),
- fMachHeader(-1), fArg(NULL) { }
- ~RemoteMemoryBlob () {
- if (fToFreeWithArg)
- fToFreeWithArg(fBuf, fArg);
- else if (fToFree)
- fToFree(fBuf);
- }
- bool contains_addr (uint64_t addr) {
- if (fStartAddr <= addr && addr < fStartAddr + fLen)
- return true;
- else
- return false;
- }
- uint8_t *get_blob_range (uint64_t remote_process_addr, int len) {
- if (this->contains_addr (remote_process_addr) == false)
- return NULL;
- if (this->contains_addr (remote_process_addr + len) == false)
- return NULL;
- return fBuf + (remote_process_addr - fStartAddr);
- }
- uint64_t getMh () const { return fMachHeader; }
- uint64_t getStartAddr() const { return fStartAddr; }
- uint64_t getLength() const { return fLen; }
-private:
- uint8_t *fBuf;
- free_callback fToFree;
- free_callback_with_arg fToFreeWithArg;
- uint64_t fStartAddr;
- uint64_t fLen;
- uint64_t fMachHeader;
- void *fArg;
-};
-
-inline bool operator<(const RemoteMemoryBlob &b1, const RemoteMemoryBlob &b2) {
- if (b1.getStartAddr() < b2.getStartAddr())
- return true;
- else
- return false;
-}
-
-// One of these for each image in memory (executable, dylib, bundle, etc)
-
-struct RemoteImageEntry
-{
- RemoteImageEntry () : mach_header(0), text_start(0), text_end(0), eh_frame_start(0), eh_frame_len(0), compact_unwind_info_start(0), compact_unwind_info_len(0) { }
- ~RemoteImageEntry () {
- std::map<uint64_t, RemoteUnwindProfile *>::iterator i;
- for (i = profiles.begin(); i != profiles.end(); ++i)
- delete i->second;
- }
- uint64_t mach_header;
- uint64_t text_start;
- uint64_t text_end;
- uint64_t eh_frame_start;
- uint64_t eh_frame_len;
- uint64_t compact_unwind_info_start;
- uint64_t compact_unwind_info_len;
-
- // unwind profiles created for thsi binary image so far,
- // key is the start address of the profile.
- std::map<uint64_t, RemoteUnwindProfile *> profiles;
-
- // a list of function address bounds for this binary image -
- // end addresses should be accurate and not inferred from potentially
- // incomplete start-address data (e.g. nlist records).
- std::vector<FuncBounds> func_bounds;
-};
-
-class RemoteImages
-{
-public:
- RemoteImages (unw_targettype_t targarch) : fTargetArch(targarch) { }
- ~RemoteImages ();
- void removeAllImageProfiles();
- void removeOneImageProfiles(uint64_t mh);
- RemoteImageEntry *remoteEntryForTextAddr (uint64_t pc);
- bool addFuncBounds (uint64_t mh, std::vector<FuncBounds> &startAddrs);
- bool haveFuncBounds (uint64_t mh);
- bool findFuncBounds (uint32_t pc, uint32_t &startAddr, uint32_t &endAddr);
- bool findFuncBounds (uint64_t pc, uint64_t &startAddr, uint64_t &endAddr);
- void addImage (uint64_t mh, uint64_t text_start, uint64_t text_end, uint64_t eh_frame, uint64_t eh_frame_len, uint64_t compact_unwind_start, uint64_t compact_unwind_len);
- bool addProfile (RemoteProcInfo* procinfo, unw_accessors_t *acc, unw_addr_space_t as, uint64_t start, uint64_t end, void *arg);
- RemoteUnwindProfile* findProfileByTextAddr (uint64_t pc);
- bool addMemBlob (RemoteMemoryBlob *blob);
- uint8_t *getMemBlobMemory (uint64_t addr, int len);
-private:
- RemoteImages();
- std::map<uint64_t, RemoteImageEntry> fImages;
- std::vector<RemoteMemoryBlob *> fMemBlobs;
- unw_targettype_t fTargetArch;
-};
-
-RemoteImages::~RemoteImages () {
- std::map<uint64_t, std::vector<RemoteMemoryBlob *> >::iterator i;
- std::vector<RemoteMemoryBlob *>::iterator j;
- for (j = fMemBlobs.begin(); j != fMemBlobs.end(); ++j) {
- delete *j;
- }
- fMemBlobs.erase(fMemBlobs.begin(), fMemBlobs.end());
-}
-
-void RemoteImages::removeAllImageProfiles() {
- fImages.erase(fImages.begin(), fImages.end());
- std::vector<RemoteMemoryBlob *>::iterator j;
- for (j = fMemBlobs.begin(); j != fMemBlobs.end(); ++j)
- delete *j;
- fMemBlobs.erase(fMemBlobs.begin(), fMemBlobs.end());
-}
-
-void RemoteImages::removeOneImageProfiles(uint64_t mh) {
- std::map<uint64_t, RemoteImageEntry>::iterator i;
- i = fImages.find(mh);
- if (i != fImages.end())
- fImages.erase(i);
-
- std::vector<RemoteMemoryBlob *>::iterator j;
- for (j = fMemBlobs.begin(); j != fMemBlobs.end(); ++j) {
- if ((*j)->getMh() == mh) {
- delete *j;
- break;
- }
- }
- if (j != fMemBlobs.end())
- fMemBlobs.erase(j);
-}
-
-RemoteImageEntry *RemoteImages::remoteEntryForTextAddr (uint64_t pc) {
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.lower_bound (pc);
- if (i == fImages.begin() && i == fImages.end())
- return NULL;
- if (i == fImages.end()) {
- --i;
- } else {
- if (i != fImages.begin() && i->first != pc)
- --i;
- }
- if (i->second.text_start <= pc && i->second.text_end > pc)
- {
- return &(i->second);
- }
- else
- {
- return NULL;
- }
-}
-
-bool RemoteImages::addFuncBounds (uint64_t mh, std::vector<FuncBounds> &startAddrs) {
- RemoteImageEntry *img = NULL;
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.find (mh);
- if (i == fImages.end())
- return false;
- img = &i->second;
- img->func_bounds = startAddrs;
- std::sort(img->func_bounds.begin(), img->func_bounds.end());
- return true;
-}
-
-bool RemoteImages::haveFuncBounds (uint64_t mh) {
- RemoteImageEntry *img = NULL;
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.find (mh);
- if (i == fImages.end())
- return false;
- img = &i->second;
- if (img->func_bounds.size() > 0)
- return true;
- return false;
-}
-
-bool RemoteImages::findFuncBounds (uint64_t pc, uint64_t &startAddr, uint64_t &endAddr) {
- RemoteImageEntry *img = NULL;
- startAddr = endAddr = 0;
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.lower_bound (pc);
- if (i == fImages.begin() && i == fImages.end())
- return false;
- if (i == fImages.end()) {
- --i;
- } else {
- if (i != fImages.begin() && i->first != pc)
- --i;
- }
- if (i->second.text_start <= pc && i->second.text_end > pc)
- {
- img = &i->second;
- }
- else
- return false;
- std::vector<FuncBounds>::iterator j;
- j = std::lower_bound(img->func_bounds.begin(), img->func_bounds.end(), FuncBounds (pc, pc));
- if (j == img->func_bounds.begin() && j == img->func_bounds.end())
- return false;
- if (j == img->func_bounds.end()) {
- --j;
- } else {
- if (j != img->func_bounds.begin() && j->fStart != pc)
- --j;
- }
- if (j->fStart <= pc && j->fEnd > pc) {
- startAddr = j->fStart;
- endAddr = j->fEnd;
- return true;
- }
- return false;
-}
-
-// Add 32-bit version of findFuncBounds so we can avoid templatizing all of these functions
-// just to handle 64 and 32 bit unwinds.
-
-bool RemoteImages::findFuncBounds (uint32_t pc, uint32_t &startAddr, uint32_t &endAddr) {
- uint64_t big_startAddr = startAddr;
- uint64_t big_endAddr = endAddr;
- bool ret;
- ret = findFuncBounds (pc, big_startAddr, big_endAddr);
- startAddr = (uint32_t) big_startAddr & 0xffffffff;
- endAddr = (uint32_t) big_endAddr & 0xffffffff;
- return ret;
-}
-
-// Make sure we don't cache the same memory range more than once
-// I'm not checking the length of the blobs to check for overlap -
-// as this is used today, the only duplication will be with the same
-// start address.
-
-bool
-RemoteImages::addMemBlob (RemoteMemoryBlob *blob) {
-
- if (fMemBlobs.empty())
- {
- fMemBlobs.push_back(blob);
- }
- else
- {
- std::vector<RemoteMemoryBlob *>::iterator pos;
-
- pos = std::lower_bound (fMemBlobs.begin(), fMemBlobs.end(), blob);
-
- if (pos != fMemBlobs.end() && (*pos)->getStartAddr() == blob->getStartAddr())
- return false;
-
- fMemBlobs.insert (pos, blob);
- }
- return true;
-}
-
-uint8_t *RemoteImages::getMemBlobMemory (uint64_t addr, int len) {
- uint8_t *res = NULL;
- std::vector<RemoteMemoryBlob *>::iterator j;
- RemoteMemoryBlob *searchobj = new RemoteMemoryBlob(addr);
- j = std::lower_bound (fMemBlobs.begin(), fMemBlobs.end(), searchobj);
- delete searchobj;
- if (j == fMemBlobs.end() && j == fMemBlobs.begin())
- return NULL;
- if (j == fMemBlobs.end()) {
- --j;
- } else {
- if (j != fMemBlobs.begin() && (*j)->getStartAddr() != addr)
- --j;
- }
- res = (*j)->get_blob_range (addr, len);
- if (res != NULL)
- return res;
- for (j = fMemBlobs.begin(); j != fMemBlobs.end(); ++j) {
- res = (*j)->get_blob_range (addr, len);
- if (res != NULL)
- break;
- }
- return res;
-}
-
-void RemoteImages::addImage (uint64_t mh, uint64_t text_start,
- uint64_t text_end, uint64_t eh_frame,
- uint64_t eh_frame_len,
- uint64_t compact_unwind_start,
- uint64_t compact_unwind_len) {
- struct RemoteImageEntry img;
- img.mach_header = mh;
- img.text_start = text_start;
- img.text_end = text_end;
- img.eh_frame_start = eh_frame;
- img.eh_frame_len = eh_frame_len;
- img.compact_unwind_info_start = compact_unwind_start;
- img.compact_unwind_info_len = compact_unwind_len;
- fImages[mh] = img;
-}
-
-// The binary image for this start/end address must already be present
-bool RemoteImages::addProfile (RemoteProcInfo* procinfo, unw_accessors_t *acc, unw_addr_space_t as, uint64_t start, uint64_t end, void *arg) {
- RemoteImageEntry *img = NULL;
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.lower_bound (start);
- if (i == fImages.begin() && i == fImages.end())
- return false;
- if (i == fImages.end()) {
- --i;
- } else {
- if (i != fImages.begin() && i->first != start) {
- --i;
- }
- }
- if (i->second.text_start <= start && i->second.text_end > start)
- {
- img = &i->second;
- }
- else
- return false;
- RemoteUnwindProfile* profile = new RemoteUnwindProfile;
- if (AssemblyParse (procinfo, acc, as, start, end, *profile, arg)) {
- img->profiles[start] = profile;
- return true;
- }
- return false;
-}
-
-RemoteUnwindProfile* RemoteImages::findProfileByTextAddr (uint64_t pc) {
- RemoteImageEntry *img = NULL;
- std::map<uint64_t, RemoteImageEntry>::iterator i = fImages.lower_bound (pc);
- if (i == fImages.begin() && i == fImages.end())
- return NULL;
- if (i == fImages.end()) {
- --i;
- } else {
- if (i != fImages.begin() && i->first != pc)
- --i;
- }
- if (i->second.text_start <= pc && i->second.text_end > pc)
- {
- img = &i->second;
- }
- else
- return NULL;
- std::map<uint64_t, RemoteUnwindProfile *>::iterator j;
- j = img->profiles.lower_bound (pc);
- if (j == img->profiles.begin() && j == img->profiles.end())
- return NULL;
- if (j == img->profiles.end()) {
- --j;
- } else {
- if (j != img->profiles.begin() && j->first != pc)
- --j;
- }
- if (j->second->fStart <= pc && j->second->fEnd > pc)
- {
- return j->second;
- }
- return NULL;
-}
-
-///
-/// RemoteProcInfo is used as a template parameter to UnwindCursor when
-/// unwinding a thread that has a custom set of accessors. It calls the
-/// custom accessors for all data.
-///
-class RemoteProcInfo
-{
-public:
-
-// libunwind documentation specifies that unw_create_addr_space defaults to
-// UNW_CACHE_NONE but that's going to work very poorly for us so we're
-// defaulting to UNW_CACHE_GLOBAL.
-
- RemoteProcInfo(unw_accessors_t* accessors, unw_targettype_t targarch) :
- fAccessors(*accessors), fCachingPolicy(UNW_CACHE_GLOBAL),
- fTargetArch(targarch), fImages(targarch), fLogging(NULL),
- fLogLevel(UNW_LOG_LEVEL_NONE)
- {
- fWrapper.type = UNW_REMOTE;
- fWrapper.ras = this;
- fRemoteRegisterMap = new RemoteRegisterMap(accessors, targarch);
- if (fTargetArch == UNW_TARGET_X86_64 || fTargetArch == UNW_TARGET_I386
- || fTargetArch == UNW_TARGET_ARM)
- fLittleEndian = true;
- else
- fLittleEndian = false;
- }
-
- ~RemoteProcInfo () {
- delete fRemoteRegisterMap;
- }
-
- bool haveProfile (uint64_t pc) {
- if (fImages.findProfileByTextAddr (pc))
- return true;
- else
- return false;
- }
-
- // returns NULL if profile does not yet exist.
- RemoteUnwindProfile* findProfile (uint64_t pc) {
- return fImages.findProfileByTextAddr (pc);
- }
-
- // returns NULL if the binary image is not yet added.
- bool addProfile (unw_accessors_t *acc, unw_addr_space_t as, uint64_t start, uint64_t end, void *arg) {
- if (fImages.addProfile (this, acc, as, start, end, arg))
- return true;
- else
- return false;
- }
-
- bool haveImageEntry (uint64_t pc, void *arg);
-
- bool getImageAddresses (uint64_t pc, uint64_t &mh, uint64_t &text_start, uint64_t &text_end,
- uint64_t &eh_frame_start, uint64_t &eh_frame_len, uint64_t &compact_unwind_start,
- void *arg);
- bool getImageAddresses (uint64_t pc, uint32_t &mh, uint32_t &text_start, uint32_t &text_end,
- uint32_t &eh_frame_start, uint32_t &eh_frame_len, uint32_t &compact_unwind_start,
- void *arg);
-
- bool addFuncBounds (uint64_t mh, std::vector<FuncBounds> &startAddrs) { return fImages.addFuncBounds (mh, startAddrs); }
- bool haveFuncBounds (uint64_t mh) { return fImages.haveFuncBounds (mh); }
- bool findStartAddr (uint64_t pc, uint32_t &startAddr, uint32_t &endAddr) { return fImages.findFuncBounds (pc, startAddr, endAddr); }
- bool findStartAddr (uint64_t pc, uint64_t &startAddr, uint64_t &endAddr) { return fImages.findFuncBounds (pc, startAddr, endAddr); }
- uint8_t *getMemBlobMemory (uint64_t addr, int len) { return fImages.getMemBlobMemory (addr, len); }
-
-
- // Functions to pull memory from the target into the debugger.
-
- int getBytes(uint64_t addr, uint64_t extent, uint8_t* buf, void* arg)
- {
- int err = readRaw(addr, extent, buf, arg);
-
- if(err)
- return 0;
-
- return 1;
- }
-
-#define DECLARE_INT_ACCESSOR(bits) \
- uint##bits##_t get##bits(uint64_t addr, void* arg) \
- { \
- uint##bits##_t ret; \
- int err = readRaw(addr, (unw_word_t)(bits / 8), (uint8_t*)&ret, arg); \
- \
- if(err) \
- ABORT("Invalid memory access in the target"); \
- \
- return ret; \
- }
- DECLARE_INT_ACCESSOR(8)
- DECLARE_INT_ACCESSOR(16)
- DECLARE_INT_ACCESSOR(32)
- DECLARE_INT_ACCESSOR(64)
-#undef DECLARE_INT_ACCESSOR
-
-// 'err' is set to 0 if there were no errors reading this
-// memory. Non-zero values indicate that the memory was not
-// read successfully. This method should be preferred over the
-// method above which asserts on failure.
-
-#define DECLARE_INT_ACCESSOR_ERR(bits) \
- uint##bits##_t get##bits(uint64_t addr, int &err, void* arg) \
- { \
- uint##bits##_t ret; \
- err = readRaw(addr, (unw_word_t)(bits / 8), (uint8_t*)&ret, arg); \
- \
- return ret; \
- }
- DECLARE_INT_ACCESSOR_ERR(8)
- DECLARE_INT_ACCESSOR_ERR(16)
- DECLARE_INT_ACCESSOR_ERR(32)
- DECLARE_INT_ACCESSOR_ERR(64)
-#undef DECLARE_INT_ACCESSOR_ERR
-
- double getDouble(uint64_t addr, void* arg)
- {
- double ret;
- int err = readRaw(addr, (unw_word_t)(sizeof(ret) / 8), (uint8_t*)&ret, arg);
- if(err)
- ABORT("Invalid memory access in the target");
- return ret;
- }
-
- v128 getVector(uint64_t addr, void* arg)
- {
- v128 ret;
- int err = readRaw(addr, (unw_word_t)(sizeof(ret) / 8), (uint8_t*)&ret, arg);
- if(err)
- ABORT("Invalid memory access in the target");
- return ret;
- }
-
- // Pull an unsigned LEB128 from the target into the debugger as a uint64_t.
- uint64_t getULEB128(uint64_t& addr, uint64_t end, void* arg)
- {
- uint64_t lAddr = addr;
- uint64_t ret = 0;
- uint8_t shift = 0;
- uint64_t byte;
- do {
- if(lAddr == end)
- ABORT("Truncated LEB128 number in the target");
-
- byte = (uint64_t)get8(lAddr, arg);
- lAddr++;
-
- if(((shift == 63) && (byte > 0x01)) || (shift > 63))
- ABORT("LEB128 number is larger than is locally representible");
-
- ret |= ((byte & 0x7f) << shift);
- shift += 7;
- } while((byte & 0x80) == 0x80);
- addr = lAddr;
- return ret;
- }
-
- // Pull an unsigned LEB128 from the target into the debugger as a uint64_t.
- uint64_t getULEB128(uint32_t& addr, uint32_t end, void* arg)
- {
- uint32_t lAddr = addr;
- uint64_t ret = 0;
- uint8_t shift = 0;
- uint64_t byte;
- do {
- if(lAddr == end)
- ABORT("Truncated LEB128 number in the target");
-
- byte = (uint64_t)get8(lAddr, arg);
- lAddr++;
-
- if(((shift == 63) && (byte > 0x01)) || (shift > 63))
- ABORT("LEB128 number is larger than is locally representible");
-
- ret |= ((byte & 0x7f) << shift);
- shift += 7;
- } while((byte & 0x80) == 0x80);
- addr = lAddr;
- return ret;
- }
-
-
- // Pull a signed LEB128 from the target into the debugger as a uint64_t.
- int64_t getSLEB128(uint64_t& addr, uint64_t end, void* arg)
- {
- uint64_t lAddr = addr;
- uint64_t ret = 0;
- uint8_t shift = 0;
- uint64_t byte;
- do {
- if(lAddr == end)
- ABORT("Truncated LEB128 number in the target");
- byte = (uint64_t)get8(lAddr, arg);
- lAddr++;
- if(((shift == 63) && (byte > 0x01)) || (shift > 63))
- ABORT("LEB128 number is larger than is locally representible");
- ret |= ((byte & 0x7f) << shift);
- shift += 7;
- } while((byte & 0x80) == 0x80);
- // Sign-extend
- if((shift < (sizeof(int64_t) * 8)) && (byte & 0x40))
- ret |= -(1 << shift);
- addr = lAddr;
- return ret;
- }
-
- // Pull a signed LEB128 from the target into the debugger as a uint64_t.
- int64_t getSLEB128(uint32_t& addr, uint32_t end, void* arg)
- {
- uint32_t lAddr = addr;
- uint64_t ret = 0;
- uint8_t shift = 0;
- uint64_t byte;
- do {
- if(lAddr == end)
- ABORT("Truncated LEB128 number in the target");
- byte = (uint64_t)get8(lAddr, arg);
- lAddr++;
- if(((shift == 63) && (byte > 0x01)) || (shift > 63))
- ABORT("LEB128 number is larger than is locally representible");
- ret |= ((byte & 0x7f) << shift);
- shift += 7;
- } while((byte & 0x80) == 0x80);
- // Sign-extend
- if((shift < (sizeof(int64_t) * 8)) && (byte & 0x40))
- ret |= -(1 << shift);
- addr = lAddr;
- return ret;
- }
-
-
- uint64_t getP (uint64_t addr, void *arg) {
- switch (fTargetArch) {
- case UNW_TARGET_X86_64:
- return get64(addr, arg);
- break;
- case UNW_TARGET_I386:
- return get32(addr, arg);
- break;
- }
- ABORT("Unknown target architecture.");
- return 0;
- }
-
- uint64_t getP (uint64_t addr, int& err, void *arg) {
- switch (fTargetArch) {
- case UNW_TARGET_X86_64:
- return get64(addr, err, arg);
- break;
- case UNW_TARGET_I386:
- return get32(addr, err, arg);
- break;
- }
- ABORT("Unknown target architecture.");
- return 0;
- }
-
- bool findFunctionName(uint64_t addr, char *buf, size_t bufLen, unw_word_t *offset, void* arg);
- bool findFunctionBounds(uint64_t addr, uint64_t& low, uint64_t& high, void* arg);
- int setCachingPolicy(unw_caching_policy_t policy);
-
- void setLoggingLevel(FILE *f, unw_log_level_t level);
- void logInfo(const char *fmt, ...);
- void logAPI(const char *fmt, ...);
- void logVerbose(const char *fmt, ...);
- void logDebug(const char *fmt, ...);
- struct timeval *timestamp_start ();
- void timestamp_stop (struct timeval *tstart, const char *fmt, ...);
-
- void flushAllCaches() { fImages.removeAllImageProfiles(); }
- void flushCacheByMachHeader(uint64_t mh) { fImages.removeOneImageProfiles(mh); }
- unw_targettype_t getTargetArch() { return fTargetArch; }
- unw_accessors_t* getAccessors () { return &fAccessors; }
- RemoteRegisterMap* getRegisterMap() { return fRemoteRegisterMap; }
- unw_addr_space_t wrap () { return (unw_addr_space_t) &fWrapper; }
- bool remoteIsLittleEndian () { return fLittleEndian; }
- unw_log_level_t getDebugLoggingLevel() { return fLogLevel; }
- bool addMemBlob (RemoteMemoryBlob *blob) { return fImages.addMemBlob(blob); }
- unw_caching_policy_t getCachingPolicy() { return fCachingPolicy; }
-
-private:
- int readRaw(uint64_t addr, uint64_t extent, uint8_t *valp, void* arg)
- {
- uint8_t *t = this->getMemBlobMemory (addr, extent);
- if (t) {
- memcpy (valp, t, extent);
- return 0;
- }
- return fAccessors.access_raw((unw_addr_space_t)this, addr, extent, valp, 0, arg);
- }
-
- struct unw_addr_space_remote fWrapper;
- unw_accessors_t fAccessors;
- unw_caching_policy_t fCachingPolicy;
- unw_targettype_t fTargetArch;
- unw_addr_space_t fAddrSpace;
- RemoteImages fImages;
- RemoteRegisterMap *fRemoteRegisterMap;
- FILE *fLogging;
- unw_log_level_t fLogLevel;
- bool fLittleEndian;
-};
-
-// Find an image containing the given pc, returns false if absent and
-// we can't add it via the accessors.
-bool RemoteProcInfo::haveImageEntry (uint64_t pc, void *arg) {
- if (fImages.remoteEntryForTextAddr (pc) == NULL) {
- unw_word_t mh, text_start, text_end, eh_frame, eh_frame_len, compact_unwind, compact_unwind_len;
- if (fAccessors.find_image_info (wrap(), pc, &mh, &text_start,
- &text_end, &eh_frame, &eh_frame_len, &compact_unwind, &compact_unwind_len, arg) == UNW_ESUCCESS) {
- fImages.addImage (mh, text_start, text_end, eh_frame, eh_frame_len, compact_unwind, compact_unwind_len);
- if (fCachingPolicy != UNW_CACHE_NONE) {
- if (compact_unwind_len != 0) {
- logVerbose ("Creating RemoteMemoryBlob of compact unwind info image at mh 0x%llx, %lld bytes", mh, (uint64_t) compact_unwind_len);
- uint8_t *buf = (uint8_t*) malloc (compact_unwind_len);
- if (this->getBytes (compact_unwind, compact_unwind_len, buf, arg)) {
- RemoteMemoryBlob *b = new RemoteMemoryBlob(buf, free, compact_unwind, compact_unwind_len, mh, NULL);
- if (fImages.addMemBlob (b) == false)
- delete b;
- }
- } else if (eh_frame_len != 0) {
- logVerbose ("Creating RemoteMemoryBlob of eh_frame for image at mh 0x%llx, %lld bytes", mh, (uint64_t) compact_unwind_len);
- uint8_t *buf = (uint8_t*) malloc (eh_frame_len);
- if (this->getBytes (eh_frame, eh_frame_len, buf, arg)) {
- RemoteMemoryBlob *b = new RemoteMemoryBlob(buf, free, eh_frame, eh_frame_len, mh, NULL);
- if (fImages.addMemBlob (b) == false)
- delete b;
- }
- }
- }
- } else {
- return false; /// find_image_info failed
- }
- } else {
- return true;
- }
- return true;
-}
-
-bool RemoteProcInfo::getImageAddresses (uint64_t pc, uint64_t &mh, uint64_t &text_start, uint64_t &text_end,
- uint64_t &eh_frame_start, uint64_t &eh_frame_len, uint64_t &compact_unwind_start,
- void *arg) {
- // Make sure we have this RemoteImageEntry already - fetch it now if needed.
- if (haveImageEntry (pc, arg) == false) {
- return false;
- }
- RemoteImageEntry *r = fImages.remoteEntryForTextAddr (pc);
- if (r) {
- mh = r->mach_header;
- text_start = r->text_start;
- text_end = r->text_end;
- eh_frame_start = r->eh_frame_start;
- eh_frame_len = r->eh_frame_len;
- compact_unwind_start = r->compact_unwind_info_start;
- return true;
- }
- return false;
-}
-
-
-bool RemoteProcInfo::findFunctionName(uint64_t addr, char *buf, size_t bufLen, unw_word_t *offset, void* arg)
-{
- if(fAccessors.get_proc_name(wrap(), addr, buf, bufLen, offset, arg) == UNW_ESUCCESS)
- return true;
- else
- return false;
-}
-
-bool RemoteProcInfo::findFunctionBounds(uint64_t addr, uint64_t& low, uint64_t& high, void* arg)
-{
- if (fAccessors.get_proc_bounds(wrap(), addr, &low, &high, arg) == UNW_ESUCCESS
- && high != 0)
- return true;
- else
- return false;
-}
-
-int RemoteProcInfo::setCachingPolicy(unw_caching_policy_t policy)
-{
- if(policy == UNW_CACHE_NONE && fCachingPolicy != UNW_CACHE_NONE)
- {
- flushAllCaches();
- }
-
- if(!(policy == UNW_CACHE_NONE || policy == UNW_CACHE_GLOBAL || policy == UNW_CACHE_PER_THREAD))
- return UNW_EINVAL;
-
- fCachingPolicy = policy;
-
- return UNW_ESUCCESS;
-}
-
-void RemoteProcInfo::setLoggingLevel(FILE *f, unw_log_level_t level)
-{
- fLogLevel = level;
- fLogging = f;
-}
-
-void RemoteProcInfo::logInfo(const char *fmt, ...)
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE)
- return;
- if (fLogLevel & UNW_LOG_LEVEL_INFO) {
- va_list ap;
- va_start (ap, fmt);
- vfprintf (fLogging, fmt, ap);
- fputs ("\n", fLogging);
- va_end (ap);
- }
-}
-
-void RemoteProcInfo::logAPI(const char *fmt, ...)
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE)
- return;
- if (fLogLevel & UNW_LOG_LEVEL_API) {
- va_list ap;
- va_start (ap, fmt);
- vfprintf (fLogging, fmt, ap);
- fputs ("\n", fLogging);
- va_end (ap);
- }
-}
-
-void RemoteProcInfo::logVerbose(const char *fmt, ...)
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE)
- return;
- if (fLogLevel & UNW_LOG_LEVEL_VERBOSE) {
- va_list ap;
- va_start (ap, fmt);
- vfprintf (fLogging, fmt, ap);
- fputs ("\n", fLogging);
- va_end (ap);
- }
-}
-
-void RemoteProcInfo::logDebug(const char *fmt, ...)
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE)
- return;
- if (fLogLevel & UNW_LOG_LEVEL_DEBUG) {
- va_list ap;
- va_start (ap, fmt);
- vfprintf (fLogging, fmt, ap);
- fputs ("\n", fLogging);
- va_end (ap);
- }
-}
-
-struct timeval *RemoteProcInfo::timestamp_start ()
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE)
- return NULL;
- if (fLogLevel & UNW_LOG_LEVEL_TIMINGS) {
- struct timeval *t = (struct timeval *) malloc (sizeof (struct timeval));
- if (gettimeofday (t, NULL) != 0) {
- free (t);
- return NULL;
- }
- return t;
- }
- return NULL;
-}
-
-void RemoteProcInfo::timestamp_stop (struct timeval *tstart, const char *fmt, ...)
-{
- if (fLogging == NULL || fLogLevel == UNW_LOG_LEVEL_NONE || tstart == NULL)
- return;
- if (fLogLevel & UNW_LOG_LEVEL_TIMINGS) {
- struct timeval tend;
- if (gettimeofday (&tend, NULL) != 0) {
- free (tstart);
- return;
- }
- struct timeval result;
- timersub (&tend, tstart, &result);
- va_list ap;
- va_start (ap, fmt);
- vprintf (fmt, ap);
- printf (" duration %0.5fs\n", (double) ((result.tv_sec * 1000000) + result.tv_usec) / 1000000.0);
- va_end (ap);
- free (tstart);
- }
-}
-
-
-// Initialize the register context at the start of a remote unwind.
-
-void getRemoteContext (RemoteProcInfo* procinfo, Registers_x86_64& r, void *arg) {
- unw_accessors_t* accessors = procinfo->getAccessors();
- unw_addr_space_t addrSpace = procinfo->wrap();
- RemoteRegisterMap* regmap = procinfo->getRegisterMap();
- uint64_t rv;
-
- // now that we have a selected process/thread, ask about the valid registers.
- regmap->scan_caller_regs (addrSpace, arg);
-
-#define FILLREG(reg) {int caller_reg; regmap->unwind_regno_to_caller_regno ((reg), caller_reg); accessors->access_reg (addrSpace, caller_reg, &rv, 0, arg); r.setRegister ((reg), rv);}
- FILLREG (UNW_X86_64_RAX);
- FILLREG (UNW_X86_64_RDX);
- FILLREG (UNW_X86_64_RCX);
- FILLREG (UNW_X86_64_RBX);
- FILLREG (UNW_X86_64_RSI);
- FILLREG (UNW_X86_64_RDI);
- FILLREG (UNW_X86_64_RBP);
- FILLREG (UNW_X86_64_RSP);
- FILLREG (UNW_X86_64_R8);
- FILLREG (UNW_X86_64_R9);
- FILLREG (UNW_X86_64_R10);
- FILLREG (UNW_X86_64_R11);
- FILLREG (UNW_X86_64_R12);
- FILLREG (UNW_X86_64_R13);
- FILLREG (UNW_X86_64_R14);
- FILLREG (UNW_X86_64_R15);
- FILLREG (UNW_REG_IP);
-#undef FILLREG
-}
-
-void getRemoteContext (RemoteProcInfo* procinfo, Registers_x86& r, void *arg) {
- unw_accessors_t* accessors = procinfo->getAccessors();
- unw_addr_space_t addrSpace = procinfo->wrap();
- RemoteRegisterMap* regmap = procinfo->getRegisterMap();
- uint64_t rv;
-
- // now that we have a selected process/thread, ask about the valid registers.
- regmap->scan_caller_regs (addrSpace, arg);
-
-#define FILLREG(reg) {int caller_reg; regmap->unwind_regno_to_caller_regno ((reg), caller_reg); accessors->access_reg (addrSpace, caller_reg, &rv, 0, arg); r.setRegister ((reg), rv);}
- FILLREG (UNW_X86_EAX);
- FILLREG (UNW_X86_ECX);
- FILLREG (UNW_X86_EDX);
- FILLREG (UNW_X86_EBX);
- FILLREG (UNW_X86_EBP);
- FILLREG (UNW_X86_ESP);
- FILLREG (UNW_X86_ESI);
- FILLREG (UNW_X86_EDI);
- FILLREG (UNW_REG_IP);
-#undef FILLREG
-}
-
-}; // namespace lldb_private
-
-
-
-#endif // SUPPORT_REMOTE_UNWINDING
-#endif // __REMOTE_PROC_INFO_HPP__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteRegisterMap.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteRegisterMap.hpp
deleted file mode 100644
index 86da827370a..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteRegisterMap.hpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- RemoteRegisterMap.hpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Provide conversions between reigster names, the libunwind internal enums,
-// and the register numbers the program calling libunwind are using.
-
-#ifndef __REMOTE_REGISTER_MAP_HPP__
-#define __REMOTE_REGISTER_MAP_HPP__
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "libunwind.h"
-#include <vector>
-
-namespace lldb_private
-{
-class RemoteRegisterMap {
-public:
- RemoteRegisterMap (unw_accessors_t *accessors, unw_targettype_t target);
- ~RemoteRegisterMap ();
- void initialize_x86_64 ();
- void initialize_i386 ();
- bool name_to_caller_regno (const char *name, int& callerr);
- bool name_to_unwind_regno (const char *name, int& unwindr);
- bool unwind_regno_to_caller_regno (int unwindr, int& callerr);
- bool nonvolatile_reg_p (int unwind_regno);
- bool argument_regnum_p (int unwind_regno);
- const char *ip_register_name();
- const char *sp_register_name();
- int caller_regno_for_ip ();
- int caller_regno_for_sp ();
- int unwind_regno_for_frame_pointer ();
- int unwind_regno_for_stack_pointer ();
- int wordsize () { return fWordSize; }
- void scan_caller_regs (unw_addr_space_t as, void *arg);
-
- bool unwind_regno_to_machine_regno (int unwindr, int& machiner);
- bool machine_regno_to_unwind_regno (int machr, int& unwindr);
- bool caller_regno_to_unwind_regno (int callerr, int& unwindr);
- const char* unwind_regno_to_name (int unwindr);
- int byte_size_for_regtype (unw_regtype_t type);
-
-private:
-
- // A structure that collects everything we need to know about a
- // given register in one place.
- struct reg {
- int unwind_regno; // What libunwind-remote uses internally
- int caller_regno; // What the libunwind-remote driver program uses
- int eh_frame_regno; // What the eh_frame section uses
- int machine_regno; // What the actual bits/bytes are in instructions
- char *name;
- unw_regtype_t type;
- reg () : unwind_regno(-1), caller_regno(-1), eh_frame_regno(-1),
- machine_regno(-1), name(NULL), type(UNW_NOT_A_REG) { }
- };
-
- unw_accessors_t fAccessors;
- unw_targettype_t fTarget;
- std::vector<RemoteRegisterMap::reg> fRegMap;
- int fWordSize;
-};
-
-void RemoteRegisterMap::initialize_x86_64 () {
-#define DEFREG(ureg, ehno, machno, regn) {RemoteRegisterMap::reg r; r.unwind_regno = ureg; r.name = regn; r.eh_frame_regno = ehno; r.machine_regno = machno; r.type = UNW_INTEGER_REG; fRegMap.push_back(r); }
- DEFREG (UNW_X86_64_RAX, 0, 0, strdup ("rax"));
- DEFREG (UNW_X86_64_RDX, 1, 2, strdup ("rdx"));
- DEFREG (UNW_X86_64_RCX, 2, 1, strdup ("rcx"));
- DEFREG (UNW_X86_64_RBX, 3, 3, strdup ("rbx"));
- DEFREG (UNW_X86_64_RSI, 4, 6, strdup ("rsi"));
- DEFREG (UNW_X86_64_RDI, 5, 7, strdup ("rdi"));
- DEFREG (UNW_X86_64_RBP, 6, 5, strdup ("rbp"));
- DEFREG (UNW_X86_64_RSP, 7, 4, strdup ("rsp"));
- DEFREG (UNW_X86_64_R8, 8, 8, strdup ("r8"));
- DEFREG (UNW_X86_64_R9, 9, 9, strdup ("r9"));
- DEFREG (UNW_X86_64_R10, 10, 10, strdup ("r10"));
- DEFREG (UNW_X86_64_R11, 11, 11, strdup ("r11"));
- DEFREG (UNW_X86_64_R12, 12, 12, strdup ("r12"));
- DEFREG (UNW_X86_64_R13, 13, 13, strdup ("r13"));
- DEFREG (UNW_X86_64_R14, 14, 14, strdup ("r14"));
- DEFREG (UNW_X86_64_R15, 15, 15, strdup ("r15"));
-#undef DEFREG
- RemoteRegisterMap::reg r;
- r.name = strdup ("rip");
- r.type = UNW_INTEGER_REG;
- r.eh_frame_regno = 16;
- fRegMap.push_back(r);
-}
-
-void RemoteRegisterMap::initialize_i386 () {
-#define DEFREG(ureg, ehno, machno, regn) {RemoteRegisterMap::reg r; r.unwind_regno = ureg; r.name = regn; r.eh_frame_regno = ehno; r.machine_regno = machno; r.type = UNW_INTEGER_REG; fRegMap.push_back(r); }
- DEFREG (UNW_X86_EAX, 0, 0, strdup ("eax"));
- DEFREG (UNW_X86_ECX, 1, 1, strdup ("ecx"));
- DEFREG (UNW_X86_EDX, 2, 2, strdup ("edx"));
- DEFREG (UNW_X86_EBX, 3, 3, strdup ("ebx"));
- // i386 EH frame info has the next two swapped,
- // v. gcc/config/i386/darwin.h:DWARF2_FRAME_REG_OUT.
- DEFREG (UNW_X86_EBP, 4, 5, strdup ("ebp"));
- DEFREG (UNW_X86_ESP, 5, 4, strdup ("esp"));
- DEFREG (UNW_X86_ESI, 6, 6, strdup ("esi"));
- DEFREG (UNW_X86_EDI, 7, 7, strdup ("edi"));
-#undef DEFREG
- RemoteRegisterMap::reg r;
- r.name = strdup ("eip");
- r.type = UNW_INTEGER_REG;
- r.eh_frame_regno = 8;
- fRegMap.push_back(r);
-}
-
-
-RemoteRegisterMap::RemoteRegisterMap (unw_accessors_t *accessors, unw_targettype_t target) {
- fAccessors = *accessors;
- fTarget = target;
- switch (target) {
- case UNW_TARGET_X86_64:
- this->initialize_x86_64();
- fWordSize = 8;
- break;
- case UNW_TARGET_I386:
- this->initialize_i386();
- fWordSize = 4;
- break;
- default:
- ABORT("RemoteRegisterMap called with unknown target");
- }
-}
-
-RemoteRegisterMap::~RemoteRegisterMap () {
- std::vector<RemoteRegisterMap::reg>::iterator j;
- for (j = fRegMap.begin(); j != fRegMap.end(); ++j)
- free (j->name);
-}
-
-bool RemoteRegisterMap::name_to_caller_regno (const char *name, int& callerr) {
- if (name == NULL)
- return false;
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (strcasecmp (j->name, name) == 0) {
- callerr = j->caller_regno;
- return true;
- }
- return false;
-}
-
-bool RemoteRegisterMap::unwind_regno_to_caller_regno (int unwindr, int& callerr) {
- if (unwindr == UNW_REG_IP) {
- callerr = this->caller_regno_for_ip ();
- return true;
- }
- if (unwindr == UNW_REG_SP) {
- callerr = this->caller_regno_for_sp ();
- return true;
- }
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (j->unwind_regno == unwindr && j->caller_regno != -1) {
- callerr = j->caller_regno;
- return true;
- }
- return false;
-}
-
-bool RemoteRegisterMap::nonvolatile_reg_p (int unwind_regno) {
- if (fTarget == UNW_TARGET_X86_64) {
- switch (unwind_regno) {
- case UNW_X86_64_RBX:
- case UNW_X86_64_RSP:
- case UNW_X86_64_RBP: // not actually a nonvolatile but often treated as such by convention
- case UNW_X86_64_R12:
- case UNW_X86_64_R13:
- case UNW_X86_64_R14:
- case UNW_X86_64_R15:
- case UNW_REG_IP:
- case UNW_REG_SP:
- return true;
- break;
- default:
- return false;
- }
- }
- if (fTarget == UNW_TARGET_I386) {
- switch (unwind_regno) {
- case UNW_X86_EBX:
- case UNW_X86_EBP: // not actually a nonvolatile but often treated as such by convention
- case UNW_X86_ESI:
- case UNW_X86_EDI:
- case UNW_X86_ESP:
- case UNW_REG_IP:
- case UNW_REG_SP:
- return true;
- break;
- default:
- return false;
- }
- }
- return false;
-}
-
-
-bool RemoteRegisterMap::argument_regnum_p (int unwind_regno) {
- if (fTarget == UNW_TARGET_X86_64) {
- switch (unwind_regno) {
- case UNW_X86_64_RDI: /* arg 1 */
- case UNW_X86_64_RSI: /* arg 2 */
- case UNW_X86_64_RDX: /* arg 3 */
- case UNW_X86_64_RCX: /* arg 4 */
- case UNW_X86_64_R8: /* arg 5 */
- case UNW_X86_64_R9: /* arg 6 */
- return true;
- break;
- default:
- return false;
- }
- }
- return false;
-}
-
-const char *RemoteRegisterMap::ip_register_name () {
- switch (fTarget) {
- case UNW_TARGET_X86_64:
- return "rip";
- case UNW_TARGET_I386:
- return "eip";
- default:
- ABORT("unsupported architecture");
- }
- return NULL;
-}
-
-const char *RemoteRegisterMap::sp_register_name () {
- switch (fTarget) {
- case UNW_TARGET_X86_64:
- return "rsp";
- case UNW_TARGET_I386:
- return "esp";
- default:
- ABORT("unsupported architecture");
- }
- return NULL;
-}
-
-int RemoteRegisterMap::caller_regno_for_ip () {
- int callerr;
- if (this->name_to_caller_regno (this->ip_register_name(), callerr))
- return callerr;
- return -1;
-}
-
-int RemoteRegisterMap::caller_regno_for_sp () {
- int callerr;
- if (this->name_to_caller_regno (this->sp_register_name(), callerr))
- return callerr;
- return -1;
-}
-
-int RemoteRegisterMap::unwind_regno_for_frame_pointer () {
- switch (fTarget) {
- case UNW_TARGET_X86_64:
- return UNW_X86_64_RBP;
- case UNW_TARGET_I386:
- return UNW_X86_EBP;
- default:
- ABORT("cannot be reached");
- }
- return -1;
-}
-
-int RemoteRegisterMap::unwind_regno_for_stack_pointer () {
- switch (fTarget) {
- case UNW_TARGET_X86_64:
- return UNW_X86_64_RSP;
- case UNW_TARGET_I386:
- return UNW_X86_ESP;
- default:
- ABORT("cannot be reached");
- }
- return -1;
-}
-
-// This call requires a "arg" which specifies a given process/thread to
-// complete unlike the rest of the RegisterMap functions. Ideally this
-// would be in the ctor but the register map is created when an
-// AddressSpace is created and we don't have a process/thread yet.
-
-void RemoteRegisterMap::scan_caller_regs (unw_addr_space_t as, void *arg) {
- for (int i = 0; i < 256; i++) {
- unw_regtype_t type;
- char namebuf[16];
- if (fAccessors.reg_info (as, i, &type, namebuf, sizeof (namebuf), arg) == UNW_ESUCCESS
- && type != UNW_NOT_A_REG) {
- std::vector<RemoteRegisterMap::reg>::iterator j;
- for (j = fRegMap.begin(); j != fRegMap.end(); ++j) {
- if (strcasecmp (j->name, namebuf) == 0) {
- j->caller_regno = i;
- // if we haven't picked up a reg type yet it will be UNW_NOT_A_REG via the ctor
- if (j->type == UNW_NOT_A_REG)
- j->type = type;
- if (j->type != type) {
- ABORT("Caller and libunwind disagree about type of register");
- break;
- }
- }
- }
- // caller knows about a register we don't have a libunwind entry for
- if (j == fRegMap.end()) {
- RemoteRegisterMap::reg r;
- r.name = strdup (namebuf);
- r.caller_regno = i;
- r.type = type;
- fRegMap.push_back(r);
- }
- }
- }
-}
-
-
-bool RemoteRegisterMap::name_to_unwind_regno (const char *name, int& unwindr) {
- if (name == NULL)
- return false;
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (strcasecmp (j->name, name) == 0) {
- unwindr = j->unwind_regno;
- return true;
- }
- return false;
-}
-
-bool RemoteRegisterMap::unwind_regno_to_machine_regno (int unwindr, int& machiner) {
- if (unwindr == UNW_REG_IP)
- unwindr = this->caller_regno_for_ip ();
- if (unwindr == UNW_REG_SP)
- unwindr = this->caller_regno_for_sp ();
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (j->unwind_regno == unwindr && j->machine_regno != -1) {
- machiner = j->machine_regno;
- return true;
- }
- return false;
-}
-bool RemoteRegisterMap::machine_regno_to_unwind_regno (int machr, int& unwindr) {
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (j->machine_regno == machr && j->unwind_regno != -1) {
- unwindr = j->unwind_regno;
- return true;
- }
- return false;
-}
-bool RemoteRegisterMap::caller_regno_to_unwind_regno (int callerr, int& unwindr) {
- if (this->caller_regno_for_ip() == callerr) {
- unwindr = UNW_REG_IP;
- return true;
- }
- if (this->caller_regno_for_sp() == callerr) {
- unwindr = UNW_REG_SP;
- return true;
- }
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (j->caller_regno == callerr && j->unwind_regno != -1) {
- unwindr = j->unwind_regno;
- return true;
- }
- return false;
-}
-
-const char* RemoteRegisterMap::unwind_regno_to_name (int unwindr) {
- for (std::vector<RemoteRegisterMap::reg>::iterator j = fRegMap.begin(); j != fRegMap.end(); ++j)
- if (j->unwind_regno == unwindr && j->name != NULL) {
- return j->name;
- }
- return NULL;
-}
-
-int RemoteRegisterMap::byte_size_for_regtype (unw_regtype_t type) {
- switch (type) {
- case UNW_TARGET_X86_64:
- case UNW_TARGET_I386:
- if (type == UNW_INTEGER_REG) return fWordSize;
- if (type == UNW_FLOATING_POINT_REG) return 8;
- if (type == UNW_VECTOR_REG) return 16;
- default:
- ABORT("cannot be reached");
- }
- return -1;
-}
-
-
-}; // namespace lldb_private
-
-#endif // SUPPORT_REMOTE_UNWINDING
-
-#endif // __REMOTE_REGISTER_MAP_HPP__
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteUnwindProfile.h b/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteUnwindProfile.h
deleted file mode 100644
index a23eb28a8ad..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/RemoteUnwindProfile.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- RemoteUnwindProfile.h -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __UNWIND_PROFILE_H__
-#define __UNWIND_PROFILE_H__
-#if defined (SUPPORT_REMOTE_UNWINDING)
-
-#include <vector>
-
-// The architecture-independent profile of a function's prologue
-
-namespace lldb_private
-{
-
-class RemoteUnwindProfile {
-public:
- RemoteUnwindProfile () : fRegistersSaved(32, 0), fRegSizes(10, 0) { }
- struct CFALocation {
- int regno;
- int offset;
- };
- enum RegisterSavedWhere { kRegisterOffsetFromCFA, kRegisterIsCFA };
- enum RegisterType { kGeneralPurposeRegister = 0, kFloatingPointRegister, kVectorRegister };
- struct SavedReg {
- int regno;
- RegisterSavedWhere location;
- int64_t value;
- int adj; // Used in kRegisterInRegister e.g. when we recover the caller's rsp by
- // taking the contents of rbp and subtracting 16.
- RegisterType type;
- };
- // In the following maps the key is the address after which this change has effect.
- //
- // 0 push %rbp
- // 1 mov %rsp, %rbp
- // 2 sub $16, %rsp
- //
- // At saved_registers<2> we'll find the record stating that rsp is now stored in rbp.
-
- std::map<uint64_t, CFALocation> cfa;
- std::map<uint64_t, std::vector<SavedReg> > saved_registers;
-
- struct CFALocation initial_cfa; // At entry to the function
-
- std::vector<uint8_t> fRegistersSaved;
- std::vector<uint8_t> fRegSizes;
- SavedReg returnAddress;
- uint64_t fStart, fEnd; // low and high pc values for this function.
- // END is the addr of the first insn outside the function.
- uint64_t fFirstInsnPastPrologue;
-};
-
-class RemoteProcInfo;
-
-bool AssemblyParse (RemoteProcInfo *procinfo, unw_accessors_t *accessor, unw_addr_space_t as, uint64_t start, uint64_t end, RemoteUnwindProfile &profile, void *arg);
-
-
-class FuncBounds {
- public:
- FuncBounds (uint64_t low, uint64_t high) : fStart(low), fEnd(high) { }
- uint64_t fStart;
- uint64_t fEnd;
-};
-
-inline bool operator<(const FuncBounds &ap1, const FuncBounds &ap2) {
- if (ap1.fStart < ap2.fStart)
- return true;
- if (ap1.fStart == ap2.fStart && ap1.fEnd < ap2.fEnd)
- return true;
- return false;
-}
-
-
-};
-#endif
-
-
-#endif // __UNWIND_PROFILE_H__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/Unwind-sjlj.c b/lldb/source/Plugins/Process/Utility/libunwind/src/Unwind-sjlj.c
deleted file mode 100644
index 584528353a4..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/Unwind-sjlj.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- Unwind-sjlj.c -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-/*
- *
- * Implements setjump-longjump based C++ exceptions
- *
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <setjmp.h>
-
-#include "unwind.h"
-#include "InternalMacros.h"
-
-//
-// ARM uses setjump/longjump based C++ exceptions.
-// Other architectures use "zero cost" exceptions.
-//
-// With SJLJ based exceptions any function that has a catch clause or needs to do any clean up when
-// an exception propagates through it, needs to call _Unwind_SjLj_Register() at the start of the
-// function and _Unwind_SjLj_Unregister() at the end. The register function is called with the
-// address of a block of memory in the function's stack frame. The runtime keeps a linked list
-// (stack) of these blocks - one per thread. The calling function also sets the personality
-// and lsda fields of the block.
-//
-//
-#if __arm__
-
-struct _Unwind_FunctionContext
-{
- // next function in stack of handlers
- struct _Unwind_FunctionContext* prev;
-
- // set by calling function before registering to be the landing pad
- uintptr_t resumeLocation;
-
- // set by personality handler to be parameters passed to landing pad function
- uintptr_t resumeParameters[4];
-
- // set by calling function before registering
- __personality_routine personality; // arm offset=24
- uintptr_t lsda; // arm offset=28
-
- // variable length array, contains registers to restore
- // 0 = r7, 1 = pc, 2 = sp
- void* jbuf[];
-};
-
-
-#if FOR_DYLD
- // implemented in dyld
- extern struct _Unwind_FunctionContext* __Unwind_SjLj_GetTopOfFunctionStack();
- extern void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext* fc);
-#else
- static pthread_key_t sPerThreadTopOfFunctionStack = 0;
- static pthread_once_t sOnceFlag = PTHREAD_ONCE_INIT;
-
- static void __Unwind_SjLj_MakeTopOfFunctionStackKey()
- {
- pthread_key_create(&sPerThreadTopOfFunctionStack, NULL);
- }
-
- static struct _Unwind_FunctionContext* __Unwind_SjLj_GetTopOfFunctionStack()
- {
- pthread_once(&sOnceFlag, __Unwind_SjLj_MakeTopOfFunctionStackKey);
- return (struct _Unwind_FunctionContext*)pthread_getspecific(sPerThreadTopOfFunctionStack);
- }
-
- static void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext* fc)
- {
- pthread_once(&sOnceFlag, __Unwind_SjLj_MakeTopOfFunctionStackKey);
- pthread_setspecific(sPerThreadTopOfFunctionStack, fc);
- }
-#endif
-
-
-//
-// Called at start of each function that catches exceptions
-//
-EXPORT void _Unwind_SjLj_Register(struct _Unwind_FunctionContext* fc)
-{
- fc->prev = __Unwind_SjLj_GetTopOfFunctionStack();
- __Unwind_SjLj_SetTopOfFunctionStack(fc);
-}
-
-
-//
-// Called at end of each function that catches exceptions
-//
-EXPORT void _Unwind_SjLj_Unregister(struct _Unwind_FunctionContext* fc)
-{
- __Unwind_SjLj_SetTopOfFunctionStack(fc->prev);
-}
-
-
-static _Unwind_Reason_Code unwind_phase1(struct _Unwind_Exception* exception_object)
-{
- _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
- DEBUG_PRINT_UNWINDING("unwind_phase1: initial function-context=%p\n", c);
-
- // walk each frame looking for a place to stop
- for (bool handlerNotFound = true; handlerNotFound; c = c->prev) {
-
- // check for no more frames
- if ( c == NULL ) {
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): reached bottom => _URC_END_OF_STACK\n", exception_object);
- return _URC_END_OF_STACK;
- }
-
- DEBUG_PRINT_UNWINDING("unwind_phase1: function-context=%p\n", c);
- // if there is a personality routine, ask it if it will want to stop at this frame
- if ( c->personality != NULL ) {
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): calling personality function %p\n", exception_object, c->personality);
- _Unwind_Reason_Code personalityResult = (*c->personality)(1, _UA_SEARCH_PHASE,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)c);
- switch ( personalityResult ) {
- case _URC_HANDLER_FOUND:
- // found a catch clause or locals that need destructing in this frame
- // stop search and remember function context
- handlerNotFound = false;
- exception_object->private_2 = (uintptr_t)c;
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND\n", exception_object);
- return _URC_NO_REASON;
-
- case _URC_CONTINUE_UNWIND:
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", exception_object);
- // continue unwinding
- break;
-
- default:
- // something went wrong
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE1_ERROR;
- }
- }
- }
- return _URC_NO_REASON;
-}
-
-
-static _Unwind_Reason_Code unwind_phase2(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
-
- // walk each frame until we reach where search phase said to stop
- _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
- while ( true ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2s(ex_ojb=%p): function-context=%p\n", exception_object, c);
-
- // check for no more frames
- if ( c == NULL ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached bottom => _URC_END_OF_STACK\n", exception_object);
- return _URC_END_OF_STACK;
- }
-
- // if there is a personality routine, tell it we are unwinding
- if ( c->personality != NULL ) {
- _Unwind_Action action = _UA_CLEANUP_PHASE;
- if ( (uintptr_t)c == exception_object->private_2 )
- action = (_Unwind_Action)(_UA_CLEANUP_PHASE|_UA_HANDLER_FRAME); // tell personality this was the frame it marked in phase 1
- _Unwind_Reason_Code personalityResult = (*c->personality)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)c);
- switch ( personalityResult ) {
- case _URC_CONTINUE_UNWIND:
- // continue unwinding
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", exception_object);
- if ( (uintptr_t)c == exception_object->private_2 ) {
- // phase 1 said we would stop at this frame, but we did not...
- ABORT("during phase1 personality function said it would stop here, but now if phase2 it did not stop here");
- }
- break;
- case _URC_INSTALL_CONTEXT:
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT, will resume at landing pad %p\n", exception_object, c->jbuf[1]);
- // personality routine says to transfer control to landing pad
- // we may get control back if landing pad calls _Unwind_Resume()
- __Unwind_SjLj_SetTopOfFunctionStack(c);
- __builtin_longjmp(c->jbuf, 1);
- // unw_resume() only returns if there was an error
- return _URC_FATAL_PHASE2_ERROR;
- default:
- // something went wrong
- DEBUG_MESSAGE("personality function returned unknown result %d", personalityResult);
- return _URC_FATAL_PHASE2_ERROR;
- }
- }
- c = c->prev;
- }
-
- // clean up phase did not resume at the frame that the search phase said it would
- return _URC_FATAL_PHASE2_ERROR;
-}
-
-
-static _Unwind_Reason_Code unwind_phase2_forced(struct _Unwind_Exception* exception_object,
- _Unwind_Stop_Fn stop, void* stop_parameter)
-{
- // walk each frame until we reach where search phase said to stop
- _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
- while ( true ) {
-
- // get next frame (skip over first which is _Unwind_RaiseException)
- if ( c == NULL ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached bottom => _URC_END_OF_STACK\n", exception_object);
- return _URC_END_OF_STACK;
- }
-
- // call stop function at each frame
- _Unwind_Action action = (_Unwind_Action)(_UA_FORCE_UNWIND|_UA_CLEANUP_PHASE);
- _Unwind_Reason_Code stopResult = (*stop)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)c, stop_parameter);
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n", exception_object, stopResult);
- if ( stopResult != _URC_NO_REASON ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n", exception_object);
- return _URC_FATAL_PHASE2_ERROR;
- }
-
- // if there is a personality routine, tell it we are unwinding
- if ( c->personality != NULL ) {
- __personality_routine p = (__personality_routine)c->personality;
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n", exception_object, p);
- _Unwind_Reason_Code personalityResult = (*p)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)c);
- switch ( personalityResult ) {
- case _URC_CONTINUE_UNWIND:
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned _URC_CONTINUE_UNWIND\n", exception_object);
- // destructors called, continue unwinding
- break;
- case _URC_INSTALL_CONTEXT:
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned _URC_INSTALL_CONTEXT\n", exception_object);
- // we may get control back if landing pad calls _Unwind_Resume()
- __Unwind_SjLj_SetTopOfFunctionStack(c);
- __builtin_longjmp(c->jbuf, 1);
- break;
- default:
- // something went wrong
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned %d, _URC_FATAL_PHASE2_ERROR\n",
- exception_object, personalityResult);
- return _URC_FATAL_PHASE2_ERROR;
- }
- }
- c = c->prev;
- }
-
- // call stop function one last time and tell it we've reached the end of the stack
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop function with _UA_END_OF_STACK\n", exception_object);
- _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND|_UA_CLEANUP_PHASE|_UA_END_OF_STACK);
- (*stop)(1, lastAction, exception_object->exception_class, exception_object, (struct _Unwind_Context*)c, stop_parameter);
-
- // clean up phase did not resume at the frame that the search phase said it would
- return _URC_FATAL_PHASE2_ERROR;
-}
-
-
-//
-// Called by __cxa_throw. Only returns if there is a fatal error
-//
-EXPORT _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_SjLj_RaiseException(ex_obj=%p)\n", exception_object);
-
- // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right thing
- exception_object->private_1 = 0;
- exception_object->private_2 = 0;
-
- // phase 1: the search phase
- _Unwind_Reason_Code phase1 = unwind_phase1(exception_object);
- if ( phase1 != _URC_NO_REASON )
- return phase1;
-
- // phase 2: the clean up phase
- return unwind_phase2(exception_object);
-}
-
-
-//
-// When _Unwind_RaiseException() is in phase2, it hands control
-// to the personality function at each frame. The personality
-// may force a jump to a landing pad in that function, the landing
-// pad code may then call _Unwind_Resume() to continue with the
-// unwinding. Note: the call to _Unwind_Resume() is from compiler
-// geneated user code. All other _Unwind_* routines are called
-// by the C++ runtime __cxa_* routines.
-//
-// Re-throwing an exception is implemented by having the code call
-// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow()
-//
-EXPORT void _Unwind_SjLj_Resume(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_SjLj_Resume(ex_obj=%p)\n", exception_object);
-
- if ( exception_object->private_1 != 0 )
- unwind_phase2_forced(exception_object, (_Unwind_Stop_Fn)exception_object->private_1, (void*)exception_object->private_2);
- else
- unwind_phase2(exception_object);
-
- // clients assume _Unwind_Resume() does not return, so all we can do is abort.
- ABORT("_Unwind_SjLj_Resume() can't return");
-}
-
-
-//
-// Called by __cxa_rethrow()
-//
-EXPORT _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("__Unwind_SjLj_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n", exception_object, exception_object->private_1);
- // if this is non-forced and a stopping place was found, then this is a re-throw
- // call _Unwind_RaiseException() as if this was a new exception
- if ( exception_object->private_1 == 0 )
- _Unwind_SjLj_RaiseException(exception_object);
-
- // call through to _Unwind_Resume() which distiguishes between forced and regular exceptions
- _Unwind_SjLj_Resume(exception_object);
- ABORT("__Unwind_SjLj_Resume_or_Rethrow() called _Unwind_SjLj_Resume() which unexpectedly returned");
-}
-
-
-//
-// Called by personality handler during phase 2 to get LSDA for current frame
-//
-EXPORT uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context* context)
-{
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- DEBUG_PRINT_API("_Unwind_GetLanguageSpecificData(context=%p) => 0x%0lX\n", context, ufc->lsda);
- return ufc->lsda;
-}
-
-
-//
-// Called by personality handler during phase 2 to get register values
-//
-EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context* context, int index)
-{
- DEBUG_PRINT_API("_Unwind_GetGR(context=%p, reg=%d)\n", context, index);
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- return ufc->resumeParameters[index];
-}
-
-
-
-//
-// Called by personality handler during phase 2 to alter register values
-//
-EXPORT void _Unwind_SetGR(struct _Unwind_Context* context, int index, uintptr_t new_value)
-{
- DEBUG_PRINT_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)\n", context, index, new_value);
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- ufc->resumeParameters[index] = new_value;
-}
-
-
-//
-// Called by personality handler during phase 2 to get instruction pointer
-//
-EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context* context)
-{
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- DEBUG_PRINT_API("_Unwind_GetIP(context=%p) => 0x%lX\n", context, ufc->resumeLocation+1);
- return ufc->resumeLocation+1;
-}
-
-//
-// Called by personality handler during phase 2 to get instruction pointer
-// ipBefore is a boolean that says if IP is already adjusted to be the call
-// site address. Normally IP is the return address.
-//
-EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context* context, int* ipBefore)
-{
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- *ipBefore = 0;
- DEBUG_PRINT_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX\n", context, ipBefore, ufc->resumeLocation+1);
- return ufc->resumeLocation+1;
-}
-
-
-//
-// Called by personality handler during phase 2 to alter instruction pointer
-//
-EXPORT void _Unwind_SetIP(struct _Unwind_Context* context, uintptr_t new_value)
-{
- DEBUG_PRINT_API("_Unwind_SetIP(context=%p, value=0x%0lX)\n", context, new_value);
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- ufc->resumeLocation = new_value-1;
-}
-
-//
-// Called by personality handler during phase 2 to find the start of the function
-//
-EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context* context)
-{
- // Not supported or needed for sjlj based unwinding
- DEBUG_PRINT_API("_Unwind_GetRegionStart(context=%p)\n", context);
- return 0;
-}
-
-//
-// Called by personality handler during phase 2 if a foreign exception is caught
-//
-EXPORT void _Unwind_DeleteException(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_DeleteException(ex_obj=%p)\n", exception_object);
- if ( exception_object->exception_cleanup != NULL )
- (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object);
-}
-
-
-//
-// Called by personality handler during phase 2 to get base address for data relative encodings
-//
-EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context* context)
-{
- // Not supported or needed for sjlj based unwinding
- DEBUG_PRINT_API("_Unwind_GetDataRelBase(context=%p)\n", context);
- ABORT("_Unwind_GetDataRelBase() not implemented");
-}
-
-
-//
-// Called by personality handler during phase 2 to get base address for text relative encodings
-//
-EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context* context)
-{
- // Not supported or needed for sjlj based unwinding
- DEBUG_PRINT_API("_Unwind_GetTextRelBase(context=%p)\n", context);
- ABORT("_Unwind_GetTextRelBase() not implemented");
-}
-
-
-
-//
-// Called by personality handler to get Call Frame Area for current frame
-//
-EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context* context)
-{
- DEBUG_PRINT_API("_Unwind_GetCFA(context=%p)\n", context);
- if ( context != NULL ) {
- _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t)context;
- // setjmp/longjmp based exceptions don't have a true CFA
- // the SP in the jmpbuf is the closest approximation
- return (uintptr_t)ufc->jbuf[2];
- }
- return 0;
-}
-
-
-
-
-
-#endif // __arm__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp b/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp
deleted file mode 100644
index 5e072b09c99..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp
+++ /dev/null
@@ -1,1313 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- UnwindCursor.hpp ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//
-// C++ interface to lower levels of libuwind
-//
-
-#ifndef __UNWINDCURSOR_HPP__
-#define __UNWINDCURSOR_HPP__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <stdarg.h>
-
-#include "libunwind.h"
-
-#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "DwarfInstructions.hpp"
-
-#include "AssemblyParser.hpp"
-#include "AssemblyInstructions.hpp"
-#include "RemoteProcInfo.hpp"
-#include "ArchDefaultUnwinder.hpp"
-#include "RemoteDebuggerDummyUnwinder.hpp"
-
-#include "CompactUnwinder.hpp"
-#include "InternalMacros.h"
-
-// private keymgr stuff
-#define KEYMGR_GCC3_DW2_OBJ_LIST 302
-extern "C" {
- extern void _keymgr_set_and_unlock_processwide_ptr(int key, void* ptr);
- extern void* _keymgr_get_and_lock_processwide_ptr(int key);
-};
-
-// undocumented libgcc "struct object"
-struct libgcc_object
-{
- void* start;
- void* unused1;
- void* unused2;
- void* fde;
- unsigned long encoding;
- void* fde_end;
- libgcc_object* next;
-};
-
-// undocumented libgcc "struct km_object_info" referenced by KEYMGR_GCC3_DW2_OBJ_LIST
-struct libgcc_object_info {
- struct libgcc_object* seen_objects;
- struct libgcc_object* unseen_objects;
- unsigned spare[2];
-};
-
-
-
-
-namespace lldb_private {
-
-#if !FOR_DYLD
-template <typename A>
-class DwarfFDECache
-{
-public:
- typedef typename A::pint_t pint_t;
- static pint_t findFDE(pint_t mh, pint_t pc);
- static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
- static void removeAllIn(pint_t mh);
- static void iterateCacheEntries(void (*func)(unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh));
-private:
- static void dyldUnloadHook(const struct mach_header* mh, intptr_t vmaddr_slide);
-
- struct entry { pint_t mh; pint_t ip_start; pint_t ip_end; pint_t fde; };
-
- // these fields are all static to avoid needing an initializer
- // there is only one instance of this class per process
- static pthread_rwlock_t fgLock;
- static bool fgRegisteredForDyldUnloads;
- // can't use std::vector<> here because this code must live in libSystem.dylib (which is below libstdc++.dylib)
- static entry* fgBuffer;
- static entry* fgBufferUsed;
- static entry* fgBufferEnd;
- static entry fgInitialBuffer[64];
-};
-
-template <typename A> typename DwarfFDECache<A>::entry* DwarfFDECache<A>::fgBuffer = fgInitialBuffer;
-template <typename A> typename DwarfFDECache<A>::entry* DwarfFDECache<A>::fgBufferUsed = fgInitialBuffer;
-template <typename A> typename DwarfFDECache<A>::entry* DwarfFDECache<A>::fgBufferEnd = &fgInitialBuffer[64];
-template <typename A> typename DwarfFDECache<A>::entry DwarfFDECache<A>::fgInitialBuffer[64];
-
-template <typename A>
-pthread_rwlock_t DwarfFDECache<A>::fgLock = PTHREAD_RWLOCK_INITIALIZER;
-
-template <typename A>
-bool DwarfFDECache<A>::fgRegisteredForDyldUnloads = false;
-
-
-template <typename A>
-typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc)
-{
- pint_t result = NULL;
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_rdlock(&fgLock));
- for(entry* p=fgBuffer; p < fgBufferUsed; ++p) {
- if ( (mh == p->mh) || (mh == 0) ) {
- if ( (p->ip_start <= pc) && (pc < p->ip_end) ) {
- result = p->fde;
- break;
- }
- }
- }
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_unlock(&fgLock));
- //fprintf(stderr, "DwarfFDECache::findFDE(mh=0x%llX, pc=0x%llX) => 0x%llX\n", (uint64_t)mh, (uint64_t)pc, (uint64_t)result);
- return result;
-}
-
-template <typename A>
-void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde)
-{
- //fprintf(stderr, "DwarfFDECache::add(mh=0x%llX, ip_start=0x%llX, ip_end=0x%llX, fde=0x%llX) pthread=%p\n",
- // (uint64_t)mh, (uint64_t)ip_start, (uint64_t)ip_end, (uint64_t)fde, pthread_self());
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_wrlock(&fgLock));
- if ( fgBufferUsed >= fgBufferEnd ) {
- int oldSize = fgBufferEnd - fgBuffer;
- int newSize = oldSize*4;
- entry* newBuffer = (entry*)malloc(newSize*sizeof(entry)); // can't use operator new in libSystem.dylib
- memcpy(newBuffer, fgBuffer, oldSize*sizeof(entry));
- //fprintf(stderr, "DwarfFDECache::add() growing buffer to %d\n", newSize);
- if ( fgBuffer != fgInitialBuffer )
- free(fgBuffer);
- fgBuffer = newBuffer;
- fgBufferUsed = &newBuffer[oldSize];
- fgBufferEnd = &newBuffer[newSize];
- }
- fgBufferUsed->mh = mh;
- fgBufferUsed->ip_start = ip_start;
- fgBufferUsed->ip_end = ip_end;
- fgBufferUsed->fde = fde;
- ++fgBufferUsed;
-#if !defined (SUPPORT_REMOTE_UNWINDING)
- if ( !fgRegisteredForDyldUnloads ) {
- _dyld_register_func_for_remove_image(&dyldUnloadHook);
- fgRegisteredForDyldUnloads = true;
- }
-#endif
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_unlock(&fgLock));
-}
-
-
-
-template <typename A>
-void DwarfFDECache<A>::removeAllIn(pint_t mh)
-{
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_wrlock(&fgLock));
- entry* d=fgBuffer;
- for(const entry* s=fgBuffer; s < fgBufferUsed; ++s) {
- if ( s->mh != mh ) {
- if ( d != s )
- *d = *s;
- ++d;
- }
- }
- fgBufferUsed = d;
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_unlock(&fgLock));
-}
-
-
-template <typename A>
-void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header* mh, intptr_t vmaddr_slide)
-{
-#if !defined (SUPPORT_REMOTE_UNWINDING)
- removeAllIn((pint_t)mh);
-#endif
-}
-
-template <typename A>
-void DwarfFDECache<A>::iterateCacheEntries(void (*func)(unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh))
-{
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_wrlock(&fgLock));
- for(entry* p=fgBuffer; p < fgBufferUsed; ++p) {
- (*func)(p->ip_start, p->ip_end, p->fde, p->mh);
- }
- DEBUG_LOG_NON_ZERO(::pthread_rwlock_unlock(&fgLock));
-}
-#endif // !FOR_DYLD
-
-
-
-
-#define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field))
-
-template <typename A>
-class UnwindSectionHeader {
-public:
- UnwindSectionHeader(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t version() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, version)); }
- uint32_t commonEncodingsArraySectionOffset() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, commonEncodingsArraySectionOffset)); }
- uint32_t commonEncodingsArrayCount() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, commonEncodingsArrayCount)); }
- uint32_t personalityArraySectionOffset() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, personalityArraySectionOffset)); }
- uint32_t personalityArrayCount() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, personalityArrayCount)); }
- uint32_t indexSectionOffset() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, indexSectionOffset)); }
- uint32_t indexCount() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_section_header, indexCount)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-template <typename A>
-class UnwindSectionIndexArray {
-public:
- UnwindSectionIndexArray(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t functionOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_section_header_index_entry, index, functionOffset)); }
- uint32_t secondLevelPagesSectionOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_section_header_index_entry, index, secondLevelPagesSectionOffset)); }
- uint32_t lsdaIndexArraySectionOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_section_header_index_entry, index, lsdaIndexArraySectionOffset)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A>
-class UnwindSectionRegularPageHeader {
-public:
- UnwindSectionRegularPageHeader(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t kind() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_regular_second_level_page_header, kind)); }
- uint16_t entryPageOffset() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_regular_second_level_page_header, entryPageOffset)); }
- uint16_t entryCount() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_regular_second_level_page_header, entryCount)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A>
-class UnwindSectionRegularArray {
-public:
- UnwindSectionRegularArray(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t functionOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_regular_second_level_entry, index, functionOffset)); }
- uint32_t encoding(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A>
-class UnwindSectionCompressedPageHeader {
-public:
- UnwindSectionCompressedPageHeader(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t kind() const INLINE { return fAddressSpace.get32(fAddr + offsetof(unwind_info_compressed_second_level_page_header, kind)); }
- uint16_t entryPageOffset() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_compressed_second_level_page_header, entryPageOffset)); }
- uint16_t entryCount() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_compressed_second_level_page_header, entryCount)); }
- uint16_t encodingsPageOffset() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_compressed_second_level_page_header, encodingsPageOffset)); }
- uint16_t encodingsCount() const INLINE { return fAddressSpace.get16(fAddr + offsetof(unwind_info_compressed_second_level_page_header, encodingsCount)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A>
-class UnwindSectionCompressedArray {
-public:
- UnwindSectionCompressedArray(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t functionOffset(int index) const INLINE { return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET( fAddressSpace.get32(fAddr + index*sizeof(uint32_t)) ); }
- uint16_t encodingIndex(int index) const INLINE { return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX( fAddressSpace.get32(fAddr + index*sizeof(uint32_t)) ); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A>
-class UnwindSectionLsdaArray {
-public:
- UnwindSectionLsdaArray(A& addressSpace, typename A::pint_t addr) : fAddressSpace(addressSpace), fAddr(addr) {}
-
- uint32_t functionOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, index, functionOffset)); }
- int32_t lsdaOffset(int index) const INLINE { return fAddressSpace.get32(fAddr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, index, lsdaOffset)); }
-private:
- A& fAddressSpace;
- typename A::pint_t fAddr;
-};
-
-
-template <typename A, typename R>
-class UnwindCursor
-{
-public:
- UnwindCursor(unw_context_t* context, A& as);
- virtual ~UnwindCursor() {}
- virtual bool validReg(int);
- virtual uint64_t getReg(int);
- virtual int getReg(int, uint64_t*);
- virtual int setReg(int, uint64_t);
- virtual bool validFloatReg(int);
- virtual double getFloatReg(int);
- virtual int getFloatReg(int, double*);
- virtual int setFloatReg(int, double);
- virtual int step();
- virtual void getInfo(unw_proc_info_t*);
- virtual void jumpto();
- virtual const char* getRegisterName(int num);
- virtual bool isSignalFrame();
- virtual bool getFunctionName(char* buf, size_t bufLen, unw_word_t* offset);
- virtual void setInfoBasedOnIPRegister(bool isReturnAddress=false);
-
- void operator delete(void* p, size_t size) {}
-
-protected:
- typedef typename A::pint_t pint_t;
- typedef uint32_t EncodedUnwindInfo;
-
- virtual bool getInfoFromCompactEncodingSection(pint_t pc, pint_t mh, pint_t unwindSectionStart);
- virtual bool getInfoFromDwarfSection(pint_t pc, pint_t mh, pint_t ehSectionStart, uint32_t sectionLength, uint32_t sectionOffsetOfFDE);
-
- virtual int stepWithDwarfFDE()
- { return DwarfInstructions<A,R>::stepWithDwarf(fAddressSpace, this->getReg(UNW_REG_IP), fInfo.unwind_info, fRegisters); }
-
- virtual int stepWithCompactEncoding() { R dummy; return stepWithCompactEncoding(dummy); }
- int stepWithCompactEncoding(Registers_x86_64&)
- { return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(fInfo.format, fInfo.start_ip, fAddressSpace, fRegisters); }
- int stepWithCompactEncoding(Registers_x86&)
- { return CompactUnwinder_x86<A>::stepWithCompactEncoding(fInfo.format, fInfo.start_ip, fAddressSpace, fRegisters); }
-
-#if FOR_DYLD
- #if __ppc__
- virtual bool mustUseDwarf() const { return true; }
- #else
- virtual bool mustUseDwarf() const { return false; }
- #endif
-#else
- virtual bool mustUseDwarf() const { R dummy; uint32_t offset; return dwarfWithOffset(dummy, offset); }
-#endif
-
- virtual bool dwarfWithOffset(uint32_t& offset) const { R dummy; return dwarfWithOffset(dummy, offset); }
- virtual bool dwarfWithOffset(Registers_x86_64&, uint32_t& offset) const {
- if ( (fInfo.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF ) {
- offset = (fInfo.format & UNWIND_X86_64_DWARF_SECTION_OFFSET);
- return true;
- }
-#if SUPPORT_OLD_BINARIES
- if ( (fInfo.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_COMPATIBILITY ) {
- if ( (fInfo.format & UNWIND_X86_64_CASE_MASK) == UNWIND_X86_64_UNWIND_REQUIRES_DWARF ) {
- offset = 0;
- return true;
- }
- }
-#endif
- return false;
- }
- virtual bool dwarfWithOffset(Registers_x86&, uint32_t& offset) const {
- if ( (fInfo.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF ) {
- offset = (fInfo.format & UNWIND_X86_DWARF_SECTION_OFFSET);
- return true;
- }
-#if SUPPORT_OLD_BINARIES
- if ( (fInfo.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_COMPATIBILITY ) {
- if ( (fInfo.format & UNWIND_X86_CASE_MASK) == UNWIND_X86_UNWIND_REQUIRES_DWARF ) {
- offset = 0;
- return true;
- }
- }
-#endif
- return false;
- }
-
- virtual compact_unwind_encoding_t dwarfEncoding() const { R dummy; return dwarfEncoding(dummy); }
- virtual compact_unwind_encoding_t dwarfEncoding(Registers_x86_64&) const { return UNWIND_X86_64_MODE_DWARF; }
- virtual compact_unwind_encoding_t dwarfEncoding(Registers_x86&) const { return UNWIND_X86_MODE_DWARF; }
-
- unw_proc_info_t fInfo;
- R fRegisters;
- A& fAddressSpace;
- bool fUnwindInfoMissing;
- bool fIsSignalFrame;
-};
-
-typedef UnwindCursor<LocalAddressSpace,Registers_x86> AbstractUnwindCursor;
-
-template <typename A, typename R>
-UnwindCursor<A,R>::UnwindCursor(unw_context_t* context, A& as)
- : fRegisters(context), fAddressSpace(as), fUnwindInfoMissing(false), fIsSignalFrame(false)
-{
- COMPILE_TIME_ASSERT( sizeof(UnwindCursor<A,R>) < sizeof(unw_cursor_t) );
-
- bzero(&fInfo, sizeof(fInfo));
-}
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::validReg(int regNum)
-{
- return fRegisters.validRegister(regNum);
-}
-
-template <typename A, typename R>
-uint64_t UnwindCursor<A,R>::getReg(int regNum)
-{
- return fRegisters.getRegister(regNum);
-}
-
-template <typename A, typename R>
-int UnwindCursor<A,R>::getReg(int regNum, uint64_t *valp)
-{
- *valp = fRegisters.getRegister(regNum);
- return UNW_ESUCCESS;
-}
-
-template <typename A, typename R>
-int UnwindCursor<A,R>::setReg(int regNum, uint64_t value)
-{
- fRegisters.setRegister(regNum, value);
- return UNW_ESUCCESS;
-}
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::validFloatReg(int regNum)
-{
- return fRegisters.validFloatRegister(regNum);
-}
-
-template <typename A, typename R>
-double UnwindCursor<A,R>::getFloatReg(int regNum)
-{
- return fRegisters.getFloatRegister(regNum);
-}
-
-template <typename A, typename R>
-int UnwindCursor<A,R>::getFloatReg(int regNum, double *valp)
-{
- *valp = fRegisters.getFloatRegister(regNum);
- return UNW_ESUCCESS;
-}
-
-template <typename A, typename R>
-int UnwindCursor<A,R>::setFloatReg(int regNum, double value)
-{
- fRegisters.setFloatRegister(regNum, value);
- return UNW_ESUCCESS;
-}
-
-template <typename A, typename R>
-void UnwindCursor<A,R>::jumpto()
-{
-#if !defined (SUPPORT_REMOTE_UNWINDING)
- fRegisters.jumpto();
-#endif
-}
-
-template <typename A, typename R>
-const char* UnwindCursor<A,R>::getRegisterName(int regNum)
-{
- return fRegisters.getRegisterName(regNum);
-}
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::isSignalFrame()
-{
- return fIsSignalFrame;
-}
-
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::getInfoFromDwarfSection(pint_t pc, pint_t mh, pint_t ehSectionStart, uint32_t sectionLength, uint32_t sectionOffsetOfFDE)
-{
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- typename CFI_Parser<A>::CIE_Info cieInfo;
- bool foundFDE = false;
- bool foundInCache = false;
- // if compact encoding table gave offset into dwarf section, go directly there
- if ( sectionOffsetOfFDE != 0 ) {
- foundFDE = CFI_Parser<A>::findFDE(fAddressSpace, pc, ehSectionStart, sectionLength, ehSectionStart+sectionOffsetOfFDE, &fdeInfo, &cieInfo);
- }
-#if !FOR_DYLD
- if ( !foundFDE ) {
- // otherwise, search cache of previously found FDEs
- pint_t cachedFDE = DwarfFDECache<A>::findFDE(mh, pc);
- //fprintf(stderr, "getInfoFromDwarfSection(pc=0x%llX) cachedFDE=0x%llX\n", (uint64_t)pc, (uint64_t)cachedFDE);
- if ( cachedFDE != 0 ) {
- foundFDE = CFI_Parser<A>::findFDE(fAddressSpace, pc, ehSectionStart, sectionLength, cachedFDE, &fdeInfo, &cieInfo);
- foundInCache = foundFDE;
- //fprintf(stderr, "cachedFDE=0x%llX, foundInCache=%d\n", (uint64_t)cachedFDE, foundInCache);
- }
- }
-#endif
- if ( !foundFDE ) {
- // still not found, do full scan of __eh_frame section
- foundFDE = CFI_Parser<A>::findFDE(fAddressSpace, pc, ehSectionStart, sectionLength, 0, &fdeInfo, &cieInfo);
- }
- if ( foundFDE ) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if ( CFI_Parser<A>::parseFDEInstructions(fAddressSpace, fdeInfo, cieInfo, pc, &prolog) ) {
- // save off parsed FDE info
- fInfo.start_ip = fdeInfo.pcStart;
- fInfo.end_ip = fdeInfo.pcEnd;
- fInfo.lsda = fdeInfo.lsda;
- fInfo.handler = cieInfo.personality;
- fInfo.gp = prolog.spExtraArgSize; // some frameless functions need SP altered when resuming in function
- fInfo.flags = 0;
- fInfo.format = dwarfEncoding();
- fInfo.unwind_info = fdeInfo.fdeStart;
- fInfo.unwind_info_size = fdeInfo.fdeLength;
- fInfo.extra = (unw_word_t)mh;
- if ( !foundInCache && (sectionOffsetOfFDE == 0) ) {
- // don't add to cache entries the compact encoding table can find quickly
- //fprintf(stderr, "getInfoFromDwarfSection(pc=0x%0llX), mh=0x%llX, start_ip=0x%0llX, fde=0x%0llX, personality=0x%0llX\n",
- // (uint64_t)pc, (uint64_t)mh, fInfo.start_ip, fInfo.unwind_info, fInfo.handler);
-#if !FOR_DYLD
- DwarfFDECache<A>::add(mh, fdeInfo.pcStart, fdeInfo.pcEnd, fdeInfo.fdeStart);
-#endif
- }
- return true;
- }
- }
- //DEBUG_MESSAGE("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc);
- return false;
-}
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::getInfoFromCompactEncodingSection(pint_t pc, pint_t mh, pint_t unwindSectionStart)
-{
- const bool log = false;
- if ( log ) fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n", (uint64_t)pc, (uint64_t)mh);
-
- const UnwindSectionHeader<A> sectionHeader(fAddressSpace, unwindSectionStart);
- if ( sectionHeader.version() != UNWIND_SECTION_VERSION )
- return false;
-
- // do a binary search of top level index to find page with unwind info
- uint32_t targetFunctionOffset = pc - mh;
- const UnwindSectionIndexArray<A> topIndex(fAddressSpace, unwindSectionStart + sectionHeader.indexSectionOffset());
- uint32_t low = 0;
- uint32_t high = sectionHeader.indexCount();
- const uint32_t last_section_header = high - 1;
- while ( low < high ) {
- uint32_t mid = (low + high)/2;
- //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n", mid, low, high, topIndex.functionOffset(mid));
- if ( topIndex.functionOffset(mid) <= targetFunctionOffset ) {
- if ( (mid == last_section_header) || (topIndex.functionOffset(mid+1) > targetFunctionOffset) ) {
- low = mid;
- break;
- }
- else {
- low = mid+1;
- }
- }
- else {
- high = mid;
- }
- }
- const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low);
- const uint32_t firstLevelNextPageFunctionOffset = topIndex.functionOffset(low+1);
- const pint_t secondLevelAddr = unwindSectionStart+topIndex.secondLevelPagesSectionOffset(low);
- const pint_t lsdaArrayStartAddr = unwindSectionStart+topIndex.lsdaIndexArraySectionOffset(low);
- const pint_t lsdaArrayEndAddr = unwindSectionStart+topIndex.lsdaIndexArraySectionOffset(low+1);
- if ( log ) fprintf(stderr, "\tfirst level search for result index=%d to secondLevelAddr=0x%llX\n",
- low, (uint64_t)secondLevelAddr);
- // do a binary search of second level page index
- uint32_t encoding = 0;
- pint_t funcStart = 0;
- pint_t funcEnd = 0;
- pint_t lsda = 0;
- pint_t personality = 0;
- uint32_t pageKind = fAddressSpace.get32(secondLevelAddr);
- if ( pageKind == UNWIND_SECOND_LEVEL_REGULAR ) {
- // regular page
- UnwindSectionRegularPageHeader<A> pageHeader(fAddressSpace, secondLevelAddr);
- UnwindSectionRegularArray<A> pageIndex(fAddressSpace, secondLevelAddr + pageHeader.entryPageOffset());
- // binary search looks for entry with e where index[e].offset <= pc < index[e+1].offset
- if ( log ) fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in regular page starting at secondLevelAddr=0x%llX\n",
- (uint64_t)targetFunctionOffset, (uint64_t)secondLevelAddr);
- low = 0;
- high = pageHeader.entryCount();
- while ( low < high ) {
- uint32_t mid = (low + high)/2;
- if ( pageIndex.functionOffset(mid) <= targetFunctionOffset ) {
- if ( mid == (uint32_t)(pageHeader.entryCount()-1) ) {
- // at end of table
- low = mid;
- funcEnd = firstLevelNextPageFunctionOffset + mh;
- break;
- }
- else if ( pageIndex.functionOffset(mid+1) > targetFunctionOffset ) {
- // next is too big, so we found it
- low = mid;
- funcEnd = pageIndex.functionOffset(low+1) + mh;
- break;
- }
- else {
- low = mid+1;
- }
- }
- else {
- high = mid;
- }
- }
- encoding = pageIndex.encoding(low);
- funcStart = pageIndex.functionOffset(low) + mh;
- if ( pc < funcStart ) {
- if ( log ) fprintf(stderr, "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", (uint64_t)pc, (uint64_t)funcStart, (uint64_t)funcEnd);
- return false;
- }
- if ( pc > funcEnd ) {
- if ( log ) fprintf(stderr, "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", (uint64_t)pc, (uint64_t)funcStart, (uint64_t)funcEnd);
- return false;
- }
- }
- else if ( pageKind == UNWIND_SECOND_LEVEL_COMPRESSED ) {
- // compressed page
- UnwindSectionCompressedPageHeader<A> pageHeader(fAddressSpace, secondLevelAddr);
- UnwindSectionCompressedArray<A> pageIndex(fAddressSpace, secondLevelAddr + pageHeader.entryPageOffset());
- const uint32_t targetFunctionPageOffset = targetFunctionOffset - firstLevelFunctionOffset;
- // binary search looks for entry with e where index[e].offset <= pc < index[e+1].offset
- if ( log ) fprintf(stderr, "\tbinary search of compressed page starting at secondLevelAddr=0x%llX\n", (uint64_t)secondLevelAddr);
- low = 0;
- const uint32_t last_page_header = pageHeader.entryCount() - 1;
- high = pageHeader.entryCount();
- while ( low < high ) {
- uint32_t mid = (low + high)/2;
- if ( pageIndex.functionOffset(mid) <= targetFunctionPageOffset ) {
- if ( (mid == last_page_header) || (pageIndex.functionOffset(mid+1) > targetFunctionPageOffset) ) {
- low = mid;
- break;
- }
- else {
- low = mid+1;
- }
- }
- else {
- high = mid;
- }
- }
- funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset + mh;
- if ( low < last_page_header )
- funcEnd = pageIndex.functionOffset(low+1) + firstLevelFunctionOffset + mh;
- else
- funcEnd = firstLevelNextPageFunctionOffset + mh;
- if ( pc < funcStart ) {
- DEBUG_MESSAGE("malformed __unwind_info, pc=0x%llX not in second level compressed unwind table. funcStart=0x%llX\n", (uint64_t)pc, (uint64_t)funcStart);
- return false;
- }
- if ( pc > funcEnd ) {
- DEBUG_MESSAGE("malformed __unwind_info, pc=0x%llX not in second level compressed unwind table. funcEnd=0x%llX\n", (uint64_t)pc, (uint64_t)funcEnd);
- return false;
- }
- uint16_t encodingIndex = pageIndex.encodingIndex(low);
- if ( encodingIndex < sectionHeader.commonEncodingsArrayCount() ) {
- // encoding is in common table in section header
- encoding = fAddressSpace.get32(unwindSectionStart+sectionHeader.commonEncodingsArraySectionOffset()+encodingIndex*sizeof(uint32_t));
- }
- else {
- // encoding is in page specific table
- uint16_t pageEncodingIndex = encodingIndex-sectionHeader.commonEncodingsArrayCount();
- encoding = fAddressSpace.get32(secondLevelAddr+pageHeader.encodingsPageOffset()+pageEncodingIndex*sizeof(uint32_t));
- }
- }
- else {
- DEBUG_MESSAGE("malformed __unwind_info at 0x%0llX bad second level page\n", (uint64_t)unwindSectionStart);
- return false;
- }
-
- // look up LSDA, if encoding says function has one
- if ( encoding & UNWIND_HAS_LSDA ) {
- UnwindSectionLsdaArray<A> lsdaIndex(fAddressSpace, lsdaArrayStartAddr);
- uint32_t funcStartOffset = funcStart - mh;
- low = 0;
- high = (lsdaArrayEndAddr-lsdaArrayStartAddr)/sizeof(unwind_info_section_header_lsda_index_entry);
- // binary search looks for entry with exact match for functionOffset
- if ( log ) fprintf(stderr, "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n", funcStartOffset);
- while ( low < high ) {
- uint32_t mid = (low + high)/2;
- if ( lsdaIndex.functionOffset(mid) == funcStartOffset ) {
- lsda = lsdaIndex.lsdaOffset(mid) + mh;
- break;
- }
- else if ( lsdaIndex.functionOffset(mid) < funcStartOffset ) {
- low = mid+1;
- }
- else {
- high = mid;
- }
- }
- if ( lsda == 0 ) {
- DEBUG_MESSAGE("found encoding 0x%08X with HAS_LSDA bit set for pc=0x%0llX, but lsda table has no entry\n", encoding, (uint64_t)pc);
- return false;
- }
- }
-
- // extact personality routine, if encoding says function has one
- uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >> (__builtin_ctz(UNWIND_PERSONALITY_MASK));
- if ( personalityIndex != 0 ) {
- --personalityIndex; // change 1-based to zero-based index
- if ( personalityIndex > sectionHeader.personalityArrayCount() ) {
- DEBUG_MESSAGE("found encoding 0x%08X with personality index %d, but personality table has only %d entires\n",
- encoding, personalityIndex, sectionHeader.personalityArrayCount());
- return false;
- }
- int32_t personalityDelta = fAddressSpace.get32(unwindSectionStart+sectionHeader.personalityArraySectionOffset()+personalityIndex*sizeof(uint32_t));
- pint_t personalityPointer = personalityDelta + mh;
- personality = fAddressSpace.getP(personalityPointer);
- if (log ) fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), personalityDelta=0x%08X, personality=0x%08llX\n",
- (uint64_t)pc, personalityDelta, (uint64_t)personality);
- }
-
- if (log ) fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
- (uint64_t)pc, encoding, (uint64_t)lsda, (uint64_t)funcStart);
- fInfo.start_ip = funcStart;
- fInfo.end_ip = funcEnd;
- fInfo.lsda = lsda;
- fInfo.handler = personality;
- fInfo.gp = 0;
- fInfo.flags = 0;
- fInfo.format = encoding;
- fInfo.unwind_info = 0;
- fInfo.unwind_info_size = 0;
- fInfo.extra = mh;
- return true;
-}
-
-template <typename A, typename R>
-void UnwindCursor<A,R>::setInfoBasedOnIPRegister(bool isReturnAddress)
-{
- pint_t pc = this->getReg(UNW_REG_IP);
-
- // if the last line of a function is a "throw" the compile sometimes
- // emits no instructions after the call to __cxa_throw. This means
- // the return address is actually the start of the next function.
- // To disambiguate this, back up the pc when we know it is a return
- // address.
- if ( isReturnAddress )
- --pc;
-
- // ask address space object to find unwind sections for this pc
- pint_t mh;
- pint_t dwarfStart;
- pint_t dwarfLength;
- pint_t compactStart;
- if ( fAddressSpace.findUnwindSections(pc, mh, dwarfStart, dwarfLength, compactStart) ) {
- // if there is a compact unwind encoding table, look there first
- if ( compactStart != 0 ) {
- if ( this->getInfoFromCompactEncodingSection(pc, mh, compactStart) ) {
-#if !FOR_DYLD
- // found info in table, done unless encoding says to use dwarf
- uint32_t offsetInDwarfSection;
- if ( (dwarfStart != 0) && dwarfWithOffset(offsetInDwarfSection) ) {
- if ( this->getInfoFromDwarfSection(pc, mh, dwarfStart, dwarfLength, offsetInDwarfSection) ) {
- // found info in dwarf, done
- return;
- }
- }
-#endif
- // if unwind table has entry, but entry says there is no unwind info, note that
- if ( fInfo.format == 0 )
- fUnwindInfoMissing = true;
-
- // old compact encoding
- if ( !mustUseDwarf() ) {
- return;
- }
- }
- }
-#if !FOR_DYLD || __ppc__
- // if there is dwarf unwind info, look there next
- if ( dwarfStart != 0 ) {
- if ( this->getInfoFromDwarfSection(pc, mh, dwarfStart, dwarfLength, 0) ) {
- // found info in dwarf, done
- return;
- }
- }
-#endif
- }
-
-#if !FOR_DYLD
- // the PC is not in code loaded by dyld, look through __register_frame() registered FDEs
- pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
- if ( cachedFDE != 0 ) {
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- typename CFI_Parser<A>::CIE_Info cieInfo;
- const char* msg = CFI_Parser<A>::decodeFDE(fAddressSpace, cachedFDE, &fdeInfo, &cieInfo);
- if ( msg == NULL ) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if ( CFI_Parser<A>::parseFDEInstructions(fAddressSpace, fdeInfo, cieInfo, pc, &prolog) ) {
- // save off parsed FDE info
- fInfo.start_ip = fdeInfo.pcStart;
- fInfo.end_ip = fdeInfo.pcEnd;
- fInfo.lsda = fdeInfo.lsda;
- fInfo.handler = cieInfo.personality;
- fInfo.gp = prolog.spExtraArgSize; // some frameless functions need SP altered when resuming in function
- fInfo.flags = 0;
- fInfo.format = dwarfEncoding();
- fInfo.unwind_info = fdeInfo.fdeStart;
- fInfo.unwind_info_size = fdeInfo.fdeLength;
- fInfo.extra = 0;
- return;
- }
- }
- }
-
-#if !defined (SUPPORT_REMOTE_UNWINDING)
- // lastly check for old style keymgr registration of dynamically generated FDEs
-
- // acquire exclusive access to libgcc_object_info
- libgcc_object_info* head = (libgcc_object_info*)_keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
- if ( head != NULL ) {
- // look at each FDE in keymgr
- for (libgcc_object* ob = head->unseen_objects; ob != NULL; ob = ob->next) {
- typename CFI_Parser<A>::FDE_Info fdeInfo;
- typename CFI_Parser<A>::CIE_Info cieInfo;
- const char* msg = CFI_Parser<A>::decodeFDE(fAddressSpace, (pint_t)ob->fde, &fdeInfo, &cieInfo);
- if ( msg == NULL ) {
- // see if this FDE is for a function that includes the pc we are looking for
- if ( (fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd) ) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if ( CFI_Parser<A>::parseFDEInstructions(fAddressSpace, fdeInfo, cieInfo, pc, &prolog) ) {
- // save off parsed FDE info
- fInfo.start_ip = fdeInfo.pcStart;
- fInfo.end_ip = fdeInfo.pcEnd;
- fInfo.lsda = fdeInfo.lsda;
- fInfo.handler = cieInfo.personality;
- fInfo.gp = prolog.spExtraArgSize; // some frameless functions need SP altered when resuming in function
- fInfo.flags = 0;
- fInfo.format = dwarfEncoding();
- fInfo.unwind_info = fdeInfo.fdeStart;
- fInfo.unwind_info_size = fdeInfo.fdeLength;
- fInfo.extra = 0;
- _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
- return;
- }
- }
- }
- }
- }
- // release libgcc_object_info
- _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
-#endif // !SUPPORT_REMOTE_UNWINDING
-
-#endif // !FOR_DYLD
-
- // no unwind info, flag that we can't reliable unwind
- fUnwindInfoMissing = true;
-}
-
-
-template <typename A, typename R>
-int UnwindCursor<A,R>::step()
-{
- // bottom of stack is defined as when no more unwind info
- if ( fUnwindInfoMissing )
- return UNW_STEP_END;
-
- // apply unwinding to register set
- int result;
- if ( this->mustUseDwarf() )
- result = this->stepWithDwarfFDE();
- else
- result = this->stepWithCompactEncoding();
-
- // update info based on new PC
- if ( result == UNW_STEP_SUCCESS ) {
- this->setInfoBasedOnIPRegister(true);
- if ( fUnwindInfoMissing )
- return UNW_STEP_END;
- }
-
- return result;
-}
-
-
-template <typename A, typename R>
-void UnwindCursor<A,R>::getInfo(unw_proc_info_t* info)
-{
- *info = fInfo;
-}
-
-
-template <typename A, typename R>
-bool UnwindCursor<A,R>::getFunctionName(char* buf, size_t bufLen, unw_word_t* offset)
-{
- return fAddressSpace.findFunctionName(this->getReg(UNW_REG_IP), buf, bufLen, offset);
-}
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-template <typename A, typename R>
-class RemoteUnwindCursor : UnwindCursor<A,R>
-{
-public:
- using UnwindCursor<A,R>::getReg;
- using UnwindCursor<A,R>::getFloatReg;
-
- typedef typename A::pint_t pint_t;
- RemoteUnwindCursor(A& as, unw_context_t* regs, void* arg);
- virtual bool validReg(int);
- virtual int getReg(int r, uint64_t*);
- virtual int setReg(int, uint64_t);
- virtual bool validFloatReg(int);
- virtual int getFloatReg(int, double*);
- virtual int setFloatReg(int, double);
- virtual const char* getRegisterName(int);
- virtual int step();
- virtual void setRemoteContext(void*);
- virtual bool remoteUnwindCursor () const {return this->fAddressSpace.getRemoteProcInfo() != NULL; }
- virtual int endOfPrologueInsns(unw_word_t, unw_word_t, unw_word_t*);
- void operator delete(void* p, size_t size) {}
-private:
- virtual bool caller_regno_to_unwind_regno (int, int&);
-
- bool fIsLeafFrame;
- bool fIsFirstFrame;
- void* fArg;
-};
-
-typedef RemoteUnwindCursor<LocalAddressSpace,Registers_x86_64> AbstractRemoteUnwindCursor;
-
-template <typename A, typename R>
-RemoteUnwindCursor<A,R>::RemoteUnwindCursor(A& as, unw_context_t* regs, void* arg)
- : UnwindCursor<A,R>::UnwindCursor(regs, as), fIsLeafFrame(false), fIsFirstFrame (false), fArg(arg)
-{
- COMPILE_TIME_ASSERT( sizeof(RemoteUnwindCursor<A,R>) < sizeof(unw_cursor_t) );
-}
-
-template <typename A, typename R>
-bool RemoteUnwindCursor<A,R>::validReg(int r)
-{
- int unwind_regno;
- if (!caller_regno_to_unwind_regno(r, unwind_regno))
- return false;
- return UnwindCursor<A,R>::fRegisters.validRegister(unwind_regno);
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::getReg(int regNum, uint64_t *valp)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo ();
- if (procinfo == NULL) {
- ABORT("getRemoteReg called with a local unwind, use getReg instead.");
- }
-
- RemoteRegisterMap *regmap = procinfo->getRegisterMap ();
- int unwind_regno;
- if (regmap->caller_regno_to_unwind_regno (regNum, unwind_regno) == false)
- return UNW_EBADREG;
- regNum = unwind_regno;
-
- // we always return nonvolatile registers. If we have the entire register state available
- // for this frame then we can return any register requested.
- if (regmap->nonvolatile_reg_p (regNum) == true || fIsLeafFrame == true) {
- return this->UnwindCursor<A,R>::getReg (unwind_regno, valp);
- }
- return UNW_EREGUNAVAILABLE;
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::setReg(int regNum, uint64_t val)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo ();
- if (procinfo == NULL) {
- ABORT("setRemoteReg called with a local unwind, use setReg instead.");
- }
-
- RemoteRegisterMap *regmap = procinfo->getRegisterMap ();
- int unwind_regno;
- if (regmap->caller_regno_to_unwind_regno (regNum, unwind_regno) == false)
- return UNW_EBADREG;
- regNum = unwind_regno;
-
- // Only allow the registers to be set if the unwind cursor is pointing to the
- // first frame. We need to track where registers were retrieved from in memory
- // in every other frame. Until then, we prohibit register setting in all but
- // the first frame.
- if (fIsFirstFrame) {
- return this->setReg(unwind_regno, val);
- }
- return UNW_EREGUNAVAILABLE;
-}
-
-template <typename A, typename R>
-bool RemoteUnwindCursor<A,R>::validFloatReg(int r)
-{
- int unwind_regno;
- if (!caller_regno_to_unwind_regno(r, unwind_regno))
- return false;
- return UnwindCursor<A,R>::fRegisters.validFloatRegister(unwind_regno);
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::getFloatReg(int regNum, double *valp)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo ();
- if (procinfo == NULL) {
- ABORT("getRemoteReg called with a local unwind, use getReg instead.");
- }
-
- RemoteRegisterMap *regmap = procinfo->getRegisterMap ();
- int unwind_regno;
- if (regmap->caller_regno_to_unwind_regno (regNum, unwind_regno) == false)
- return UNW_EBADREG;
- regNum = unwind_regno;
-
- // we always return nonvolatile registers. If we have the entire register state available
- // for this frame then we can return any register requested.
- if (regmap->nonvolatile_reg_p (regNum) == true || fIsLeafFrame == true) {
- return this->UnwindCursor<A,R>::getFloatReg (unwind_regno, valp);
- }
- return UNW_EREGUNAVAILABLE;
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::setFloatReg(int regNum, double val)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo ();
- if (procinfo == NULL) {
- ABORT("setRemoteReg called with a local unwind, use setReg instead.");
- }
-
- RemoteRegisterMap *regmap = procinfo->getRegisterMap ();
- int unwind_regno;
- if (regmap->caller_regno_to_unwind_regno (regNum, unwind_regno) == false)
- return UNW_EBADREG;
- regNum = unwind_regno;
-
- // Only allow the registers to be set if the unwind cursor is pointing to the
- // first frame. We need to track where registers were retrieved from in memory
- // in every other frame. Until then, we prohibit register setting in all but
- // the first frame.
- if (fIsFirstFrame) {
- return this->setFloatReg(unwind_regno, val);
- }
- return UNW_EREGUNAVAILABLE;
-}
-
-
-template <typename A, typename R>
-const char* RemoteUnwindCursor<A,R>::getRegisterName(int r)
-{
- int t;
- if (!this->caller_regno_to_unwind_regno(r, t))
- return NULL;
- r = t;
- return this->UnwindCursor<A,R>::getRegisterName(r);
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::step()
-{
- pint_t pc = this->UnwindCursor<A,R>::getReg(UNW_REG_IP);
- pint_t sp = this->UnwindCursor<A,R>::getReg(UNW_REG_SP);
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo();
- bool frame_is_sigtramp = false;
- bool frame_is_inferior_function_call_dummy = false;
-
- if (procinfo == NULL) {
- ABORT("stepRemote called with local unwind, use step() instead.");
- return UNW_EUNSPEC;
- }
- struct timeval *step_remote = procinfo->timestamp_start();
- procinfo->logVerbose ("stepRemote stepping out of frame with pc value 0x%llx", pc);
-
- // We'll be off of the first frame once we finish this step.
- fIsFirstFrame = false;
-
- if (UnwindCursor<A,R>::fAddressSpace.accessors()
- && UnwindCursor<A,R>::fAddressSpace.accessors()->proc_is_sigtramp != NULL
- && UnwindCursor<A,R>::fAddressSpace.accessors()->proc_is_sigtramp (procinfo->wrap(), pc, fArg)) {
- frame_is_sigtramp = true;
- }
- if (UnwindCursor<A,R>::fAddressSpace.accessors()
- && UnwindCursor<A,R>::fAddressSpace.accessors()->proc_is_inferior_function_call != NULL
- && UnwindCursor<A,R>::fAddressSpace.accessors()->proc_is_inferior_function_call (procinfo->wrap(), pc, sp, fArg)) {
- frame_is_inferior_function_call_dummy = true;
- }
-
- // If the function we're unwinding can't be a leaf function,
- // use the eh_frame or compact unwind info if possible.
- // The caller should pass couldBeLeafFunc == 0 on the first step of a new context
- // but we can't trust them in that.
-
- if ((fIsLeafFrame == false && frame_is_inferior_function_call_dummy == false)
- || frame_is_sigtramp) {
- R saved_registers(UnwindCursor<A,R>::fRegisters);
- this->setInfoBasedOnIPRegister(true);
- // bottom of stack is defined as when no more unwind info
- if ( !UnwindCursor<A,R>::fUnwindInfoMissing ) {
- int result;
- const char *method;
- if ( this->mustUseDwarf() ) {
- result = this->stepWithDwarfFDE();
- method = "dwarf";
- }
- else {
- result = this->stepWithCompactEncoding();
- method = "compact unwind";
- }
- if ( result == UNW_STEP_SUCCESS ) {
- procinfo->logInfo ("Stepped via %s", method);
- procinfo->timestamp_stop (step_remote, "stepRemote");
- if (frame_is_sigtramp)
- fIsLeafFrame = true;
- return result;
- }
- }
- UnwindCursor<A,R>::fRegisters = saved_registers;
- }
-
- if (frame_is_sigtramp || frame_is_inferior_function_call_dummy)
- fIsLeafFrame = true; // this will be true once we complete this stepRemote()
- else
- fIsLeafFrame = false;
-
- if (frame_is_inferior_function_call_dummy) {
- if (stepOutOfDebuggerDummyFrame (UnwindCursor<A,R>::fAddressSpace, UnwindCursor<A,R>::fRegisters, procinfo, pc, sp, fArg) == UNW_STEP_SUCCESS) {
- procinfo->logInfo ("Stepped via stepOutOfDebuggerDummyFrame");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return UNW_STEP_SUCCESS;
- }
- }
-
- // If we haven't already seen this function we'll need to get the function bounds via
- // eh frame info (if available) - it's the most accurate function bounds in a
- // stripped binary. After that we'll ask the driver program (via the get_proc_bounds accessor).
-
- if (procinfo->haveProfile (pc) == false) {
-
- uint64_t text_start, text_end, eh_frame_start, eh_frame_len, compact_unwind_start, mh;
- uint64_t start_addr, end_addr;
- if (pc == 0) {
- int ret = stepByArchitectureDefault (UnwindCursor<A,R>::fAddressSpace, UnwindCursor<A,R>::fRegisters, pc);
- procinfo->logInfo ("Stepped via stepByArchitectureDefault");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return ret;
- }
-
- // If the address is not contained in any image's address range either we've walked off
- // the stack into random memory or we're backtracing through jit'ed code on the heap.
- // Let's assume the latter and follow the architecture's default stack walking scheme.
-
- if (!procinfo->getImageAddresses (pc, mh, text_start, text_end, eh_frame_start, eh_frame_len, compact_unwind_start, fArg)) {
- int ret = stepByArchitectureDefault (UnwindCursor<A,R>::fAddressSpace, UnwindCursor<A,R>::fRegisters, pc);
- procinfo->logInfo ("Stepped via stepByArchitectureDefault");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return ret;
- }
- if (procinfo->haveFuncBounds (mh) == false) {
- struct timeval *get_func_bounds = procinfo->timestamp_start();
- std::vector<FuncBounds> func_bounds;
- // CFI entries are usually around 38 bytes but under-estimate a bit
- // because we're not distinguishing between CIEs and FDEs.
- if (eh_frame_len > 0)
- func_bounds.reserve (eh_frame_len / 16);
- if (procinfo->getCachingPolicy() != UNW_CACHE_NONE) {
- // cache the entire eh frame section - we'll need to read the whole
- // thing anyway so we might as well save it.
- uint8_t *eh_buf = (uint8_t *)malloc (eh_frame_len);
- if (UnwindCursor<A,R>::fAddressSpace.getBytes (eh_frame_start, eh_frame_len, eh_buf) == 0)
- {
- free (eh_buf);
- return UNW_EUNSPEC;
- }
- RemoteMemoryBlob *ehmem = new RemoteMemoryBlob(eh_buf, free, eh_frame_start, eh_frame_len, mh, NULL);
- if (procinfo->addMemBlob (ehmem) == false)
- delete ehmem;
- }
-
- if (CFI_Parser<A>::functionFuncBoundsViaFDE(UnwindCursor<A,R>::fAddressSpace, eh_frame_start, eh_frame_len, func_bounds)) {
- procinfo->addFuncBounds(mh, func_bounds);
- procinfo->logVerbose ("Added %d function bounds", (int) func_bounds.size());
- procinfo->timestamp_stop (get_func_bounds, "getting function bounds from EH frame FDEs");
- }
- }
- if (procinfo->findStartAddr (pc, start_addr, end_addr)) {
- // If end_addr is 0, we might be looking at the final function in this binary image
- if (start_addr != 0 && end_addr == 0)
- end_addr = text_end;
- procinfo->logVerbose ("Got function bounds from func bounds vector, 0x%llx-0x%llx", start_addr, end_addr);
- } else {
- if (UnwindCursor<A,R>::fAddressSpace.accessors()->get_proc_bounds (procinfo->wrap(), pc, &start_addr, &end_addr, fArg) != UNW_ESUCCESS) {
- int ret = stepByArchitectureDefault (UnwindCursor<A,R>::fAddressSpace, UnwindCursor<A,R>::fRegisters, pc);
- procinfo->logInfo ("Stepped via stepByArchitectureDefault");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return ret;
- }
- else {
- procinfo->logVerbose ("Got function bounds from get_proc_bounds callback, 0x%llx-0x%llx", start_addr, end_addr);
- }
- }
- if (start_addr != 0) {
- procinfo->addProfile (UnwindCursor<A,R>::fAddressSpace.accessors(), UnwindCursor<A,R>::fAddressSpace.wrap(), start_addr, end_addr, fArg);
- }
- }
-
- RemoteUnwindProfile *profile = procinfo->findProfile (pc);
- if (profile == NULL)
- return UNW_ENOINFO;
-
- int retval = stepWithAssembly (UnwindCursor<A,R>::fAddressSpace, pc, profile, UnwindCursor<A,R>::fRegisters);
- if (retval >= 0) {
- procinfo->logInfo ("Stepped via stepWithAssembly");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return retval;
- }
-
- retval = stepByArchitectureDefault (UnwindCursor<A,R>::fAddressSpace, UnwindCursor<A,R>::fRegisters, pc);
- procinfo->logInfo ("Stepped via stepByArchitectureDefault");
- procinfo->timestamp_stop (step_remote, "stepRemote");
- return retval;
-}
-
-template <typename A, typename R>
-void RemoteUnwindCursor<A,R>::setRemoteContext(void *arg)
-{
- // fill in the register state for the currently executing frame.
- getRemoteContext (UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo(), UnwindCursor<A,R>::fRegisters, arg);
-
- // Flag that this unwind cursor is pointing at the zeroth frame. We don't
- // want to use compact unwind info / eh frame info to unwind out of this
- // frame.
-
- fIsLeafFrame = true;
- fIsFirstFrame = true;
-}
-
-// This needs to be done in many of the functions and in libuwind.cxx in one or two
-// places so I'm defining a convenience method.
-template <typename A, typename R>
-bool RemoteUnwindCursor<A,R>::caller_regno_to_unwind_regno (int caller_regno, int& unwind_regno)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo ();
- if (procinfo == NULL) {
- unwind_regno = caller_regno;
- return true;
- }
- if (procinfo->getRegisterMap()->caller_regno_to_unwind_regno (caller_regno, unwind_regno))
- return true;
- return false;
-}
-
-template <typename A, typename R>
-int RemoteUnwindCursor<A,R>::endOfPrologueInsns (unw_word_t start, unw_word_t end, unw_word_t *endofprologue)
-{
- RemoteProcInfo *procinfo = UnwindCursor<A,R>::fAddressSpace.getRemoteProcInfo();
- *endofprologue = start;
- if (procinfo == NULL) {
- ABORT("findEndOfPrologueSetup called with local unwind.");
- return UNW_EUNSPEC;
- }
- if (procinfo->haveProfile (start) == false) {
- uint64_t text_start, text_end, eh_frame_start, eh_frame_len, compact_unwind_start, mh;
- if (!procinfo->getImageAddresses (start, mh, text_start, text_end, eh_frame_start, eh_frame_len, compact_unwind_start, fArg))
- return UNW_EUNSPEC;
- if (end == 0) {
- if (procinfo->haveFuncBounds (mh) == false) {
- std::vector<FuncBounds> func_bounds;
- // CFI entries are usually around 38 bytes but under-estimate a bit
- // because we're not distinguishing between CIEs and FDEs.
- if (eh_frame_len > 0)
- func_bounds.reserve (eh_frame_len / 16);
- if (procinfo->getCachingPolicy() != UNW_CACHE_NONE) {
- // cache the entire eh frame section - we'll need to read the whole
- // thing anyway so we might as well save it.
- uint8_t *eh_buf = (uint8_t *)malloc (eh_frame_len);
- if (UnwindCursor<A,R>::fAddressSpace.getBytes (eh_frame_start, eh_frame_len, eh_buf) == 0)
- {
- free (eh_buf);
- return UNW_EUNSPEC;
- }
- RemoteMemoryBlob *ehmem = new RemoteMemoryBlob(eh_buf, free, eh_frame_start, eh_frame_len, mh, NULL);
- if (procinfo->addMemBlob (ehmem) == false)
- delete ehmem;
- }
- if (CFI_Parser<A>::functionFuncBoundsViaFDE(UnwindCursor<A,R>::fAddressSpace, eh_frame_start, eh_frame_len, func_bounds)) {
- procinfo->addFuncBounds(mh, func_bounds);
- }
- }
- uint64_t bounded_start, bounded_end;
- if (procinfo->findStartAddr (start, bounded_start, bounded_end)) {
- end = bounded_end;
- } else {
- if (UnwindCursor<A,R>::fAddressSpace.accessors()->get_proc_bounds (procinfo->wrap(), start, &bounded_start, &bounded_end, fArg) != UNW_ESUCCESS)
- if (bounded_end != 0)
- end = bounded_end;
- }
- }
- if (procinfo->addProfile (UnwindCursor<A,R>::fAddressSpace.accessors(), UnwindCursor<A,R>::fAddressSpace.wrap(), start, end, fArg) == false)
- return UNW_EUNSPEC;
- }
- RemoteUnwindProfile *profile = procinfo->findProfile (start);
- if (profile == NULL)
- return UNW_ENOINFO;
- *endofprologue = profile->fFirstInsnPastPrologue;
- return UNW_ESUCCESS;
-}
-
-#endif // SUPPORT_REMOTE_UNWINDING
-
-
-}; // namespace lldb_private
-
-
-#endif // __UNWINDCURSOR_HPP__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1-gcc-ext.c b/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1-gcc-ext.c
deleted file mode 100644
index 7103c719ba2..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1-gcc-ext.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- UnwindLevel1-gcc-ext.c ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-/*
- * Implements gcc extensions to the C++ ABI Exception Handling Level 1 as documented at:
- * <http://www.codesourcery.com/cxx-abi/abi-eh.html>
- * using libunwind
- *
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "libunwind.h"
-#include "unwind.h"
-#include "libunwind_priv.h"
-#include "InternalMacros.h"
-
-
-#if __ppc__ || __i386__ || __x86_64__
-
-//
-// Called by __cxa_rethrow()
-//
-EXPORT _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n", exception_object, exception_object->private_1);
- // if this is non-forced and a stopping place was found, then this is a re-throw
- // call _Unwind_RaiseException() as if this was a new exception
- if ( exception_object->private_1 == 0 )
- _Unwind_RaiseException(exception_object);
-
- // call through to _Unwind_Resume() which distiguishes between forced and regular exceptions
- _Unwind_Resume(exception_object);
- ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException() which unexpectedly returned");
-}
-
-
-
-//
-// Called by personality handler during phase 2 to get base address for data relative encodings
-//
-EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context* context)
-{
- DEBUG_PRINT_API("_Unwind_GetDataRelBase(context=%p)\n", context);
- ABORT("_Unwind_GetDataRelBase() not implemented");
-}
-
-//
-// Called by personality handler during phase 2 to get base address for text relative encodings
-//
-EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context* context)
-{
- DEBUG_PRINT_API("_Unwind_GetTextRelBase(context=%p)\n", context);
- ABORT("_Unwind_GetTextRelBase() not implemented");
-}
-
-
-
-//
-// Scans unwind information to find the function that contains the
-// specified code address "pc".
-//
-EXPORT void* _Unwind_FindEnclosingFunction(void* pc)
-{
- DEBUG_PRINT_API("_Unwind_FindEnclosingFunction(pc=%p)\n", pc);
- ABORT("_Unwind_FindEnclosingFunction() not implemented");
-}
-
-
-//
-// Walk every frame and call trace function at each one. If trace function
-// returns anything other than _URC_NO_REASON, then walk is terminated.
-//
-EXPORT _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn callback, void* ref)
-{
- unw_cursor_t cursor;
- unw_context_t uc;
- unw_getcontext(&uc);
- unw_init_local(&cursor, &uc);
-
- DEBUG_PRINT_API("_Unwind_Backtrace(callback=%p)\n", callback);
-
- // walk each frame
- while ( true ) {
-
- // ask libuwind to get next frame (skip over first frame which is _Unwind_Backtrace())
- if ( unw_step(&cursor) <= 0 ) {
- DEBUG_PRINT_UNWINDING(" _backtrace: ended because cursor reached bottom of stack, returning %d\n", _URC_END_OF_STACK);
- return _URC_END_OF_STACK;
- }
-
- // debugging
- if ( DEBUG_PRINT_UNWINDING_TEST ) {
- char functionName[512];
- unw_proc_info_t frameInfo;
- unw_word_t offset;
- unw_get_proc_name(&cursor, functionName, 512, &offset);
- unw_get_proc_info(&cursor, &frameInfo);
- DEBUG_PRINT_UNWINDING(" _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p\n",
- frameInfo.start_ip, functionName, frameInfo.lsda, &cursor);
- }
-
- // call trace function with this frame
- _Unwind_Reason_Code result = (*callback)((struct _Unwind_Context*)(&cursor), ref);
- if ( result != _URC_NO_REASON ) {
- DEBUG_PRINT_UNWINDING(" _backtrace: ended because callback returned %d\n", result);
- return result;
- }
- }
-}
-
-
-//
-// Find dwarf unwind info for an address 'pc' in some function.
-//
-EXPORT const void* _Unwind_Find_FDE(const void* pc, struct dwarf_eh_bases* bases)
-{
- // This is slow, but works.
- // We create an unwind cursor then alter the IP to be pc
- unw_cursor_t cursor;
- unw_context_t uc;
- unw_proc_info_t info;
- unw_getcontext(&uc);
- unw_init_local(&cursor, &uc);
- unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long)pc);
- unw_get_proc_info(&cursor, &info);
- bases->tbase = info.extra;
- bases->dbase = 0; // dbase not used on Mac OS X
- bases->func = info.start_ip;
- DEBUG_PRINT_API("_Unwind_Find_FDE(pc=%p) => %p\n", pc, (void*)(long)info.unwind_info);
- return (void*)(long)info.unwind_info;
-}
-
-
-
-EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context* context)
-{
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_word_t result;
- unw_get_reg(cursor, UNW_REG_SP, &result);
- DEBUG_PRINT_API("_Unwind_GetCFA(context=%p) => 0x%llX\n", context, (uint64_t)result);
- return result;
-}
-
-
-//
-// Called by personality handler during phase 2 to get instruction pointer.
-// ipBefore is a boolean that says if IP is already adjusted to be the call
-// site address. Normally IP is the return address.
-//
-EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context* context, int* ipBefore)
-{
- DEBUG_PRINT_API("_Unwind_GetIPInfo(context=%p)\n", context);
- *ipBefore = 0;
- return _Unwind_GetIP(context);
-}
-
-
-//
-// Called by programs with dynamic code generators that want
-// to register a dynamically generated FDE.
-// This function has existed on Mac OS X since 10.4, but
-// never worked before.
-//
-EXPORT void __register_frame(const void* fde)
-{
- DEBUG_PRINT_API("__register_frame(%p)\n", fde);
- _unw_add_dynamic_fde((unw_word_t)(uintptr_t)fde);
-}
-
-
-//
-// Called by programs with dynamic code generators that want
-// to unregister a dynamically generated FDE.
-// This function has existed on Mac OS X since 10.4, but
-// never worked before.
-//
-EXPORT void __deregister_frame(const void* fde)
-{
- DEBUG_PRINT_API("__deregister_frame(%p)\n", fde);
- _unw_remove_dynamic_fde((unw_word_t)(uintptr_t)fde);
-}
-
-
-
-//
-// The following register/deregister functions are gcc extensions.
-// They have existed on Mac OS X, but have never worked because Mac OS X
-// before 10.6 used keymgr to track known FDEs, but these functions
-// never got updated to use keymgr.
-// For now, we implement these as do-nothing functions to keep any existing
-// applications working. We also add the not in 10.6 symbol so that nwe
-// application won't be able to use them.
-//
-
-EXPORT void __register_frame_info_bases(const void* fde, void* ob, void* tb, void* db)
-{
- DEBUG_PRINT_API("__register_frame_info_bases(%p,%p, %p, %p)\n", fde, ob, tb, db);
- // do nothing, this function never worked in Mac OS X
-}
-
-EXPORT void __register_frame_info(const void* fde, void* ob)
-{
- DEBUG_PRINT_API("__register_frame_info(%p, %p)\n", fde, ob);
- // do nothing, this function never worked in Mac OS X
-}
-
-
-EXPORT void __register_frame_info_table_bases(const void* fde, void* ob, void* tb, void* db)
-{
- DEBUG_PRINT_API("__register_frame_info_table_bases(%p,%p, %p, %p)\n", fde, ob, tb, db);
- // do nothing, this function never worked in Mac OS X
-}
-
-EXPORT void __register_frame_info_table(const void* fde, void* ob)
-{
- DEBUG_PRINT_API("__register_frame_info_table(%p, %p)\n", fde, ob);
- // do nothing, this function never worked in Mac OS X
-}
-
-EXPORT void __register_frame_table(const void* fde)
-{
- DEBUG_PRINT_API("__register_frame_table(%p)\n", fde);
- // do nothing, this function never worked in Mac OS X
-}
-
-EXPORT void* __deregister_frame_info(const void* fde)
-{
- DEBUG_PRINT_API("__deregister_frame_info(%p)\n", fde);
- // do nothing, this function never worked in Mac OS X
- return NULL;
-}
-
-EXPORT void* __deregister_frame_info_bases(const void* fde)
-{
- DEBUG_PRINT_API("__deregister_frame_info_bases(%p)\n", fde);
- // do nothing, this function never worked in Mac OS X
- return NULL;
-}
-
-
-
-
-//
-// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in earlier versions
-//
-NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
-NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
-NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
-NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
-NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
-NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
-NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
-
-NOT_HERE_BEFORE_10_6(__register_frame)
-NOT_HERE_BEFORE_10_6(__deregister_frame)
-
-
-//
-// symbols in libSystem.dylib for compatibility, but we don't want any new code using them
-//
-NEVER_HERE(__register_frame_info_bases)
-NEVER_HERE(__register_frame_info)
-NEVER_HERE(__register_frame_info_table_bases)
-NEVER_HERE(__register_frame_info_table)
-NEVER_HERE(__register_frame_table)
-NEVER_HERE(__deregister_frame_info)
-NEVER_HERE(__deregister_frame_info_bases)
-
-
-#endif // __ppc__ || __i386__ || __x86_64__
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1.c b/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1.c
deleted file mode 100644
index 3aa2b6f552c..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/UnwindLevel1.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- UnwindLevel1.c ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-/*
- *
- * Implements C++ ABI Exception Handling Level 1 as documented at:
- * <http://www.codesourcery.com/cxx-abi/abi-eh.html>
- * using libunwind
- *
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libunwind.h"
-#include "unwind.h"
-#include "InternalMacros.h"
-
-#if __ppc__ || __i386__ || __x86_64__
-
-static _Unwind_Reason_Code unwind_phase1(unw_context_t* uc, struct _Unwind_Exception* exception_object)
-{
- unw_cursor_t cursor1;
- unw_init_local(&cursor1, uc);
-
- // walk each frame looking for a place to stop
- for (bool handlerNotFound = true; handlerNotFound; ) {
-
- // ask libuwind to get next frame (skip over first which is _Unwind_RaiseException)
- int stepResult = unw_step(&cursor1);
- if ( stepResult == 0 ) {
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached bottom => _URC_END_OF_STACK\n", exception_object);
- return _URC_END_OF_STACK;
- }
- else if ( stepResult < 0 ) {
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE1_ERROR;
- }
-
- // see if frame has code to run (has personality routine)
- unw_proc_info_t frameInfo;
- unw_word_t sp;
- if ( unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS ) {
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info failed => _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE1_ERROR;
- }
-
- // debugging
- if ( DEBUG_PRINT_UNWINDING_TEST ) {
- char functionName[512];
- unw_word_t offset;
- if ( (unw_get_proc_name(&cursor1, functionName, 512, &offset) != UNW_ESUCCESS) || (frameInfo.start_ip+offset > frameInfo.end_ip) )
- strcpy(functionName, ".anonymous.");
- unw_word_t pc;
- unw_get_reg(&cursor1, UNW_REG_IP, &pc);
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, lsda=0x%llX, personality=0x%llX\n",
- exception_object, pc, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler);
- }
-
- // if there is a personality routine, ask it if it will want to stop at this frame
- if ( frameInfo.handler != 0 ) {
- __personality_routine p = (__personality_routine)(long)(frameInfo.handler);
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): calling personality function %p\n", exception_object, p);
- _Unwind_Reason_Code personalityResult = (*p)(1, _UA_SEARCH_PHASE,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)(&cursor1));
- switch ( personalityResult ) {
- case _URC_HANDLER_FOUND:
- // found a catch clause or locals that need destructing in this frame
- // stop search and remember stack pointer at the frame
- handlerNotFound = false;
- unw_get_reg(&cursor1, UNW_REG_SP, &sp);
- exception_object->private_2 = sp;
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND\n", exception_object);
- return _URC_NO_REASON;
-
- case _URC_CONTINUE_UNWIND:
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", exception_object);
- // continue unwinding
- break;
-
- default:
- // something went wrong
- DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE1_ERROR;
- }
- }
- }
- return _URC_NO_REASON;
-}
-
-
-static _Unwind_Reason_Code unwind_phase2(unw_context_t* uc, struct _Unwind_Exception* exception_object)
-{
- unw_cursor_t cursor2;
- unw_init_local(&cursor2, uc);
-
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
-
- // walk each frame until we reach where search phase said to stop
- while ( true ) {
-
- // ask libuwind to get next frame (skip over first which is _Unwind_RaiseException)
- int stepResult = unw_step(&cursor2);
- if ( stepResult == 0 ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached bottom => _URC_END_OF_STACK\n", exception_object);
- return _URC_END_OF_STACK;
- }
- else if ( stepResult < 0 ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE2_ERROR;
- }
-
- // get info about this frame
- unw_word_t sp;
- unw_proc_info_t frameInfo;
- unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- if ( unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info failed => _URC_FATAL_PHASE1_ERROR\n", exception_object);
- return _URC_FATAL_PHASE2_ERROR;
- }
-
- // debugging
- if ( DEBUG_PRINT_UNWINDING_TEST ) {
- char functionName[512];
- unw_word_t offset;
- if ( (unw_get_proc_name(&cursor2, functionName, 512, &offset) != UNW_ESUCCESS) || (frameInfo.start_ip+offset > frameInfo.end_ip) )
- strcpy(functionName, ".anonymous.");
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, lsda=0x%llX, personality=0x%llX\n",
- exception_object, frameInfo.start_ip, functionName, sp, frameInfo.lsda, frameInfo.handler);
- }
-
- // if there is a personality routine, tell it we are unwinding
- if ( frameInfo.handler != 0 ) {
- __personality_routine p = (__personality_routine)(long)(frameInfo.handler);
- _Unwind_Action action = _UA_CLEANUP_PHASE;
- if ( sp == exception_object->private_2 )
- action = (_Unwind_Action)(_UA_CLEANUP_PHASE|_UA_HANDLER_FRAME); // tell personality this was the frame it marked in phase 1
- _Unwind_Reason_Code personalityResult = (*p)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)(&cursor2));
- switch ( personalityResult ) {
- case _URC_CONTINUE_UNWIND:
- // continue unwinding
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", exception_object);
- if ( sp == exception_object->private_2 ) {
- // phase 1 said we would stop at this frame, but we did not...
- ABORT("during phase1 personality function said it would stop here, but now if phase2 it did not stop here");
- }
- break;
- case _URC_INSTALL_CONTEXT:
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n", exception_object);
- // personality routine says to transfer control to landing pad
- // we may get control back if landing pad calls _Unwind_Resume()
- if ( DEBUG_PRINT_UNWINDING_TEST ) {
- unw_word_t pc;
- unw_word_t sp;
- unw_get_reg(&cursor2, UNW_REG_IP, &pc);
- unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- DEBUG_PRINT_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering user code with ip=0x%llX, sp=0x%llX\n", exception_object, pc, sp);
- }
- unw_resume(&cursor2);
- // unw_resume() only returns if there was an error
- return _URC_FATAL_PHASE2_ERROR;
- default:
- // something went wrong
- DEBUG_MESSAGE("personality function returned unknown result %d", personalityResult);
- return _URC_FATAL_PHASE2_ERROR;
- }
- }
- }
-
- // clean up phase did not resume at the frame that the search phase said it would
- return _URC_FATAL_PHASE2_ERROR;
-}
-
-
-static _Unwind_Reason_Code unwind_phase2_forced(unw_context_t* uc, struct _Unwind_Exception* exception_object,
- _Unwind_Stop_Fn stop, void* stop_parameter)
-{
- unw_cursor_t cursor2;
- unw_init_local(&cursor2, uc);
-
- // walk each frame until we reach where search phase said to stop
- while ( unw_step(&cursor2) > 0 ) {
-
- // get info about this frame
- unw_proc_info_t frameInfo;
- if ( unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step failed => _URC_END_OF_STACK\n", exception_object);
- return _URC_FATAL_PHASE1_ERROR;
- }
-
- // debugging
- if ( DEBUG_PRINT_UNWINDING_TEST ) {
- char functionName[512];
- unw_word_t offset;
- if ( (unw_get_proc_name(&cursor2, functionName, 512, &offset) != UNW_ESUCCESS) || (frameInfo.start_ip+offset > frameInfo.end_ip) )
- strcpy(functionName, ".anonymous.");
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): start_ip=0x%llX, func=%s, lsda=0x%llX, personality=0x%llX\n",
- exception_object, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler);
- }
-
- // call stop function at each frame
- _Unwind_Action action = (_Unwind_Action)(_UA_FORCE_UNWIND|_UA_CLEANUP_PHASE);
- _Unwind_Reason_Code stopResult = (*stop)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)(&cursor2), stop_parameter);
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n", exception_object, stopResult);
- if ( stopResult != _URC_NO_REASON ) {
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n", exception_object);
- return _URC_FATAL_PHASE2_ERROR;
- }
-
- // if there is a personality routine, tell it we are unwinding
- if ( frameInfo.handler != 0 ) {
- __personality_routine p = (__personality_routine)(long)(frameInfo.handler);
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n", exception_object, p);
- _Unwind_Reason_Code personalityResult = (*p)(1, action,
- exception_object->exception_class, exception_object,
- (struct _Unwind_Context*)(&cursor2));
- switch ( personalityResult ) {
- case _URC_CONTINUE_UNWIND:
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned _URC_CONTINUE_UNWIND\n", exception_object);
- // destructors called, continue unwinding
- break;
- case _URC_INSTALL_CONTEXT:
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned _URC_INSTALL_CONTEXT\n", exception_object);
- // we may get control back if landing pad calls _Unwind_Resume()
- unw_resume(&cursor2);
- break;
- default:
- // something went wrong
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): personality returned %d, _URC_FATAL_PHASE2_ERROR\n",
- exception_object, personalityResult);
- return _URC_FATAL_PHASE2_ERROR;
- }
- }
- }
-
- // call stop function one last time and tell it we've reached the end of the stack
- DEBUG_PRINT_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop function with _UA_END_OF_STACK\n", exception_object);
- _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND|_UA_CLEANUP_PHASE|_UA_END_OF_STACK);
- (*stop)(1, lastAction, exception_object->exception_class, exception_object, (struct _Unwind_Context*)(&cursor2), stop_parameter);
-
- // clean up phase did not resume at the frame that the search phase said it would
- return _URC_FATAL_PHASE2_ERROR;
-}
-
-
-//
-// Called by __cxa_throw. Only returns if there is a fatal error
-//
-EXPORT _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_RaiseException(ex_obj=%p)\n", exception_object);
- unw_context_t uc;
- unw_getcontext(&uc);
-
- // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right thing
- exception_object->private_1 = 0;
- exception_object->private_2 = 0;
-
- // phase 1: the search phase
- _Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
- if ( phase1 != _URC_NO_REASON )
- return phase1;
-
- // phase 2: the clean up phase
- return unwind_phase2(&uc, exception_object);
-}
-
-
-//
-// When _Unwind_RaiseException() is in phase2, it hands control
-// to the personality function at each frame. The personality
-// may force a jump to a landing pad in that function, the landing
-// pad code may then call _Unwind_Resume() to continue with the
-// unwinding. Note: the call to _Unwind_Resume() is from compiler
-// geneated user code. All other _Unwind_* routines are called
-// by the C++ runtime __cxa_* routines.
-//
-// Re-throwing an exception is implemented by having the code call
-// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow()
-//
-EXPORT void _Unwind_Resume(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
- unw_context_t uc;
- unw_getcontext(&uc);
-
- if ( exception_object->private_1 != 0 )
- unwind_phase2_forced(&uc, exception_object, (_Unwind_Stop_Fn)exception_object->private_1, (void*)exception_object->private_2);
- else
- unwind_phase2(&uc, exception_object);
-
- // clients assume _Unwind_Resume() does not return, so all we can do is abort.
- ABORT("_Unwind_Resume() can't return");
-}
-
-
-
-//
-// Not used by C++.
-// Unwinds stack, calling "stop" function at each frame
-// Could be used to implement longjmp().
-//
-EXPORT _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception* exception_object, _Unwind_Stop_Fn stop, void* stop_parameter)
-{
- DEBUG_PRINT_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n", exception_object, stop);
- unw_context_t uc;
- unw_getcontext(&uc);
-
- // mark that this is a forced unwind, so _Unwind_Resume() can do the right thing
- exception_object->private_1 = (uintptr_t)stop;
- exception_object->private_2 = (uintptr_t)stop_parameter;
-
- // doit
- return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter);
-}
-
-
-//
-// Called by personality handler during phase 2 to get LSDA for current frame
-//
-EXPORT uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context* context)
-{
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_proc_info_t frameInfo;
- uintptr_t result = 0;
- if ( unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS )
- result = frameInfo.lsda;
- DEBUG_PRINT_API("_Unwind_GetLanguageSpecificData(context=%p) => 0x%lX\n", context, result);
- if ( result != 0 ) {
- if ( *((uint8_t*)result) != 0xFF )
- DEBUG_MESSAGE("lsda at 0x%lX does not start with 0xFF\n", result);
- }
- return result;
-}
-
-
-//
-// Called by personality handler during phase 2 to get register values
-//
-EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context* context, int index)
-{
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_word_t result;
- unw_get_reg(cursor, index, &result);
- DEBUG_PRINT_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%llX\n", context, index, (uint64_t)result);
- return result;
-}
-
-
-//
-// Called by personality handler during phase 2 to alter register values
-//
-EXPORT void _Unwind_SetGR(struct _Unwind_Context* context, int index, uintptr_t new_value)
-{
- DEBUG_PRINT_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0llX)\n", context, index, (uint64_t)new_value);
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_set_reg(cursor, index, new_value);
-}
-
-
-//
-// Called by personality handler during phase 2 to get instruction pointer
-//
-EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context* context)
-{
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_word_t result;
- unw_get_reg(cursor, UNW_REG_IP, &result);
- DEBUG_PRINT_API("_Unwind_GetIP(context=%p) => 0x%llX\n", context, (uint64_t)result);
- return result;
-}
-
-
-//
-// Called by personality handler during phase 2 to alter instruction pointer
-//
-EXPORT void _Unwind_SetIP(struct _Unwind_Context* context, uintptr_t new_value)
-{
- DEBUG_PRINT_API("_Unwind_SetIP(context=%p, value=0x%0llX)\n", context, (uint64_t)new_value);
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_set_reg(cursor, UNW_REG_IP, new_value);
-}
-
-
-//
-// Called by personality handler during phase 2 to find the start of the function
-//
-EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context* context)
-{
- unw_cursor_t* cursor = (unw_cursor_t*)context;
- unw_proc_info_t frameInfo;
- uintptr_t result = 0;
- if ( unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS )
- result = frameInfo.start_ip;
- DEBUG_PRINT_API("_Unwind_GetRegionStart(context=%p) => 0x%lX\n", context, result);
- return result;
-}
-
-
-//
-// Called by personality handler during phase 2 if a foreign exception is caught
-//
-EXPORT void _Unwind_DeleteException(struct _Unwind_Exception* exception_object)
-{
- DEBUG_PRINT_API("_Unwind_DeleteException(ex_obj=%p)\n", exception_object);
- if ( exception_object->exception_cleanup != NULL )
- (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, exception_object);
-}
-
-
-
-
-//
-// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in earlier versions
-//
-NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
-NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
-NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
-NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
-NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
-NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
-NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
-NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
-NOT_HERE_BEFORE_10_6(_Unwind_Resume)
-NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
-NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
-
-#endif // __ppc__ || __i386__ || __x86_64__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/dwarf2.h b/lldb/source/Plugins/Process/Utility/libunwind/src/dwarf2.h
deleted file mode 100644
index 83414332c5e..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/dwarf2.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- dwarf2.h ------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-/* These constants were taken from version 3 of the DWARF standard,
- which is Copyright (c) 2005 Free Standards Group, and
- Copyright (c) 1992, 1993 UNIX International, Inc.
-*/
-
-
-#ifndef __DWARF2__
-#define __DWARF2__
-
-namespace lldb_private {
-
-// dwarf unwind instructions
-enum {
- DW_CFA_nop = 0x0,
- DW_CFA_set_loc = 0x1,
- DW_CFA_advance_loc1 = 0x2,
- DW_CFA_advance_loc2 = 0x3,
- DW_CFA_advance_loc4 = 0x4,
- DW_CFA_offset_extended = 0x5,
- DW_CFA_restore_extended = 0x6,
- DW_CFA_undefined = 0x7,
- DW_CFA_same_value = 0x8,
- DW_CFA_register = 0x9,
- DW_CFA_remember_state = 0xA,
- DW_CFA_restore_state = 0xB,
- DW_CFA_def_cfa = 0xC,
- DW_CFA_def_cfa_register = 0xD,
- DW_CFA_def_cfa_offset = 0xE,
- DW_CFA_def_cfa_expression = 0xF,
- DW_CFA_expression = 0x10,
- DW_CFA_offset_extended_sf = 0x11,
- DW_CFA_def_cfa_sf = 0x12,
- DW_CFA_def_cfa_offset_sf = 0x13,
- DW_CFA_val_offset = 0x14,
- DW_CFA_val_offset_sf = 0x15,
- DW_CFA_val_expression = 0x16,
- DW_CFA_advance_loc = 0x40, // high 2 bits are 0x1, lower 6 bits are delta
- DW_CFA_offset = 0x80, // high 2 bits are 0x2, lower 6 bits are register
- DW_CFA_restore = 0xC0, // high 2 bits are 0x3, lower 6 bits are register
-
- // GNU extensions
- DW_CFA_GNU_window_save = 0x2D,
- DW_CFA_GNU_args_size = 0x2E,
- DW_CFA_GNU_negative_offset_extended = 0x2F
-};
-
-
-// FSF exception handling Pointer-Encoding constants
-// Used in CFI augmentation by gcc compiler
-enum {
- DW_EH_PE_ptr = 0x00,
- DW_EH_PE_uleb128 = 0x01,
- DW_EH_PE_udata2 = 0x02,
- DW_EH_PE_udata4 = 0x03,
- DW_EH_PE_udata8 = 0x04,
- DW_EH_PE_signed = 0x08,
- DW_EH_PE_sleb128 = 0x09,
- DW_EH_PE_sdata2 = 0x0A,
- DW_EH_PE_sdata4 = 0x0B,
- DW_EH_PE_sdata8 = 0x0C,
- DW_EH_PE_absptr = 0x00,
- DW_EH_PE_pcrel = 0x10,
- DW_EH_PE_textrel = 0x20,
- DW_EH_PE_datarel = 0x30,
- DW_EH_PE_funcrel = 0x40,
- DW_EH_PE_aligned = 0x50,
- DW_EH_PE_indirect = 0x80,
- DW_EH_PE_omit = 0xFF
-};
-
-
-// DWARF expressions
-enum {
- DW_OP_addr = 0x03, // constant address (size target specific)
- DW_OP_deref = 0x06,
- DW_OP_const1u = 0x08, // 1-byte constant
- DW_OP_const1s = 0x09, // 1-byte constant
- DW_OP_const2u = 0x0A, // 2-byte constant
- DW_OP_const2s = 0x0B, // 2-byte constant
- DW_OP_const4u = 0x0C, // 4-byte constant
- DW_OP_const4s = 0x0D, // 4-byte constant
- DW_OP_const8u = 0x0E, // 8-byte constant
- DW_OP_const8s = 0x0F, // 8-byte constant
- DW_OP_constu = 0x10, // ULEB128 constant
- DW_OP_consts = 0x11, // SLEB128 constant
- DW_OP_dup = 0x12,
- DW_OP_drop = 0x13,
- DW_OP_over = 0x14,
- DW_OP_pick = 0x15, // 1-byte stack index
- DW_OP_swap = 0x16,
- DW_OP_rot = 0x17,
- DW_OP_xderef = 0x18,
- DW_OP_abs = 0x19,
- DW_OP_and = 0x1A,
- DW_OP_div = 0x1B,
- DW_OP_minus = 0x1C,
- DW_OP_mod = 0x1D,
- DW_OP_mul = 0x1E,
- DW_OP_neg = 0x1F,
- DW_OP_not = 0x20,
- DW_OP_or = 0x21,
- DW_OP_plus = 0x22,
- DW_OP_plus_uconst = 0x23, // ULEB128 addend
- DW_OP_shl = 0x24,
- DW_OP_shr = 0x25,
- DW_OP_shra = 0x26,
- DW_OP_xor = 0x27,
- DW_OP_skip = 0x2F, // signed 2-byte constant
- DW_OP_bra = 0x28, // signed 2-byte constant
- DW_OP_eq = 0x29,
- DW_OP_ge = 0x2A,
- DW_OP_gt = 0x2B,
- DW_OP_le = 0x2C,
- DW_OP_lt = 0x2D,
- DW_OP_ne = 0x2E,
- DW_OP_lit0 = 0x30, // Literal 0
- DW_OP_lit1 = 0x31, // Literal 1
- DW_OP_lit2 = 0x32, // Literal 2
- DW_OP_lit3 = 0x33, // Literal 3
- DW_OP_lit4 = 0x34, // Literal 4
- DW_OP_lit5 = 0x35, // Literal 5
- DW_OP_lit6 = 0x36, // Literal 6
- DW_OP_lit7 = 0x37, // Literal 7
- DW_OP_lit8 = 0x38, // Literal 8
- DW_OP_lit9 = 0x39, // Literal 9
- DW_OP_lit10 = 0x3A, // Literal 10
- DW_OP_lit11 = 0x3B, // Literal 11
- DW_OP_lit12 = 0x3C, // Literal 12
- DW_OP_lit13 = 0x3D, // Literal 13
- DW_OP_lit14 = 0x3E, // Literal 14
- DW_OP_lit15 = 0x3F, // Literal 15
- DW_OP_lit16 = 0x40, // Literal 16
- DW_OP_lit17 = 0x41, // Literal 17
- DW_OP_lit18 = 0x42, // Literal 18
- DW_OP_lit19 = 0x43, // Literal 19
- DW_OP_lit20 = 0x44, // Literal 20
- DW_OP_lit21 = 0x45, // Literal 21
- DW_OP_lit22 = 0x46, // Literal 22
- DW_OP_lit23 = 0x47, // Literal 23
- DW_OP_lit24 = 0x48, // Literal 24
- DW_OP_lit25 = 0x49, // Literal 25
- DW_OP_lit26 = 0x4A, // Literal 26
- DW_OP_lit27 = 0x4B, // Literal 27
- DW_OP_lit28 = 0x4C, // Literal 28
- DW_OP_lit29 = 0x4D, // Literal 29
- DW_OP_lit30 = 0x4E, // Literal 30
- DW_OP_lit31 = 0x4F, // Literal 31
- DW_OP_reg0 = 0x50, // Contents of reg0
- DW_OP_reg1 = 0x51, // Contents of reg1
- DW_OP_reg2 = 0x52, // Contents of reg2
- DW_OP_reg3 = 0x53, // Contents of reg3
- DW_OP_reg4 = 0x54, // Contents of reg4
- DW_OP_reg5 = 0x55, // Contents of reg5
- DW_OP_reg6 = 0x56, // Contents of reg6
- DW_OP_reg7 = 0x57, // Contents of reg7
- DW_OP_reg8 = 0x58, // Contents of reg8
- DW_OP_reg9 = 0x59, // Contents of reg9
- DW_OP_reg10 = 0x5A, // Contents of reg10
- DW_OP_reg11 = 0x5B, // Contents of reg11
- DW_OP_reg12 = 0x5C, // Contents of reg12
- DW_OP_reg13 = 0x5D, // Contents of reg13
- DW_OP_reg14 = 0x5E, // Contents of reg14
- DW_OP_reg15 = 0x5F, // Contents of reg15
- DW_OP_reg16 = 0x60, // Contents of reg16
- DW_OP_reg17 = 0x61, // Contents of reg17
- DW_OP_reg18 = 0x62, // Contents of reg18
- DW_OP_reg19 = 0x63, // Contents of reg19
- DW_OP_reg20 = 0x64, // Contents of reg20
- DW_OP_reg21 = 0x65, // Contents of reg21
- DW_OP_reg22 = 0x66, // Contents of reg22
- DW_OP_reg23 = 0x67, // Contents of reg23
- DW_OP_reg24 = 0x68, // Contents of reg24
- DW_OP_reg25 = 0x69, // Contents of reg25
- DW_OP_reg26 = 0x6A, // Contents of reg26
- DW_OP_reg27 = 0x6B, // Contents of reg27
- DW_OP_reg28 = 0x6C, // Contents of reg28
- DW_OP_reg29 = 0x6D, // Contents of reg29
- DW_OP_reg30 = 0x6E, // Contents of reg30
- DW_OP_reg31 = 0x6F, // Contents of reg31
- DW_OP_breg0 = 0x70, // base register 0 + SLEB128 offset
- DW_OP_breg1 = 0x71, // base register 1 + SLEB128 offset
- DW_OP_breg2 = 0x72, // base register 2 + SLEB128 offset
- DW_OP_breg3 = 0x73, // base register 3 + SLEB128 offset
- DW_OP_breg4 = 0x74, // base register 4 + SLEB128 offset
- DW_OP_breg5 = 0x75, // base register 5 + SLEB128 offset
- DW_OP_breg6 = 0x76, // base register 6 + SLEB128 offset
- DW_OP_breg7 = 0x77, // base register 7 + SLEB128 offset
- DW_OP_breg8 = 0x78, // base register 8 + SLEB128 offset
- DW_OP_breg9 = 0x79, // base register 9 + SLEB128 offset
- DW_OP_breg10 = 0x7A, // base register 10 + SLEB128 offset
- DW_OP_breg11 = 0x7B, // base register 11 + SLEB128 offset
- DW_OP_breg12 = 0x7C, // base register 12 + SLEB128 offset
- DW_OP_breg13 = 0x7D, // base register 13 + SLEB128 offset
- DW_OP_breg14 = 0x7E, // base register 14 + SLEB128 offset
- DW_OP_breg15 = 0x7F, // base register 15 + SLEB128 offset
- DW_OP_breg16 = 0x80, // base register 16 + SLEB128 offset
- DW_OP_breg17 = 0x81, // base register 17 + SLEB128 offset
- DW_OP_breg18 = 0x82, // base register 18 + SLEB128 offset
- DW_OP_breg19 = 0x83, // base register 19 + SLEB128 offset
- DW_OP_breg20 = 0x84, // base register 20 + SLEB128 offset
- DW_OP_breg21 = 0x85, // base register 21 + SLEB128 offset
- DW_OP_breg22 = 0x86, // base register 22 + SLEB128 offset
- DW_OP_breg23 = 0x87, // base register 23 + SLEB128 offset
- DW_OP_breg24 = 0x88, // base register 24 + SLEB128 offset
- DW_OP_breg25 = 0x89, // base register 25 + SLEB128 offset
- DW_OP_breg26 = 0x8A, // base register 26 + SLEB128 offset
- DW_OP_breg27 = 0x8B, // base register 27 + SLEB128 offset
- DW_OP_breg28 = 0x8C, // base register 28 + SLEB128 offset
- DW_OP_breg29 = 0x8D, // base register 29 + SLEB128 offset
- DW_OP_breg30 = 0x8E, // base register 30 + SLEB128 offset
- DW_OP_breg31 = 0x8F, // base register 31 + SLEB128 offset
- DW_OP_regx = 0x90, // ULEB128 register
- DW_OP_fbreg = 0x91, // SLEB128 offset
- DW_OP_bregx = 0x92, // ULEB128 register followed by SLEB128 offset
- DW_OP_piece = 0x93, // ULEB128 size of piece addressed
- DW_OP_deref_size = 0x94, // 1-byte size of data retrieved
- DW_OP_xderef_size = 0x95, // 1-byte size of data retrieved
- DW_OP_nop = 0x96,
- DW_OP_push_object_addres = 0x97,
- DW_OP_call2 = 0x98, // 2-byte offset of DIE
- DW_OP_call4 = 0x99, // 4-byte offset of DIE
- DW_OP_call_ref = 0x9A, // 4- or 8-byte offset of DIE
- DW_OP_lo_user = 0xE0,
- DW_OP_APPLE_uninit = 0xF0,
- DW_OP_hi_user = 0xFF
-};
-
-
-}; // namespace lldb_private
-
-
-#endif
-
-
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/libunwind_priv.h b/lldb/source/Plugins/Process/Utility/libunwind/src/libunwind_priv.h
deleted file mode 100644
index fe25780c538..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/libunwind_priv.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- libunwind_priv.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __LIBUNWIND_PRIV__
-#define __LIBUNWIND_PRIV__
-
-namespace lldb_private {
-#include "libunwind.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- // SPI
- extern void unw_iterate_dwarf_unwind_cache(void (*func)(unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh));
-
- // IPI
- extern void _unw_add_dynamic_fde(unw_word_t fde);
- extern void _unw_remove_dynamic_fde(unw_word_t fde);
-
-#ifdef __cplusplus
-}
-#endif
-
-}; // namespace lldb_private
-
-
-#endif
-
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx b/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx
deleted file mode 100644
index d841677db37..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx
+++ /dev/null
@@ -1,428 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 vi:set tabstop=4 expandtab: -*/
-//===-- libuwind.cxx --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if __ppc__ || __i386__ || __x86_64__
-
-#include <mach/mach_types.h>
-#include <mach/machine.h>
-#include <new>
-
-#include "libunwind.h"
-#include "libunwind_priv.h"
-
-#include "UnwindCursor.hpp"
-#include "AddressSpace.hpp"
-
-#include "RemoteProcInfo.hpp"
-
-namespace lldb_private {
-
-// setup debug logging hooks
-INITIALIZE_DEBUG_PRINT_API
-INITIALIZE_DEBUG_PRINT_UNWINDING
-
-// internal object to represent this processes address space
-static LocalAddressSpace sThisAddressSpace;
-
-#pragma mark Local API
-
-///
-/// record the registers and stack position of the caller
-///
-extern int unw_getcontext(unw_context_t*);
-// note: unw_getcontext() implemented in assembly
-
-///
-/// create a cursor of a thread in this process given 'context' recorded by unw_getcontext()
-///
-EXPORT int unw_init_local(unw_cursor_t* cursor, unw_context_t* context)
-{
- DEBUG_PRINT_API("unw_init_local(cursor=%p, context=%p)\n", cursor, context);
- // use "placement new" to allocate UnwindCursor in the cursor buffer
-#if __i386__
- new ((void*)cursor) UnwindCursor<LocalAddressSpace,Registers_x86>(context, sThisAddressSpace);
-#elif __x86_64__
- new ((void*)cursor) UnwindCursor<LocalAddressSpace,Registers_x86_64>(context, sThisAddressSpace);
-#elif __ppc__
- new ((void*)cursor) UnwindCursor<LocalAddressSpace,Registers_ppc>(context, sThisAddressSpace);
-#endif
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- co->setInfoBasedOnIPRegister(NULL);
-
- return UNW_ESUCCESS;
-}
-
-///
-/// move cursor to next frame
-///
-EXPORT int unw_step(unw_cursor_t* cursor)
-{
- DEBUG_PRINT_API("unw_step(cursor=%p)\n", cursor);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- return co->step();
-}
-
-///
-/// get value of specified register at cursor position in stack frame
-///
-EXPORT int unw_get_reg(unw_cursor_t* cursor, unw_regnum_t regNum, unw_word_t* value)
-{
- DEBUG_PRINT_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)\n", cursor, regNum, value);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
-
- if (co->validReg(regNum) == 0)
- return UNW_EBADREG;
- return co->getReg(regNum, value);
-}
-
-///
-/// get value of specified float register at cursor position in stack frame
-///
-EXPORT int unw_get_fpreg(unw_cursor_t* cursor, unw_regnum_t regNum, unw_fpreg_t* value)
-{
- DEBUG_PRINT_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)\n", cursor, regNum, value);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
-
- if ( co->validFloatReg(regNum) ) {
- return co->getFloatReg(regNum, value);
- }
- return UNW_EBADREG;
-}
-
-///
-/// set value of specified register at cursor position in stack frame
-///
-EXPORT int unw_set_reg(unw_cursor_t* cursor, unw_regnum_t regNum, unw_word_t value)
-{
- DEBUG_PRINT_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)\n", cursor, regNum, value);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
-
- if ( co->validReg(regNum) ) {
- co->setReg(regNum, value);
- // specical case altering IP to re-find info (being called by personality function)
- if ( regNum == UNW_REG_IP ) {
- unw_proc_info_t info;
- co->getInfo(&info);
- uint64_t orgArgSize = info.gp;
- uint64_t orgFuncStart = info.start_ip;
- co->setInfoBasedOnIPRegister(false);
- // and adjust REG_SP if there was a DW_CFA_GNU_args_size
- if ( (orgFuncStart == info.start_ip) && (orgArgSize != 0) )
- co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + orgArgSize);
- }
- return UNW_ESUCCESS;
- }
- return UNW_EBADREG;
-}
-
-///
-/// set value of specified float register at cursor position in stack frame
-///
-EXPORT int unw_set_fpreg(unw_cursor_t* cursor, unw_regnum_t regNum, unw_fpreg_t value)
-{
- DEBUG_PRINT_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n", cursor, regNum, value);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
-
- if ( co->validFloatReg(regNum) ) {
- return co->setFloatReg(regNum, value);
- }
- return UNW_EBADREG;
-}
-
-///
-/// resume execution at cursor position (aka longjump)
-///
-EXPORT int unw_resume(unw_cursor_t* cursor)
-{
- DEBUG_PRINT_API("unw_resume(cursor=%p)\n", cursor);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
-
- co->jumpto();
- return UNW_EUNSPEC;
-}
-
-///
-/// returns the name of a register
-///
-EXPORT const char* unw_regname(unw_cursor_t* cursor, unw_regnum_t regNum)
-{
- DEBUG_PRINT_API("unw_regname(cursor=%p, regNum=%d)\n", cursor, regNum);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- return co->getRegisterName(regNum);
-}
-
-///
-/// get unwind info at cursor position in stack frame
-///
-EXPORT int unw_get_proc_info(unw_cursor_t* cursor, unw_proc_info_t* info)
-{
- DEBUG_PRINT_API("unw_get_proc_info(cursor=%p, &info=%p)\n", cursor, info);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- co->getInfo(info);
- if ( info->end_ip == 0 )
- return UNW_ENOINFO;
- else
- return UNW_ESUCCESS;
-}
-
-///
-/// checks if a register is a floating-point register
-///
-EXPORT int unw_is_fpreg(unw_cursor_t* cursor, unw_regnum_t regNum)
-{
- DEBUG_PRINT_API("unw_is_fpreg(cursor=%p, regNum=%d)\n", cursor, regNum);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- return co->validFloatReg(regNum);
-}
-
-///
-/// checks if current frame is signal trampoline
-///
-EXPORT int unw_is_signal_frame(unw_cursor_t* cursor)
-{
- DEBUG_PRINT_API("unw_is_signal_frame(cursor=%p)\n", cursor);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- return co->isSignalFrame();
-}
-
-///
-/// get name of function at cursor position in stack frame
-///
-EXPORT int unw_get_proc_name(unw_cursor_t* cursor, char* buf, size_t bufLen, unw_word_t* offset)
-{
- DEBUG_PRINT_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%ld)\n", cursor, buf, bufLen);
- AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor;
- if ( co->getFunctionName(buf, bufLen, offset) )
- return UNW_ESUCCESS;
- else
- return UNW_EUNSPEC;
-}
-
-#pragma mark Remote API
-
-#if defined (SUPPORT_REMOTE_UNWINDING)
-EXPORT int unw_init_remote(unw_cursor_t *cursor, unw_addr_space_t as, void *arg)
-{
- DEBUG_PRINT_API("init_remote(c=%p, as=%p, arg=%p)\n", cursor, as, arg);
-
- // API docs at http://www.nongnu.org/libunwind/docs.html say we should
- // handle a local address space but we're not doing the "remote" unwinding
- // with local process accessors so punt on that.
-
- if(as->type != UNW_REMOTE)
- {
- ABORT("unw_init_remote was passed a non-remote address space");
- return UNW_EINVAL;
- }
-
- unw_accessors_t* acc = unw_get_accessors(as);
- if(!acc) {
- ABORT("unw_get_accessors returned NULL");
- return UNW_EINVAL;
- }
-
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
-
- // use "placement new" to allocate UnwindCursor in the cursor buffer
- // It isn't really necessary to use placement new in the remote API but we'll stay consistent
- // with the rest of the code here.
- switch ( remote->ras->getTargetArch() ) {
- case UNW_TARGET_I386:
- {
- Registers_x86 r;
- // LEAK: "addrSpace" is being leaked every time here with no easy solution.
- // The address space is in the cursor and the cursor may get
- // duplicated, though if it does get duplicated, it will just be
- // memcpy'ed since unw_cursor_t is just a bunch of uint64_t types...
- OtherAddressSpace<Pointer32<LittleEndian> > *addrSpace = new OtherAddressSpace<Pointer32<LittleEndian> >(as, arg);
- getRemoteContext (remote->ras, r, arg);
- unw_context_t *context = (unw_context_t*) &r;
- new ((void*)cursor) RemoteUnwindCursor<OtherAddressSpace<Pointer32<LittleEndian> >, Registers_x86>(*addrSpace, context, arg);
- }
- break;
- case UNW_TARGET_X86_64:
- {
- Registers_x86_64 r;
- // LEAK: "addrSpace" is being leaked every time here with no easy solution.
- // The address space is in the cursor and the cursor may get
- // duplicated, though if it does get duplicated, it will just be
- // memcpy'ed since unw_cursor_t is just a bunch of uint64_t types...
- OtherAddressSpace<Pointer64<LittleEndian> > *addrSpace = new OtherAddressSpace<Pointer64<LittleEndian> >(as, arg);
- getRemoteContext (remote->ras, r, arg);
- unw_context_t *context = (unw_context_t*) &r;
- new ((void*)cursor) RemoteUnwindCursor<OtherAddressSpace<Pointer64<LittleEndian> >, Registers_x86_64>(*addrSpace, context, arg);
- }
- break;
-
- case UNW_TARGET_PPC:
- ABORT("ppc not supported for remote unwinds");
- break;
-
- case UNW_TARGET_ARM:
- ABORT("arm not supported for remote unwinds");
- break;
-
- default:
- return UNW_EUNSPEC;
- }
-
- AbstractRemoteUnwindCursor* co = (AbstractRemoteUnwindCursor*)cursor;
- co->setRemoteContext(arg);
-
- return UNW_ESUCCESS;
-}
-
-// The documentation disagrees about whether or not this returns a pointer. Now it does.
-EXPORT unw_accessors_t* unw_get_accessors(unw_addr_space_t as)
-{
- if(as->type != UNW_REMOTE)
- {
- ABORT("unw_get_accessors was passed a non-remote address space");
- return NULL;
- }
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
-
- if(remote->type != UNW_REMOTE)
- return NULL;
-
- return remote->ras->getAccessors();
-}
-
-EXPORT unw_addr_space_t unw_create_addr_space(unw_accessors_t *ap, unw_targettype_t targarch)
-{
- unw_addr_space_remote* remote = (unw_addr_space_remote*)malloc(sizeof(unw_addr_space_remote));
- remote->type = UNW_REMOTE;
- remote->ras = new RemoteProcInfo(ap, targarch);
- return (unw_addr_space_t)remote;
-}
-
-EXPORT void unw_flush_caches(unw_addr_space_t as)
-{
- if(as->type != UNW_REMOTE)
- {
- ABORT("unw_flush_caches was passed a non-remote address space");
- return;
- }
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
- remote->ras->flushAllCaches();
-
- return;
-}
-
-EXPORT void unw_image_was_unloaded (unw_addr_space_t as, unw_word_t mh)
-{
- if(as->type != UNW_REMOTE)
- {
- ABORT("unw_image_was_unloaded was passed a non-remote address space");
- return;
- }
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
- remote->ras->flushCacheByMachHeader(mh);
-
- return;
-}
-
-
-EXPORT int unw_set_caching_policy(unw_addr_space_t as, unw_caching_policy_t policy)
-{
- if(as->type != UNW_REMOTE)
- {
- ABORT("unw_set_caching_policy was passed a non-remote address space");
- return UNW_EINVAL;
- }
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
- return remote->ras->setCachingPolicy(policy);
-}
-
-EXPORT unw_addr_space_t unw_local_addr_space = (unw_addr_space_t)&sThisAddressSpace;
-
-///
-/// delete an address_space object
-///
-EXPORT void unw_destroy_addr_space(unw_addr_space_t asp)
-{
- if(asp->type != UNW_REMOTE) {
- ABORT("unw_destroy_addr_space was passed a non-remote address space");
- return;
- }
-
- unw_addr_space_remote* remote = (unw_addr_space_remote*)asp;
- delete remote->ras;
-}
-
-EXPORT void unw_set_logging_level(unw_addr_space_t as, FILE *f, unw_log_level_t level)
-{
- if (as->type != UNW_REMOTE) {
- ABORT("unw_set_logging_level was passed a non-remote address space");
- return;
- }
-
- unw_addr_space_remote* remote = (unw_addr_space_remote*)as;
- return remote->ras->setLoggingLevel(f, level);
-}
-
-
-EXPORT int unw_end_of_prologue_setup(unw_cursor_t* cursor, unw_word_t start, unw_word_t end, unw_word_t *endofprologue)
-{
- AbstractRemoteUnwindCursor* co = (AbstractRemoteUnwindCursor*)cursor;
- if (!co->remoteUnwindCursor())
- ABORT("unw_end_of_prologue_setup called with a non-remote unwind cursor.");
-
- return co->endOfPrologueInsns (start, end, endofprologue);
-}
-
-
-#endif // SUPPORT_REMOTE_UNWINDING
-
-#pragma mark Dynamic unwinding API
-
-#if !FOR_DYLD
-///
-/// SPI: walks cached dwarf entries
-///
-EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)(unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh))
-{
- DEBUG_PRINT_API("unw_iterate_dwarf_unwind_cache(func=%p)\n", func);
- DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
-}
-#endif // !FOR_DYLD
-
-#if !FOR_DYLD
-//
-// IPI: for __register_frame()
-//
-void _unw_add_dynamic_fde(unw_word_t fde)
-{
- CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
- CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
- const char* message = CFI_Parser<LocalAddressSpace>::decodeFDE(sThisAddressSpace, (LocalAddressSpace::pint_t)fde, & fdeInfo, &cieInfo);
- if ( message == NULL ) {
- // dynamically registered FDEs don't have a mach_header group they are in. Use fde as mh_group
- unw_word_t mh_group = fdeInfo.fdeStart;
- DwarfFDECache<LocalAddressSpace>::add(mh_group, fdeInfo.pcStart, fdeInfo.pcEnd, fdeInfo.fdeStart);
- }
- else {
- DEBUG_MESSAGE("_unw_add_dynamic_fde: bad fde: %s", message);
- }
-}
-
-//
-// IPI: for __deregister_frame()
-//
-void _unw_remove_dynamic_fde(unw_word_t fde)
-{
- // fde is own mh_group
- DwarfFDECache<LocalAddressSpace>::removeAllIn(fde);
-}
-#endif
-
-}; // namespace lldb_private
-
-#endif // __ppc__ || __i386__ || __x86_64__
diff --git a/lldb/source/Plugins/Process/Utility/libunwind/src/unw_getcontext.s b/lldb/source/Plugins/Process/Utility/libunwind/src/unw_getcontext.s
deleted file mode 100644
index 8d3a451fd92..00000000000
--- a/lldb/source/Plugins/Process/Utility/libunwind/src/unw_getcontext.s
+++ /dev/null
@@ -1,229 +0,0 @@
-
-#if __i386__ || __x86_64__ || __ppc__
-
- .text
- .globl _unw_getcontext
-_unw_getcontext:
-
-#endif // __i386__ || __x86_64__ || __ppc__
-
-
-#if __i386__
-
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-#
-# On entry:
-# + +
-# +-----------------------+
-# + thread_state pointer +
-# +-----------------------+
-# + return address +
-# +-----------------------+ <-- SP
-# + +
-#
- push %eax
- movl 8(%esp), %eax
- movl %ebx, 4(%eax)
- movl %ecx, 8(%eax)
- movl %edx, 12(%eax)
- movl %edi, 16(%eax)
- movl %esi, 20(%eax)
- movl %ebp, 24(%eax)
- movl %esp, %edx
- addl $8, %edx
- movl %edx, 28(%eax) # store what sp was at call site as esp
- # skip ss
- # skip eflags
- movl 4(%esp), %edx
- movl %edx, 40(%eax) # store return address as eip
- # skip cs
- # skip ds
- # skip es
- # skip fs
- # skip gs
- movl (%esp), %edx
- movl %edx, (%eax) # store original eax
- popl %eax
- xorl %eax, %eax # return UNW_ESUCCESS
- ret
-
-#elif __x86_64__
-
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-#
-# On entry:
-# thread_state pointer is in rdi
-#
- movq %rax, (%rdi)
- movq %rbx, 8(%rdi)
- movq %rcx, 16(%rdi)
- movq %rdx, 24(%rdi)
- movq %rdi, 32(%rdi)
- movq %rsi, 40(%rdi)
- movq %rbp, 48(%rdi)
- movq %rsp, 56(%rdi)
- addq $8, 56(%rdi)
- movq %r8, 64(%rdi)
- movq %r9, 72(%rdi)
- movq %r10, 80(%rdi)
- movq %r11, 88(%rdi)
- movq %r12, 96(%rdi)
- movq %r13,104(%rdi)
- movq %r14,112(%rdi)
- movq %r15,120(%rdi)
- movq (%rsp),%rsi
- movq %rsi,128(%rdi) # store return address as rip
- # skip rflags
- # skip cs
- # skip fs
- # skip gs
- xorl %eax, %eax # return UNW_ESUCCESS
- ret
-
-#elif __ppc__
-
-;
-; extern int unw_getcontext(unw_context_t* thread_state)
-;
-; On entry:
-; thread_state pointer is in r3
-;
- stw r0, 8(r3)
- mflr r0
- stw r0, 0(r3) ; store lr as ssr0
- stw r1, 12(r3)
- stw r2, 16(r3)
- stw r3, 20(r3)
- stw r4, 24(r3)
- stw r5, 28(r3)
- stw r6, 32(r3)
- stw r7, 36(r3)
- stw r8, 40(r3)
- stw r9, 44(r3)
- stw r10, 48(r3)
- stw r11, 52(r3)
- stw r12, 56(r3)
- stw r13, 60(r3)
- stw r14, 64(r3)
- stw r15, 68(r3)
- stw r16, 72(r3)
- stw r17, 76(r3)
- stw r18, 80(r3)
- stw r19, 84(r3)
- stw r20, 88(r3)
- stw r21, 92(r3)
- stw r22, 96(r3)
- stw r23,100(r3)
- stw r24,104(r3)
- stw r25,108(r3)
- stw r26,112(r3)
- stw r27,116(r3)
- stw r28,120(r3)
- stw r29,124(r3)
- stw r30,128(r3)
- stw r31,132(r3)
-
- ; save VRSave register
- mfspr r0,256
- stw r0,156(r3)
- ; save CR registers
- mfcr r0
- stw r0,136(r3)
- ; save CTR register
- mfctr r0
- stw r0,148(r3)
-
- ; save float registers
- stfd f0, 160(r3)
- stfd f1, 168(r3)
- stfd f2, 176(r3)
- stfd f3, 184(r3)
- stfd f4, 192(r3)
- stfd f5, 200(r3)
- stfd f6, 208(r3)
- stfd f7, 216(r3)
- stfd f8, 224(r3)
- stfd f9, 232(r3)
- stfd f10,240(r3)
- stfd f11,248(r3)
- stfd f12,256(r3)
- stfd f13,264(r3)
- stfd f14,272(r3)
- stfd f15,280(r3)
- stfd f16,288(r3)
- stfd f17,296(r3)
- stfd f18,304(r3)
- stfd f19,312(r3)
- stfd f20,320(r3)
- stfd f21,328(r3)
- stfd f22,336(r3)
- stfd f23,344(r3)
- stfd f24,352(r3)
- stfd f25,360(r3)
- stfd f26,368(r3)
- stfd f27,376(r3)
- stfd f28,384(r3)
- stfd f29,392(r3)
- stfd f30,400(r3)
- stfd f31,408(r3)
-
-
- ; save vector registers
-
- subi r4,r1,16
- rlwinm r4,r4,0,0,27 ; mask low 4-bits
- ; r4 is now a 16-byte aligned pointer into the red zone
-
-#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
- stvx _vec,0,r4 @\
- lwz r5, 0(r4) @\
- stw r5, _offset(r3) @\
- lwz r5, 4(r4) @\
- stw r5, _offset+4(r3) @\
- lwz r5, 8(r4) @\
- stw r5, _offset+8(r3) @\
- lwz r5, 12(r4) @\
- stw r5, _offset+12(r3)
-
- SAVE_VECTOR_UNALIGNED( v0, 424+0x000)
- SAVE_VECTOR_UNALIGNED( v1, 424+0x010)
- SAVE_VECTOR_UNALIGNED( v2, 424+0x020)
- SAVE_VECTOR_UNALIGNED( v3, 424+0x030)
- SAVE_VECTOR_UNALIGNED( v4, 424+0x040)
- SAVE_VECTOR_UNALIGNED( v5, 424+0x050)
- SAVE_VECTOR_UNALIGNED( v6, 424+0x060)
- SAVE_VECTOR_UNALIGNED( v7, 424+0x070)
- SAVE_VECTOR_UNALIGNED( v8, 424+0x080)
- SAVE_VECTOR_UNALIGNED( v9, 424+0x090)
- SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0)
- SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0)
- SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0)
- SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0)
- SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0)
- SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0)
- SAVE_VECTOR_UNALIGNED(v16, 424+0x100)
- SAVE_VECTOR_UNALIGNED(v17, 424+0x110)
- SAVE_VECTOR_UNALIGNED(v18, 424+0x120)
- SAVE_VECTOR_UNALIGNED(v19, 424+0x130)
- SAVE_VECTOR_UNALIGNED(v20, 424+0x140)
- SAVE_VECTOR_UNALIGNED(v21, 424+0x150)
- SAVE_VECTOR_UNALIGNED(v22, 424+0x160)
- SAVE_VECTOR_UNALIGNED(v23, 424+0x170)
- SAVE_VECTOR_UNALIGNED(v24, 424+0x180)
- SAVE_VECTOR_UNALIGNED(v25, 424+0x190)
- SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0)
- SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0)
- SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0)
- SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0)
- SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0)
- SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0)
-
- li r3, 0 ; return UNW_ESUCCESS
- blr
-
-
-
-#endif
-
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 1f0bc149833..934c00a3d1a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -45,7 +45,6 @@
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
-#include "MacOSXLibunwindCallbacks.h"
#include "StopInfoMachException.h"
@@ -119,8 +118,6 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
m_packet_timeout (1),
m_max_memory_size (512),
- m_libunwind_target_type (UNW_TARGET_UNSPECIFIED),
- m_libunwind_addr_space (NULL),
m_waiting_for_attach (false),
m_local_debugserver (true)
{
@@ -1615,7 +1612,6 @@ ProcessGDBRemote::Clear()
Mutex::Locker locker(m_stdio_mutex);
m_stdout_data.clear();
}
- DestoryLibUnwindAddressSpace();
}
Error
@@ -2170,45 +2166,6 @@ ProcessGDBRemote::AsyncThread (void *arg)
return NULL;
}
-lldb_private::unw_addr_space_t
-ProcessGDBRemote::GetLibUnwindAddressSpace ()
-{
- unw_targettype_t target_type = UNW_TARGET_UNSPECIFIED;
-
- ArchSpec::CPU arch_cpu = m_target.GetArchitecture().GetGenericCPUType();
- if (arch_cpu == ArchSpec::eCPU_i386)
- target_type = UNW_TARGET_I386;
- else if (arch_cpu == ArchSpec::eCPU_x86_64)
- target_type = UNW_TARGET_X86_64;
-
- if (m_libunwind_addr_space)
- {
- if (m_libunwind_target_type != target_type)
- DestoryLibUnwindAddressSpace();
- else
- return m_libunwind_addr_space;
- }
- unw_accessors_t callbacks = get_macosx_libunwind_callbacks ();
- m_libunwind_addr_space = unw_create_addr_space (&callbacks, target_type);
- if (m_libunwind_addr_space)
- m_libunwind_target_type = target_type;
- else
- m_libunwind_target_type = UNW_TARGET_UNSPECIFIED;
- return m_libunwind_addr_space;
-}
-
-void
-ProcessGDBRemote::DestoryLibUnwindAddressSpace ()
-{
- if (m_libunwind_addr_space)
- {
- unw_destroy_addr_space (m_libunwind_addr_space);
- m_libunwind_addr_space = NULL;
- }
- m_libunwind_target_type = UNW_TARGET_UNSPECIFIED;
-}
-
-
const char *
ProcessGDBRemote::GetDispatchQueueNameForThread
(
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index a2b5898b34e..74905d0e646 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -29,7 +29,6 @@
#include "GDBRemoteCommunication.h"
#include "Utility/StringExtractor.h"
#include "GDBRemoteRegisterContext.h"
-#include "libunwind/include/libunwind.h"
class ThreadGDBRemote;
@@ -335,8 +334,6 @@ protected:
lldb::addr_t m_dispatch_queue_offsets_addr;
uint32_t m_packet_timeout;
size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory
- lldb_private::unw_targettype_t m_libunwind_target_type;
- lldb_private::unw_addr_space_t m_libunwind_addr_space; // libunwind address space object for this process.
bool m_waiting_for_attach;
bool m_local_debugserver; // Is the debugserver process we are talking to local or on another machine.
@@ -384,11 +381,6 @@ private:
//------------------------------------------------------------------
DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
- lldb_private::unw_addr_space_t
- GetLibUnwindAddressSpace ();
-
- void
- DestoryLibUnwindAddressSpace ();
};
#endif // liblldb_ProcessGDBRemote_h_
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index c1b5fa47d93..f5491cb9202 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -20,11 +20,9 @@
#include "lldb/Target/Unwind.h"
#include "lldb/Breakpoint/WatchpointLocation.h"
-#include "LibUnwindRegisterContext.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "Utility/StringExtractorGDBRemote.h"
-#include "UnwindLibUnwind.h"
#include "UnwindMacOSXFrameBackchain.h"
#include "UnwindLLDB.h"
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index a6deead8f15..2b7344d128a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -14,7 +14,6 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
-#include "libunwind/include/libunwind.h"
class StringExtractor;
class ProcessGDBRemote;
OpenPOWER on IntegriCloud