1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* ARM EABI compliant unwinding routines 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Contributed by Paul Brook 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project This file is free software; you can redistribute it and/or modify it 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project under the terms of the GNU General Public License as published by the 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Free Software Foundation; either version 2, or (at your option) any 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project later version. 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project In addition to the permissions in the GNU General Public License, the 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Free Software Foundation gives you unlimited permission to link the 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project compiled version of this file into combinations with other programs, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project and to distribute those combinations without any restriction coming 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project from the use of this file. (The General Public License restrictions 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do apply in other respects; for example, they cover modification of 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project the file, and distribution when not linked into a combine 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project executable.) 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project This file is distributed in the hope that it will be useful, but 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project WITHOUT ANY WARRANTY; without even the implied warranty of 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project General Public License for more details. 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project You should have received a copy of the GNU General Public License 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project along with this program; see the file COPYING. If not, write to 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Boston, MA 02110-1301, USA. */ 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************** 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The functions here are derived from gcc/config/arm/pr-support.c from the 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4.3.x release. The main changes here involve the use of ptrace to retrieve 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * memory/processor states from a remote process. 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ****************************************************************************/ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unwind.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utility.h" 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* We add a prototype for abort here to avoid creating a dependency on 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project target headers. */ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern void abort (void); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Derived from _Unwind_VRS_Pop to use ptrace */ 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern _Unwind_VRS_Result 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunwind_VRS_Pop_with_ptrace (_Unwind_Context *context, 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_RegClass regclass, 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw discriminator, 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_DataRepresentation representation, 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Misc constants. */ 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define R_IP 12 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define R_SP 13 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define R_LR 14 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define R_PC 15 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define uint32_highbit (((_uw) 1) << 31) 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Unwind descriptors. */ 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw16 length; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw16 offset; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EHT16; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw length; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw offset; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EHT32; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Personality routine helper functions. */ 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CODE_FINISH (0xb0) 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Derived from next_unwind_byte to use ptrace */ 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Return the next byte of unwinding information, or CODE_FINISH if there is 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project no data remaining. */ 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline _uw8 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnext_unwind_byte_with_ptrace (__gnu_unwind_state * uws, pid_t pid) 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw8 b; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (uws->bytes_left == 0) 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Load another word */ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (uws->words_left == 0) 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return CODE_FINISH; /* Nothing left. */ 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->words_left--; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->data = get_remote_word(pid, uws->next); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->next++; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->bytes_left = 3; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->bytes_left--; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Extract the most significant byte. */ 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project b = (uws->data >> 24) & 0xff; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project uws->data <<= 8; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return b; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Execute the unwinding instructions described by UWS. */ 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_Unwind_Reason_Code 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunwind_execute_with_ptrace(_Unwind_Context * context, __gnu_unwind_state * uws, 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid) 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw op; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int set_pc; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw reg; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_pc = 0; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == CODE_FINISH) 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If we haven't already set pc then copy it from lr. */ 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!set_pc) 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ®); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ®); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_pc = 1; 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Drop out of the loop. */ 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0x80) == 0) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* vsp = vsp +- (imm6 << 2 + 4). */ 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw offset; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project offset = ((op & 0x3f) << 2) + 4; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op & 0x40) 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg -= offset; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg += offset; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf0) == 0x80) 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = (op << 8) | next_unwind_byte_with_ptrace (uws, pid); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0x8000) 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Refuse to unwind. */ 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop r4-r15 under mask. */ 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = (op << 4) & 0xfff0; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, _UVRSD_UINT32, 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op & (1 << R_PC)) 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_pc = 1; 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf0) == 0x90) 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op &= 0xf; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 13 || op == 15) 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Reserved. */ 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* vsp = r[nnnn]. */ 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf0) == 0xa0) 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop r4-r[4+nnn], [lr]. */ 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _uw mask; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mask = (0xff0 >> (7 - (op & 7))) & 0xff0; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op & 8) 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mask |= (1 << R_LR); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, mask, _UVRSD_UINT32, 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf0) == 0xb0) 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* op == 0xb0 already handled. */ 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xb1) 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0 || ((op & 0xf0) != 0)) 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Spare. */ 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop r0-r4 under mask. */ 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_UINT32, pid) 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xb2) 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* vsp = vsp + 0x204 + (uleb128 << 2). */ 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int shift; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ®); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project shift = 2; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (op & 0x80) 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg += ((op & 0x7f) << shift); 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project shift += 7; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg += ((op & 0x7f) << shift) + 0x204; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ®); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xb3) 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop VFP registers with fldmx. */ 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xfc) == 0xb4) 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop FPA E[4]-E[4+nn]. */ 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = 0x40000 | ((op & 3) + 1); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* op & 0xf8 == 0xb8. */ 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop VFP D[8]-D[8+nnn] with fldmx. */ 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = 0x80000 | ((op & 7) + 1); 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, pid) 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf0) == 0xc0) 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xc6) 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop iWMMXt D registers. */ 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_UINT64, pid) 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xc7) 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0 || (op & 0xf0) != 0) 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Spare. */ 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop iWMMXt wCGR{3,2,1,0} under mask. */ 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXC, op, 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_UINT32, pid) 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf8) == 0xc0) 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop iWMMXt wR[10]-wR[10+nnn]. */ 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = 0xa0000 | ((op & 0xf) + 1); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_UINT64, pid) 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xc8) 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef __VFP_FP__ 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop FPA registers. */ 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop VFPv3 registers D[16+ssss]-D[16+ssss+cccc] with vldm. */ 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = (((op & 0xf0) + 16) << 12) | ((op & 0xf) + 1); 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_DOUBLE, pid) 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (op == 0xc9) 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop VFP registers with fldmd. */ 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = next_unwind_byte_with_ptrace (uws, pid); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _UVRSD_DOUBLE, pid) 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Spare. */ 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((op & 0xf8) == 0xd0) 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Pop VFP D[8]-D[8+nnn] with fldmd. */ 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project op = 0x80000 | ((op & 7) + 1); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_DOUBLE, 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid) 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project != _UVRSR_OK) 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Spare. */ 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_FAILURE; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return _URC_OK; 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 346