OLD | NEW |
1 /* GNU/Linux/CRIS specific low level interface, for the remote server for GDB. | 1 /* GNU/Linux/CRIS specific low level interface, for the remote server for GDB. |
2 Copyright (C) 1995-1996, 1998-2005, 2007-2012 Free Software | 2 Copyright (C) 1995-1996, 1998-2005, 2007-2012 Free Software |
3 Foundation, Inc. | 3 Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 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 | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 return 0; | 224 return 0; |
225 } | 225 } |
226 | 226 |
227 static int | 227 static int |
228 cris_remove_point (char type, CORE_ADDR addr, int len) | 228 cris_remove_point (char type, CORE_ADDR addr, int len) |
229 { | 229 { |
230 int bp; | 230 int bp; |
231 unsigned long bp_ctrl; | 231 unsigned long bp_ctrl; |
232 unsigned long start, end; | 232 unsigned long start, end; |
233 struct regcache *regcache; | 233 struct regcache *regcache; |
| 234 unsigned long bp_d_regs[12]; |
234 | 235 |
235 /* Breakpoint/watchpoint types: | 236 /* Breakpoint/watchpoint types: |
236 0 = memory breakpoint for instructions | 237 0 = memory breakpoint for instructions |
237 (not supported; done via memory write instead) | 238 (not supported; done via memory write instead) |
238 1 = hardware breakpoint for instructions (not supported) | 239 1 = hardware breakpoint for instructions (not supported) |
239 2 = write watchpoint (supported) | 240 2 = write watchpoint (supported) |
240 3 = read watchpoint (supported) | 241 3 = read watchpoint (supported) |
241 4 = access watchpoint (supported). */ | 242 4 = access watchpoint (supported). */ |
242 if (type < '2' || type > '4') | 243 if (type < '2' || type > '4') |
243 return -1; | 244 return -1; |
244 | 245 |
245 regcache = get_thread_regcache (current_inferior, 1); | 246 regcache = get_thread_regcache (current_inferior, 1); |
246 | 247 |
247 /* Read watchpoints are set as access watchpoints, because of GDB's | 248 /* Read watchpoints are set as access watchpoints, because of GDB's |
248 inability to deal with pure read watchpoints. */ | 249 inability to deal with pure read watchpoints. */ |
249 if (type == '3') | 250 if (type == '3') |
250 type = '4'; | 251 type = '4'; |
251 | 252 |
252 /* Get the configuration register. */ | 253 /* Get the configuration register. */ |
253 collect_register_by_name (regcache, "s0", &bp_ctrl); | 254 collect_register_by_name (regcache, "s0", &bp_ctrl); |
254 | 255 |
255 /* Try to find a watchpoint that is configured for the | 256 /* Try to find a watchpoint that is configured for the |
256 specified range, then check that read/write also matches. */ | 257 specified range, then check that read/write also matches. */ |
257 | 258 |
258 /* Ugly pointer arithmetic, since I cannot rely on a | 259 /* Ugly pointer arithmetic, since I cannot rely on a |
259 single switch (addr) as there may be several watchpoints with | 260 single switch (addr) as there may be several watchpoints with |
260 the same start address for example. */ | 261 the same start address for example. */ |
261 | 262 |
262 unsigned long bp_d_regs[12]; | |
263 | |
264 /* Get all range registers to simplify search. */ | 263 /* Get all range registers to simplify search. */ |
265 collect_register_by_name (regcache, "s3", &bp_d_regs[0]); | 264 collect_register_by_name (regcache, "s3", &bp_d_regs[0]); |
266 collect_register_by_name (regcache, "s4", &bp_d_regs[1]); | 265 collect_register_by_name (regcache, "s4", &bp_d_regs[1]); |
267 collect_register_by_name (regcache, "s5", &bp_d_regs[2]); | 266 collect_register_by_name (regcache, "s5", &bp_d_regs[2]); |
268 collect_register_by_name (regcache, "s6", &bp_d_regs[3]); | 267 collect_register_by_name (regcache, "s6", &bp_d_regs[3]); |
269 collect_register_by_name (regcache, "s7", &bp_d_regs[4]); | 268 collect_register_by_name (regcache, "s7", &bp_d_regs[4]); |
270 collect_register_by_name (regcache, "s8", &bp_d_regs[5]); | 269 collect_register_by_name (regcache, "s8", &bp_d_regs[5]); |
271 collect_register_by_name (regcache, "s9", &bp_d_regs[6]); | 270 collect_register_by_name (regcache, "s9", &bp_d_regs[6]); |
272 collect_register_by_name (regcache, "s10", &bp_d_regs[7]); | 271 collect_register_by_name (regcache, "s10", &bp_d_regs[7]); |
273 collect_register_by_name (regcache, "s11", &bp_d_regs[8]); | 272 collect_register_by_name (regcache, "s11", &bp_d_regs[8]); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 cris_write_data_breakpoint (regcache, bp, start, end); | 313 cris_write_data_breakpoint (regcache, bp, start, end); |
315 | 314 |
316 /* Note that we don't clear the S1 flag here. It's done when continuing. */ | 315 /* Note that we don't clear the S1 flag here. It's done when continuing. */ |
317 return 0; | 316 return 0; |
318 } | 317 } |
319 | 318 |
320 static int | 319 static int |
321 cris_stopped_by_watchpoint (void) | 320 cris_stopped_by_watchpoint (void) |
322 { | 321 { |
323 unsigned long exs; | 322 unsigned long exs; |
| 323 struct regcache *regcache = get_thread_regcache (current_inferior, 1); |
324 | 324 |
325 collect_register_by_name ("exs", &exs); | 325 collect_register_by_name (regcache, "exs", &exs); |
326 | 326 |
327 return (((exs & 0xff00) >> 8) == 0xc); | 327 return (((exs & 0xff00) >> 8) == 0xc); |
328 } | 328 } |
329 | 329 |
330 static CORE_ADDR | 330 static CORE_ADDR |
331 cris_stopped_data_address (void) | 331 cris_stopped_data_address (void) |
332 { | 332 { |
333 unsigned long eda; | 333 unsigned long eda; |
| 334 struct regcache *regcache = get_thread_regcache (current_inferior, 1); |
334 | 335 |
335 collect_register_by_name ("eda", &eda); | 336 collect_register_by_name (regcache, "eda", &eda); |
336 | 337 |
337 /* FIXME: Possibly adjust to match watched range. */ | 338 /* FIXME: Possibly adjust to match watched range. */ |
338 return eda; | 339 return eda; |
339 } | 340 } |
340 | 341 |
341 static void | 342 static void |
342 cris_fill_gregset (void *buf) | 343 cris_fill_gregset (struct regcache *regcache, void *buf) |
343 { | 344 { |
344 int i; | 345 int i; |
345 | 346 |
346 for (i = 0; i < cris_num_regs; i++) | 347 for (i = 0; i < cris_num_regs; i++) |
347 { | 348 { |
348 if (cris_regmap[i] != -1) | 349 if (cris_regmap[i] != -1) |
349 » collect_register (i, ((char *) buf) + cris_regmap[i]); | 350 » collect_register (regcache, i, ((char *) buf) + cris_regmap[i]); |
350 } | 351 } |
351 } | 352 } |
352 | 353 |
353 static void | 354 static void |
354 cris_store_gregset (const void *buf) | 355 cris_store_gregset (struct regcache *regcache, const void *buf) |
355 { | 356 { |
356 int i; | 357 int i; |
357 | 358 |
358 for (i = 0; i < cris_num_regs; i++) | 359 for (i = 0; i < cris_num_regs; i++) |
359 { | 360 { |
360 if (cris_regmap[i] != -1) | 361 if (cris_regmap[i] != -1) |
361 » supply_register (i, ((char *) buf) + cris_regmap[i]); | 362 » supply_register (regcache, i, ((char *) buf) + cris_regmap[i]); |
362 } | 363 } |
363 } | 364 } |
364 | 365 |
365 typedef unsigned long elf_gregset_t[cris_num_regs]; | |
366 | |
367 struct regset_info target_regsets[] = { | 366 struct regset_info target_regsets[] = { |
368 { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), | 367 { PTRACE_GETREGS, PTRACE_SETREGS, 0, cris_num_regs * 4, |
369 GENERAL_REGS, cris_fill_gregset, cris_store_gregset }, | 368 GENERAL_REGS, cris_fill_gregset, cris_store_gregset }, |
370 { 0, 0, 0, -1, -1, NULL, NULL } | 369 { 0, 0, 0, -1, -1, NULL, NULL } |
371 }; | 370 }; |
372 | 371 |
373 struct linux_target_ops the_low_target = { | 372 struct linux_target_ops the_low_target = { |
374 init_register_crisv32, | 373 init_registers_crisv32, |
375 -1, | 374 -1, |
376 NULL, | 375 NULL, |
377 NULL, | 376 NULL, |
378 NULL, | 377 NULL, |
| 378 NULL, |
| 379 NULL, /* fetch_register */ |
379 cris_get_pc, | 380 cris_get_pc, |
380 cris_set_pc, | 381 cris_set_pc, |
381 (const unsigned char *) &cris_breakpoint, | 382 (const unsigned char *) &cris_breakpoint, |
382 cris_breakpoint_len, | 383 cris_breakpoint_len, |
383 cris_reinsert_addr, | 384 cris_reinsert_addr, |
384 0, | 385 0, |
385 cris_breakpoint_at, | 386 cris_breakpoint_at, |
386 cris_insert_point, | 387 cris_insert_point, |
387 cris_remove_point, | 388 cris_remove_point, |
388 cris_stopped_by_watchpoint, | 389 cris_stopped_by_watchpoint, |
389 cris_stopped_data_address, | 390 cris_stopped_data_address, |
390 }; | 391 }; |
OLD | NEW |