diff options
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx')
| -rw-r--r-- | lldb/source/Plugins/Process/Utility/libunwind/src/libuwind.cxx | 428 |
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__ |

