1501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/*
2501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Copyright (C) 2011 The Android Open Source Project
3501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *
4501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * you may not use this file except in compliance with the License.
6501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * You may obtain a copy of the License at
7501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *
8501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *
10501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unless required by applicable law or agreed to in writing, software
11501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * See the License for the specific language governing permissions and
14501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * limitations under the License.
15501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */
16501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
17501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* Useful ptrace() utility functions. */
18501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
19501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifndef _CORKSCREW_PTRACE_H
20501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#define _CORKSCREW_PTRACE_H
21501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
22501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/map_info.h>
23501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/symbol_table.h>
24501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
25501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <sys/types.h>
26501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <stdbool.h>
27420a7fa82d0fba6516d76d6024728de010b1cb8dElliott Hughes#include <stdint.h>
28501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
29501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef __cplusplus
30501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownextern "C" {
31501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif
32501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
33501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* Stores information about a process that is used for several different
34501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * ptrace() based operations. */
35501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Browntypedef struct {
36501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    map_info_t* map_info_list;
37501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} ptrace_context_t;
38501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
39f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown/* Describes how to access memory from a process. */
40f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Browntypedef struct {
41f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    pid_t tid;
42f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown    const map_info_t* map_info_list;
43f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown} memory_t;
44f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown
45501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#if __i386__
46501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* ptrace() register context. */
47501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Browntypedef struct pt_regs_x86 {
48501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t ebx;
49501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t ecx;
50501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t edx;
51501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t esi;
52501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t edi;
53501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t ebp;
54501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t eax;
55501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xds;
56501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xes;
57501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xfs;
58501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xgs;
59501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t orig_eax;
60501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t eip;
61501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xcs;
62501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t eflags;
63501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t esp;
64501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown    uint32_t xss;
65501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} pt_regs_x86_t;
66501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif
67501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
68231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman#if __mips__
69231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman/* ptrace() GET_REGS context. */
70231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearmantypedef struct pt_regs_mips {
71231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t regs[32];
72231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t lo;
73231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t hi;
74231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t cp0_epc;
75231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t cp0_badvaddr;
76231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t cp0_status;
77231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman    uint64_t cp0_cause;
78231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman} pt_regs_mips_t;
79231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman#endif
80231e3c83a3a70b11160fb0da108ebf2e0e7470e2Chris Dearman
81501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/*
82f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * Initializes a memory structure for accessing memory from this process.
83f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown */
84f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brownvoid init_memory(memory_t* memory, const map_info_t* map_info_list);
85f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown
86f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown/*
87f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * Initializes a memory structure for accessing memory from another process
88f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * using ptrace().
89f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown */
90f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brownvoid init_memory_ptrace(memory_t* memory, pid_t tid);
91f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown
92f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown/*
93501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Reads a word of memory safely.
94f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * If the memory is local, ensures that the address is readable before dereferencing it.
95f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * Returns false and a value of 0xffffffff if the word could not be read.
96f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown */
97f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brownbool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value);
98f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown
99f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown/*
100f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * Reads a word of memory safely using ptrace().
101f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown * Returns false and a value of 0xffffffff if the word could not be read.
102501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */
103f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brownbool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value);
104501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
105501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/*
106501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Loads information needed for examining a remote process using ptrace().
107501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The caller must already have successfully attached to the process
108501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * using ptrace().
109501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *
110501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The context can be used for any threads belonging to that process
111501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * assuming ptrace() is attached to them before performing the actual
112501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * unwinding.  The context can continue to be used to decode backtraces
113501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * even after ptrace() has been detached from the process.
114501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */
115501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownptrace_context_t* load_ptrace_context(pid_t pid);
116501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
117501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/*
118501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Frees a ptrace context.
119501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */
120501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid free_ptrace_context(ptrace_context_t* context);
121501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
122501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/*
123501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Finds a symbol using ptrace.
124501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Returns the containing map and information about the symbol, or
125501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * NULL if one or the other is not available.
126501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */
127501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid find_symbol_ptrace(const ptrace_context_t* context,
128501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown        uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol);
129501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
130501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef __cplusplus
131501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown}
132501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif
133501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown
134501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif // _CORKSCREW_PTRACE_H
135