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> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utility.h" 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Get a word from pid using ptrace. The result is the return value. */ 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint get_remote_word(int pid, void *src) 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ptrace(PTRACE_PEEKTEXT, pid, src, NULL); 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Handy routine to read aggregated data from pid using ptrace. The read 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * values are written to the dest locations directly. 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid get_remote_struct(int pid, void *src, void *dst, size_t size) 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int i; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i+4 <= size; i+=4) { 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *(int *)(dst+i) = ptrace(PTRACE_PEEKTEXT, pid, src+i, NULL); 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i < size) { 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int val; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project assert((size - i) < 4); 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project val = ptrace(PTRACE_PEEKTEXT, pid, src+i, NULL); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (i < size) { 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((unsigned char *)dst)[i] = val & 0xff; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project i++; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project val >>= 8; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Map a pc address to the name of the containing ELF file */ 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *map_to_name(mapinfo *mi, unsigned pc, const char* def) 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(mi) { 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((pc >= mi->start) && (pc < mi->end)){ 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mi->name; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mi = mi->next; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return def; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Find the containing map info for the pc */ 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc) 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(mi) { 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((pc >= mi->start) && (pc < mi->end)){ 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Only calculate the relative offset for shared libraries 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (strstr(mi->name, ".so")) { 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *rel_pc = pc - mi->start; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mi; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mi = mi->next; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 84