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 31 static 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 38 static int 39 arm_cannot_store_register (int regno) 40 { 41 return (regno >= arm_num_regs); 42 } 43 44 static int 45 arm_cannot_fetch_register (int regno) 46 { 47 return (regno >= arm_num_regs); 48 } 49 50 extern int debug_threads; 51 52 static CORE_ADDR 53 arm_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 62 static void 63 arm_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. */ 70 static const unsigned long arm_breakpoint = 0xef9f0001; 71 #define arm_breakpoint_len 4 72 73 static int 74 arm_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. */ 90 static CORE_ADDR 91 arm_reinsert_addr () 92 { 93 unsigned long pc; 94 collect_register_by_name ("lr", &pc); 95 return pc; 96 } 97 98 struct 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