utility.c revision 136dcc5ce628a1ba600a6818e5cb24d5f15eb016
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* system/debuggerd/utility.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2008, The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License. 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ptrace.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/exec_elf.h> 20136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden#include <signal.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utility.h" 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Get a word from pid using ptrace. The result is the return value. */ 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint get_remote_word(int pid, void *src) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ptrace(PTRACE_PEEKTEXT, pid, src, NULL); 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Handy routine to read aggregated data from pid using ptrace. The read 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * values are written to the dest locations directly. 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid get_remote_struct(int pid, void *src, void *dst, size_t size) 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int i; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i+4 <= size; i+=4) { 42849249064cae9c1bb23b0204b5d35b832567801eBruce Beare *(int *)((char *)dst+i) = ptrace(PTRACE_PEEKTEXT, pid, (char *)src+i, NULL); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i < size) { 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int val; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project assert((size - i) < 4); 49849249064cae9c1bb23b0204b5d35b832567801eBruce Beare val = ptrace(PTRACE_PEEKTEXT, pid, (char *)src+i, NULL); 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (i < size) { 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((unsigned char *)dst)[i] = val & 0xff; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i++; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project val >>= 8; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Map a pc address to the name of the containing ELF file */ 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *map_to_name(mapinfo *mi, unsigned pc, const char* def) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(mi) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((pc >= mi->start) && (pc < mi->end)){ 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mi->name; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mi = mi->next; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return def; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Find the containing map info for the pc */ 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc) 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 736cc492308712613cd23bee9240b1757428841a2fBruce Beare *rel_pc = pc; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(mi) { 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((pc >= mi->start) && (pc < mi->end)){ 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Only calculate the relative offset for shared libraries 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strstr(mi->name, ".so")) { 786cc492308712613cd23bee9240b1757428841a2fBruce Beare *rel_pc -= mi->start; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mi; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mi = mi->next; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 86136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden 87136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden/* 88136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden * Returns true if the specified signal has an associated address (i.e. it 89136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden * sets siginfo_t.si_addr). 90136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden */ 91136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFaddenbool signal_has_address(int sig) 92136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden{ 93136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden switch (sig) { 94136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden case SIGILL: 95136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden case SIGFPE: 96136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden case SIGSEGV: 97136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden case SIGBUS: 98136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden return true; 99136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden default: 100136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden return false; 101136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden } 102136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden} 103