* Makefile.in (mips-tdep.o, target-descriptions.o): Update.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-mips-low.c
CommitLineData
0a30fbc4 1/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
21b0f40c 2 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2006
0a30fbc4
DJ
3 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
6f0f660e
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
0a30fbc4
DJ
21
22#include "server.h"
58caa3dc 23#include "linux-low.h"
0a30fbc4 24
21b0f40c
DJ
25#include <sys/ptrace.h>
26
27#include "gdb_proc_service.h"
28
29#ifndef PTRACE_GET_THREAD_AREA
30#define PTRACE_GET_THREAD_AREA 25
31#endif
32
0a30fbc4
DJ
33#ifdef HAVE_SYS_REG_H
34#include <sys/reg.h>
35#endif
36
2ec06d2e 37#define mips_num_regs 90
0a30fbc4
DJ
38
39#include <asm/ptrace.h>
40
41/* Return the ptrace ``address'' of register REGNO. */
42
43/* Matches mips_generic32_regs */
2ec06d2e 44static int mips_regmap[] = {
0a30fbc4
DJ
45 0, 1, 2, 3, 4, 5, 6, 7,
46 8, 9, 10, 11, 12, 13, 14, 15,
47 16, 17, 18, 19, 20, 21, 22, 23,
48 24, 25, 26, 27, 28, 29, 30, 31,
49
50 -1, MMLO, MMHI, BADVADDR, CAUSE, PC,
51
52 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3,
53 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7,
54 FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11,
55 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15,
56 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19,
57 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23,
58 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27,
59 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31,
60 FPC_CSR, FPC_EIR,
61
62 -1, -1,
63 -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1,
65};
66
67/* From mips-linux-nat.c. */
68
69/* Pseudo registers can not be read. ptrace does not provide a way to
70 read (or set) PS_REGNUM, and there's no point in reading or setting
71 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
72 ptrace(). */
73
2ec06d2e
DJ
74static int
75mips_cannot_fetch_register (int regno)
0a30fbc4 76{
2ec06d2e 77 if (mips_regmap[regno] == -1)
0a30fbc4
DJ
78 return 1;
79
aa32f823 80 if (find_regno ("zero") == regno)
0a30fbc4
DJ
81 return 1;
82
83 return 0;
84}
85
2ec06d2e
DJ
86static int
87mips_cannot_store_register (int regno)
0a30fbc4 88{
2ec06d2e 89 if (mips_regmap[regno] == -1)
0a30fbc4
DJ
90 return 1;
91
1d33e73a 92 if (find_regno ("zero") == regno)
0a30fbc4
DJ
93 return 1;
94
1d33e73a 95 if (find_regno ("cause") == regno)
0a30fbc4
DJ
96 return 1;
97
1d33e73a 98 if (find_regno ("bad") == regno)
0a30fbc4
DJ
99 return 1;
100
1d33e73a 101 if (find_regno ("fir") == regno)
0a30fbc4
DJ
102 return 1;
103
104 return 0;
105}
2ec06d2e 106
0d62e5e8
DJ
107static CORE_ADDR
108mips_get_pc ()
109{
110 unsigned long pc;
111 collect_register_by_name ("pc", &pc);
112 return pc;
113}
114
115static void
116mips_set_pc (CORE_ADDR pc)
117{
118 unsigned long newpc = pc;
119 supply_register_by_name ("pc", &newpc);
120}
121
122/* Correct in either endianness. */
123static const unsigned long mips_breakpoint = 0x0005000d;
124#define mips_breakpoint_len 4
125
126/* We only place breakpoints in empty marker functions, and thread locking
127 is outside of the function. So rather than importing software single-step,
128 we can just run until exit. */
129static CORE_ADDR
130mips_reinsert_addr ()
131{
132 unsigned long pc;
133 collect_register_by_name ("ra", &pc);
134 return pc;
135}
136
137static int
138mips_breakpoint_at (CORE_ADDR where)
139{
140 unsigned long insn;
141
f450004a 142 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
0d62e5e8
DJ
143 if (insn == mips_breakpoint)
144 return 1;
145
146 /* If necessary, recognize more trap instructions here. GDB only uses the
147 one. */
148 return 0;
149}
150
21b0f40c
DJ
151/* Fetch the thread-local storage pointer for libthread_db. */
152
153ps_err_e
154ps_get_thread_area (const struct ps_prochandle *ph,
155 lwpid_t lwpid, int idx, void **base)
156{
157 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
158 return PS_ERR;
159
160 /* IDX is the bias from the thread pointer to the beginning of the
161 thread descriptor. It has to be subtracted due to implementation
162 quirks in libthread_db. */
163 *base = (void *) ((char *)*base - idx);
164
165 return PS_OK;
166}
167
2ec06d2e
DJ
168struct linux_target_ops the_low_target = {
169 mips_num_regs,
170 mips_regmap,
171 mips_cannot_fetch_register,
172 mips_cannot_store_register,
0d62e5e8
DJ
173 mips_get_pc,
174 mips_set_pc,
f450004a 175 (const unsigned char *) &mips_breakpoint,
0d62e5e8
DJ
176 mips_breakpoint_len,
177 mips_reinsert_addr,
178 0,
179 mips_breakpoint_at,
2ec06d2e 180};
This page took 0.449236 seconds and 4 git commands to generate.