120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris/* 220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * 320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * Copyright 2006, The Android Open Source Project 420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * 520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * you may not use this file except in compliance with the License. 720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * You may obtain a copy of the License at 820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * 920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 1020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * 1120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * Unless required by applicable law or agreed to in writing, software 1220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * See the License for the specific language governing permissions and 1520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris * limitations under the License. 1620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris */ 17849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 18b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris#define LOG_TAG "DEBUG" 19b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris 209e7d2180c7ac60d4bec1c7a91f52dc765b39814cElliott Hughes#include <errno.h> 21e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris#include <stdint.h> 22053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <string.h> 23849249064cae9c1bb23b0204b5d35b832567801eBruce Beare#include <sys/ptrace.h> 24849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 25e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris#include <backtrace/Backtrace.h> 26b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris#include <log/log.h> 27849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 28e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris#include "machine.h" 29e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris#include "utility.h" 30e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris 31e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferrisvoid dump_memory_and_code(log_t* log, Backtrace* backtrace) { 32e7f18e14a9e9267150e24f0cb8bd8bd52db7946eElliott Hughes pt_regs regs; 33e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, ®s)) { 34b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris ALOGE("cannot get registers: %s\n", strerror(errno)); 3520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris return; 3620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 3720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 38e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris static const char reg_names[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp"; 3920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 4062ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smith for (int reg = 0; reg < 14; reg++) { 41e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris dump_memory(log, backtrace, regs.uregs[reg], "memory near %.2s:", ®_names[reg * 2]); 4220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 43849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 44e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris dump_memory(log, backtrace, static_cast<uintptr_t>(regs.ARM_pc), "code around pc:"); 45f2eae5a860ebdf0dd47669c9bf58b8824b57728cAndy McFadden 4620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris if (regs.ARM_pc != regs.ARM_lr) { 47e8bc77eb845ab5557a4c98fe0da604d4a3740befChristopher Ferris dump_memory(log, backtrace, static_cast<uintptr_t>(regs.ARM_lr), "code around lr:"); 4820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 49849249064cae9c1bb23b0204b5d35b832567801eBruce Beare} 50849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 5162ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smithvoid dump_registers(log_t* log, pid_t tid) { 52e7f18e14a9e9267150e24f0cb8bd8bd52db7946eElliott Hughes pt_regs r; 5320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris if (ptrace(PTRACE_GETREGS, tid, 0, &r)) { 54b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris ALOGE("cannot get registers: %s\n", strerror(errno)); 5520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris return; 5620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 5720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 5862ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smith _LOG(log, logtype::REGISTERS, " r0 %08x r1 %08x r2 %08x r3 %08x\n", 5920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1), 6020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3)); 6162ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smith _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n", 6220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5), 6320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7)); 6462ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smith _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n", 6520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9), 6620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp)); 6762ba489ba00a2689d4e257bc178cff87495f99d7Brigid Smith _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", 6820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp), 6920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc), 7020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris static_cast<uint32_t>(r.ARM_cpsr)); 71849249064cae9c1bb23b0204b5d35b832567801eBruce Beare 72e7f18e14a9e9267150e24f0cb8bd8bd52db7946eElliott Hughes user_vfp vfp_regs; 7320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) { 74b36b5923386be8d74da2767dfc1dc62a0012a655Christopher Ferris ALOGE("cannot get FP registers: %s\n", strerror(errno)); 7520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris return; 7620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 7720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 78e7f18e14a9e9267150e24f0cb8bd8bd52db7946eElliott Hughes for (size_t i = 0; i < 32; i += 2) { 79b40c50351ebd9fb40b76a3169ad5cc6a25c453f1Elliott Hughes _LOG(log, logtype::FP_REGISTERS, " d%-2d %016llx d%-2d %016llx\n", 8020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]); 8120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 82b40c50351ebd9fb40b76a3169ad5cc6a25c453f1Elliott Hughes _LOG(log, logtype::FP_REGISTERS, " scr %08lx\n", vfp_regs.fpscr); 83849249064cae9c1bb23b0204b5d35b832567801eBruce Beare} 84