GDB (API)
|
00001 /* Target-dependent code for ARM BSD's. 00002 00003 Copyright (C) 2006-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "osabi.h" 00022 #include "regcache.h" 00023 #include "regset.h" 00024 00025 #include "gdb_assert.h" 00026 #include "gdb_string.h" 00027 00028 #include "arm-tdep.h" 00029 00030 /* Core file support. */ 00031 00032 /* Sizeof `struct reg' in <machine/reg.h>. */ 00033 #define ARMBSD_SIZEOF_GREGS (17 * 4) 00034 00035 /* Sizeof `struct fpreg' in <machine/reg.h. */ 00036 #define ARMBSD_SIZEOF_FPREGS ((1 + (8 * 3)) * 4) 00037 00038 static int 00039 armbsd_fpreg_offset (int regnum) 00040 { 00041 if (regnum == ARM_FPS_REGNUM) 00042 return 0; 00043 00044 return 4 + (regnum - ARM_F0_REGNUM) * 12; 00045 } 00046 00047 /* Supply register REGNUM from the buffer specified by FPREGS and LEN 00048 in the floating-point register set REGSET to register cache 00049 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ 00050 00051 static void 00052 armbsd_supply_fpregset (const struct regset *regset, 00053 struct regcache *regcache, 00054 int regnum, const void *fpregs, size_t len) 00055 { 00056 const gdb_byte *regs = fpregs; 00057 int i; 00058 00059 gdb_assert (len >= ARMBSD_SIZEOF_FPREGS); 00060 00061 for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++) 00062 { 00063 if (regnum == i || regnum == -1) 00064 regcache_raw_supply (regcache, i, regs + armbsd_fpreg_offset (i)); 00065 } 00066 } 00067 00068 /* Supply register REGNUM from the buffer specified by GREGS and LEN 00069 in the general-purpose register set REGSET to register cache 00070 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ 00071 00072 static void 00073 armbsd_supply_gregset (const struct regset *regset, 00074 struct regcache *regcache, 00075 int regnum, const void *gregs, size_t len) 00076 { 00077 const gdb_byte *regs = gregs; 00078 int i; 00079 00080 gdb_assert (len >= ARMBSD_SIZEOF_GREGS); 00081 00082 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++) 00083 { 00084 if (regnum == i || regnum == -1) 00085 regcache_raw_supply (regcache, i, regs + i * 4); 00086 } 00087 00088 if (regnum == ARM_PS_REGNUM || regnum == -1) 00089 regcache_raw_supply (regcache, i, regs + 16 * 4); 00090 00091 if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS) 00092 { 00093 regs += ARMBSD_SIZEOF_GREGS; 00094 len -= ARMBSD_SIZEOF_GREGS; 00095 armbsd_supply_fpregset (regset, regcache, regnum, regs, len); 00096 } 00097 } 00098 00099 /* ARM register sets. */ 00100 00101 static struct regset armbsd_gregset = 00102 { 00103 NULL, 00104 armbsd_supply_gregset 00105 }; 00106 00107 static struct regset armbsd_fpregset = 00108 { 00109 NULL, 00110 armbsd_supply_fpregset 00111 }; 00112 00113 /* Return the appropriate register set for the core section identified 00114 by SECT_NAME and SECT_SIZE. */ 00115 00116 const struct regset * 00117 armbsd_regset_from_core_section (struct gdbarch *gdbarch, 00118 const char *sect_name, size_t sect_size) 00119 { 00120 if (strcmp (sect_name, ".reg") == 0 && sect_size >= ARMBSD_SIZEOF_GREGS) 00121 return &armbsd_gregset; 00122 00123 if (strcmp (sect_name, ".reg2") == 0 && sect_size >= ARMBSD_SIZEOF_FPREGS) 00124 return &armbsd_fpregset; 00125 00126 return NULL; 00127 }