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