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