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