summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx')
-rw-r--r--lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx428
1 files changed, 0 insertions, 428 deletions
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__
OpenPOWER on IntegriCloud