GDBserver
|
00001 /* GNU/Linux/x86-64 specific low level interface, for the in-process 00002 agent library for GDB. 00003 00004 Copyright (C) 2010-2013 Free Software Foundation, Inc. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "server.h" 00022 #include "tracepoint.h" 00023 00024 /* Defined in auto-generated file amd64-linux.c. */ 00025 void init_registers_amd64_linux (void); 00026 extern const struct target_desc *tdesc_amd64_linux; 00027 00028 /* fast tracepoints collect registers. */ 00029 00030 #define FT_CR_RIP 0 00031 #define FT_CR_EFLAGS 1 00032 #define FT_CR_R8 2 00033 #define FT_CR_R9 3 00034 #define FT_CR_R10 4 00035 #define FT_CR_R11 5 00036 #define FT_CR_R12 6 00037 #define FT_CR_R13 7 00038 #define FT_CR_R14 8 00039 #define FT_CR_R15 9 00040 #define FT_CR_RAX 10 00041 #define FT_CR_RBX 11 00042 #define FT_CR_RCX 12 00043 #define FT_CR_RDX 13 00044 #define FT_CR_RSI 14 00045 #define FT_CR_RDI 15 00046 #define FT_CR_RBP 16 00047 #define FT_CR_RSP 17 00048 00049 static const int x86_64_ft_collect_regmap[] = { 00050 FT_CR_RAX * 8, FT_CR_RBX * 8, FT_CR_RCX * 8, FT_CR_RDX * 8, 00051 FT_CR_RSI * 8, FT_CR_RDI * 8, FT_CR_RBP * 8, FT_CR_RSP * 8, 00052 FT_CR_R8 * 8, FT_CR_R9 * 8, FT_CR_R10 * 8, FT_CR_R11 * 8, 00053 FT_CR_R12 * 8, FT_CR_R13 * 8, FT_CR_R14 * 8, FT_CR_R15 * 8, 00054 FT_CR_RIP * 8, FT_CR_EFLAGS * 8 00055 }; 00056 00057 #define X86_64_NUM_FT_COLLECT_GREGS \ 00058 (sizeof (x86_64_ft_collect_regmap) / sizeof(x86_64_ft_collect_regmap[0])) 00059 00060 void 00061 supply_fast_tracepoint_registers (struct regcache *regcache, 00062 const unsigned char *buf) 00063 { 00064 int i; 00065 00066 for (i = 0; i < X86_64_NUM_FT_COLLECT_GREGS; i++) 00067 supply_register (regcache, i, 00068 ((char *) buf) + x86_64_ft_collect_regmap[i]); 00069 } 00070 00071 ULONGEST __attribute__ ((visibility("default"), used)) 00072 gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum) 00073 { 00074 if (regnum >= X86_64_NUM_FT_COLLECT_GREGS) 00075 return 0; 00076 00077 return *(ULONGEST *) (raw_regs + x86_64_ft_collect_regmap[regnum]); 00078 } 00079 00080 #ifdef HAVE_UST 00081 00082 #include <ust/processor.h> 00083 00084 /* "struct registers" is the UST object type holding the registers at 00085 the time of the static tracepoint marker call. This doesn't 00086 contain RIP, but we know what it must have been (the marker 00087 address). */ 00088 00089 #define ST_REGENTRY(REG) \ 00090 { \ 00091 offsetof (struct registers, REG), \ 00092 sizeof (((struct registers *) NULL)->REG) \ 00093 } 00094 00095 static struct 00096 { 00097 int offset; 00098 int size; 00099 } x86_64_st_collect_regmap[] = 00100 { 00101 ST_REGENTRY(rax), 00102 ST_REGENTRY(rbx), 00103 ST_REGENTRY(rcx), 00104 ST_REGENTRY(rdx), 00105 ST_REGENTRY(rsi), 00106 ST_REGENTRY(rdi), 00107 ST_REGENTRY(rbp), 00108 ST_REGENTRY(rsp), 00109 ST_REGENTRY(r8), 00110 ST_REGENTRY(r9), 00111 ST_REGENTRY(r10), 00112 ST_REGENTRY(r11), 00113 ST_REGENTRY(r12), 00114 ST_REGENTRY(r13), 00115 ST_REGENTRY(r14), 00116 ST_REGENTRY(r15), 00117 { -1, 0 }, 00118 ST_REGENTRY(rflags), 00119 ST_REGENTRY(cs), 00120 ST_REGENTRY(ss), 00121 }; 00122 00123 #define X86_64_NUM_ST_COLLECT_GREGS \ 00124 (sizeof (x86_64_st_collect_regmap) / sizeof (x86_64_st_collect_regmap[0])) 00125 00126 /* GDB's RIP register number. */ 00127 #define AMD64_RIP_REGNUM 16 00128 00129 void 00130 supply_static_tracepoint_registers (struct regcache *regcache, 00131 const unsigned char *buf, 00132 CORE_ADDR pc) 00133 { 00134 int i; 00135 unsigned long newpc = pc; 00136 00137 supply_register (regcache, AMD64_RIP_REGNUM, &newpc); 00138 00139 for (i = 0; i < X86_64_NUM_ST_COLLECT_GREGS; i++) 00140 if (x86_64_st_collect_regmap[i].offset != -1) 00141 { 00142 switch (x86_64_st_collect_regmap[i].size) 00143 { 00144 case 8: 00145 supply_register (regcache, i, 00146 ((char *) buf) 00147 + x86_64_st_collect_regmap[i].offset); 00148 break; 00149 case 2: 00150 { 00151 unsigned long reg 00152 = * (short *) (((char *) buf) 00153 + x86_64_st_collect_regmap[i].offset); 00154 reg &= 0xffff; 00155 supply_register (regcache, i, ®); 00156 } 00157 break; 00158 default: 00159 internal_error (__FILE__, __LINE__, 00160 "unhandled register size: %d", 00161 x86_64_st_collect_regmap[i].size); 00162 break; 00163 } 00164 } 00165 } 00166 00167 #endif /* HAVE_UST */ 00168 00169 void 00170 initialize_low_tracepoint (void) 00171 { 00172 init_registers_amd64_linux (); 00173 ipa_tdesc = tdesc_amd64_linux; 00174 }