summaryrefslogtreecommitdiffstats
path: root/debuggerd/pr-support.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:29:04 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:29:04 -0800
commite54eebbf1a908d65ee8cf80bab62821c05666d70 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /debuggerd/pr-support.c
parenta1e1c1b106423de09bc918502e7a51d4ffe5a4ae (diff)
downloadsystem_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.c345
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,
- &reg);
- _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32,
- &reg);
- 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, &reg);
- if (op & 0x40)
- reg -= offset;
- else
- reg += offset;
- _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &reg);
- 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, &reg);
- _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &reg);
- 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,
- &reg);
- 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,
- &reg);
- 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;
-}