1/* GNU/Linux/ARM specific low level interface, for the remote server for GDB. 2 Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22#include "server.h" 23#include "linux-low.h" 24 25#ifdef HAVE_SYS_REG_H 26#include <sys/reg.h> 27#endif 28 29#define arm_num_regs 26 30 31static int arm_regmap[] = { 32 0, 4, 8, 12, 16, 20, 24, 28, 33 32, 36, 40, 44, 48, 52, 56, 60, 34 -1, -1, -1, -1, -1, -1, -1, -1, -1, 35 64 36}; 37 38static int 39arm_cannot_store_register (int regno) 40{ 41 return (regno >= arm_num_regs); 42} 43 44static int 45arm_cannot_fetch_register (int regno) 46{ 47 return (regno >= arm_num_regs); 48} 49 50extern int debug_threads; 51 52static CORE_ADDR 53arm_get_pc () 54{ 55 unsigned long pc; 56 collect_register_by_name ("pc", &pc); 57 if (debug_threads) 58 fprintf (stderr, "stop pc is %08lx\n", pc); 59 return pc; 60} 61 62static void 63arm_set_pc (CORE_ADDR pc) 64{ 65 unsigned long newpc = pc; 66 supply_register_by_name ("pc", &newpc); 67} 68 69/* Correct in either endianness. We do not support Thumb yet. */ 70static const unsigned long arm_breakpoint = 0xef9f0001; 71#define arm_breakpoint_len 4 72 73static int 74arm_breakpoint_at (CORE_ADDR where) 75{ 76 unsigned long insn; 77 78 (*the_target->read_memory) (where, (char *) &insn, 4); 79 if (insn == arm_breakpoint) 80 return 1; 81 82 /* If necessary, recognize more trap instructions here. GDB only uses the 83 one. */ 84 return 0; 85} 86 87/* We only place breakpoints in empty marker functions, and thread locking 88 is outside of the function. So rather than importing software single-step, 89 we can just run until exit. */ 90static CORE_ADDR 91arm_reinsert_addr () 92{ 93 unsigned long pc; 94 collect_register_by_name ("lr", &pc); 95 return pc; 96} 97 98struct linux_target_ops the_low_target = { 99 arm_num_regs, 100 arm_regmap, 101 arm_cannot_fetch_register, 102 arm_cannot_store_register, 103 arm_get_pc, 104 arm_set_pc, 105 (const char *) &arm_breakpoint, 106 arm_breakpoint_len, 107 arm_reinsert_addr, 108 0, 109 arm_breakpoint_at, 110}; 111