diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:29:04 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:29:04 -0800 |
commit | e54eebbf1a908d65ee8cf80bab62821c05666d70 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /debuggerd/pr-support.c | |
parent | a1e1c1b106423de09bc918502e7a51d4ffe5a4ae (diff) | |
download | system_core-e54eebbf1a908d65ee8cf80bab62821c05666d70.tar.gz system_core-e54eebbf1a908d65ee8cf80bab62821c05666d70.tar.bz2 system_core-e54eebbf1a908d65ee8cf80bab62821c05666d70.zip |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'debuggerd/pr-support.c')
-rw-r--r-- | debuggerd/pr-support.c | 345 |
1 files changed, 0 insertions, 345 deletions
diff --git a/debuggerd/pr-support.c b/debuggerd/pr-support.c deleted file mode 100644 index 358d9b77a..000000000 --- a/debuggerd/pr-support.c +++ /dev/null @@ -1,345 +0,0 @@ -/* ARM EABI compliant unwinding routines - Copyright (C) 2004, 2005 Free Software Foundation, Inc. - Contributed by Paul Brook - - This file is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - In addition to the permissions in the GNU General Public License, the - Free Software Foundation gives you unlimited permission to link the - compiled version of this file into combinations with other programs, - and to distribute those combinations without any restriction coming - from the use of this file. (The General Public License restrictions - do apply in other respects; for example, they cover modification of - the file, and distribution when not linked into a combine - executable.) - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/**************************************************************************** - * The functions here are derived from gcc/config/arm/pr-support.c from the - * 4.3.x release. The main changes here involve the use of ptrace to retrieve - * memory/processor states from a remote process. - ****************************************************************************/ - -#include <sys/types.h> -#include <unwind.h> - -#include "utility.h" - -/* We add a prototype for abort here to avoid creating a dependency on - target headers. */ -extern void abort (void); - -/* Derived from _Unwind_VRS_Pop to use ptrace */ -extern _Unwind_VRS_Result -unwind_VRS_Pop_with_ptrace (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw discriminator, - _Unwind_VRS_DataRepresentation representation, - pid_t pid); - -typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ - -/* Misc constants. */ -#define R_IP 12 -#define R_SP 13 -#define R_LR 14 -#define R_PC 15 - -#define uint32_highbit (((_uw) 1) << 31) - -void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); - -/* Unwind descriptors. */ - -typedef struct -{ - _uw16 length; - _uw16 offset; -} EHT16; - -typedef struct -{ - _uw length; - _uw offset; -} EHT32; - -/* Personality routine helper functions. */ - -#define CODE_FINISH (0xb0) - -/* Derived from next_unwind_byte to use ptrace */ -/* Return the next byte of unwinding information, or CODE_FINISH if there is - no data remaining. */ -static inline _uw8 -next_unwind_byte_with_ptrace (__gnu_unwind_state * uws, pid_t pid) -{ - _uw8 b; - - if (uws->bytes_left == 0) - { - /* Load another word */ - if (uws->words_left == 0) - return CODE_FINISH; /* Nothing left. */ - uws->words_left--; - uws->data = get_remote_word(pid, uws->next); - uws->next++; - uws->bytes_left = 3; - } - else - uws->bytes_left--; - - /* Extract the most significant byte. */ - b = (uws->data >> 24) & 0xff; - uws->data <<= 8; - return b; -} - -/* Execute the unwinding instructions described by UWS. */ -_Unwind_Reason_Code -unwind_execute_with_ptrace(_Unwind_Context * context, __gnu_unwind_state * uws, - pid_t pid) -{ - _uw op; - int set_pc; - _uw reg; - - set_pc = 0; - for (;;) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == CODE_FINISH) - { - /* If we haven't already set pc then copy it from lr. */ - if (!set_pc) - { - _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, - ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, - ®); - set_pc = 1; - } - /* Drop out of the loop. */ - break; - } - if ((op & 0x80) == 0) - { - /* vsp = vsp +- (imm6 << 2 + 4). */ - _uw offset; - - offset = ((op & 0x3f) << 2) + 4; - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - if (op & 0x40) - reg -= offset; - else - reg += offset; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - - if ((op & 0xf0) == 0x80) - { - op = (op << 8) | next_unwind_byte_with_ptrace (uws, pid); - if (op == 0x8000) - { - /* Refuse to unwind. */ - return _URC_FAILURE; - } - /* Pop r4-r15 under mask. */ - op = (op << 4) & 0xfff0; - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, _UVRSD_UINT32, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - if (op & (1 << R_PC)) - set_pc = 1; - continue; - } - if ((op & 0xf0) == 0x90) - { - op &= 0xf; - if (op == 13 || op == 15) - /* Reserved. */ - return _URC_FAILURE; - /* vsp = r[nnnn]. */ - _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - if ((op & 0xf0) == 0xa0) - { - /* Pop r4-r[4+nnn], [lr]. */ - _uw mask; - - mask = (0xff0 >> (7 - (op & 7))) & 0xff0; - if (op & 8) - mask |= (1 << R_LR); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, mask, _UVRSD_UINT32, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xb0) - { - /* op == 0xb0 already handled. */ - if (op == 0xb1) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == 0 || ((op & 0xf0) != 0)) - /* Spare. */ - return _URC_FAILURE; - /* Pop r0-r4 under mask. */ - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, - _UVRSD_UINT32, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xb2) - { - /* vsp = vsp + 0x204 + (uleb128 << 2). */ - int shift; - - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - op = next_unwind_byte_with_ptrace (uws, pid); - shift = 2; - while (op & 0x80) - { - reg += ((op & 0x7f) << shift); - shift += 7; - op = next_unwind_byte_with_ptrace (uws, pid); - } - reg += ((op & 0x7f) << shift) + 0x204; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - continue; - } - if (op == 0xb3) - { - /* Pop VFP registers with fldmx. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xfc) == 0xb4) - { - /* Pop FPA E[4]-E[4+nn]. */ - op = 0x40000 | ((op & 3) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* op & 0xf8 == 0xb8. */ - /* Pop VFP D[8]-D[8+nnn] with fldmx. */ - op = 0x80000 | ((op & 7) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xc0) - { - if (op == 0xc6) - { - /* Pop iWMMXt D registers. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, - _UVRSD_UINT64, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc7) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == 0 || (op & 0xf0) != 0) - /* Spare. */ - return _URC_FAILURE; - /* Pop iWMMXt wCGR{3,2,1,0} under mask. */ - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXC, op, - _UVRSD_UINT32, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf8) == 0xc0) - { - /* Pop iWMMXt wR[10]-wR[10+nnn]. */ - op = 0xa0000 | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, - _UVRSD_UINT64, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc8) - { -#ifndef __VFP_FP__ - /* Pop FPA registers. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#else - /* Pop VFPv3 registers D[16+ssss]-D[16+ssss+cccc] with vldm. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = (((op & 0xf0) + 16) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, - _UVRSD_DOUBLE, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#endif - } - if (op == 0xc9) - { - /* Pop VFP registers with fldmd. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, - _UVRSD_DOUBLE, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - if ((op & 0xf8) == 0xd0) - { - /* Pop VFP D[8]-D[8+nnn] with fldmd. */ - op = 0x80000 | ((op & 7) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_DOUBLE, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - return _URC_OK; -} |