GDBserver
/home/stan/gdb/src/gdb/gdbserver/linux-amd64-ipa.c
Go to the documentation of this file.
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, &reg);
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines