xref: /dflybsd-src/contrib/gdb-7/gdb/amd64-tdep.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Target-dependent code for AMD64.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 2001-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Jiri Smid, SuSE Labs.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "opcode/i386.h"
245796c8dcSSimon Schubert #include "dis-asm.h"
255796c8dcSSimon Schubert #include "arch-utils.h"
265796c8dcSSimon Schubert #include "block.h"
275796c8dcSSimon Schubert #include "dummy-frame.h"
285796c8dcSSimon Schubert #include "frame.h"
295796c8dcSSimon Schubert #include "frame-base.h"
305796c8dcSSimon Schubert #include "frame-unwind.h"
315796c8dcSSimon Schubert #include "inferior.h"
325796c8dcSSimon Schubert #include "gdbcmd.h"
335796c8dcSSimon Schubert #include "gdbcore.h"
345796c8dcSSimon Schubert #include "objfiles.h"
355796c8dcSSimon Schubert #include "regcache.h"
365796c8dcSSimon Schubert #include "regset.h"
375796c8dcSSimon Schubert #include "symfile.h"
38cf7f2e2dSJohn Marino #include "disasm.h"
395796c8dcSSimon Schubert #include "gdb_assert.h"
40c50c785cSJohn Marino #include "exceptions.h"
415796c8dcSSimon Schubert #include "amd64-tdep.h"
425796c8dcSSimon Schubert #include "i387-tdep.h"
435796c8dcSSimon Schubert 
44cf7f2e2dSJohn Marino #include "features/i386/amd64.c"
45cf7f2e2dSJohn Marino #include "features/i386/amd64-avx.c"
46*ef5ccd6cSJohn Marino #include "features/i386/x32.c"
47*ef5ccd6cSJohn Marino #include "features/i386/x32-avx.c"
48cf7f2e2dSJohn Marino 
49a45ae5f8SJohn Marino #include "ax.h"
50a45ae5f8SJohn Marino #include "ax-gdb.h"
51a45ae5f8SJohn Marino 
525796c8dcSSimon Schubert /* Note that the AMD64 architecture was previously known as x86-64.
535796c8dcSSimon Schubert    The latter is (forever) engraved into the canonical system name as
545796c8dcSSimon Schubert    returned by config.guess, and used as the name for the AMD64 port
555796c8dcSSimon Schubert    of GNU/Linux.  The BSD's have renamed their ports to amd64; they
565796c8dcSSimon Schubert    don't like to shout.  For GDB we prefer the amd64_-prefix over the
575796c8dcSSimon Schubert    x86_64_-prefix since it's so much easier to type.  */
585796c8dcSSimon Schubert 
595796c8dcSSimon Schubert /* Register information.  */
605796c8dcSSimon Schubert 
615796c8dcSSimon Schubert static const char *amd64_register_names[] =
625796c8dcSSimon Schubert {
635796c8dcSSimon Schubert   "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp",
645796c8dcSSimon Schubert 
655796c8dcSSimon Schubert   /* %r8 is indeed register number 8.  */
665796c8dcSSimon Schubert   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
675796c8dcSSimon Schubert   "rip", "eflags", "cs", "ss", "ds", "es", "fs", "gs",
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert   /* %st0 is register number 24.  */
705796c8dcSSimon Schubert   "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7",
715796c8dcSSimon Schubert   "fctrl", "fstat", "ftag", "fiseg", "fioff", "foseg", "fooff", "fop",
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert   /* %xmm0 is register number 40.  */
745796c8dcSSimon Schubert   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
755796c8dcSSimon Schubert   "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
765796c8dcSSimon Schubert   "mxcsr",
775796c8dcSSimon Schubert };
785796c8dcSSimon Schubert 
79cf7f2e2dSJohn Marino static const char *amd64_ymm_names[] =
805796c8dcSSimon Schubert {
81cf7f2e2dSJohn Marino   "ymm0", "ymm1", "ymm2", "ymm3",
82cf7f2e2dSJohn Marino   "ymm4", "ymm5", "ymm6", "ymm7",
83cf7f2e2dSJohn Marino   "ymm8", "ymm9", "ymm10", "ymm11",
84cf7f2e2dSJohn Marino   "ymm12", "ymm13", "ymm14", "ymm15"
85cf7f2e2dSJohn Marino };
865796c8dcSSimon Schubert 
87cf7f2e2dSJohn Marino static const char *amd64_ymmh_names[] =
885796c8dcSSimon Schubert {
89cf7f2e2dSJohn Marino   "ymm0h", "ymm1h", "ymm2h", "ymm3h",
90cf7f2e2dSJohn Marino   "ymm4h", "ymm5h", "ymm6h", "ymm7h",
91cf7f2e2dSJohn Marino   "ymm8h", "ymm9h", "ymm10h", "ymm11h",
92cf7f2e2dSJohn Marino   "ymm12h", "ymm13h", "ymm14h", "ymm15h"
93cf7f2e2dSJohn Marino };
945796c8dcSSimon Schubert 
95cf7f2e2dSJohn Marino /* The registers used to pass integer arguments during a function call.  */
96cf7f2e2dSJohn Marino static int amd64_dummy_call_integer_regs[] =
97cf7f2e2dSJohn Marino {
98cf7f2e2dSJohn Marino   AMD64_RDI_REGNUM,		/* %rdi */
99cf7f2e2dSJohn Marino   AMD64_RSI_REGNUM,		/* %rsi */
100cf7f2e2dSJohn Marino   AMD64_RDX_REGNUM,		/* %rdx */
101cf7f2e2dSJohn Marino   AMD64_RCX_REGNUM,		/* %rcx */
102cf7f2e2dSJohn Marino   8,				/* %r8 */
103cf7f2e2dSJohn Marino   9				/* %r9 */
104cf7f2e2dSJohn Marino };
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert /* DWARF Register Number Mapping as defined in the System V psABI,
1075796c8dcSSimon Schubert    section 3.6.  */
1085796c8dcSSimon Schubert 
1095796c8dcSSimon Schubert static int amd64_dwarf_regmap[] =
1105796c8dcSSimon Schubert {
1115796c8dcSSimon Schubert   /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI.  */
1125796c8dcSSimon Schubert   AMD64_RAX_REGNUM, AMD64_RDX_REGNUM,
1135796c8dcSSimon Schubert   AMD64_RCX_REGNUM, AMD64_RBX_REGNUM,
1145796c8dcSSimon Schubert   AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
1155796c8dcSSimon Schubert 
1165796c8dcSSimon Schubert   /* Frame Pointer Register RBP.  */
1175796c8dcSSimon Schubert   AMD64_RBP_REGNUM,
1185796c8dcSSimon Schubert 
1195796c8dcSSimon Schubert   /* Stack Pointer Register RSP.  */
1205796c8dcSSimon Schubert   AMD64_RSP_REGNUM,
1215796c8dcSSimon Schubert 
1225796c8dcSSimon Schubert   /* Extended Integer Registers 8 - 15.  */
1235796c8dcSSimon Schubert   8, 9, 10, 11, 12, 13, 14, 15,
1245796c8dcSSimon Schubert 
1255796c8dcSSimon Schubert   /* Return Address RA.  Mapped to RIP.  */
1265796c8dcSSimon Schubert   AMD64_RIP_REGNUM,
1275796c8dcSSimon Schubert 
1285796c8dcSSimon Schubert   /* SSE Registers 0 - 7.  */
1295796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM,
1305796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3,
1315796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5,
1325796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7,
1335796c8dcSSimon Schubert 
1345796c8dcSSimon Schubert   /* Extended SSE Registers 8 - 15.  */
1355796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 8, AMD64_XMM0_REGNUM + 9,
1365796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 10, AMD64_XMM0_REGNUM + 11,
1375796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 12, AMD64_XMM0_REGNUM + 13,
1385796c8dcSSimon Schubert   AMD64_XMM0_REGNUM + 14, AMD64_XMM0_REGNUM + 15,
1395796c8dcSSimon Schubert 
1405796c8dcSSimon Schubert   /* Floating Point Registers 0-7.  */
1415796c8dcSSimon Schubert   AMD64_ST0_REGNUM + 0, AMD64_ST0_REGNUM + 1,
1425796c8dcSSimon Schubert   AMD64_ST0_REGNUM + 2, AMD64_ST0_REGNUM + 3,
1435796c8dcSSimon Schubert   AMD64_ST0_REGNUM + 4, AMD64_ST0_REGNUM + 5,
1445796c8dcSSimon Schubert   AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7,
1455796c8dcSSimon Schubert 
1465796c8dcSSimon Schubert   /* Control and Status Flags Register.  */
1475796c8dcSSimon Schubert   AMD64_EFLAGS_REGNUM,
1485796c8dcSSimon Schubert 
1495796c8dcSSimon Schubert   /* Selector Registers.  */
1505796c8dcSSimon Schubert   AMD64_ES_REGNUM,
1515796c8dcSSimon Schubert   AMD64_CS_REGNUM,
1525796c8dcSSimon Schubert   AMD64_SS_REGNUM,
1535796c8dcSSimon Schubert   AMD64_DS_REGNUM,
1545796c8dcSSimon Schubert   AMD64_FS_REGNUM,
1555796c8dcSSimon Schubert   AMD64_GS_REGNUM,
1565796c8dcSSimon Schubert   -1,
1575796c8dcSSimon Schubert   -1,
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert   /* Segment Base Address Registers.  */
1605796c8dcSSimon Schubert   -1,
1615796c8dcSSimon Schubert   -1,
1625796c8dcSSimon Schubert   -1,
1635796c8dcSSimon Schubert   -1,
1645796c8dcSSimon Schubert 
1655796c8dcSSimon Schubert   /* Special Selector Registers.  */
1665796c8dcSSimon Schubert   -1,
1675796c8dcSSimon Schubert   -1,
1685796c8dcSSimon Schubert 
1695796c8dcSSimon Schubert   /* Floating Point Control Registers.  */
1705796c8dcSSimon Schubert   AMD64_MXCSR_REGNUM,
1715796c8dcSSimon Schubert   AMD64_FCTRL_REGNUM,
1725796c8dcSSimon Schubert   AMD64_FSTAT_REGNUM
1735796c8dcSSimon Schubert };
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert static const int amd64_dwarf_regmap_len =
1765796c8dcSSimon Schubert   (sizeof (amd64_dwarf_regmap) / sizeof (amd64_dwarf_regmap[0]));
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert /* Convert DWARF register number REG to the appropriate register
1795796c8dcSSimon Schubert    number used by GDB.  */
1805796c8dcSSimon Schubert 
1815796c8dcSSimon Schubert static int
amd64_dwarf_reg_to_regnum(struct gdbarch * gdbarch,int reg)1825796c8dcSSimon Schubert amd64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
1835796c8dcSSimon Schubert {
184cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
185cf7f2e2dSJohn Marino   int ymm0_regnum = tdep->ymm0_regnum;
1865796c8dcSSimon Schubert   int regnum = -1;
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert   if (reg >= 0 && reg < amd64_dwarf_regmap_len)
1895796c8dcSSimon Schubert     regnum = amd64_dwarf_regmap[reg];
1905796c8dcSSimon Schubert 
1915796c8dcSSimon Schubert   if (regnum == -1)
1925796c8dcSSimon Schubert     warning (_("Unmapped DWARF Register #%d encountered."), reg);
193cf7f2e2dSJohn Marino   else if (ymm0_regnum >= 0
194cf7f2e2dSJohn Marino 	   && i386_xmm_regnum_p (gdbarch, regnum))
195cf7f2e2dSJohn Marino     regnum += ymm0_regnum - I387_XMM0_REGNUM (tdep);
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert   return regnum;
1985796c8dcSSimon Schubert }
1995796c8dcSSimon Schubert 
2005796c8dcSSimon Schubert /* Map architectural register numbers to gdb register numbers.  */
2015796c8dcSSimon Schubert 
2025796c8dcSSimon Schubert static const int amd64_arch_regmap[16] =
2035796c8dcSSimon Schubert {
2045796c8dcSSimon Schubert   AMD64_RAX_REGNUM,	/* %rax */
2055796c8dcSSimon Schubert   AMD64_RCX_REGNUM,	/* %rcx */
2065796c8dcSSimon Schubert   AMD64_RDX_REGNUM,	/* %rdx */
2075796c8dcSSimon Schubert   AMD64_RBX_REGNUM,	/* %rbx */
2085796c8dcSSimon Schubert   AMD64_RSP_REGNUM,	/* %rsp */
2095796c8dcSSimon Schubert   AMD64_RBP_REGNUM,	/* %rbp */
2105796c8dcSSimon Schubert   AMD64_RSI_REGNUM,	/* %rsi */
2115796c8dcSSimon Schubert   AMD64_RDI_REGNUM,	/* %rdi */
2125796c8dcSSimon Schubert   AMD64_R8_REGNUM,	/* %r8 */
2135796c8dcSSimon Schubert   AMD64_R9_REGNUM,	/* %r9 */
2145796c8dcSSimon Schubert   AMD64_R10_REGNUM,	/* %r10 */
2155796c8dcSSimon Schubert   AMD64_R11_REGNUM,	/* %r11 */
2165796c8dcSSimon Schubert   AMD64_R12_REGNUM,	/* %r12 */
2175796c8dcSSimon Schubert   AMD64_R13_REGNUM,	/* %r13 */
2185796c8dcSSimon Schubert   AMD64_R14_REGNUM,	/* %r14 */
2195796c8dcSSimon Schubert   AMD64_R15_REGNUM	/* %r15 */
2205796c8dcSSimon Schubert };
2215796c8dcSSimon Schubert 
2225796c8dcSSimon Schubert static const int amd64_arch_regmap_len =
2235796c8dcSSimon Schubert   (sizeof (amd64_arch_regmap) / sizeof (amd64_arch_regmap[0]));
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert /* Convert architectural register number REG to the appropriate register
2265796c8dcSSimon Schubert    number used by GDB.  */
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert static int
amd64_arch_reg_to_regnum(int reg)2295796c8dcSSimon Schubert amd64_arch_reg_to_regnum (int reg)
2305796c8dcSSimon Schubert {
2315796c8dcSSimon Schubert   gdb_assert (reg >= 0 && reg < amd64_arch_regmap_len);
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert   return amd64_arch_regmap[reg];
2345796c8dcSSimon Schubert }
2355796c8dcSSimon Schubert 
236cf7f2e2dSJohn Marino /* Register names for byte pseudo-registers.  */
2375796c8dcSSimon Schubert 
238cf7f2e2dSJohn Marino static const char *amd64_byte_names[] =
2395796c8dcSSimon Schubert {
240cf7f2e2dSJohn Marino   "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
241cf7f2e2dSJohn Marino   "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l",
242cf7f2e2dSJohn Marino   "ah", "bh", "ch", "dh"
2435796c8dcSSimon Schubert };
2445796c8dcSSimon Schubert 
245cf7f2e2dSJohn Marino /* Number of lower byte registers.  */
246cf7f2e2dSJohn Marino #define AMD64_NUM_LOWER_BYTE_REGS 16
247cf7f2e2dSJohn Marino 
248cf7f2e2dSJohn Marino /* Register names for word pseudo-registers.  */
249cf7f2e2dSJohn Marino 
250cf7f2e2dSJohn Marino static const char *amd64_word_names[] =
251cf7f2e2dSJohn Marino {
252cf7f2e2dSJohn Marino   "ax", "bx", "cx", "dx", "si", "di", "bp", "",
253cf7f2e2dSJohn Marino   "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
254cf7f2e2dSJohn Marino };
255cf7f2e2dSJohn Marino 
256cf7f2e2dSJohn Marino /* Register names for dword pseudo-registers.  */
257cf7f2e2dSJohn Marino 
258cf7f2e2dSJohn Marino static const char *amd64_dword_names[] =
259cf7f2e2dSJohn Marino {
260cf7f2e2dSJohn Marino   "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp",
261*ef5ccd6cSJohn Marino   "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
262*ef5ccd6cSJohn Marino   "eip"
263cf7f2e2dSJohn Marino };
264cf7f2e2dSJohn Marino 
265cf7f2e2dSJohn Marino /* Return the name of register REGNUM.  */
266cf7f2e2dSJohn Marino 
267cf7f2e2dSJohn Marino static const char *
amd64_pseudo_register_name(struct gdbarch * gdbarch,int regnum)268cf7f2e2dSJohn Marino amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
269cf7f2e2dSJohn Marino {
270cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
271cf7f2e2dSJohn Marino   if (i386_byte_regnum_p (gdbarch, regnum))
272cf7f2e2dSJohn Marino     return amd64_byte_names[regnum - tdep->al_regnum];
273cf7f2e2dSJohn Marino   else if (i386_ymm_regnum_p (gdbarch, regnum))
274cf7f2e2dSJohn Marino     return amd64_ymm_names[regnum - tdep->ymm0_regnum];
275cf7f2e2dSJohn Marino   else if (i386_word_regnum_p (gdbarch, regnum))
276cf7f2e2dSJohn Marino     return amd64_word_names[regnum - tdep->ax_regnum];
277cf7f2e2dSJohn Marino   else if (i386_dword_regnum_p (gdbarch, regnum))
278cf7f2e2dSJohn Marino     return amd64_dword_names[regnum - tdep->eax_regnum];
279cf7f2e2dSJohn Marino   else
280cf7f2e2dSJohn Marino     return i386_pseudo_register_name (gdbarch, regnum);
281cf7f2e2dSJohn Marino }
282cf7f2e2dSJohn Marino 
283a45ae5f8SJohn Marino static struct value *
amd64_pseudo_register_read_value(struct gdbarch * gdbarch,struct regcache * regcache,int regnum)284a45ae5f8SJohn Marino amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
285cf7f2e2dSJohn Marino 				  struct regcache *regcache,
286a45ae5f8SJohn Marino 				  int regnum)
287cf7f2e2dSJohn Marino {
288cf7f2e2dSJohn Marino   gdb_byte raw_buf[MAX_REGISTER_SIZE];
289cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
290c50c785cSJohn Marino   enum register_status status;
291a45ae5f8SJohn Marino   struct value *result_value;
292a45ae5f8SJohn Marino   gdb_byte *buf;
293a45ae5f8SJohn Marino 
294a45ae5f8SJohn Marino   result_value = allocate_value (register_type (gdbarch, regnum));
295a45ae5f8SJohn Marino   VALUE_LVAL (result_value) = lval_register;
296a45ae5f8SJohn Marino   VALUE_REGNUM (result_value) = regnum;
297a45ae5f8SJohn Marino   buf = value_contents_raw (result_value);
298cf7f2e2dSJohn Marino 
299cf7f2e2dSJohn Marino   if (i386_byte_regnum_p (gdbarch, regnum))
300cf7f2e2dSJohn Marino     {
301cf7f2e2dSJohn Marino       int gpnum = regnum - tdep->al_regnum;
302cf7f2e2dSJohn Marino 
303cf7f2e2dSJohn Marino       /* Extract (always little endian).  */
304cf7f2e2dSJohn Marino       if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
305cf7f2e2dSJohn Marino 	{
306cf7f2e2dSJohn Marino 	  /* Special handling for AH, BH, CH, DH.  */
307c50c785cSJohn Marino 	  status = regcache_raw_read (regcache,
308c50c785cSJohn Marino 				      gpnum - AMD64_NUM_LOWER_BYTE_REGS,
309c50c785cSJohn Marino 				      raw_buf);
310c50c785cSJohn Marino 	  if (status == REG_VALID)
311cf7f2e2dSJohn Marino 	    memcpy (buf, raw_buf + 1, 1);
312a45ae5f8SJohn Marino 	  else
313a45ae5f8SJohn Marino 	    mark_value_bytes_unavailable (result_value, 0,
314a45ae5f8SJohn Marino 					  TYPE_LENGTH (value_type (result_value)));
315cf7f2e2dSJohn Marino 	}
316cf7f2e2dSJohn Marino       else
317cf7f2e2dSJohn Marino 	{
318c50c785cSJohn Marino 	  status = regcache_raw_read (regcache, gpnum, raw_buf);
319c50c785cSJohn Marino 	  if (status == REG_VALID)
320cf7f2e2dSJohn Marino 	    memcpy (buf, raw_buf, 1);
321a45ae5f8SJohn Marino 	  else
322a45ae5f8SJohn Marino 	    mark_value_bytes_unavailable (result_value, 0,
323a45ae5f8SJohn Marino 					  TYPE_LENGTH (value_type (result_value)));
324cf7f2e2dSJohn Marino 	}
325cf7f2e2dSJohn Marino     }
326cf7f2e2dSJohn Marino   else if (i386_dword_regnum_p (gdbarch, regnum))
327cf7f2e2dSJohn Marino     {
328cf7f2e2dSJohn Marino       int gpnum = regnum - tdep->eax_regnum;
329cf7f2e2dSJohn Marino       /* Extract (always little endian).  */
330c50c785cSJohn Marino       status = regcache_raw_read (regcache, gpnum, raw_buf);
331c50c785cSJohn Marino       if (status == REG_VALID)
332cf7f2e2dSJohn Marino 	memcpy (buf, raw_buf, 4);
333a45ae5f8SJohn Marino       else
334a45ae5f8SJohn Marino 	mark_value_bytes_unavailable (result_value, 0,
335a45ae5f8SJohn Marino 				      TYPE_LENGTH (value_type (result_value)));
336cf7f2e2dSJohn Marino     }
337cf7f2e2dSJohn Marino   else
338a45ae5f8SJohn Marino     i386_pseudo_register_read_into_value (gdbarch, regcache, regnum,
339a45ae5f8SJohn Marino 					  result_value);
340a45ae5f8SJohn Marino 
341a45ae5f8SJohn Marino   return result_value;
342cf7f2e2dSJohn Marino }
343cf7f2e2dSJohn Marino 
344cf7f2e2dSJohn Marino static void
amd64_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,const gdb_byte * buf)345cf7f2e2dSJohn Marino amd64_pseudo_register_write (struct gdbarch *gdbarch,
346cf7f2e2dSJohn Marino 			     struct regcache *regcache,
347cf7f2e2dSJohn Marino 			     int regnum, const gdb_byte *buf)
348cf7f2e2dSJohn Marino {
349cf7f2e2dSJohn Marino   gdb_byte raw_buf[MAX_REGISTER_SIZE];
350cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
351cf7f2e2dSJohn Marino 
352cf7f2e2dSJohn Marino   if (i386_byte_regnum_p (gdbarch, regnum))
353cf7f2e2dSJohn Marino     {
354cf7f2e2dSJohn Marino       int gpnum = regnum - tdep->al_regnum;
355cf7f2e2dSJohn Marino 
356cf7f2e2dSJohn Marino       if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
357cf7f2e2dSJohn Marino 	{
358cf7f2e2dSJohn Marino 	  /* Read ... AH, BH, CH, DH.  */
359cf7f2e2dSJohn Marino 	  regcache_raw_read (regcache,
360cf7f2e2dSJohn Marino 			     gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
361cf7f2e2dSJohn Marino 	  /* ... Modify ... (always little endian).  */
362cf7f2e2dSJohn Marino 	  memcpy (raw_buf + 1, buf, 1);
363cf7f2e2dSJohn Marino 	  /* ... Write.  */
364cf7f2e2dSJohn Marino 	  regcache_raw_write (regcache,
365cf7f2e2dSJohn Marino 			      gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
366cf7f2e2dSJohn Marino 	}
367cf7f2e2dSJohn Marino       else
368cf7f2e2dSJohn Marino 	{
369cf7f2e2dSJohn Marino 	  /* Read ...  */
370cf7f2e2dSJohn Marino 	  regcache_raw_read (regcache, gpnum, raw_buf);
371cf7f2e2dSJohn Marino 	  /* ... Modify ... (always little endian).  */
372cf7f2e2dSJohn Marino 	  memcpy (raw_buf, buf, 1);
373cf7f2e2dSJohn Marino 	  /* ... Write.  */
374cf7f2e2dSJohn Marino 	  regcache_raw_write (regcache, gpnum, raw_buf);
375cf7f2e2dSJohn Marino 	}
376cf7f2e2dSJohn Marino     }
377cf7f2e2dSJohn Marino   else if (i386_dword_regnum_p (gdbarch, regnum))
378cf7f2e2dSJohn Marino     {
379cf7f2e2dSJohn Marino       int gpnum = regnum - tdep->eax_regnum;
380cf7f2e2dSJohn Marino 
381cf7f2e2dSJohn Marino       /* Read ...  */
382cf7f2e2dSJohn Marino       regcache_raw_read (regcache, gpnum, raw_buf);
383cf7f2e2dSJohn Marino       /* ... Modify ... (always little endian).  */
384cf7f2e2dSJohn Marino       memcpy (raw_buf, buf, 4);
385cf7f2e2dSJohn Marino       /* ... Write.  */
386cf7f2e2dSJohn Marino       regcache_raw_write (regcache, gpnum, raw_buf);
387cf7f2e2dSJohn Marino     }
388cf7f2e2dSJohn Marino   else
389cf7f2e2dSJohn Marino     i386_pseudo_register_write (gdbarch, regcache, regnum, buf);
390cf7f2e2dSJohn Marino }
391cf7f2e2dSJohn Marino 
392cf7f2e2dSJohn Marino 
393cf7f2e2dSJohn Marino 
3945796c8dcSSimon Schubert /* Return the union class of CLASS1 and CLASS2.  See the psABI for
3955796c8dcSSimon Schubert    details.  */
3965796c8dcSSimon Schubert 
3975796c8dcSSimon Schubert static enum amd64_reg_class
amd64_merge_classes(enum amd64_reg_class class1,enum amd64_reg_class class2)3985796c8dcSSimon Schubert amd64_merge_classes (enum amd64_reg_class class1, enum amd64_reg_class class2)
3995796c8dcSSimon Schubert {
4005796c8dcSSimon Schubert   /* Rule (a): If both classes are equal, this is the resulting class.  */
4015796c8dcSSimon Schubert   if (class1 == class2)
4025796c8dcSSimon Schubert     return class1;
4035796c8dcSSimon Schubert 
4045796c8dcSSimon Schubert   /* Rule (b): If one of the classes is NO_CLASS, the resulting class
4055796c8dcSSimon Schubert      is the other class.  */
4065796c8dcSSimon Schubert   if (class1 == AMD64_NO_CLASS)
4075796c8dcSSimon Schubert     return class2;
4085796c8dcSSimon Schubert   if (class2 == AMD64_NO_CLASS)
4095796c8dcSSimon Schubert     return class1;
4105796c8dcSSimon Schubert 
4115796c8dcSSimon Schubert   /* Rule (c): If one of the classes is MEMORY, the result is MEMORY.  */
4125796c8dcSSimon Schubert   if (class1 == AMD64_MEMORY || class2 == AMD64_MEMORY)
4135796c8dcSSimon Schubert     return AMD64_MEMORY;
4145796c8dcSSimon Schubert 
4155796c8dcSSimon Schubert   /* Rule (d): If one of the classes is INTEGER, the result is INTEGER.  */
4165796c8dcSSimon Schubert   if (class1 == AMD64_INTEGER || class2 == AMD64_INTEGER)
4175796c8dcSSimon Schubert     return AMD64_INTEGER;
4185796c8dcSSimon Schubert 
4195796c8dcSSimon Schubert   /* Rule (e): If one of the classes is X87, X87UP, COMPLEX_X87 class,
4205796c8dcSSimon Schubert      MEMORY is used as class.  */
4215796c8dcSSimon Schubert   if (class1 == AMD64_X87 || class1 == AMD64_X87UP
4225796c8dcSSimon Schubert       || class1 == AMD64_COMPLEX_X87 || class2 == AMD64_X87
4235796c8dcSSimon Schubert       || class2 == AMD64_X87UP || class2 == AMD64_COMPLEX_X87)
4245796c8dcSSimon Schubert     return AMD64_MEMORY;
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert   /* Rule (f): Otherwise class SSE is used.  */
4275796c8dcSSimon Schubert   return AMD64_SSE;
4285796c8dcSSimon Schubert }
4295796c8dcSSimon Schubert 
4305796c8dcSSimon Schubert /* Return non-zero if TYPE is a non-POD structure or union type.  */
4315796c8dcSSimon Schubert 
4325796c8dcSSimon Schubert static int
amd64_non_pod_p(struct type * type)4335796c8dcSSimon Schubert amd64_non_pod_p (struct type *type)
4345796c8dcSSimon Schubert {
4355796c8dcSSimon Schubert   /* ??? A class with a base class certainly isn't POD, but does this
4365796c8dcSSimon Schubert      catch all non-POD structure types?  */
4375796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_N_BASECLASSES (type) > 0)
4385796c8dcSSimon Schubert     return 1;
4395796c8dcSSimon Schubert 
4405796c8dcSSimon Schubert   return 0;
4415796c8dcSSimon Schubert }
4425796c8dcSSimon Schubert 
4435796c8dcSSimon Schubert /* Classify TYPE according to the rules for aggregate (structures and
4445796c8dcSSimon Schubert    arrays) and union types, and store the result in CLASS.  */
4455796c8dcSSimon Schubert 
4465796c8dcSSimon Schubert static void
amd64_classify_aggregate(struct type * type,enum amd64_reg_class class[2])4475796c8dcSSimon Schubert amd64_classify_aggregate (struct type *type, enum amd64_reg_class class[2])
4485796c8dcSSimon Schubert {
4495796c8dcSSimon Schubert   /* 1. If the size of an object is larger than two eightbytes, or in
4505796c8dcSSimon Schubert         C++, is a non-POD structure or union type, or contains
4515796c8dcSSimon Schubert         unaligned fields, it has class memory.  */
452*ef5ccd6cSJohn Marino   if (TYPE_LENGTH (type) > 16 || amd64_non_pod_p (type))
4535796c8dcSSimon Schubert     {
4545796c8dcSSimon Schubert       class[0] = class[1] = AMD64_MEMORY;
4555796c8dcSSimon Schubert       return;
4565796c8dcSSimon Schubert     }
4575796c8dcSSimon Schubert 
4585796c8dcSSimon Schubert   /* 2. Both eightbytes get initialized to class NO_CLASS.  */
4595796c8dcSSimon Schubert   class[0] = class[1] = AMD64_NO_CLASS;
4605796c8dcSSimon Schubert 
4615796c8dcSSimon Schubert   /* 3. Each field of an object is classified recursively so that
4625796c8dcSSimon Schubert         always two fields are considered. The resulting class is
4635796c8dcSSimon Schubert         calculated according to the classes of the fields in the
4645796c8dcSSimon Schubert         eightbyte: */
4655796c8dcSSimon Schubert 
4665796c8dcSSimon Schubert   if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
4675796c8dcSSimon Schubert     {
4685796c8dcSSimon Schubert       struct type *subtype = check_typedef (TYPE_TARGET_TYPE (type));
4695796c8dcSSimon Schubert 
4705796c8dcSSimon Schubert       /* All fields in an array have the same type.  */
4715796c8dcSSimon Schubert       amd64_classify (subtype, class);
472*ef5ccd6cSJohn Marino       if (TYPE_LENGTH (type) > 8 && class[1] == AMD64_NO_CLASS)
4735796c8dcSSimon Schubert 	class[1] = class[0];
4745796c8dcSSimon Schubert     }
4755796c8dcSSimon Schubert   else
4765796c8dcSSimon Schubert     {
4775796c8dcSSimon Schubert       int i;
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert       /* Structure or union.  */
4805796c8dcSSimon Schubert       gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
4815796c8dcSSimon Schubert 		  || TYPE_CODE (type) == TYPE_CODE_UNION);
4825796c8dcSSimon Schubert 
4835796c8dcSSimon Schubert       for (i = 0; i < TYPE_NFIELDS (type); i++)
4845796c8dcSSimon Schubert 	{
4855796c8dcSSimon Schubert 	  struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
4865796c8dcSSimon Schubert 	  int pos = TYPE_FIELD_BITPOS (type, i) / 64;
4875796c8dcSSimon Schubert 	  enum amd64_reg_class subclass[2];
488cf7f2e2dSJohn Marino 	  int bitsize = TYPE_FIELD_BITSIZE (type, i);
489cf7f2e2dSJohn Marino 	  int endpos;
490cf7f2e2dSJohn Marino 
491cf7f2e2dSJohn Marino 	  if (bitsize == 0)
492cf7f2e2dSJohn Marino 	    bitsize = TYPE_LENGTH (subtype) * 8;
493cf7f2e2dSJohn Marino 	  endpos = (TYPE_FIELD_BITPOS (type, i) + bitsize - 1) / 64;
4945796c8dcSSimon Schubert 
4955796c8dcSSimon Schubert 	  /* Ignore static fields.  */
4965796c8dcSSimon Schubert 	  if (field_is_static (&TYPE_FIELD (type, i)))
4975796c8dcSSimon Schubert 	    continue;
4985796c8dcSSimon Schubert 
4995796c8dcSSimon Schubert 	  gdb_assert (pos == 0 || pos == 1);
5005796c8dcSSimon Schubert 
5015796c8dcSSimon Schubert 	  amd64_classify (subtype, subclass);
5025796c8dcSSimon Schubert 	  class[pos] = amd64_merge_classes (class[pos], subclass[0]);
503cf7f2e2dSJohn Marino 	  if (bitsize <= 64 && pos == 0 && endpos == 1)
504cf7f2e2dSJohn Marino 	    /* This is a bit of an odd case:  We have a field that would
505cf7f2e2dSJohn Marino 	       normally fit in one of the two eightbytes, except that
506cf7f2e2dSJohn Marino 	       it is placed in a way that this field straddles them.
507cf7f2e2dSJohn Marino 	       This has been seen with a structure containing an array.
508cf7f2e2dSJohn Marino 
509cf7f2e2dSJohn Marino 	       The ABI is a bit unclear in this case, but we assume that
510cf7f2e2dSJohn Marino 	       this field's class (stored in subclass[0]) must also be merged
511cf7f2e2dSJohn Marino 	       into class[1].  In other words, our field has a piece stored
512cf7f2e2dSJohn Marino 	       in the second eight-byte, and thus its class applies to
513cf7f2e2dSJohn Marino 	       the second eight-byte as well.
514cf7f2e2dSJohn Marino 
515cf7f2e2dSJohn Marino 	       In the case where the field length exceeds 8 bytes,
516cf7f2e2dSJohn Marino 	       it should not be necessary to merge the field class
517cf7f2e2dSJohn Marino 	       into class[1].  As LEN > 8, subclass[1] is necessarily
518cf7f2e2dSJohn Marino 	       different from AMD64_NO_CLASS.  If subclass[1] is equal
519cf7f2e2dSJohn Marino 	       to subclass[0], then the normal class[1]/subclass[1]
520cf7f2e2dSJohn Marino 	       merging will take care of everything.  For subclass[1]
521cf7f2e2dSJohn Marino 	       to be different from subclass[0], I can only see the case
522cf7f2e2dSJohn Marino 	       where we have a SSE/SSEUP or X87/X87UP pair, which both
523cf7f2e2dSJohn Marino 	       use up all 16 bytes of the aggregate, and are already
524cf7f2e2dSJohn Marino 	       handled just fine (because each portion sits on its own
525cf7f2e2dSJohn Marino 	       8-byte).  */
526cf7f2e2dSJohn Marino 	    class[1] = amd64_merge_classes (class[1], subclass[0]);
5275796c8dcSSimon Schubert 	  if (pos == 0)
5285796c8dcSSimon Schubert 	    class[1] = amd64_merge_classes (class[1], subclass[1]);
5295796c8dcSSimon Schubert 	}
5305796c8dcSSimon Schubert     }
5315796c8dcSSimon Schubert 
5325796c8dcSSimon Schubert   /* 4. Then a post merger cleanup is done:  */
5335796c8dcSSimon Schubert 
5345796c8dcSSimon Schubert   /* Rule (a): If one of the classes is MEMORY, the whole argument is
5355796c8dcSSimon Schubert      passed in memory.  */
5365796c8dcSSimon Schubert   if (class[0] == AMD64_MEMORY || class[1] == AMD64_MEMORY)
5375796c8dcSSimon Schubert     class[0] = class[1] = AMD64_MEMORY;
5385796c8dcSSimon Schubert 
539a45ae5f8SJohn Marino   /* Rule (b): If SSEUP is not preceded by SSE, it is converted to
5405796c8dcSSimon Schubert      SSE.  */
5415796c8dcSSimon Schubert   if (class[0] == AMD64_SSEUP)
5425796c8dcSSimon Schubert     class[0] = AMD64_SSE;
5435796c8dcSSimon Schubert   if (class[1] == AMD64_SSEUP && class[0] != AMD64_SSE)
5445796c8dcSSimon Schubert     class[1] = AMD64_SSE;
5455796c8dcSSimon Schubert }
5465796c8dcSSimon Schubert 
5475796c8dcSSimon Schubert /* Classify TYPE, and store the result in CLASS.  */
5485796c8dcSSimon Schubert 
549cf7f2e2dSJohn Marino void
amd64_classify(struct type * type,enum amd64_reg_class class[2])5505796c8dcSSimon Schubert amd64_classify (struct type *type, enum amd64_reg_class class[2])
5515796c8dcSSimon Schubert {
5525796c8dcSSimon Schubert   enum type_code code = TYPE_CODE (type);
5535796c8dcSSimon Schubert   int len = TYPE_LENGTH (type);
5545796c8dcSSimon Schubert 
5555796c8dcSSimon Schubert   class[0] = class[1] = AMD64_NO_CLASS;
5565796c8dcSSimon Schubert 
5575796c8dcSSimon Schubert   /* Arguments of types (signed and unsigned) _Bool, char, short, int,
5585796c8dcSSimon Schubert      long, long long, and pointers are in the INTEGER class.  Similarly,
5595796c8dcSSimon Schubert      range types, used by languages such as Ada, are also in the INTEGER
5605796c8dcSSimon Schubert      class.  */
5615796c8dcSSimon Schubert   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
5625796c8dcSSimon Schubert        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
5635796c8dcSSimon Schubert        || code == TYPE_CODE_CHAR
5645796c8dcSSimon Schubert        || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
5655796c8dcSSimon Schubert       && (len == 1 || len == 2 || len == 4 || len == 8))
5665796c8dcSSimon Schubert     class[0] = AMD64_INTEGER;
5675796c8dcSSimon Schubert 
5685796c8dcSSimon Schubert   /* Arguments of types float, double, _Decimal32, _Decimal64 and __m64
5695796c8dcSSimon Schubert      are in class SSE.  */
5705796c8dcSSimon Schubert   else if ((code == TYPE_CODE_FLT || code == TYPE_CODE_DECFLOAT)
5715796c8dcSSimon Schubert 	   && (len == 4 || len == 8))
5725796c8dcSSimon Schubert     /* FIXME: __m64 .  */
5735796c8dcSSimon Schubert     class[0] = AMD64_SSE;
5745796c8dcSSimon Schubert 
5755796c8dcSSimon Schubert   /* Arguments of types __float128, _Decimal128 and __m128 are split into
5765796c8dcSSimon Schubert      two halves.  The least significant ones belong to class SSE, the most
5775796c8dcSSimon Schubert      significant one to class SSEUP.  */
5785796c8dcSSimon Schubert   else if (code == TYPE_CODE_DECFLOAT && len == 16)
5795796c8dcSSimon Schubert     /* FIXME: __float128, __m128.  */
5805796c8dcSSimon Schubert     class[0] = AMD64_SSE, class[1] = AMD64_SSEUP;
5815796c8dcSSimon Schubert 
5825796c8dcSSimon Schubert   /* The 64-bit mantissa of arguments of type long double belongs to
5835796c8dcSSimon Schubert      class X87, the 16-bit exponent plus 6 bytes of padding belongs to
5845796c8dcSSimon Schubert      class X87UP.  */
5855796c8dcSSimon Schubert   else if (code == TYPE_CODE_FLT && len == 16)
5865796c8dcSSimon Schubert     /* Class X87 and X87UP.  */
5875796c8dcSSimon Schubert     class[0] = AMD64_X87, class[1] = AMD64_X87UP;
5885796c8dcSSimon Schubert 
589*ef5ccd6cSJohn Marino   /* Arguments of complex T where T is one of the types float or
590*ef5ccd6cSJohn Marino      double get treated as if they are implemented as:
591*ef5ccd6cSJohn Marino 
592*ef5ccd6cSJohn Marino      struct complexT {
593*ef5ccd6cSJohn Marino        T real;
594*ef5ccd6cSJohn Marino        T imag;
595*ef5ccd6cSJohn Marino      };  */
596*ef5ccd6cSJohn Marino   else if (code == TYPE_CODE_COMPLEX && len == 8)
597*ef5ccd6cSJohn Marino     class[0] = AMD64_SSE;
598*ef5ccd6cSJohn Marino   else if (code == TYPE_CODE_COMPLEX && len == 16)
599*ef5ccd6cSJohn Marino     class[0] = class[1] = AMD64_SSE;
600*ef5ccd6cSJohn Marino 
601*ef5ccd6cSJohn Marino   /* A variable of type complex long double is classified as type
602*ef5ccd6cSJohn Marino      COMPLEX_X87.  */
603*ef5ccd6cSJohn Marino   else if (code == TYPE_CODE_COMPLEX && len == 32)
604*ef5ccd6cSJohn Marino     class[0] = AMD64_COMPLEX_X87;
605*ef5ccd6cSJohn Marino 
6065796c8dcSSimon Schubert   /* Aggregates.  */
6075796c8dcSSimon Schubert   else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT
6085796c8dcSSimon Schubert 	   || code == TYPE_CODE_UNION)
6095796c8dcSSimon Schubert     amd64_classify_aggregate (type, class);
6105796c8dcSSimon Schubert }
6115796c8dcSSimon Schubert 
6125796c8dcSSimon Schubert static enum return_value_convention
amd64_return_value(struct gdbarch * gdbarch,struct value * function,struct type * type,struct regcache * regcache,gdb_byte * readbuf,const gdb_byte * writebuf)613*ef5ccd6cSJohn Marino amd64_return_value (struct gdbarch *gdbarch, struct value *function,
6145796c8dcSSimon Schubert 		    struct type *type, struct regcache *regcache,
6155796c8dcSSimon Schubert 		    gdb_byte *readbuf, const gdb_byte *writebuf)
6165796c8dcSSimon Schubert {
617cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
6185796c8dcSSimon Schubert   enum amd64_reg_class class[2];
6195796c8dcSSimon Schubert   int len = TYPE_LENGTH (type);
6205796c8dcSSimon Schubert   static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM };
6215796c8dcSSimon Schubert   static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM };
6225796c8dcSSimon Schubert   int integer_reg = 0;
6235796c8dcSSimon Schubert   int sse_reg = 0;
6245796c8dcSSimon Schubert   int i;
6255796c8dcSSimon Schubert 
6265796c8dcSSimon Schubert   gdb_assert (!(readbuf && writebuf));
627cf7f2e2dSJohn Marino   gdb_assert (tdep->classify);
6285796c8dcSSimon Schubert 
6295796c8dcSSimon Schubert   /* 1. Classify the return type with the classification algorithm.  */
630cf7f2e2dSJohn Marino   tdep->classify (type, class);
6315796c8dcSSimon Schubert 
6325796c8dcSSimon Schubert   /* 2. If the type has class MEMORY, then the caller provides space
6335796c8dcSSimon Schubert      for the return value and passes the address of this storage in
6345796c8dcSSimon Schubert      %rdi as if it were the first argument to the function.  In effect,
6355796c8dcSSimon Schubert      this address becomes a hidden first argument.
6365796c8dcSSimon Schubert 
6375796c8dcSSimon Schubert      On return %rax will contain the address that has been passed in
6385796c8dcSSimon Schubert      by the caller in %rdi.  */
6395796c8dcSSimon Schubert   if (class[0] == AMD64_MEMORY)
6405796c8dcSSimon Schubert     {
6415796c8dcSSimon Schubert       /* As indicated by the comment above, the ABI guarantees that we
6425796c8dcSSimon Schubert          can always find the return value just after the function has
6435796c8dcSSimon Schubert          returned.  */
6445796c8dcSSimon Schubert 
6455796c8dcSSimon Schubert       if (readbuf)
6465796c8dcSSimon Schubert 	{
6475796c8dcSSimon Schubert 	  ULONGEST addr;
6485796c8dcSSimon Schubert 
6495796c8dcSSimon Schubert 	  regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
6505796c8dcSSimon Schubert 	  read_memory (addr, readbuf, TYPE_LENGTH (type));
6515796c8dcSSimon Schubert 	}
6525796c8dcSSimon Schubert 
6535796c8dcSSimon Schubert       return RETURN_VALUE_ABI_RETURNS_ADDRESS;
6545796c8dcSSimon Schubert     }
6555796c8dcSSimon Schubert 
656*ef5ccd6cSJohn Marino   /* 8. If the class is COMPLEX_X87, the real part of the value is
657*ef5ccd6cSJohn Marino         returned in %st0 and the imaginary part in %st1.  */
658*ef5ccd6cSJohn Marino   if (class[0] == AMD64_COMPLEX_X87)
659*ef5ccd6cSJohn Marino     {
660*ef5ccd6cSJohn Marino       if (readbuf)
661*ef5ccd6cSJohn Marino 	{
662*ef5ccd6cSJohn Marino 	  regcache_raw_read (regcache, AMD64_ST0_REGNUM, readbuf);
663*ef5ccd6cSJohn Marino 	  regcache_raw_read (regcache, AMD64_ST1_REGNUM, readbuf + 16);
664*ef5ccd6cSJohn Marino 	}
665*ef5ccd6cSJohn Marino 
666*ef5ccd6cSJohn Marino       if (writebuf)
667*ef5ccd6cSJohn Marino 	{
668*ef5ccd6cSJohn Marino 	  i387_return_value (gdbarch, regcache);
669*ef5ccd6cSJohn Marino 	  regcache_raw_write (regcache, AMD64_ST0_REGNUM, writebuf);
670*ef5ccd6cSJohn Marino 	  regcache_raw_write (regcache, AMD64_ST1_REGNUM, writebuf + 16);
671*ef5ccd6cSJohn Marino 
672*ef5ccd6cSJohn Marino 	  /* Fix up the tag word such that both %st(0) and %st(1) are
673*ef5ccd6cSJohn Marino 	     marked as valid.  */
674*ef5ccd6cSJohn Marino 	  regcache_raw_write_unsigned (regcache, AMD64_FTAG_REGNUM, 0xfff);
675*ef5ccd6cSJohn Marino 	}
676*ef5ccd6cSJohn Marino 
677*ef5ccd6cSJohn Marino       return RETURN_VALUE_REGISTER_CONVENTION;
678*ef5ccd6cSJohn Marino     }
679*ef5ccd6cSJohn Marino 
6805796c8dcSSimon Schubert   gdb_assert (class[1] != AMD64_MEMORY);
6815796c8dcSSimon Schubert   gdb_assert (len <= 16);
6825796c8dcSSimon Schubert 
6835796c8dcSSimon Schubert   for (i = 0; len > 0; i++, len -= 8)
6845796c8dcSSimon Schubert     {
6855796c8dcSSimon Schubert       int regnum = -1;
6865796c8dcSSimon Schubert       int offset = 0;
6875796c8dcSSimon Schubert 
6885796c8dcSSimon Schubert       switch (class[i])
6895796c8dcSSimon Schubert 	{
6905796c8dcSSimon Schubert 	case AMD64_INTEGER:
6915796c8dcSSimon Schubert 	  /* 3. If the class is INTEGER, the next available register
6925796c8dcSSimon Schubert 	     of the sequence %rax, %rdx is used.  */
6935796c8dcSSimon Schubert 	  regnum = integer_regnum[integer_reg++];
6945796c8dcSSimon Schubert 	  break;
6955796c8dcSSimon Schubert 
6965796c8dcSSimon Schubert 	case AMD64_SSE:
6975796c8dcSSimon Schubert 	  /* 4. If the class is SSE, the next available SSE register
6985796c8dcSSimon Schubert              of the sequence %xmm0, %xmm1 is used.  */
6995796c8dcSSimon Schubert 	  regnum = sse_regnum[sse_reg++];
7005796c8dcSSimon Schubert 	  break;
7015796c8dcSSimon Schubert 
7025796c8dcSSimon Schubert 	case AMD64_SSEUP:
7035796c8dcSSimon Schubert 	  /* 5. If the class is SSEUP, the eightbyte is passed in the
7045796c8dcSSimon Schubert 	     upper half of the last used SSE register.  */
7055796c8dcSSimon Schubert 	  gdb_assert (sse_reg > 0);
7065796c8dcSSimon Schubert 	  regnum = sse_regnum[sse_reg - 1];
7075796c8dcSSimon Schubert 	  offset = 8;
7085796c8dcSSimon Schubert 	  break;
7095796c8dcSSimon Schubert 
7105796c8dcSSimon Schubert 	case AMD64_X87:
7115796c8dcSSimon Schubert 	  /* 6. If the class is X87, the value is returned on the X87
7125796c8dcSSimon Schubert              stack in %st0 as 80-bit x87 number.  */
7135796c8dcSSimon Schubert 	  regnum = AMD64_ST0_REGNUM;
7145796c8dcSSimon Schubert 	  if (writebuf)
7155796c8dcSSimon Schubert 	    i387_return_value (gdbarch, regcache);
7165796c8dcSSimon Schubert 	  break;
7175796c8dcSSimon Schubert 
7185796c8dcSSimon Schubert 	case AMD64_X87UP:
7195796c8dcSSimon Schubert 	  /* 7. If the class is X87UP, the value is returned together
7205796c8dcSSimon Schubert              with the previous X87 value in %st0.  */
7215796c8dcSSimon Schubert 	  gdb_assert (i > 0 && class[0] == AMD64_X87);
7225796c8dcSSimon Schubert 	  regnum = AMD64_ST0_REGNUM;
7235796c8dcSSimon Schubert 	  offset = 8;
7245796c8dcSSimon Schubert 	  len = 2;
7255796c8dcSSimon Schubert 	  break;
7265796c8dcSSimon Schubert 
7275796c8dcSSimon Schubert 	case AMD64_NO_CLASS:
7285796c8dcSSimon Schubert 	  continue;
7295796c8dcSSimon Schubert 
7305796c8dcSSimon Schubert 	default:
7315796c8dcSSimon Schubert 	  gdb_assert (!"Unexpected register class.");
7325796c8dcSSimon Schubert 	}
7335796c8dcSSimon Schubert 
7345796c8dcSSimon Schubert       gdb_assert (regnum != -1);
7355796c8dcSSimon Schubert 
7365796c8dcSSimon Schubert       if (readbuf)
7375796c8dcSSimon Schubert 	regcache_raw_read_part (regcache, regnum, offset, min (len, 8),
7385796c8dcSSimon Schubert 				readbuf + i * 8);
7395796c8dcSSimon Schubert       if (writebuf)
7405796c8dcSSimon Schubert 	regcache_raw_write_part (regcache, regnum, offset, min (len, 8),
7415796c8dcSSimon Schubert 				 writebuf + i * 8);
7425796c8dcSSimon Schubert     }
7435796c8dcSSimon Schubert 
7445796c8dcSSimon Schubert   return RETURN_VALUE_REGISTER_CONVENTION;
7455796c8dcSSimon Schubert }
7465796c8dcSSimon Schubert 
7475796c8dcSSimon Schubert 
7485796c8dcSSimon Schubert static CORE_ADDR
amd64_push_arguments(struct regcache * regcache,int nargs,struct value ** args,CORE_ADDR sp,int struct_return)7495796c8dcSSimon Schubert amd64_push_arguments (struct regcache *regcache, int nargs,
7505796c8dcSSimon Schubert 		      struct value **args, CORE_ADDR sp, int struct_return)
7515796c8dcSSimon Schubert {
752cf7f2e2dSJohn Marino   struct gdbarch *gdbarch = get_regcache_arch (regcache);
753cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
754cf7f2e2dSJohn Marino   int *integer_regs = tdep->call_dummy_integer_regs;
755cf7f2e2dSJohn Marino   int num_integer_regs = tdep->call_dummy_num_integer_regs;
756cf7f2e2dSJohn Marino 
7575796c8dcSSimon Schubert   static int sse_regnum[] =
7585796c8dcSSimon Schubert   {
7595796c8dcSSimon Schubert     /* %xmm0 ... %xmm7 */
7605796c8dcSSimon Schubert     AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM,
7615796c8dcSSimon Schubert     AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3,
7625796c8dcSSimon Schubert     AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5,
7635796c8dcSSimon Schubert     AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7,
7645796c8dcSSimon Schubert   };
7655796c8dcSSimon Schubert   struct value **stack_args = alloca (nargs * sizeof (struct value *));
766cf7f2e2dSJohn Marino   /* An array that mirrors the stack_args array.  For all arguments
767cf7f2e2dSJohn Marino      that are passed by MEMORY, if that argument's address also needs
768cf7f2e2dSJohn Marino      to be stored in a register, the ARG_ADDR_REGNO array will contain
769cf7f2e2dSJohn Marino      that register number (or a negative value otherwise).  */
770cf7f2e2dSJohn Marino   int *arg_addr_regno = alloca (nargs * sizeof (int));
7715796c8dcSSimon Schubert   int num_stack_args = 0;
7725796c8dcSSimon Schubert   int num_elements = 0;
7735796c8dcSSimon Schubert   int element = 0;
7745796c8dcSSimon Schubert   int integer_reg = 0;
7755796c8dcSSimon Schubert   int sse_reg = 0;
7765796c8dcSSimon Schubert   int i;
7775796c8dcSSimon Schubert 
778cf7f2e2dSJohn Marino   gdb_assert (tdep->classify);
779cf7f2e2dSJohn Marino 
7805796c8dcSSimon Schubert   /* Reserve a register for the "hidden" argument.  */
7815796c8dcSSimon Schubert   if (struct_return)
7825796c8dcSSimon Schubert     integer_reg++;
7835796c8dcSSimon Schubert 
7845796c8dcSSimon Schubert   for (i = 0; i < nargs; i++)
7855796c8dcSSimon Schubert     {
7865796c8dcSSimon Schubert       struct type *type = value_type (args[i]);
7875796c8dcSSimon Schubert       int len = TYPE_LENGTH (type);
7885796c8dcSSimon Schubert       enum amd64_reg_class class[2];
7895796c8dcSSimon Schubert       int needed_integer_regs = 0;
7905796c8dcSSimon Schubert       int needed_sse_regs = 0;
7915796c8dcSSimon Schubert       int j;
7925796c8dcSSimon Schubert 
7935796c8dcSSimon Schubert       /* Classify argument.  */
794cf7f2e2dSJohn Marino       tdep->classify (type, class);
7955796c8dcSSimon Schubert 
7965796c8dcSSimon Schubert       /* Calculate the number of integer and SSE registers needed for
7975796c8dcSSimon Schubert          this argument.  */
7985796c8dcSSimon Schubert       for (j = 0; j < 2; j++)
7995796c8dcSSimon Schubert 	{
8005796c8dcSSimon Schubert 	  if (class[j] == AMD64_INTEGER)
8015796c8dcSSimon Schubert 	    needed_integer_regs++;
8025796c8dcSSimon Schubert 	  else if (class[j] == AMD64_SSE)
8035796c8dcSSimon Schubert 	    needed_sse_regs++;
8045796c8dcSSimon Schubert 	}
8055796c8dcSSimon Schubert 
8065796c8dcSSimon Schubert       /* Check whether enough registers are available, and if the
8075796c8dcSSimon Schubert          argument should be passed in registers at all.  */
808cf7f2e2dSJohn Marino       if (integer_reg + needed_integer_regs > num_integer_regs
8095796c8dcSSimon Schubert 	  || sse_reg + needed_sse_regs > ARRAY_SIZE (sse_regnum)
8105796c8dcSSimon Schubert 	  || (needed_integer_regs == 0 && needed_sse_regs == 0))
8115796c8dcSSimon Schubert 	{
8125796c8dcSSimon Schubert 	  /* The argument will be passed on the stack.  */
8135796c8dcSSimon Schubert 	  num_elements += ((len + 7) / 8);
814cf7f2e2dSJohn Marino 	  stack_args[num_stack_args] = args[i];
815cf7f2e2dSJohn Marino           /* If this is an AMD64_MEMORY argument whose address must also
816cf7f2e2dSJohn Marino              be passed in one of the integer registers, reserve that
817cf7f2e2dSJohn Marino              register and associate this value to that register so that
818cf7f2e2dSJohn Marino              we can store the argument address as soon as we know it.  */
819cf7f2e2dSJohn Marino           if (class[0] == AMD64_MEMORY
820cf7f2e2dSJohn Marino               && tdep->memory_args_by_pointer
821cf7f2e2dSJohn Marino               && integer_reg < tdep->call_dummy_num_integer_regs)
822cf7f2e2dSJohn Marino             arg_addr_regno[num_stack_args] =
823cf7f2e2dSJohn Marino               tdep->call_dummy_integer_regs[integer_reg++];
824cf7f2e2dSJohn Marino           else
825cf7f2e2dSJohn Marino             arg_addr_regno[num_stack_args] = -1;
826cf7f2e2dSJohn Marino           num_stack_args++;
8275796c8dcSSimon Schubert 	}
8285796c8dcSSimon Schubert       else
8295796c8dcSSimon Schubert 	{
8305796c8dcSSimon Schubert 	  /* The argument will be passed in registers.  */
8315796c8dcSSimon Schubert 	  const gdb_byte *valbuf = value_contents (args[i]);
8325796c8dcSSimon Schubert 	  gdb_byte buf[8];
8335796c8dcSSimon Schubert 
8345796c8dcSSimon Schubert 	  gdb_assert (len <= 16);
8355796c8dcSSimon Schubert 
8365796c8dcSSimon Schubert 	  for (j = 0; len > 0; j++, len -= 8)
8375796c8dcSSimon Schubert 	    {
8385796c8dcSSimon Schubert 	      int regnum = -1;
8395796c8dcSSimon Schubert 	      int offset = 0;
8405796c8dcSSimon Schubert 
8415796c8dcSSimon Schubert 	      switch (class[j])
8425796c8dcSSimon Schubert 		{
8435796c8dcSSimon Schubert 		case AMD64_INTEGER:
844cf7f2e2dSJohn Marino 		  regnum = integer_regs[integer_reg++];
8455796c8dcSSimon Schubert 		  break;
8465796c8dcSSimon Schubert 
8475796c8dcSSimon Schubert 		case AMD64_SSE:
8485796c8dcSSimon Schubert 		  regnum = sse_regnum[sse_reg++];
8495796c8dcSSimon Schubert 		  break;
8505796c8dcSSimon Schubert 
8515796c8dcSSimon Schubert 		case AMD64_SSEUP:
8525796c8dcSSimon Schubert 		  gdb_assert (sse_reg > 0);
8535796c8dcSSimon Schubert 		  regnum = sse_regnum[sse_reg - 1];
8545796c8dcSSimon Schubert 		  offset = 8;
8555796c8dcSSimon Schubert 		  break;
8565796c8dcSSimon Schubert 
8575796c8dcSSimon Schubert 		default:
8585796c8dcSSimon Schubert 		  gdb_assert (!"Unexpected register class.");
8595796c8dcSSimon Schubert 		}
8605796c8dcSSimon Schubert 
8615796c8dcSSimon Schubert 	      gdb_assert (regnum != -1);
8625796c8dcSSimon Schubert 	      memset (buf, 0, sizeof buf);
8635796c8dcSSimon Schubert 	      memcpy (buf, valbuf + j * 8, min (len, 8));
8645796c8dcSSimon Schubert 	      regcache_raw_write_part (regcache, regnum, offset, 8, buf);
8655796c8dcSSimon Schubert 	    }
8665796c8dcSSimon Schubert 	}
8675796c8dcSSimon Schubert     }
8685796c8dcSSimon Schubert 
8695796c8dcSSimon Schubert   /* Allocate space for the arguments on the stack.  */
8705796c8dcSSimon Schubert   sp -= num_elements * 8;
8715796c8dcSSimon Schubert 
8725796c8dcSSimon Schubert   /* The psABI says that "The end of the input argument area shall be
8735796c8dcSSimon Schubert      aligned on a 16 byte boundary."  */
8745796c8dcSSimon Schubert   sp &= ~0xf;
8755796c8dcSSimon Schubert 
8765796c8dcSSimon Schubert   /* Write out the arguments to the stack.  */
8775796c8dcSSimon Schubert   for (i = 0; i < num_stack_args; i++)
8785796c8dcSSimon Schubert     {
8795796c8dcSSimon Schubert       struct type *type = value_type (stack_args[i]);
8805796c8dcSSimon Schubert       const gdb_byte *valbuf = value_contents (stack_args[i]);
881cf7f2e2dSJohn Marino       CORE_ADDR arg_addr = sp + element * 8;
8825796c8dcSSimon Schubert 
883*ef5ccd6cSJohn Marino       write_memory (arg_addr, valbuf, TYPE_LENGTH (type));
884cf7f2e2dSJohn Marino       if (arg_addr_regno[i] >= 0)
885cf7f2e2dSJohn Marino         {
886cf7f2e2dSJohn Marino           /* We also need to store the address of that argument in
887cf7f2e2dSJohn Marino              the given register.  */
888cf7f2e2dSJohn Marino           gdb_byte buf[8];
889cf7f2e2dSJohn Marino           enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
890cf7f2e2dSJohn Marino 
891cf7f2e2dSJohn Marino           store_unsigned_integer (buf, 8, byte_order, arg_addr);
892cf7f2e2dSJohn Marino           regcache_cooked_write (regcache, arg_addr_regno[i], buf);
893cf7f2e2dSJohn Marino         }
894*ef5ccd6cSJohn Marino       element += ((TYPE_LENGTH (type) + 7) / 8);
8955796c8dcSSimon Schubert     }
8965796c8dcSSimon Schubert 
8975796c8dcSSimon Schubert   /* The psABI says that "For calls that may call functions that use
8985796c8dcSSimon Schubert      varargs or stdargs (prototype-less calls or calls to functions
8995796c8dcSSimon Schubert      containing ellipsis (...) in the declaration) %al is used as
9005796c8dcSSimon Schubert      hidden argument to specify the number of SSE registers used.  */
9015796c8dcSSimon Schubert   regcache_raw_write_unsigned (regcache, AMD64_RAX_REGNUM, sse_reg);
9025796c8dcSSimon Schubert   return sp;
9035796c8dcSSimon Schubert }
9045796c8dcSSimon Schubert 
9055796c8dcSSimon Schubert static CORE_ADDR
amd64_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)9065796c8dcSSimon Schubert amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
9075796c8dcSSimon Schubert 		       struct regcache *regcache, CORE_ADDR bp_addr,
9085796c8dcSSimon Schubert 		       int nargs, struct value **args,	CORE_ADDR sp,
9095796c8dcSSimon Schubert 		       int struct_return, CORE_ADDR struct_addr)
9105796c8dcSSimon Schubert {
9115796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
912cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
9135796c8dcSSimon Schubert   gdb_byte buf[8];
9145796c8dcSSimon Schubert 
9155796c8dcSSimon Schubert   /* Pass arguments.  */
9165796c8dcSSimon Schubert   sp = amd64_push_arguments (regcache, nargs, args, sp, struct_return);
9175796c8dcSSimon Schubert 
9185796c8dcSSimon Schubert   /* Pass "hidden" argument".  */
9195796c8dcSSimon Schubert   if (struct_return)
9205796c8dcSSimon Schubert     {
921cf7f2e2dSJohn Marino       /* The "hidden" argument is passed throught the first argument
922cf7f2e2dSJohn Marino          register.  */
923cf7f2e2dSJohn Marino       const int arg_regnum = tdep->call_dummy_integer_regs[0];
924cf7f2e2dSJohn Marino 
9255796c8dcSSimon Schubert       store_unsigned_integer (buf, 8, byte_order, struct_addr);
926cf7f2e2dSJohn Marino       regcache_cooked_write (regcache, arg_regnum, buf);
9275796c8dcSSimon Schubert     }
9285796c8dcSSimon Schubert 
929cf7f2e2dSJohn Marino   /* Reserve some memory on the stack for the integer-parameter registers,
930cf7f2e2dSJohn Marino      if required by the ABI.  */
931cf7f2e2dSJohn Marino   if (tdep->integer_param_regs_saved_in_caller_frame)
932cf7f2e2dSJohn Marino     sp -= tdep->call_dummy_num_integer_regs * 8;
933cf7f2e2dSJohn Marino 
9345796c8dcSSimon Schubert   /* Store return address.  */
9355796c8dcSSimon Schubert   sp -= 8;
9365796c8dcSSimon Schubert   store_unsigned_integer (buf, 8, byte_order, bp_addr);
9375796c8dcSSimon Schubert   write_memory (sp, buf, 8);
9385796c8dcSSimon Schubert 
9395796c8dcSSimon Schubert   /* Finally, update the stack pointer...  */
9405796c8dcSSimon Schubert   store_unsigned_integer (buf, 8, byte_order, sp);
9415796c8dcSSimon Schubert   regcache_cooked_write (regcache, AMD64_RSP_REGNUM, buf);
9425796c8dcSSimon Schubert 
9435796c8dcSSimon Schubert   /* ...and fake a frame pointer.  */
9445796c8dcSSimon Schubert   regcache_cooked_write (regcache, AMD64_RBP_REGNUM, buf);
9455796c8dcSSimon Schubert 
9465796c8dcSSimon Schubert   return sp + 16;
9475796c8dcSSimon Schubert }
9485796c8dcSSimon Schubert 
9495796c8dcSSimon Schubert /* Displaced instruction handling.  */
9505796c8dcSSimon Schubert 
9515796c8dcSSimon Schubert /* A partially decoded instruction.
9525796c8dcSSimon Schubert    This contains enough details for displaced stepping purposes.  */
9535796c8dcSSimon Schubert 
9545796c8dcSSimon Schubert struct amd64_insn
9555796c8dcSSimon Schubert {
9565796c8dcSSimon Schubert   /* The number of opcode bytes.  */
9575796c8dcSSimon Schubert   int opcode_len;
9585796c8dcSSimon Schubert   /* The offset of the rex prefix or -1 if not present.  */
9595796c8dcSSimon Schubert   int rex_offset;
9605796c8dcSSimon Schubert   /* The offset to the first opcode byte.  */
9615796c8dcSSimon Schubert   int opcode_offset;
9625796c8dcSSimon Schubert   /* The offset to the modrm byte or -1 if not present.  */
9635796c8dcSSimon Schubert   int modrm_offset;
9645796c8dcSSimon Schubert 
9655796c8dcSSimon Schubert   /* The raw instruction.  */
9665796c8dcSSimon Schubert   gdb_byte *raw_insn;
9675796c8dcSSimon Schubert };
9685796c8dcSSimon Schubert 
9695796c8dcSSimon Schubert struct displaced_step_closure
9705796c8dcSSimon Schubert {
9715796c8dcSSimon Schubert   /* For rip-relative insns, saved copy of the reg we use instead of %rip.  */
9725796c8dcSSimon Schubert   int tmp_used;
9735796c8dcSSimon Schubert   int tmp_regno;
9745796c8dcSSimon Schubert   ULONGEST tmp_save;
9755796c8dcSSimon Schubert 
9765796c8dcSSimon Schubert   /* Details of the instruction.  */
9775796c8dcSSimon Schubert   struct amd64_insn insn_details;
9785796c8dcSSimon Schubert 
9795796c8dcSSimon Schubert   /* Amount of space allocated to insn_buf.  */
9805796c8dcSSimon Schubert   int max_len;
9815796c8dcSSimon Schubert 
9825796c8dcSSimon Schubert   /* The possibly modified insn.
9835796c8dcSSimon Schubert      This is a variable-length field.  */
9845796c8dcSSimon Schubert   gdb_byte insn_buf[1];
9855796c8dcSSimon Schubert };
9865796c8dcSSimon Schubert 
9875796c8dcSSimon Schubert /* WARNING: Keep onebyte_has_modrm, twobyte_has_modrm in sync with
9885796c8dcSSimon Schubert    ../opcodes/i386-dis.c (until libopcodes exports them, or an alternative,
9895796c8dcSSimon Schubert    at which point delete these in favor of libopcodes' versions).  */
9905796c8dcSSimon Schubert 
9915796c8dcSSimon Schubert static const unsigned char onebyte_has_modrm[256] = {
9925796c8dcSSimon Schubert   /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
9935796c8dcSSimon Schubert   /*	   -------------------------------	  */
9945796c8dcSSimon Schubert   /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
9955796c8dcSSimon Schubert   /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
9965796c8dcSSimon Schubert   /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
9975796c8dcSSimon Schubert   /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
9985796c8dcSSimon Schubert   /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
9995796c8dcSSimon Schubert   /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
10005796c8dcSSimon Schubert   /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
10015796c8dcSSimon Schubert   /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
10025796c8dcSSimon Schubert   /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
10035796c8dcSSimon Schubert   /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
10045796c8dcSSimon Schubert   /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
10055796c8dcSSimon Schubert   /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
10065796c8dcSSimon Schubert   /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
10075796c8dcSSimon Schubert   /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
10085796c8dcSSimon Schubert   /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
10095796c8dcSSimon Schubert   /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
10105796c8dcSSimon Schubert   /*	   -------------------------------	  */
10115796c8dcSSimon Schubert   /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
10125796c8dcSSimon Schubert };
10135796c8dcSSimon Schubert 
10145796c8dcSSimon Schubert static const unsigned char twobyte_has_modrm[256] = {
10155796c8dcSSimon Schubert   /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
10165796c8dcSSimon Schubert   /*	   -------------------------------	  */
10175796c8dcSSimon Schubert   /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
10185796c8dcSSimon Schubert   /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
10195796c8dcSSimon Schubert   /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
10205796c8dcSSimon Schubert   /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
10215796c8dcSSimon Schubert   /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
10225796c8dcSSimon Schubert   /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
10235796c8dcSSimon Schubert   /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
10245796c8dcSSimon Schubert   /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
10255796c8dcSSimon Schubert   /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
10265796c8dcSSimon Schubert   /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
10275796c8dcSSimon Schubert   /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
10285796c8dcSSimon Schubert   /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
10295796c8dcSSimon Schubert   /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
10305796c8dcSSimon Schubert   /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
10315796c8dcSSimon Schubert   /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
10325796c8dcSSimon Schubert   /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
10335796c8dcSSimon Schubert   /*	   -------------------------------	  */
10345796c8dcSSimon Schubert   /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
10355796c8dcSSimon Schubert };
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert static int amd64_syscall_p (const struct amd64_insn *insn, int *lengthp);
10385796c8dcSSimon Schubert 
10395796c8dcSSimon Schubert static int
rex_prefix_p(gdb_byte pfx)10405796c8dcSSimon Schubert rex_prefix_p (gdb_byte pfx)
10415796c8dcSSimon Schubert {
10425796c8dcSSimon Schubert   return REX_PREFIX_P (pfx);
10435796c8dcSSimon Schubert }
10445796c8dcSSimon Schubert 
10455796c8dcSSimon Schubert /* Skip the legacy instruction prefixes in INSN.
10465796c8dcSSimon Schubert    We assume INSN is properly sentineled so we don't have to worry
10475796c8dcSSimon Schubert    about falling off the end of the buffer.  */
10485796c8dcSSimon Schubert 
10495796c8dcSSimon Schubert static gdb_byte *
amd64_skip_prefixes(gdb_byte * insn)10505796c8dcSSimon Schubert amd64_skip_prefixes (gdb_byte *insn)
10515796c8dcSSimon Schubert {
10525796c8dcSSimon Schubert   while (1)
10535796c8dcSSimon Schubert     {
10545796c8dcSSimon Schubert       switch (*insn)
10555796c8dcSSimon Schubert 	{
10565796c8dcSSimon Schubert 	case DATA_PREFIX_OPCODE:
10575796c8dcSSimon Schubert 	case ADDR_PREFIX_OPCODE:
10585796c8dcSSimon Schubert 	case CS_PREFIX_OPCODE:
10595796c8dcSSimon Schubert 	case DS_PREFIX_OPCODE:
10605796c8dcSSimon Schubert 	case ES_PREFIX_OPCODE:
10615796c8dcSSimon Schubert 	case FS_PREFIX_OPCODE:
10625796c8dcSSimon Schubert 	case GS_PREFIX_OPCODE:
10635796c8dcSSimon Schubert 	case SS_PREFIX_OPCODE:
10645796c8dcSSimon Schubert 	case LOCK_PREFIX_OPCODE:
10655796c8dcSSimon Schubert 	case REPE_PREFIX_OPCODE:
10665796c8dcSSimon Schubert 	case REPNE_PREFIX_OPCODE:
10675796c8dcSSimon Schubert 	  ++insn;
10685796c8dcSSimon Schubert 	  continue;
10695796c8dcSSimon Schubert 	default:
10705796c8dcSSimon Schubert 	  break;
10715796c8dcSSimon Schubert 	}
10725796c8dcSSimon Schubert       break;
10735796c8dcSSimon Schubert     }
10745796c8dcSSimon Schubert 
10755796c8dcSSimon Schubert   return insn;
10765796c8dcSSimon Schubert }
10775796c8dcSSimon Schubert 
10785796c8dcSSimon Schubert /* Return an integer register (other than RSP) that is unused as an input
10795796c8dcSSimon Schubert    operand in INSN.
10805796c8dcSSimon Schubert    In order to not require adding a rex prefix if the insn doesn't already
10815796c8dcSSimon Schubert    have one, the result is restricted to RAX ... RDI, sans RSP.
10825796c8dcSSimon Schubert    The register numbering of the result follows architecture ordering,
10835796c8dcSSimon Schubert    e.g. RDI = 7.  */
10845796c8dcSSimon Schubert 
10855796c8dcSSimon Schubert static int
amd64_get_unused_input_int_reg(const struct amd64_insn * details)10865796c8dcSSimon Schubert amd64_get_unused_input_int_reg (const struct amd64_insn *details)
10875796c8dcSSimon Schubert {
10885796c8dcSSimon Schubert   /* 1 bit for each reg */
10895796c8dcSSimon Schubert   int used_regs_mask = 0;
10905796c8dcSSimon Schubert 
10915796c8dcSSimon Schubert   /* There can be at most 3 int regs used as inputs in an insn, and we have
10925796c8dcSSimon Schubert      7 to choose from (RAX ... RDI, sans RSP).
10935796c8dcSSimon Schubert      This allows us to take a conservative approach and keep things simple.
10945796c8dcSSimon Schubert      E.g. By avoiding RAX, we don't have to specifically watch for opcodes
10955796c8dcSSimon Schubert      that implicitly specify RAX.  */
10965796c8dcSSimon Schubert 
10975796c8dcSSimon Schubert   /* Avoid RAX.  */
10985796c8dcSSimon Schubert   used_regs_mask |= 1 << EAX_REG_NUM;
10995796c8dcSSimon Schubert   /* Similarily avoid RDX, implicit operand in divides.  */
11005796c8dcSSimon Schubert   used_regs_mask |= 1 << EDX_REG_NUM;
11015796c8dcSSimon Schubert   /* Avoid RSP.  */
11025796c8dcSSimon Schubert   used_regs_mask |= 1 << ESP_REG_NUM;
11035796c8dcSSimon Schubert 
11045796c8dcSSimon Schubert   /* If the opcode is one byte long and there's no ModRM byte,
11055796c8dcSSimon Schubert      assume the opcode specifies a register.  */
11065796c8dcSSimon Schubert   if (details->opcode_len == 1 && details->modrm_offset == -1)
11075796c8dcSSimon Schubert     used_regs_mask |= 1 << (details->raw_insn[details->opcode_offset] & 7);
11085796c8dcSSimon Schubert 
11095796c8dcSSimon Schubert   /* Mark used regs in the modrm/sib bytes.  */
11105796c8dcSSimon Schubert   if (details->modrm_offset != -1)
11115796c8dcSSimon Schubert     {
11125796c8dcSSimon Schubert       int modrm = details->raw_insn[details->modrm_offset];
11135796c8dcSSimon Schubert       int mod = MODRM_MOD_FIELD (modrm);
11145796c8dcSSimon Schubert       int reg = MODRM_REG_FIELD (modrm);
11155796c8dcSSimon Schubert       int rm = MODRM_RM_FIELD (modrm);
11165796c8dcSSimon Schubert       int have_sib = mod != 3 && rm == 4;
11175796c8dcSSimon Schubert 
11185796c8dcSSimon Schubert       /* Assume the reg field of the modrm byte specifies a register.  */
11195796c8dcSSimon Schubert       used_regs_mask |= 1 << reg;
11205796c8dcSSimon Schubert 
11215796c8dcSSimon Schubert       if (have_sib)
11225796c8dcSSimon Schubert 	{
11235796c8dcSSimon Schubert 	  int base = SIB_BASE_FIELD (details->raw_insn[details->modrm_offset + 1]);
1124a45ae5f8SJohn Marino 	  int idx = SIB_INDEX_FIELD (details->raw_insn[details->modrm_offset + 1]);
11255796c8dcSSimon Schubert 	  used_regs_mask |= 1 << base;
1126a45ae5f8SJohn Marino 	  used_regs_mask |= 1 << idx;
11275796c8dcSSimon Schubert 	}
11285796c8dcSSimon Schubert       else
11295796c8dcSSimon Schubert 	{
11305796c8dcSSimon Schubert 	  used_regs_mask |= 1 << rm;
11315796c8dcSSimon Schubert 	}
11325796c8dcSSimon Schubert     }
11335796c8dcSSimon Schubert 
11345796c8dcSSimon Schubert   gdb_assert (used_regs_mask < 256);
11355796c8dcSSimon Schubert   gdb_assert (used_regs_mask != 255);
11365796c8dcSSimon Schubert 
11375796c8dcSSimon Schubert   /* Finally, find a free reg.  */
11385796c8dcSSimon Schubert   {
11395796c8dcSSimon Schubert     int i;
11405796c8dcSSimon Schubert 
11415796c8dcSSimon Schubert     for (i = 0; i < 8; ++i)
11425796c8dcSSimon Schubert       {
11435796c8dcSSimon Schubert 	if (! (used_regs_mask & (1 << i)))
11445796c8dcSSimon Schubert 	  return i;
11455796c8dcSSimon Schubert       }
11465796c8dcSSimon Schubert 
11475796c8dcSSimon Schubert     /* We shouldn't get here.  */
11485796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__, _("unable to find free reg"));
11495796c8dcSSimon Schubert   }
11505796c8dcSSimon Schubert }
11515796c8dcSSimon Schubert 
11525796c8dcSSimon Schubert /* Extract the details of INSN that we need.  */
11535796c8dcSSimon Schubert 
11545796c8dcSSimon Schubert static void
amd64_get_insn_details(gdb_byte * insn,struct amd64_insn * details)11555796c8dcSSimon Schubert amd64_get_insn_details (gdb_byte *insn, struct amd64_insn *details)
11565796c8dcSSimon Schubert {
11575796c8dcSSimon Schubert   gdb_byte *start = insn;
11585796c8dcSSimon Schubert   int need_modrm;
11595796c8dcSSimon Schubert 
11605796c8dcSSimon Schubert   details->raw_insn = insn;
11615796c8dcSSimon Schubert 
11625796c8dcSSimon Schubert   details->opcode_len = -1;
11635796c8dcSSimon Schubert   details->rex_offset = -1;
11645796c8dcSSimon Schubert   details->opcode_offset = -1;
11655796c8dcSSimon Schubert   details->modrm_offset = -1;
11665796c8dcSSimon Schubert 
11675796c8dcSSimon Schubert   /* Skip legacy instruction prefixes.  */
11685796c8dcSSimon Schubert   insn = amd64_skip_prefixes (insn);
11695796c8dcSSimon Schubert 
11705796c8dcSSimon Schubert   /* Skip REX instruction prefix.  */
11715796c8dcSSimon Schubert   if (rex_prefix_p (*insn))
11725796c8dcSSimon Schubert     {
11735796c8dcSSimon Schubert       details->rex_offset = insn - start;
11745796c8dcSSimon Schubert       ++insn;
11755796c8dcSSimon Schubert     }
11765796c8dcSSimon Schubert 
11775796c8dcSSimon Schubert   details->opcode_offset = insn - start;
11785796c8dcSSimon Schubert 
11795796c8dcSSimon Schubert   if (*insn == TWO_BYTE_OPCODE_ESCAPE)
11805796c8dcSSimon Schubert     {
11815796c8dcSSimon Schubert       /* Two or three-byte opcode.  */
11825796c8dcSSimon Schubert       ++insn;
11835796c8dcSSimon Schubert       need_modrm = twobyte_has_modrm[*insn];
11845796c8dcSSimon Schubert 
11855796c8dcSSimon Schubert       /* Check for three-byte opcode.  */
11865796c8dcSSimon Schubert       switch (*insn)
11875796c8dcSSimon Schubert 	{
11885796c8dcSSimon Schubert 	case 0x24:
11895796c8dcSSimon Schubert 	case 0x25:
11905796c8dcSSimon Schubert 	case 0x38:
11915796c8dcSSimon Schubert 	case 0x3a:
11925796c8dcSSimon Schubert 	case 0x7a:
11935796c8dcSSimon Schubert 	case 0x7b:
11945796c8dcSSimon Schubert 	  ++insn;
11955796c8dcSSimon Schubert 	  details->opcode_len = 3;
11965796c8dcSSimon Schubert 	  break;
11975796c8dcSSimon Schubert 	default:
11985796c8dcSSimon Schubert 	  details->opcode_len = 2;
11995796c8dcSSimon Schubert 	  break;
12005796c8dcSSimon Schubert 	}
12015796c8dcSSimon Schubert     }
12025796c8dcSSimon Schubert   else
12035796c8dcSSimon Schubert     {
12045796c8dcSSimon Schubert       /* One-byte opcode.  */
12055796c8dcSSimon Schubert       need_modrm = onebyte_has_modrm[*insn];
12065796c8dcSSimon Schubert       details->opcode_len = 1;
12075796c8dcSSimon Schubert     }
12085796c8dcSSimon Schubert 
12095796c8dcSSimon Schubert   if (need_modrm)
12105796c8dcSSimon Schubert     {
12115796c8dcSSimon Schubert       ++insn;
12125796c8dcSSimon Schubert       details->modrm_offset = insn - start;
12135796c8dcSSimon Schubert     }
12145796c8dcSSimon Schubert }
12155796c8dcSSimon Schubert 
12165796c8dcSSimon Schubert /* Update %rip-relative addressing in INSN.
12175796c8dcSSimon Schubert 
12185796c8dcSSimon Schubert    %rip-relative addressing only uses a 32-bit displacement.
12195796c8dcSSimon Schubert    32 bits is not enough to be guaranteed to cover the distance between where
12205796c8dcSSimon Schubert    the real instruction is and where its copy is.
12215796c8dcSSimon Schubert    Convert the insn to use base+disp addressing.
12225796c8dcSSimon Schubert    We set base = pc + insn_length so we can leave disp unchanged.  */
12235796c8dcSSimon Schubert 
12245796c8dcSSimon Schubert static void
fixup_riprel(struct gdbarch * gdbarch,struct displaced_step_closure * dsc,CORE_ADDR from,CORE_ADDR to,struct regcache * regs)12255796c8dcSSimon Schubert fixup_riprel (struct gdbarch *gdbarch, struct displaced_step_closure *dsc,
12265796c8dcSSimon Schubert 	      CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
12275796c8dcSSimon Schubert {
12285796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
12295796c8dcSSimon Schubert   const struct amd64_insn *insn_details = &dsc->insn_details;
12305796c8dcSSimon Schubert   int modrm_offset = insn_details->modrm_offset;
12315796c8dcSSimon Schubert   gdb_byte *insn = insn_details->raw_insn + modrm_offset;
12325796c8dcSSimon Schubert   CORE_ADDR rip_base;
12335796c8dcSSimon Schubert   int32_t disp;
12345796c8dcSSimon Schubert   int insn_length;
12355796c8dcSSimon Schubert   int arch_tmp_regno, tmp_regno;
12365796c8dcSSimon Schubert   ULONGEST orig_value;
12375796c8dcSSimon Schubert 
12385796c8dcSSimon Schubert   /* %rip+disp32 addressing mode, displacement follows ModRM byte.  */
12395796c8dcSSimon Schubert   ++insn;
12405796c8dcSSimon Schubert 
12415796c8dcSSimon Schubert   /* Compute the rip-relative address.	*/
12425796c8dcSSimon Schubert   disp = extract_signed_integer (insn, sizeof (int32_t), byte_order);
1243cf7f2e2dSJohn Marino   insn_length = gdb_buffered_insn_length (gdbarch, dsc->insn_buf,
1244cf7f2e2dSJohn Marino 					  dsc->max_len, from);
12455796c8dcSSimon Schubert   rip_base = from + insn_length;
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert   /* We need a register to hold the address.
12485796c8dcSSimon Schubert      Pick one not used in the insn.
12495796c8dcSSimon Schubert      NOTE: arch_tmp_regno uses architecture ordering, e.g. RDI = 7.  */
12505796c8dcSSimon Schubert   arch_tmp_regno = amd64_get_unused_input_int_reg (insn_details);
12515796c8dcSSimon Schubert   tmp_regno = amd64_arch_reg_to_regnum (arch_tmp_regno);
12525796c8dcSSimon Schubert 
12535796c8dcSSimon Schubert   /* REX.B should be unset as we were using rip-relative addressing,
12545796c8dcSSimon Schubert      but ensure it's unset anyway, tmp_regno is not r8-r15.  */
12555796c8dcSSimon Schubert   if (insn_details->rex_offset != -1)
12565796c8dcSSimon Schubert     dsc->insn_buf[insn_details->rex_offset] &= ~REX_B;
12575796c8dcSSimon Schubert 
12585796c8dcSSimon Schubert   regcache_cooked_read_unsigned (regs, tmp_regno, &orig_value);
12595796c8dcSSimon Schubert   dsc->tmp_regno = tmp_regno;
12605796c8dcSSimon Schubert   dsc->tmp_save = orig_value;
12615796c8dcSSimon Schubert   dsc->tmp_used = 1;
12625796c8dcSSimon Schubert 
12635796c8dcSSimon Schubert   /* Convert the ModRM field to be base+disp.  */
12645796c8dcSSimon Schubert   dsc->insn_buf[modrm_offset] &= ~0xc7;
12655796c8dcSSimon Schubert   dsc->insn_buf[modrm_offset] |= 0x80 + arch_tmp_regno;
12665796c8dcSSimon Schubert 
12675796c8dcSSimon Schubert   regcache_cooked_write_unsigned (regs, tmp_regno, rip_base);
12685796c8dcSSimon Schubert 
12695796c8dcSSimon Schubert   if (debug_displaced)
12705796c8dcSSimon Schubert     fprintf_unfiltered (gdb_stdlog, "displaced: %%rip-relative addressing used.\n"
12715796c8dcSSimon Schubert 			"displaced: using temp reg %d, old value %s, new value %s\n",
12725796c8dcSSimon Schubert 			dsc->tmp_regno, paddress (gdbarch, dsc->tmp_save),
12735796c8dcSSimon Schubert 			paddress (gdbarch, rip_base));
12745796c8dcSSimon Schubert }
12755796c8dcSSimon Schubert 
12765796c8dcSSimon Schubert static void
fixup_displaced_copy(struct gdbarch * gdbarch,struct displaced_step_closure * dsc,CORE_ADDR from,CORE_ADDR to,struct regcache * regs)12775796c8dcSSimon Schubert fixup_displaced_copy (struct gdbarch *gdbarch,
12785796c8dcSSimon Schubert 		      struct displaced_step_closure *dsc,
12795796c8dcSSimon Schubert 		      CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
12805796c8dcSSimon Schubert {
12815796c8dcSSimon Schubert   const struct amd64_insn *details = &dsc->insn_details;
12825796c8dcSSimon Schubert 
12835796c8dcSSimon Schubert   if (details->modrm_offset != -1)
12845796c8dcSSimon Schubert     {
12855796c8dcSSimon Schubert       gdb_byte modrm = details->raw_insn[details->modrm_offset];
12865796c8dcSSimon Schubert 
12875796c8dcSSimon Schubert       if ((modrm & 0xc7) == 0x05)
12885796c8dcSSimon Schubert 	{
12895796c8dcSSimon Schubert 	  /* The insn uses rip-relative addressing.
12905796c8dcSSimon Schubert 	     Deal with it.  */
12915796c8dcSSimon Schubert 	  fixup_riprel (gdbarch, dsc, from, to, regs);
12925796c8dcSSimon Schubert 	}
12935796c8dcSSimon Schubert     }
12945796c8dcSSimon Schubert }
12955796c8dcSSimon Schubert 
12965796c8dcSSimon Schubert struct displaced_step_closure *
amd64_displaced_step_copy_insn(struct gdbarch * gdbarch,CORE_ADDR from,CORE_ADDR to,struct regcache * regs)12975796c8dcSSimon Schubert amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
12985796c8dcSSimon Schubert 				CORE_ADDR from, CORE_ADDR to,
12995796c8dcSSimon Schubert 				struct regcache *regs)
13005796c8dcSSimon Schubert {
13015796c8dcSSimon Schubert   int len = gdbarch_max_insn_length (gdbarch);
1302*ef5ccd6cSJohn Marino   /* Extra space for sentinels so fixup_{riprel,displaced_copy} don't have to
13035796c8dcSSimon Schubert      continually watch for running off the end of the buffer.  */
13045796c8dcSSimon Schubert   int fixup_sentinel_space = len;
13055796c8dcSSimon Schubert   struct displaced_step_closure *dsc =
13065796c8dcSSimon Schubert     xmalloc (sizeof (*dsc) + len + fixup_sentinel_space);
13075796c8dcSSimon Schubert   gdb_byte *buf = &dsc->insn_buf[0];
13085796c8dcSSimon Schubert   struct amd64_insn *details = &dsc->insn_details;
13095796c8dcSSimon Schubert 
13105796c8dcSSimon Schubert   dsc->tmp_used = 0;
13115796c8dcSSimon Schubert   dsc->max_len = len + fixup_sentinel_space;
13125796c8dcSSimon Schubert 
13135796c8dcSSimon Schubert   read_memory (from, buf, len);
13145796c8dcSSimon Schubert 
13155796c8dcSSimon Schubert   /* Set up the sentinel space so we don't have to worry about running
13165796c8dcSSimon Schubert      off the end of the buffer.  An excessive number of leading prefixes
13175796c8dcSSimon Schubert      could otherwise cause this.  */
13185796c8dcSSimon Schubert   memset (buf + len, 0, fixup_sentinel_space);
13195796c8dcSSimon Schubert 
13205796c8dcSSimon Schubert   amd64_get_insn_details (buf, details);
13215796c8dcSSimon Schubert 
13225796c8dcSSimon Schubert   /* GDB may get control back after the insn after the syscall.
13235796c8dcSSimon Schubert      Presumably this is a kernel bug.
13245796c8dcSSimon Schubert      If this is a syscall, make sure there's a nop afterwards.  */
13255796c8dcSSimon Schubert   {
13265796c8dcSSimon Schubert     int syscall_length;
13275796c8dcSSimon Schubert 
13285796c8dcSSimon Schubert     if (amd64_syscall_p (details, &syscall_length))
13295796c8dcSSimon Schubert       buf[details->opcode_offset + syscall_length] = NOP_OPCODE;
13305796c8dcSSimon Schubert   }
13315796c8dcSSimon Schubert 
13325796c8dcSSimon Schubert   /* Modify the insn to cope with the address where it will be executed from.
13335796c8dcSSimon Schubert      In particular, handle any rip-relative addressing.	 */
13345796c8dcSSimon Schubert   fixup_displaced_copy (gdbarch, dsc, from, to, regs);
13355796c8dcSSimon Schubert 
13365796c8dcSSimon Schubert   write_memory (to, buf, len);
13375796c8dcSSimon Schubert 
13385796c8dcSSimon Schubert   if (debug_displaced)
13395796c8dcSSimon Schubert     {
13405796c8dcSSimon Schubert       fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
13415796c8dcSSimon Schubert 			  paddress (gdbarch, from), paddress (gdbarch, to));
13425796c8dcSSimon Schubert       displaced_step_dump_bytes (gdb_stdlog, buf, len);
13435796c8dcSSimon Schubert     }
13445796c8dcSSimon Schubert 
13455796c8dcSSimon Schubert   return dsc;
13465796c8dcSSimon Schubert }
13475796c8dcSSimon Schubert 
13485796c8dcSSimon Schubert static int
amd64_absolute_jmp_p(const struct amd64_insn * details)13495796c8dcSSimon Schubert amd64_absolute_jmp_p (const struct amd64_insn *details)
13505796c8dcSSimon Schubert {
13515796c8dcSSimon Schubert   const gdb_byte *insn = &details->raw_insn[details->opcode_offset];
13525796c8dcSSimon Schubert 
13535796c8dcSSimon Schubert   if (insn[0] == 0xff)
13545796c8dcSSimon Schubert     {
13555796c8dcSSimon Schubert       /* jump near, absolute indirect (/4) */
13565796c8dcSSimon Schubert       if ((insn[1] & 0x38) == 0x20)
13575796c8dcSSimon Schubert 	return 1;
13585796c8dcSSimon Schubert 
13595796c8dcSSimon Schubert       /* jump far, absolute indirect (/5) */
13605796c8dcSSimon Schubert       if ((insn[1] & 0x38) == 0x28)
13615796c8dcSSimon Schubert 	return 1;
13625796c8dcSSimon Schubert     }
13635796c8dcSSimon Schubert 
13645796c8dcSSimon Schubert   return 0;
13655796c8dcSSimon Schubert }
13665796c8dcSSimon Schubert 
13675796c8dcSSimon Schubert static int
amd64_absolute_call_p(const struct amd64_insn * details)13685796c8dcSSimon Schubert amd64_absolute_call_p (const struct amd64_insn *details)
13695796c8dcSSimon Schubert {
13705796c8dcSSimon Schubert   const gdb_byte *insn = &details->raw_insn[details->opcode_offset];
13715796c8dcSSimon Schubert 
13725796c8dcSSimon Schubert   if (insn[0] == 0xff)
13735796c8dcSSimon Schubert     {
13745796c8dcSSimon Schubert       /* Call near, absolute indirect (/2) */
13755796c8dcSSimon Schubert       if ((insn[1] & 0x38) == 0x10)
13765796c8dcSSimon Schubert 	return 1;
13775796c8dcSSimon Schubert 
13785796c8dcSSimon Schubert       /* Call far, absolute indirect (/3) */
13795796c8dcSSimon Schubert       if ((insn[1] & 0x38) == 0x18)
13805796c8dcSSimon Schubert 	return 1;
13815796c8dcSSimon Schubert     }
13825796c8dcSSimon Schubert 
13835796c8dcSSimon Schubert   return 0;
13845796c8dcSSimon Schubert }
13855796c8dcSSimon Schubert 
13865796c8dcSSimon Schubert static int
amd64_ret_p(const struct amd64_insn * details)13875796c8dcSSimon Schubert amd64_ret_p (const struct amd64_insn *details)
13885796c8dcSSimon Schubert {
13895796c8dcSSimon Schubert   /* NOTE: gcc can emit "repz ; ret".  */
13905796c8dcSSimon Schubert   const gdb_byte *insn = &details->raw_insn[details->opcode_offset];
13915796c8dcSSimon Schubert 
13925796c8dcSSimon Schubert   switch (insn[0])
13935796c8dcSSimon Schubert     {
13945796c8dcSSimon Schubert     case 0xc2: /* ret near, pop N bytes */
13955796c8dcSSimon Schubert     case 0xc3: /* ret near */
13965796c8dcSSimon Schubert     case 0xca: /* ret far, pop N bytes */
13975796c8dcSSimon Schubert     case 0xcb: /* ret far */
13985796c8dcSSimon Schubert     case 0xcf: /* iret */
13995796c8dcSSimon Schubert       return 1;
14005796c8dcSSimon Schubert 
14015796c8dcSSimon Schubert     default:
14025796c8dcSSimon Schubert       return 0;
14035796c8dcSSimon Schubert     }
14045796c8dcSSimon Schubert }
14055796c8dcSSimon Schubert 
14065796c8dcSSimon Schubert static int
amd64_call_p(const struct amd64_insn * details)14075796c8dcSSimon Schubert amd64_call_p (const struct amd64_insn *details)
14085796c8dcSSimon Schubert {
14095796c8dcSSimon Schubert   const gdb_byte *insn = &details->raw_insn[details->opcode_offset];
14105796c8dcSSimon Schubert 
14115796c8dcSSimon Schubert   if (amd64_absolute_call_p (details))
14125796c8dcSSimon Schubert     return 1;
14135796c8dcSSimon Schubert 
14145796c8dcSSimon Schubert   /* call near, relative */
14155796c8dcSSimon Schubert   if (insn[0] == 0xe8)
14165796c8dcSSimon Schubert     return 1;
14175796c8dcSSimon Schubert 
14185796c8dcSSimon Schubert   return 0;
14195796c8dcSSimon Schubert }
14205796c8dcSSimon Schubert 
14215796c8dcSSimon Schubert /* Return non-zero if INSN is a system call, and set *LENGTHP to its
14225796c8dcSSimon Schubert    length in bytes.  Otherwise, return zero.  */
14235796c8dcSSimon Schubert 
14245796c8dcSSimon Schubert static int
amd64_syscall_p(const struct amd64_insn * details,int * lengthp)14255796c8dcSSimon Schubert amd64_syscall_p (const struct amd64_insn *details, int *lengthp)
14265796c8dcSSimon Schubert {
14275796c8dcSSimon Schubert   const gdb_byte *insn = &details->raw_insn[details->opcode_offset];
14285796c8dcSSimon Schubert 
14295796c8dcSSimon Schubert   if (insn[0] == 0x0f && insn[1] == 0x05)
14305796c8dcSSimon Schubert     {
14315796c8dcSSimon Schubert       *lengthp = 2;
14325796c8dcSSimon Schubert       return 1;
14335796c8dcSSimon Schubert     }
14345796c8dcSSimon Schubert 
14355796c8dcSSimon Schubert   return 0;
14365796c8dcSSimon Schubert }
14375796c8dcSSimon Schubert 
14385796c8dcSSimon Schubert /* Fix up the state of registers and memory after having single-stepped
14395796c8dcSSimon Schubert    a displaced instruction.  */
14405796c8dcSSimon Schubert 
14415796c8dcSSimon Schubert void
amd64_displaced_step_fixup(struct gdbarch * gdbarch,struct displaced_step_closure * dsc,CORE_ADDR from,CORE_ADDR to,struct regcache * regs)14425796c8dcSSimon Schubert amd64_displaced_step_fixup (struct gdbarch *gdbarch,
14435796c8dcSSimon Schubert 			    struct displaced_step_closure *dsc,
14445796c8dcSSimon Schubert 			    CORE_ADDR from, CORE_ADDR to,
14455796c8dcSSimon Schubert 			    struct regcache *regs)
14465796c8dcSSimon Schubert {
14475796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
14485796c8dcSSimon Schubert   /* The offset we applied to the instruction's address.  */
14495796c8dcSSimon Schubert   ULONGEST insn_offset = to - from;
14505796c8dcSSimon Schubert   gdb_byte *insn = dsc->insn_buf;
14515796c8dcSSimon Schubert   const struct amd64_insn *insn_details = &dsc->insn_details;
14525796c8dcSSimon Schubert 
14535796c8dcSSimon Schubert   if (debug_displaced)
14545796c8dcSSimon Schubert     fprintf_unfiltered (gdb_stdlog,
14555796c8dcSSimon Schubert 			"displaced: fixup (%s, %s), "
14565796c8dcSSimon Schubert 			"insn = 0x%02x 0x%02x ...\n",
14575796c8dcSSimon Schubert 			paddress (gdbarch, from), paddress (gdbarch, to),
14585796c8dcSSimon Schubert 			insn[0], insn[1]);
14595796c8dcSSimon Schubert 
14605796c8dcSSimon Schubert   /* If we used a tmp reg, restore it.	*/
14615796c8dcSSimon Schubert 
14625796c8dcSSimon Schubert   if (dsc->tmp_used)
14635796c8dcSSimon Schubert     {
14645796c8dcSSimon Schubert       if (debug_displaced)
14655796c8dcSSimon Schubert 	fprintf_unfiltered (gdb_stdlog, "displaced: restoring reg %d to %s\n",
14665796c8dcSSimon Schubert 			    dsc->tmp_regno, paddress (gdbarch, dsc->tmp_save));
14675796c8dcSSimon Schubert       regcache_cooked_write_unsigned (regs, dsc->tmp_regno, dsc->tmp_save);
14685796c8dcSSimon Schubert     }
14695796c8dcSSimon Schubert 
14705796c8dcSSimon Schubert   /* The list of issues to contend with here is taken from
14715796c8dcSSimon Schubert      resume_execution in arch/x86/kernel/kprobes.c, Linux 2.6.28.
14725796c8dcSSimon Schubert      Yay for Free Software!  */
14735796c8dcSSimon Schubert 
14745796c8dcSSimon Schubert   /* Relocate the %rip back to the program's instruction stream,
14755796c8dcSSimon Schubert      if necessary.  */
14765796c8dcSSimon Schubert 
14775796c8dcSSimon Schubert   /* Except in the case of absolute or indirect jump or call
14785796c8dcSSimon Schubert      instructions, or a return instruction, the new rip is relative to
14795796c8dcSSimon Schubert      the displaced instruction; make it relative to the original insn.
14805796c8dcSSimon Schubert      Well, signal handler returns don't need relocation either, but we use the
14815796c8dcSSimon Schubert      value of %rip to recognize those; see below.  */
14825796c8dcSSimon Schubert   if (! amd64_absolute_jmp_p (insn_details)
14835796c8dcSSimon Schubert       && ! amd64_absolute_call_p (insn_details)
14845796c8dcSSimon Schubert       && ! amd64_ret_p (insn_details))
14855796c8dcSSimon Schubert     {
14865796c8dcSSimon Schubert       ULONGEST orig_rip;
14875796c8dcSSimon Schubert       int insn_len;
14885796c8dcSSimon Schubert 
14895796c8dcSSimon Schubert       regcache_cooked_read_unsigned (regs, AMD64_RIP_REGNUM, &orig_rip);
14905796c8dcSSimon Schubert 
14915796c8dcSSimon Schubert       /* A signal trampoline system call changes the %rip, resuming
14925796c8dcSSimon Schubert 	 execution of the main program after the signal handler has
14935796c8dcSSimon Schubert 	 returned.  That makes them like 'return' instructions; we
14945796c8dcSSimon Schubert 	 shouldn't relocate %rip.
14955796c8dcSSimon Schubert 
14965796c8dcSSimon Schubert 	 But most system calls don't, and we do need to relocate %rip.
14975796c8dcSSimon Schubert 
14985796c8dcSSimon Schubert 	 Our heuristic for distinguishing these cases: if stepping
14995796c8dcSSimon Schubert 	 over the system call instruction left control directly after
15005796c8dcSSimon Schubert 	 the instruction, the we relocate --- control almost certainly
15015796c8dcSSimon Schubert 	 doesn't belong in the displaced copy.	Otherwise, we assume
15025796c8dcSSimon Schubert 	 the instruction has put control where it belongs, and leave
15035796c8dcSSimon Schubert 	 it unrelocated.  Goodness help us if there are PC-relative
15045796c8dcSSimon Schubert 	 system calls.	*/
15055796c8dcSSimon Schubert       if (amd64_syscall_p (insn_details, &insn_len)
15065796c8dcSSimon Schubert 	  && orig_rip != to + insn_len
15075796c8dcSSimon Schubert 	  /* GDB can get control back after the insn after the syscall.
15085796c8dcSSimon Schubert 	     Presumably this is a kernel bug.
15095796c8dcSSimon Schubert 	     Fixup ensures its a nop, we add one to the length for it.  */
15105796c8dcSSimon Schubert 	  && orig_rip != to + insn_len + 1)
15115796c8dcSSimon Schubert 	{
15125796c8dcSSimon Schubert 	  if (debug_displaced)
15135796c8dcSSimon Schubert 	    fprintf_unfiltered (gdb_stdlog,
15145796c8dcSSimon Schubert 				"displaced: syscall changed %%rip; "
15155796c8dcSSimon Schubert 				"not relocating\n");
15165796c8dcSSimon Schubert 	}
15175796c8dcSSimon Schubert       else
15185796c8dcSSimon Schubert 	{
15195796c8dcSSimon Schubert 	  ULONGEST rip = orig_rip - insn_offset;
15205796c8dcSSimon Schubert 
15215796c8dcSSimon Schubert 	  /* If we just stepped over a breakpoint insn, we don't backup
15225796c8dcSSimon Schubert 	     the pc on purpose; this is to match behaviour without
15235796c8dcSSimon Schubert 	     stepping.  */
15245796c8dcSSimon Schubert 
15255796c8dcSSimon Schubert 	  regcache_cooked_write_unsigned (regs, AMD64_RIP_REGNUM, rip);
15265796c8dcSSimon Schubert 
15275796c8dcSSimon Schubert 	  if (debug_displaced)
15285796c8dcSSimon Schubert 	    fprintf_unfiltered (gdb_stdlog,
15295796c8dcSSimon Schubert 				"displaced: "
15305796c8dcSSimon Schubert 				"relocated %%rip from %s to %s\n",
15315796c8dcSSimon Schubert 				paddress (gdbarch, orig_rip),
15325796c8dcSSimon Schubert 				paddress (gdbarch, rip));
15335796c8dcSSimon Schubert 	}
15345796c8dcSSimon Schubert     }
15355796c8dcSSimon Schubert 
15365796c8dcSSimon Schubert   /* If the instruction was PUSHFL, then the TF bit will be set in the
15375796c8dcSSimon Schubert      pushed value, and should be cleared.  We'll leave this for later,
15385796c8dcSSimon Schubert      since GDB already messes up the TF flag when stepping over a
15395796c8dcSSimon Schubert      pushfl.  */
15405796c8dcSSimon Schubert 
15415796c8dcSSimon Schubert   /* If the instruction was a call, the return address now atop the
15425796c8dcSSimon Schubert      stack is the address following the copied instruction.  We need
15435796c8dcSSimon Schubert      to make it the address following the original instruction.	 */
15445796c8dcSSimon Schubert   if (amd64_call_p (insn_details))
15455796c8dcSSimon Schubert     {
15465796c8dcSSimon Schubert       ULONGEST rsp;
15475796c8dcSSimon Schubert       ULONGEST retaddr;
15485796c8dcSSimon Schubert       const ULONGEST retaddr_len = 8;
15495796c8dcSSimon Schubert 
15505796c8dcSSimon Schubert       regcache_cooked_read_unsigned (regs, AMD64_RSP_REGNUM, &rsp);
15515796c8dcSSimon Schubert       retaddr = read_memory_unsigned_integer (rsp, retaddr_len, byte_order);
15525796c8dcSSimon Schubert       retaddr = (retaddr - insn_offset) & 0xffffffffUL;
15535796c8dcSSimon Schubert       write_memory_unsigned_integer (rsp, retaddr_len, byte_order, retaddr);
15545796c8dcSSimon Schubert 
15555796c8dcSSimon Schubert       if (debug_displaced)
15565796c8dcSSimon Schubert 	fprintf_unfiltered (gdb_stdlog,
15575796c8dcSSimon Schubert 			    "displaced: relocated return addr at %s "
15585796c8dcSSimon Schubert 			    "to %s\n",
15595796c8dcSSimon Schubert 			    paddress (gdbarch, rsp),
15605796c8dcSSimon Schubert 			    paddress (gdbarch, retaddr));
15615796c8dcSSimon Schubert     }
15625796c8dcSSimon Schubert }
1563cf7f2e2dSJohn Marino 
1564cf7f2e2dSJohn Marino /* If the instruction INSN uses RIP-relative addressing, return the
1565cf7f2e2dSJohn Marino    offset into the raw INSN where the displacement to be adjusted is
1566cf7f2e2dSJohn Marino    found.  Returns 0 if the instruction doesn't use RIP-relative
1567cf7f2e2dSJohn Marino    addressing.  */
1568cf7f2e2dSJohn Marino 
1569cf7f2e2dSJohn Marino static int
rip_relative_offset(struct amd64_insn * insn)1570cf7f2e2dSJohn Marino rip_relative_offset (struct amd64_insn *insn)
1571cf7f2e2dSJohn Marino {
1572cf7f2e2dSJohn Marino   if (insn->modrm_offset != -1)
1573cf7f2e2dSJohn Marino     {
1574cf7f2e2dSJohn Marino       gdb_byte modrm = insn->raw_insn[insn->modrm_offset];
1575cf7f2e2dSJohn Marino 
1576cf7f2e2dSJohn Marino       if ((modrm & 0xc7) == 0x05)
1577cf7f2e2dSJohn Marino 	{
1578cf7f2e2dSJohn Marino 	  /* The displacement is found right after the ModRM byte.  */
1579cf7f2e2dSJohn Marino 	  return insn->modrm_offset + 1;
1580cf7f2e2dSJohn Marino 	}
1581cf7f2e2dSJohn Marino     }
1582cf7f2e2dSJohn Marino 
1583cf7f2e2dSJohn Marino   return 0;
1584cf7f2e2dSJohn Marino }
1585cf7f2e2dSJohn Marino 
1586cf7f2e2dSJohn Marino static void
append_insns(CORE_ADDR * to,ULONGEST len,const gdb_byte * buf)1587cf7f2e2dSJohn Marino append_insns (CORE_ADDR *to, ULONGEST len, const gdb_byte *buf)
1588cf7f2e2dSJohn Marino {
1589cf7f2e2dSJohn Marino   target_write_memory (*to, buf, len);
1590cf7f2e2dSJohn Marino   *to += len;
1591cf7f2e2dSJohn Marino }
1592cf7f2e2dSJohn Marino 
1593a45ae5f8SJohn Marino static void
amd64_relocate_instruction(struct gdbarch * gdbarch,CORE_ADDR * to,CORE_ADDR oldloc)1594cf7f2e2dSJohn Marino amd64_relocate_instruction (struct gdbarch *gdbarch,
1595cf7f2e2dSJohn Marino 			    CORE_ADDR *to, CORE_ADDR oldloc)
1596cf7f2e2dSJohn Marino {
1597cf7f2e2dSJohn Marino   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1598cf7f2e2dSJohn Marino   int len = gdbarch_max_insn_length (gdbarch);
1599cf7f2e2dSJohn Marino   /* Extra space for sentinels.  */
1600cf7f2e2dSJohn Marino   int fixup_sentinel_space = len;
1601cf7f2e2dSJohn Marino   gdb_byte *buf = xmalloc (len + fixup_sentinel_space);
1602cf7f2e2dSJohn Marino   struct amd64_insn insn_details;
1603cf7f2e2dSJohn Marino   int offset = 0;
1604cf7f2e2dSJohn Marino   LONGEST rel32, newrel;
1605cf7f2e2dSJohn Marino   gdb_byte *insn;
1606cf7f2e2dSJohn Marino   int insn_length;
1607cf7f2e2dSJohn Marino 
1608cf7f2e2dSJohn Marino   read_memory (oldloc, buf, len);
1609cf7f2e2dSJohn Marino 
1610cf7f2e2dSJohn Marino   /* Set up the sentinel space so we don't have to worry about running
1611cf7f2e2dSJohn Marino      off the end of the buffer.  An excessive number of leading prefixes
1612cf7f2e2dSJohn Marino      could otherwise cause this.  */
1613cf7f2e2dSJohn Marino   memset (buf + len, 0, fixup_sentinel_space);
1614cf7f2e2dSJohn Marino 
1615cf7f2e2dSJohn Marino   insn = buf;
1616cf7f2e2dSJohn Marino   amd64_get_insn_details (insn, &insn_details);
1617cf7f2e2dSJohn Marino 
1618cf7f2e2dSJohn Marino   insn_length = gdb_buffered_insn_length (gdbarch, insn, len, oldloc);
1619cf7f2e2dSJohn Marino 
1620cf7f2e2dSJohn Marino   /* Skip legacy instruction prefixes.  */
1621cf7f2e2dSJohn Marino   insn = amd64_skip_prefixes (insn);
1622cf7f2e2dSJohn Marino 
1623cf7f2e2dSJohn Marino   /* Adjust calls with 32-bit relative addresses as push/jump, with
1624cf7f2e2dSJohn Marino      the address pushed being the location where the original call in
1625cf7f2e2dSJohn Marino      the user program would return to.  */
1626cf7f2e2dSJohn Marino   if (insn[0] == 0xe8)
1627cf7f2e2dSJohn Marino     {
1628cf7f2e2dSJohn Marino       gdb_byte push_buf[16];
1629cf7f2e2dSJohn Marino       unsigned int ret_addr;
1630cf7f2e2dSJohn Marino 
1631cf7f2e2dSJohn Marino       /* Where "ret" in the original code will return to.  */
1632cf7f2e2dSJohn Marino       ret_addr = oldloc + insn_length;
1633cf7f2e2dSJohn Marino       push_buf[0] = 0x68; /* pushq $...  */
1634*ef5ccd6cSJohn Marino       store_unsigned_integer (&push_buf[1], 4, byte_order, ret_addr);
1635cf7f2e2dSJohn Marino       /* Push the push.  */
1636cf7f2e2dSJohn Marino       append_insns (to, 5, push_buf);
1637cf7f2e2dSJohn Marino 
1638cf7f2e2dSJohn Marino       /* Convert the relative call to a relative jump.  */
1639cf7f2e2dSJohn Marino       insn[0] = 0xe9;
1640cf7f2e2dSJohn Marino 
1641cf7f2e2dSJohn Marino       /* Adjust the destination offset.  */
1642cf7f2e2dSJohn Marino       rel32 = extract_signed_integer (insn + 1, 4, byte_order);
1643cf7f2e2dSJohn Marino       newrel = (oldloc - *to) + rel32;
1644c50c785cSJohn Marino       store_signed_integer (insn + 1, 4, byte_order, newrel);
1645c50c785cSJohn Marino 
1646c50c785cSJohn Marino       if (debug_displaced)
1647c50c785cSJohn Marino 	fprintf_unfiltered (gdb_stdlog,
1648c50c785cSJohn Marino 			    "Adjusted insn rel32=%s at %s to"
1649c50c785cSJohn Marino 			    " rel32=%s at %s\n",
1650c50c785cSJohn Marino 			    hex_string (rel32), paddress (gdbarch, oldloc),
1651c50c785cSJohn Marino 			    hex_string (newrel), paddress (gdbarch, *to));
1652cf7f2e2dSJohn Marino 
1653cf7f2e2dSJohn Marino       /* Write the adjusted jump into its displaced location.  */
1654cf7f2e2dSJohn Marino       append_insns (to, 5, insn);
1655cf7f2e2dSJohn Marino       return;
1656cf7f2e2dSJohn Marino     }
1657cf7f2e2dSJohn Marino 
1658cf7f2e2dSJohn Marino   offset = rip_relative_offset (&insn_details);
1659cf7f2e2dSJohn Marino   if (!offset)
1660cf7f2e2dSJohn Marino     {
1661cf7f2e2dSJohn Marino       /* Adjust jumps with 32-bit relative addresses.  Calls are
1662cf7f2e2dSJohn Marino 	 already handled above.  */
1663cf7f2e2dSJohn Marino       if (insn[0] == 0xe9)
1664cf7f2e2dSJohn Marino 	offset = 1;
1665cf7f2e2dSJohn Marino       /* Adjust conditional jumps.  */
1666cf7f2e2dSJohn Marino       else if (insn[0] == 0x0f && (insn[1] & 0xf0) == 0x80)
1667cf7f2e2dSJohn Marino 	offset = 2;
1668cf7f2e2dSJohn Marino     }
1669cf7f2e2dSJohn Marino 
1670cf7f2e2dSJohn Marino   if (offset)
1671cf7f2e2dSJohn Marino     {
1672cf7f2e2dSJohn Marino       rel32 = extract_signed_integer (insn + offset, 4, byte_order);
1673cf7f2e2dSJohn Marino       newrel = (oldloc - *to) + rel32;
1674c50c785cSJohn Marino       store_signed_integer (insn + offset, 4, byte_order, newrel);
1675cf7f2e2dSJohn Marino       if (debug_displaced)
1676cf7f2e2dSJohn Marino 	fprintf_unfiltered (gdb_stdlog,
1677c50c785cSJohn Marino 			    "Adjusted insn rel32=%s at %s to"
1678c50c785cSJohn Marino 			    " rel32=%s at %s\n",
1679cf7f2e2dSJohn Marino 			    hex_string (rel32), paddress (gdbarch, oldloc),
1680cf7f2e2dSJohn Marino 			    hex_string (newrel), paddress (gdbarch, *to));
1681cf7f2e2dSJohn Marino     }
1682cf7f2e2dSJohn Marino 
1683cf7f2e2dSJohn Marino   /* Write the adjusted instruction into its displaced location.  */
1684cf7f2e2dSJohn Marino   append_insns (to, insn_length, buf);
1685cf7f2e2dSJohn Marino }
1686cf7f2e2dSJohn Marino 
16875796c8dcSSimon Schubert 
16885796c8dcSSimon Schubert /* The maximum number of saved registers.  This should include %rip.  */
16895796c8dcSSimon Schubert #define AMD64_NUM_SAVED_REGS	AMD64_NUM_GREGS
16905796c8dcSSimon Schubert 
16915796c8dcSSimon Schubert struct amd64_frame_cache
16925796c8dcSSimon Schubert {
16935796c8dcSSimon Schubert   /* Base address.  */
16945796c8dcSSimon Schubert   CORE_ADDR base;
1695c50c785cSJohn Marino   int base_p;
16965796c8dcSSimon Schubert   CORE_ADDR sp_offset;
16975796c8dcSSimon Schubert   CORE_ADDR pc;
16985796c8dcSSimon Schubert 
16995796c8dcSSimon Schubert   /* Saved registers.  */
17005796c8dcSSimon Schubert   CORE_ADDR saved_regs[AMD64_NUM_SAVED_REGS];
17015796c8dcSSimon Schubert   CORE_ADDR saved_sp;
17025796c8dcSSimon Schubert   int saved_sp_reg;
17035796c8dcSSimon Schubert 
17045796c8dcSSimon Schubert   /* Do we have a frame?  */
17055796c8dcSSimon Schubert   int frameless_p;
17065796c8dcSSimon Schubert };
17075796c8dcSSimon Schubert 
17085796c8dcSSimon Schubert /* Initialize a frame cache.  */
17095796c8dcSSimon Schubert 
17105796c8dcSSimon Schubert static void
amd64_init_frame_cache(struct amd64_frame_cache * cache)17115796c8dcSSimon Schubert amd64_init_frame_cache (struct amd64_frame_cache *cache)
17125796c8dcSSimon Schubert {
17135796c8dcSSimon Schubert   int i;
17145796c8dcSSimon Schubert 
17155796c8dcSSimon Schubert   /* Base address.  */
17165796c8dcSSimon Schubert   cache->base = 0;
1717c50c785cSJohn Marino   cache->base_p = 0;
17185796c8dcSSimon Schubert   cache->sp_offset = -8;
17195796c8dcSSimon Schubert   cache->pc = 0;
17205796c8dcSSimon Schubert 
17215796c8dcSSimon Schubert   /* Saved registers.  We initialize these to -1 since zero is a valid
1722cf7f2e2dSJohn Marino      offset (that's where %rbp is supposed to be stored).
1723cf7f2e2dSJohn Marino      The values start out as being offsets, and are later converted to
1724cf7f2e2dSJohn Marino      addresses (at which point -1 is interpreted as an address, still meaning
1725cf7f2e2dSJohn Marino      "invalid").  */
17265796c8dcSSimon Schubert   for (i = 0; i < AMD64_NUM_SAVED_REGS; i++)
17275796c8dcSSimon Schubert     cache->saved_regs[i] = -1;
17285796c8dcSSimon Schubert   cache->saved_sp = 0;
17295796c8dcSSimon Schubert   cache->saved_sp_reg = -1;
17305796c8dcSSimon Schubert 
17315796c8dcSSimon Schubert   /* Frameless until proven otherwise.  */
17325796c8dcSSimon Schubert   cache->frameless_p = 1;
17335796c8dcSSimon Schubert }
17345796c8dcSSimon Schubert 
17355796c8dcSSimon Schubert /* Allocate and initialize a frame cache.  */
17365796c8dcSSimon Schubert 
17375796c8dcSSimon Schubert static struct amd64_frame_cache *
amd64_alloc_frame_cache(void)17385796c8dcSSimon Schubert amd64_alloc_frame_cache (void)
17395796c8dcSSimon Schubert {
17405796c8dcSSimon Schubert   struct amd64_frame_cache *cache;
17415796c8dcSSimon Schubert 
17425796c8dcSSimon Schubert   cache = FRAME_OBSTACK_ZALLOC (struct amd64_frame_cache);
17435796c8dcSSimon Schubert   amd64_init_frame_cache (cache);
17445796c8dcSSimon Schubert   return cache;
17455796c8dcSSimon Schubert }
17465796c8dcSSimon Schubert 
17475796c8dcSSimon Schubert /* GCC 4.4 and later, can put code in the prologue to realign the
17485796c8dcSSimon Schubert    stack pointer.  Check whether PC points to such code, and update
17495796c8dcSSimon Schubert    CACHE accordingly.  Return the first instruction after the code
17505796c8dcSSimon Schubert    sequence or CURRENT_PC, whichever is smaller.  If we don't
17515796c8dcSSimon Schubert    recognize the code, return PC.  */
17525796c8dcSSimon Schubert 
17535796c8dcSSimon Schubert static CORE_ADDR
amd64_analyze_stack_align(CORE_ADDR pc,CORE_ADDR current_pc,struct amd64_frame_cache * cache)17545796c8dcSSimon Schubert amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
17555796c8dcSSimon Schubert 			   struct amd64_frame_cache *cache)
17565796c8dcSSimon Schubert {
17575796c8dcSSimon Schubert   /* There are 2 code sequences to re-align stack before the frame
17585796c8dcSSimon Schubert      gets set up:
17595796c8dcSSimon Schubert 
17605796c8dcSSimon Schubert 	1. Use a caller-saved saved register:
17615796c8dcSSimon Schubert 
17625796c8dcSSimon Schubert 		leaq  8(%rsp), %reg
17635796c8dcSSimon Schubert 		andq  $-XXX, %rsp
17645796c8dcSSimon Schubert 		pushq -8(%reg)
17655796c8dcSSimon Schubert 
17665796c8dcSSimon Schubert 	2. Use a callee-saved saved register:
17675796c8dcSSimon Schubert 
17685796c8dcSSimon Schubert 		pushq %reg
17695796c8dcSSimon Schubert 		leaq  16(%rsp), %reg
17705796c8dcSSimon Schubert 		andq  $-XXX, %rsp
17715796c8dcSSimon Schubert 		pushq -8(%reg)
17725796c8dcSSimon Schubert 
17735796c8dcSSimon Schubert      "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes:
17745796c8dcSSimon Schubert 
17755796c8dcSSimon Schubert      	0x48 0x83 0xe4 0xf0			andq $-16, %rsp
17765796c8dcSSimon Schubert      	0x48 0x81 0xe4 0x00 0xff 0xff 0xff	andq $-256, %rsp
17775796c8dcSSimon Schubert    */
17785796c8dcSSimon Schubert 
17795796c8dcSSimon Schubert   gdb_byte buf[18];
17805796c8dcSSimon Schubert   int reg, r;
17815796c8dcSSimon Schubert   int offset, offset_and;
17825796c8dcSSimon Schubert 
17835796c8dcSSimon Schubert   if (target_read_memory (pc, buf, sizeof buf))
17845796c8dcSSimon Schubert     return pc;
17855796c8dcSSimon Schubert 
17865796c8dcSSimon Schubert   /* Check caller-saved saved register.  The first instruction has
17875796c8dcSSimon Schubert      to be "leaq 8(%rsp), %reg".  */
17885796c8dcSSimon Schubert   if ((buf[0] & 0xfb) == 0x48
17895796c8dcSSimon Schubert       && buf[1] == 0x8d
17905796c8dcSSimon Schubert       && buf[3] == 0x24
17915796c8dcSSimon Schubert       && buf[4] == 0x8)
17925796c8dcSSimon Schubert     {
17935796c8dcSSimon Schubert       /* MOD must be binary 10 and R/M must be binary 100.  */
17945796c8dcSSimon Schubert       if ((buf[2] & 0xc7) != 0x44)
17955796c8dcSSimon Schubert 	return pc;
17965796c8dcSSimon Schubert 
17975796c8dcSSimon Schubert       /* REG has register number.  */
17985796c8dcSSimon Schubert       reg = (buf[2] >> 3) & 7;
17995796c8dcSSimon Schubert 
18005796c8dcSSimon Schubert       /* Check the REX.R bit.  */
18015796c8dcSSimon Schubert       if (buf[0] == 0x4c)
18025796c8dcSSimon Schubert 	reg += 8;
18035796c8dcSSimon Schubert 
18045796c8dcSSimon Schubert       offset = 5;
18055796c8dcSSimon Schubert     }
18065796c8dcSSimon Schubert   else
18075796c8dcSSimon Schubert     {
18085796c8dcSSimon Schubert       /* Check callee-saved saved register.  The first instruction
18095796c8dcSSimon Schubert 	 has to be "pushq %reg".  */
18105796c8dcSSimon Schubert       reg = 0;
18115796c8dcSSimon Schubert       if ((buf[0] & 0xf8) == 0x50)
18125796c8dcSSimon Schubert 	offset = 0;
18135796c8dcSSimon Schubert       else if ((buf[0] & 0xf6) == 0x40
18145796c8dcSSimon Schubert 	       && (buf[1] & 0xf8) == 0x50)
18155796c8dcSSimon Schubert 	{
18165796c8dcSSimon Schubert 	  /* Check the REX.B bit.  */
18175796c8dcSSimon Schubert 	  if ((buf[0] & 1) != 0)
18185796c8dcSSimon Schubert 	    reg = 8;
18195796c8dcSSimon Schubert 
18205796c8dcSSimon Schubert 	  offset = 1;
18215796c8dcSSimon Schubert 	}
18225796c8dcSSimon Schubert       else
18235796c8dcSSimon Schubert 	return pc;
18245796c8dcSSimon Schubert 
18255796c8dcSSimon Schubert       /* Get register.  */
18265796c8dcSSimon Schubert       reg += buf[offset] & 0x7;
18275796c8dcSSimon Schubert 
18285796c8dcSSimon Schubert       offset++;
18295796c8dcSSimon Schubert 
18305796c8dcSSimon Schubert       /* The next instruction has to be "leaq 16(%rsp), %reg".  */
18315796c8dcSSimon Schubert       if ((buf[offset] & 0xfb) != 0x48
18325796c8dcSSimon Schubert 	  || buf[offset + 1] != 0x8d
18335796c8dcSSimon Schubert 	  || buf[offset + 3] != 0x24
18345796c8dcSSimon Schubert 	  || buf[offset + 4] != 0x10)
18355796c8dcSSimon Schubert 	return pc;
18365796c8dcSSimon Schubert 
18375796c8dcSSimon Schubert       /* MOD must be binary 10 and R/M must be binary 100.  */
18385796c8dcSSimon Schubert       if ((buf[offset + 2] & 0xc7) != 0x44)
18395796c8dcSSimon Schubert 	return pc;
18405796c8dcSSimon Schubert 
18415796c8dcSSimon Schubert       /* REG has register number.  */
18425796c8dcSSimon Schubert       r = (buf[offset + 2] >> 3) & 7;
18435796c8dcSSimon Schubert 
18445796c8dcSSimon Schubert       /* Check the REX.R bit.  */
18455796c8dcSSimon Schubert       if (buf[offset] == 0x4c)
18465796c8dcSSimon Schubert 	r += 8;
18475796c8dcSSimon Schubert 
18485796c8dcSSimon Schubert       /* Registers in pushq and leaq have to be the same.  */
18495796c8dcSSimon Schubert       if (reg != r)
18505796c8dcSSimon Schubert 	return pc;
18515796c8dcSSimon Schubert 
18525796c8dcSSimon Schubert       offset += 5;
18535796c8dcSSimon Schubert     }
18545796c8dcSSimon Schubert 
18555796c8dcSSimon Schubert   /* Rigister can't be %rsp nor %rbp.  */
18565796c8dcSSimon Schubert   if (reg == 4 || reg == 5)
18575796c8dcSSimon Schubert     return pc;
18585796c8dcSSimon Schubert 
18595796c8dcSSimon Schubert   /* The next instruction has to be "andq $-XXX, %rsp".  */
18605796c8dcSSimon Schubert   if (buf[offset] != 0x48
18615796c8dcSSimon Schubert       || buf[offset + 2] != 0xe4
18625796c8dcSSimon Schubert       || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83))
18635796c8dcSSimon Schubert     return pc;
18645796c8dcSSimon Schubert 
18655796c8dcSSimon Schubert   offset_and = offset;
18665796c8dcSSimon Schubert   offset += buf[offset + 1] == 0x81 ? 7 : 4;
18675796c8dcSSimon Schubert 
18685796c8dcSSimon Schubert   /* The next instruction has to be "pushq -8(%reg)".  */
18695796c8dcSSimon Schubert   r = 0;
18705796c8dcSSimon Schubert   if (buf[offset] == 0xff)
18715796c8dcSSimon Schubert     offset++;
18725796c8dcSSimon Schubert   else if ((buf[offset] & 0xf6) == 0x40
18735796c8dcSSimon Schubert 	   && buf[offset + 1] == 0xff)
18745796c8dcSSimon Schubert     {
18755796c8dcSSimon Schubert       /* Check the REX.B bit.  */
18765796c8dcSSimon Schubert       if ((buf[offset] & 0x1) != 0)
18775796c8dcSSimon Schubert 	r = 8;
18785796c8dcSSimon Schubert       offset += 2;
18795796c8dcSSimon Schubert     }
18805796c8dcSSimon Schubert   else
18815796c8dcSSimon Schubert     return pc;
18825796c8dcSSimon Schubert 
18835796c8dcSSimon Schubert   /* 8bit -8 is 0xf8.  REG must be binary 110 and MOD must be binary
18845796c8dcSSimon Schubert      01.  */
18855796c8dcSSimon Schubert   if (buf[offset + 1] != 0xf8
18865796c8dcSSimon Schubert       || (buf[offset] & 0xf8) != 0x70)
18875796c8dcSSimon Schubert     return pc;
18885796c8dcSSimon Schubert 
18895796c8dcSSimon Schubert   /* R/M has register.  */
18905796c8dcSSimon Schubert   r += buf[offset] & 7;
18915796c8dcSSimon Schubert 
18925796c8dcSSimon Schubert   /* Registers in leaq and pushq have to be the same.  */
18935796c8dcSSimon Schubert   if (reg != r)
18945796c8dcSSimon Schubert     return pc;
18955796c8dcSSimon Schubert 
18965796c8dcSSimon Schubert   if (current_pc > pc + offset_and)
18975796c8dcSSimon Schubert     cache->saved_sp_reg = amd64_arch_reg_to_regnum (reg);
18985796c8dcSSimon Schubert 
18995796c8dcSSimon Schubert   return min (pc + offset + 2, current_pc);
19005796c8dcSSimon Schubert }
19015796c8dcSSimon Schubert 
1902*ef5ccd6cSJohn Marino /* Similar to amd64_analyze_stack_align for x32.  */
1903*ef5ccd6cSJohn Marino 
1904*ef5ccd6cSJohn Marino static CORE_ADDR
amd64_x32_analyze_stack_align(CORE_ADDR pc,CORE_ADDR current_pc,struct amd64_frame_cache * cache)1905*ef5ccd6cSJohn Marino amd64_x32_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
1906*ef5ccd6cSJohn Marino 			       struct amd64_frame_cache *cache)
1907*ef5ccd6cSJohn Marino {
1908*ef5ccd6cSJohn Marino   /* There are 2 code sequences to re-align stack before the frame
1909*ef5ccd6cSJohn Marino      gets set up:
1910*ef5ccd6cSJohn Marino 
1911*ef5ccd6cSJohn Marino 	1. Use a caller-saved saved register:
1912*ef5ccd6cSJohn Marino 
1913*ef5ccd6cSJohn Marino 		leaq  8(%rsp), %reg
1914*ef5ccd6cSJohn Marino 		andq  $-XXX, %rsp
1915*ef5ccd6cSJohn Marino 		pushq -8(%reg)
1916*ef5ccd6cSJohn Marino 
1917*ef5ccd6cSJohn Marino 	   or
1918*ef5ccd6cSJohn Marino 
1919*ef5ccd6cSJohn Marino 		[addr32] leal  8(%rsp), %reg
1920*ef5ccd6cSJohn Marino 		andl  $-XXX, %esp
1921*ef5ccd6cSJohn Marino 		[addr32] pushq -8(%reg)
1922*ef5ccd6cSJohn Marino 
1923*ef5ccd6cSJohn Marino 	2. Use a callee-saved saved register:
1924*ef5ccd6cSJohn Marino 
1925*ef5ccd6cSJohn Marino 		pushq %reg
1926*ef5ccd6cSJohn Marino 		leaq  16(%rsp), %reg
1927*ef5ccd6cSJohn Marino 		andq  $-XXX, %rsp
1928*ef5ccd6cSJohn Marino 		pushq -8(%reg)
1929*ef5ccd6cSJohn Marino 
1930*ef5ccd6cSJohn Marino 	   or
1931*ef5ccd6cSJohn Marino 
1932*ef5ccd6cSJohn Marino 		pushq %reg
1933*ef5ccd6cSJohn Marino 		[addr32] leal  16(%rsp), %reg
1934*ef5ccd6cSJohn Marino 		andl  $-XXX, %esp
1935*ef5ccd6cSJohn Marino 		[addr32] pushq -8(%reg)
1936*ef5ccd6cSJohn Marino 
1937*ef5ccd6cSJohn Marino      "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes:
1938*ef5ccd6cSJohn Marino 
1939*ef5ccd6cSJohn Marino      	0x48 0x83 0xe4 0xf0			andq $-16, %rsp
1940*ef5ccd6cSJohn Marino      	0x48 0x81 0xe4 0x00 0xff 0xff 0xff	andq $-256, %rsp
1941*ef5ccd6cSJohn Marino 
1942*ef5ccd6cSJohn Marino      "andl $-XXX, %esp" can be either 3 bytes or 6 bytes:
1943*ef5ccd6cSJohn Marino 
1944*ef5ccd6cSJohn Marino      	0x83 0xe4 0xf0			andl $-16, %esp
1945*ef5ccd6cSJohn Marino      	0x81 0xe4 0x00 0xff 0xff 0xff	andl $-256, %esp
1946*ef5ccd6cSJohn Marino    */
1947*ef5ccd6cSJohn Marino 
1948*ef5ccd6cSJohn Marino   gdb_byte buf[19];
1949*ef5ccd6cSJohn Marino   int reg, r;
1950*ef5ccd6cSJohn Marino   int offset, offset_and;
1951*ef5ccd6cSJohn Marino 
1952*ef5ccd6cSJohn Marino   if (target_read_memory (pc, buf, sizeof buf))
1953*ef5ccd6cSJohn Marino     return pc;
1954*ef5ccd6cSJohn Marino 
1955*ef5ccd6cSJohn Marino   /* Skip optional addr32 prefix.  */
1956*ef5ccd6cSJohn Marino   offset = buf[0] == 0x67 ? 1 : 0;
1957*ef5ccd6cSJohn Marino 
1958*ef5ccd6cSJohn Marino   /* Check caller-saved saved register.  The first instruction has
1959*ef5ccd6cSJohn Marino      to be "leaq 8(%rsp), %reg" or "leal 8(%rsp), %reg".  */
1960*ef5ccd6cSJohn Marino   if (((buf[offset] & 0xfb) == 0x48 || (buf[offset] & 0xfb) == 0x40)
1961*ef5ccd6cSJohn Marino       && buf[offset + 1] == 0x8d
1962*ef5ccd6cSJohn Marino       && buf[offset + 3] == 0x24
1963*ef5ccd6cSJohn Marino       && buf[offset + 4] == 0x8)
1964*ef5ccd6cSJohn Marino     {
1965*ef5ccd6cSJohn Marino       /* MOD must be binary 10 and R/M must be binary 100.  */
1966*ef5ccd6cSJohn Marino       if ((buf[offset + 2] & 0xc7) != 0x44)
1967*ef5ccd6cSJohn Marino 	return pc;
1968*ef5ccd6cSJohn Marino 
1969*ef5ccd6cSJohn Marino       /* REG has register number.  */
1970*ef5ccd6cSJohn Marino       reg = (buf[offset + 2] >> 3) & 7;
1971*ef5ccd6cSJohn Marino 
1972*ef5ccd6cSJohn Marino       /* Check the REX.R bit.  */
1973*ef5ccd6cSJohn Marino       if ((buf[offset] & 0x4) != 0)
1974*ef5ccd6cSJohn Marino 	reg += 8;
1975*ef5ccd6cSJohn Marino 
1976*ef5ccd6cSJohn Marino       offset += 5;
1977*ef5ccd6cSJohn Marino     }
1978*ef5ccd6cSJohn Marino   else
1979*ef5ccd6cSJohn Marino     {
1980*ef5ccd6cSJohn Marino       /* Check callee-saved saved register.  The first instruction
1981*ef5ccd6cSJohn Marino 	 has to be "pushq %reg".  */
1982*ef5ccd6cSJohn Marino       reg = 0;
1983*ef5ccd6cSJohn Marino       if ((buf[offset] & 0xf6) == 0x40
1984*ef5ccd6cSJohn Marino 	  && (buf[offset + 1] & 0xf8) == 0x50)
1985*ef5ccd6cSJohn Marino 	{
1986*ef5ccd6cSJohn Marino 	  /* Check the REX.B bit.  */
1987*ef5ccd6cSJohn Marino 	  if ((buf[offset] & 1) != 0)
1988*ef5ccd6cSJohn Marino 	    reg = 8;
1989*ef5ccd6cSJohn Marino 
1990*ef5ccd6cSJohn Marino 	  offset += 1;
1991*ef5ccd6cSJohn Marino 	}
1992*ef5ccd6cSJohn Marino       else if ((buf[offset] & 0xf8) != 0x50)
1993*ef5ccd6cSJohn Marino 	return pc;
1994*ef5ccd6cSJohn Marino 
1995*ef5ccd6cSJohn Marino       /* Get register.  */
1996*ef5ccd6cSJohn Marino       reg += buf[offset] & 0x7;
1997*ef5ccd6cSJohn Marino 
1998*ef5ccd6cSJohn Marino       offset++;
1999*ef5ccd6cSJohn Marino 
2000*ef5ccd6cSJohn Marino       /* Skip optional addr32 prefix.  */
2001*ef5ccd6cSJohn Marino       if (buf[offset] == 0x67)
2002*ef5ccd6cSJohn Marino 	offset++;
2003*ef5ccd6cSJohn Marino 
2004*ef5ccd6cSJohn Marino       /* The next instruction has to be "leaq 16(%rsp), %reg" or
2005*ef5ccd6cSJohn Marino 	 "leal 16(%rsp), %reg".  */
2006*ef5ccd6cSJohn Marino       if (((buf[offset] & 0xfb) != 0x48 && (buf[offset] & 0xfb) != 0x40)
2007*ef5ccd6cSJohn Marino 	  || buf[offset + 1] != 0x8d
2008*ef5ccd6cSJohn Marino 	  || buf[offset + 3] != 0x24
2009*ef5ccd6cSJohn Marino 	  || buf[offset + 4] != 0x10)
2010*ef5ccd6cSJohn Marino 	return pc;
2011*ef5ccd6cSJohn Marino 
2012*ef5ccd6cSJohn Marino       /* MOD must be binary 10 and R/M must be binary 100.  */
2013*ef5ccd6cSJohn Marino       if ((buf[offset + 2] & 0xc7) != 0x44)
2014*ef5ccd6cSJohn Marino 	return pc;
2015*ef5ccd6cSJohn Marino 
2016*ef5ccd6cSJohn Marino       /* REG has register number.  */
2017*ef5ccd6cSJohn Marino       r = (buf[offset + 2] >> 3) & 7;
2018*ef5ccd6cSJohn Marino 
2019*ef5ccd6cSJohn Marino       /* Check the REX.R bit.  */
2020*ef5ccd6cSJohn Marino       if ((buf[offset] & 0x4) != 0)
2021*ef5ccd6cSJohn Marino 	r += 8;
2022*ef5ccd6cSJohn Marino 
2023*ef5ccd6cSJohn Marino       /* Registers in pushq and leaq have to be the same.  */
2024*ef5ccd6cSJohn Marino       if (reg != r)
2025*ef5ccd6cSJohn Marino 	return pc;
2026*ef5ccd6cSJohn Marino 
2027*ef5ccd6cSJohn Marino       offset += 5;
2028*ef5ccd6cSJohn Marino     }
2029*ef5ccd6cSJohn Marino 
2030*ef5ccd6cSJohn Marino   /* Rigister can't be %rsp nor %rbp.  */
2031*ef5ccd6cSJohn Marino   if (reg == 4 || reg == 5)
2032*ef5ccd6cSJohn Marino     return pc;
2033*ef5ccd6cSJohn Marino 
2034*ef5ccd6cSJohn Marino   /* The next instruction may be "andq $-XXX, %rsp" or
2035*ef5ccd6cSJohn Marino      "andl $-XXX, %esp".  */
2036*ef5ccd6cSJohn Marino   if (buf[offset] != 0x48)
2037*ef5ccd6cSJohn Marino     offset--;
2038*ef5ccd6cSJohn Marino 
2039*ef5ccd6cSJohn Marino   if (buf[offset + 2] != 0xe4
2040*ef5ccd6cSJohn Marino       || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83))
2041*ef5ccd6cSJohn Marino     return pc;
2042*ef5ccd6cSJohn Marino 
2043*ef5ccd6cSJohn Marino   offset_and = offset;
2044*ef5ccd6cSJohn Marino   offset += buf[offset + 1] == 0x81 ? 7 : 4;
2045*ef5ccd6cSJohn Marino 
2046*ef5ccd6cSJohn Marino   /* Skip optional addr32 prefix.  */
2047*ef5ccd6cSJohn Marino   if (buf[offset] == 0x67)
2048*ef5ccd6cSJohn Marino     offset++;
2049*ef5ccd6cSJohn Marino 
2050*ef5ccd6cSJohn Marino   /* The next instruction has to be "pushq -8(%reg)".  */
2051*ef5ccd6cSJohn Marino   r = 0;
2052*ef5ccd6cSJohn Marino   if (buf[offset] == 0xff)
2053*ef5ccd6cSJohn Marino     offset++;
2054*ef5ccd6cSJohn Marino   else if ((buf[offset] & 0xf6) == 0x40
2055*ef5ccd6cSJohn Marino 	   && buf[offset + 1] == 0xff)
2056*ef5ccd6cSJohn Marino     {
2057*ef5ccd6cSJohn Marino       /* Check the REX.B bit.  */
2058*ef5ccd6cSJohn Marino       if ((buf[offset] & 0x1) != 0)
2059*ef5ccd6cSJohn Marino 	r = 8;
2060*ef5ccd6cSJohn Marino       offset += 2;
2061*ef5ccd6cSJohn Marino     }
2062*ef5ccd6cSJohn Marino   else
2063*ef5ccd6cSJohn Marino     return pc;
2064*ef5ccd6cSJohn Marino 
2065*ef5ccd6cSJohn Marino   /* 8bit -8 is 0xf8.  REG must be binary 110 and MOD must be binary
2066*ef5ccd6cSJohn Marino      01.  */
2067*ef5ccd6cSJohn Marino   if (buf[offset + 1] != 0xf8
2068*ef5ccd6cSJohn Marino       || (buf[offset] & 0xf8) != 0x70)
2069*ef5ccd6cSJohn Marino     return pc;
2070*ef5ccd6cSJohn Marino 
2071*ef5ccd6cSJohn Marino   /* R/M has register.  */
2072*ef5ccd6cSJohn Marino   r += buf[offset] & 7;
2073*ef5ccd6cSJohn Marino 
2074*ef5ccd6cSJohn Marino   /* Registers in leaq and pushq have to be the same.  */
2075*ef5ccd6cSJohn Marino   if (reg != r)
2076*ef5ccd6cSJohn Marino     return pc;
2077*ef5ccd6cSJohn Marino 
2078*ef5ccd6cSJohn Marino   if (current_pc > pc + offset_and)
2079*ef5ccd6cSJohn Marino     cache->saved_sp_reg = amd64_arch_reg_to_regnum (reg);
2080*ef5ccd6cSJohn Marino 
2081*ef5ccd6cSJohn Marino   return min (pc + offset + 2, current_pc);
2082*ef5ccd6cSJohn Marino }
2083*ef5ccd6cSJohn Marino 
20845796c8dcSSimon Schubert /* Do a limited analysis of the prologue at PC and update CACHE
20855796c8dcSSimon Schubert    accordingly.  Bail out early if CURRENT_PC is reached.  Return the
20865796c8dcSSimon Schubert    address where the analysis stopped.
20875796c8dcSSimon Schubert 
20885796c8dcSSimon Schubert    We will handle only functions beginning with:
20895796c8dcSSimon Schubert 
20905796c8dcSSimon Schubert       pushq %rbp        0x55
2091*ef5ccd6cSJohn Marino       movq %rsp, %rbp   0x48 0x89 0xe5 (or 0x48 0x8b 0xec)
20925796c8dcSSimon Schubert 
2093*ef5ccd6cSJohn Marino    or (for the X32 ABI):
2094*ef5ccd6cSJohn Marino 
2095*ef5ccd6cSJohn Marino       pushq %rbp        0x55
2096*ef5ccd6cSJohn Marino       movl %esp, %ebp   0x89 0xe5 (or 0x8b 0xec)
2097*ef5ccd6cSJohn Marino 
2098*ef5ccd6cSJohn Marino    Any function that doesn't start with one of these sequences will be
2099*ef5ccd6cSJohn Marino    assumed to have no prologue and thus no valid frame pointer in
2100*ef5ccd6cSJohn Marino    %rbp.  */
21015796c8dcSSimon Schubert 
21025796c8dcSSimon Schubert static CORE_ADDR
amd64_analyze_prologue(struct gdbarch * gdbarch,CORE_ADDR pc,CORE_ADDR current_pc,struct amd64_frame_cache * cache)21035796c8dcSSimon Schubert amd64_analyze_prologue (struct gdbarch *gdbarch,
21045796c8dcSSimon Schubert 			CORE_ADDR pc, CORE_ADDR current_pc,
21055796c8dcSSimon Schubert 			struct amd64_frame_cache *cache)
21065796c8dcSSimon Schubert {
21075796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2108*ef5ccd6cSJohn Marino   /* There are two variations of movq %rsp, %rbp.  */
2109*ef5ccd6cSJohn Marino   static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
2110*ef5ccd6cSJohn Marino   static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
2111*ef5ccd6cSJohn Marino   /* Ditto for movl %esp, %ebp.  */
2112*ef5ccd6cSJohn Marino   static const gdb_byte mov_esp_ebp_1[2] = { 0x89, 0xe5 };
2113*ef5ccd6cSJohn Marino   static const gdb_byte mov_esp_ebp_2[2] = { 0x8b, 0xec };
2114*ef5ccd6cSJohn Marino 
21155796c8dcSSimon Schubert   gdb_byte buf[3];
21165796c8dcSSimon Schubert   gdb_byte op;
21175796c8dcSSimon Schubert 
21185796c8dcSSimon Schubert   if (current_pc <= pc)
21195796c8dcSSimon Schubert     return current_pc;
21205796c8dcSSimon Schubert 
2121*ef5ccd6cSJohn Marino   if (gdbarch_ptr_bit (gdbarch) == 32)
2122*ef5ccd6cSJohn Marino     pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
2123*ef5ccd6cSJohn Marino   else
21245796c8dcSSimon Schubert     pc = amd64_analyze_stack_align (pc, current_pc, cache);
21255796c8dcSSimon Schubert 
21265796c8dcSSimon Schubert   op = read_memory_unsigned_integer (pc, 1, byte_order);
21275796c8dcSSimon Schubert 
21285796c8dcSSimon Schubert   if (op == 0x55)		/* pushq %rbp */
21295796c8dcSSimon Schubert     {
21305796c8dcSSimon Schubert       /* Take into account that we've executed the `pushq %rbp' that
21315796c8dcSSimon Schubert          starts this instruction sequence.  */
21325796c8dcSSimon Schubert       cache->saved_regs[AMD64_RBP_REGNUM] = 0;
21335796c8dcSSimon Schubert       cache->sp_offset += 8;
21345796c8dcSSimon Schubert 
21355796c8dcSSimon Schubert       /* If that's all, return now.  */
21365796c8dcSSimon Schubert       if (current_pc <= pc + 1)
21375796c8dcSSimon Schubert         return current_pc;
21385796c8dcSSimon Schubert 
21395796c8dcSSimon Schubert       read_memory (pc + 1, buf, 3);
21405796c8dcSSimon Schubert 
2141*ef5ccd6cSJohn Marino       /* Check for `movq %rsp, %rbp'.  */
2142*ef5ccd6cSJohn Marino       if (memcmp (buf, mov_rsp_rbp_1, 3) == 0
2143*ef5ccd6cSJohn Marino 	  || memcmp (buf, mov_rsp_rbp_2, 3) == 0)
2144*ef5ccd6cSJohn Marino 	{
21455796c8dcSSimon Schubert 	  /* OK, we actually have a frame.  */
21465796c8dcSSimon Schubert 	  cache->frameless_p = 0;
21475796c8dcSSimon Schubert 	  return pc + 4;
21485796c8dcSSimon Schubert 	}
21495796c8dcSSimon Schubert 
2150*ef5ccd6cSJohn Marino       /* For X32, also check for `movq %esp, %ebp'.  */
2151*ef5ccd6cSJohn Marino       if (gdbarch_ptr_bit (gdbarch) == 32)
2152*ef5ccd6cSJohn Marino 	{
2153*ef5ccd6cSJohn Marino 	  if (memcmp (buf, mov_esp_ebp_1, 2) == 0
2154*ef5ccd6cSJohn Marino 	      || memcmp (buf, mov_esp_ebp_2, 2) == 0)
2155*ef5ccd6cSJohn Marino 	    {
2156*ef5ccd6cSJohn Marino 	      /* OK, we actually have a frame.  */
2157*ef5ccd6cSJohn Marino 	      cache->frameless_p = 0;
2158*ef5ccd6cSJohn Marino 	      return pc + 3;
2159*ef5ccd6cSJohn Marino 	    }
2160*ef5ccd6cSJohn Marino 	}
2161*ef5ccd6cSJohn Marino 
2162*ef5ccd6cSJohn Marino       return pc + 1;
2163*ef5ccd6cSJohn Marino     }
2164*ef5ccd6cSJohn Marino 
21655796c8dcSSimon Schubert   return pc;
21665796c8dcSSimon Schubert }
21675796c8dcSSimon Schubert 
2168a45ae5f8SJohn Marino /* Work around false termination of prologue - GCC PR debug/48827.
2169a45ae5f8SJohn Marino 
2170a45ae5f8SJohn Marino    START_PC is the first instruction of a function, PC is its minimal already
2171a45ae5f8SJohn Marino    determined advanced address.  Function returns PC if it has nothing to do.
2172a45ae5f8SJohn Marino 
2173a45ae5f8SJohn Marino    84 c0                test   %al,%al
2174a45ae5f8SJohn Marino    74 23                je     after
2175a45ae5f8SJohn Marino    <-- here is 0 lines advance - the false prologue end marker.
2176a45ae5f8SJohn Marino    0f 29 85 70 ff ff ff movaps %xmm0,-0x90(%rbp)
2177a45ae5f8SJohn Marino    0f 29 4d 80          movaps %xmm1,-0x80(%rbp)
2178a45ae5f8SJohn Marino    0f 29 55 90          movaps %xmm2,-0x70(%rbp)
2179a45ae5f8SJohn Marino    0f 29 5d a0          movaps %xmm3,-0x60(%rbp)
2180a45ae5f8SJohn Marino    0f 29 65 b0          movaps %xmm4,-0x50(%rbp)
2181a45ae5f8SJohn Marino    0f 29 6d c0          movaps %xmm5,-0x40(%rbp)
2182a45ae5f8SJohn Marino    0f 29 75 d0          movaps %xmm6,-0x30(%rbp)
2183a45ae5f8SJohn Marino    0f 29 7d e0          movaps %xmm7,-0x20(%rbp)
2184a45ae5f8SJohn Marino    after:  */
2185a45ae5f8SJohn Marino 
2186a45ae5f8SJohn Marino static CORE_ADDR
amd64_skip_xmm_prologue(CORE_ADDR pc,CORE_ADDR start_pc)2187a45ae5f8SJohn Marino amd64_skip_xmm_prologue (CORE_ADDR pc, CORE_ADDR start_pc)
2188a45ae5f8SJohn Marino {
2189a45ae5f8SJohn Marino   struct symtab_and_line start_pc_sal, next_sal;
2190a45ae5f8SJohn Marino   gdb_byte buf[4 + 8 * 7];
2191a45ae5f8SJohn Marino   int offset, xmmreg;
2192a45ae5f8SJohn Marino 
2193a45ae5f8SJohn Marino   if (pc == start_pc)
2194a45ae5f8SJohn Marino     return pc;
2195a45ae5f8SJohn Marino 
2196a45ae5f8SJohn Marino   start_pc_sal = find_pc_sect_line (start_pc, NULL, 0);
2197a45ae5f8SJohn Marino   if (start_pc_sal.symtab == NULL
2198a45ae5f8SJohn Marino       || producer_is_gcc_ge_4 (start_pc_sal.symtab->producer) < 6
2199a45ae5f8SJohn Marino       || start_pc_sal.pc != start_pc || pc >= start_pc_sal.end)
2200a45ae5f8SJohn Marino     return pc;
2201a45ae5f8SJohn Marino 
2202a45ae5f8SJohn Marino   next_sal = find_pc_sect_line (start_pc_sal.end, NULL, 0);
2203a45ae5f8SJohn Marino   if (next_sal.line != start_pc_sal.line)
2204a45ae5f8SJohn Marino     return pc;
2205a45ae5f8SJohn Marino 
2206a45ae5f8SJohn Marino   /* START_PC can be from overlayed memory, ignored here.  */
2207a45ae5f8SJohn Marino   if (target_read_memory (next_sal.pc - 4, buf, sizeof (buf)) != 0)
2208a45ae5f8SJohn Marino     return pc;
2209a45ae5f8SJohn Marino 
2210a45ae5f8SJohn Marino   /* test %al,%al */
2211a45ae5f8SJohn Marino   if (buf[0] != 0x84 || buf[1] != 0xc0)
2212a45ae5f8SJohn Marino     return pc;
2213a45ae5f8SJohn Marino   /* je AFTER */
2214a45ae5f8SJohn Marino   if (buf[2] != 0x74)
2215a45ae5f8SJohn Marino     return pc;
2216a45ae5f8SJohn Marino 
2217a45ae5f8SJohn Marino   offset = 4;
2218a45ae5f8SJohn Marino   for (xmmreg = 0; xmmreg < 8; xmmreg++)
2219a45ae5f8SJohn Marino     {
2220a45ae5f8SJohn Marino       /* 0x0f 0x29 0b??000101 movaps %xmmreg?,-0x??(%rbp) */
2221a45ae5f8SJohn Marino       if (buf[offset] != 0x0f || buf[offset + 1] != 0x29
2222a45ae5f8SJohn Marino           || (buf[offset + 2] & 0x3f) != (xmmreg << 3 | 0x5))
2223a45ae5f8SJohn Marino 	return pc;
2224a45ae5f8SJohn Marino 
2225a45ae5f8SJohn Marino       /* 0b01?????? */
2226a45ae5f8SJohn Marino       if ((buf[offset + 2] & 0xc0) == 0x40)
2227a45ae5f8SJohn Marino 	{
2228a45ae5f8SJohn Marino 	  /* 8-bit displacement.  */
2229a45ae5f8SJohn Marino 	  offset += 4;
2230a45ae5f8SJohn Marino 	}
2231a45ae5f8SJohn Marino       /* 0b10?????? */
2232a45ae5f8SJohn Marino       else if ((buf[offset + 2] & 0xc0) == 0x80)
2233a45ae5f8SJohn Marino 	{
2234a45ae5f8SJohn Marino 	  /* 32-bit displacement.  */
2235a45ae5f8SJohn Marino 	  offset += 7;
2236a45ae5f8SJohn Marino 	}
2237a45ae5f8SJohn Marino       else
2238a45ae5f8SJohn Marino 	return pc;
2239a45ae5f8SJohn Marino     }
2240a45ae5f8SJohn Marino 
2241a45ae5f8SJohn Marino   /* je AFTER */
2242a45ae5f8SJohn Marino   if (offset - 4 != buf[3])
2243a45ae5f8SJohn Marino     return pc;
2244a45ae5f8SJohn Marino 
2245a45ae5f8SJohn Marino   return next_sal.end;
2246a45ae5f8SJohn Marino }
2247a45ae5f8SJohn Marino 
22485796c8dcSSimon Schubert /* Return PC of first real instruction.  */
22495796c8dcSSimon Schubert 
22505796c8dcSSimon Schubert static CORE_ADDR
amd64_skip_prologue(struct gdbarch * gdbarch,CORE_ADDR start_pc)22515796c8dcSSimon Schubert amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
22525796c8dcSSimon Schubert {
22535796c8dcSSimon Schubert   struct amd64_frame_cache cache;
22545796c8dcSSimon Schubert   CORE_ADDR pc;
2255*ef5ccd6cSJohn Marino   CORE_ADDR func_addr;
2256*ef5ccd6cSJohn Marino 
2257*ef5ccd6cSJohn Marino   if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL))
2258*ef5ccd6cSJohn Marino     {
2259*ef5ccd6cSJohn Marino       CORE_ADDR post_prologue_pc
2260*ef5ccd6cSJohn Marino 	= skip_prologue_using_sal (gdbarch, func_addr);
2261*ef5ccd6cSJohn Marino       struct symtab *s = find_pc_symtab (func_addr);
2262*ef5ccd6cSJohn Marino 
2263*ef5ccd6cSJohn Marino       /* Clang always emits a line note before the prologue and another
2264*ef5ccd6cSJohn Marino 	 one after.  We trust clang to emit usable line notes.  */
2265*ef5ccd6cSJohn Marino       if (post_prologue_pc
2266*ef5ccd6cSJohn Marino 	  && (s != NULL
2267*ef5ccd6cSJohn Marino 	      && s->producer != NULL
2268*ef5ccd6cSJohn Marino 	      && strncmp (s->producer, "clang ", sizeof ("clang ") - 1) == 0))
2269*ef5ccd6cSJohn Marino         return max (start_pc, post_prologue_pc);
2270*ef5ccd6cSJohn Marino     }
22715796c8dcSSimon Schubert 
22725796c8dcSSimon Schubert   amd64_init_frame_cache (&cache);
22735796c8dcSSimon Schubert   pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL,
22745796c8dcSSimon Schubert 			       &cache);
22755796c8dcSSimon Schubert   if (cache.frameless_p)
22765796c8dcSSimon Schubert     return start_pc;
22775796c8dcSSimon Schubert 
2278a45ae5f8SJohn Marino   return amd64_skip_xmm_prologue (pc, start_pc);
22795796c8dcSSimon Schubert }
22805796c8dcSSimon Schubert 
22815796c8dcSSimon Schubert 
22825796c8dcSSimon Schubert /* Normal frames.  */
22835796c8dcSSimon Schubert 
2284c50c785cSJohn Marino static void
amd64_frame_cache_1(struct frame_info * this_frame,struct amd64_frame_cache * cache)2285c50c785cSJohn Marino amd64_frame_cache_1 (struct frame_info *this_frame,
2286c50c785cSJohn Marino 		     struct amd64_frame_cache *cache)
22875796c8dcSSimon Schubert {
22885796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (this_frame);
22895796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
22905796c8dcSSimon Schubert   gdb_byte buf[8];
22915796c8dcSSimon Schubert   int i;
22925796c8dcSSimon Schubert 
22935796c8dcSSimon Schubert   cache->pc = get_frame_func (this_frame);
22945796c8dcSSimon Schubert   if (cache->pc != 0)
22955796c8dcSSimon Schubert     amd64_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame),
22965796c8dcSSimon Schubert 			    cache);
22975796c8dcSSimon Schubert 
22985796c8dcSSimon Schubert   if (cache->frameless_p)
22995796c8dcSSimon Schubert     {
23005796c8dcSSimon Schubert       /* We didn't find a valid frame.  If we're at the start of a
23015796c8dcSSimon Schubert 	 function, or somewhere half-way its prologue, the function's
23025796c8dcSSimon Schubert 	 frame probably hasn't been fully setup yet.  Try to
23035796c8dcSSimon Schubert 	 reconstruct the base address for the stack frame by looking
23045796c8dcSSimon Schubert 	 at the stack pointer.  For truly "frameless" functions this
23055796c8dcSSimon Schubert 	 might work too.  */
23065796c8dcSSimon Schubert 
23075796c8dcSSimon Schubert       if (cache->saved_sp_reg != -1)
23085796c8dcSSimon Schubert 	{
2309c50c785cSJohn Marino 	  /* Stack pointer has been saved.  */
2310c50c785cSJohn Marino 	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
2311c50c785cSJohn Marino 	  cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);
2312c50c785cSJohn Marino 
23135796c8dcSSimon Schubert 	  /* We're halfway aligning the stack.  */
23145796c8dcSSimon Schubert 	  cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8;
23155796c8dcSSimon Schubert 	  cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8;
23165796c8dcSSimon Schubert 
23175796c8dcSSimon Schubert 	  /* This will be added back below.  */
23185796c8dcSSimon Schubert 	  cache->saved_regs[AMD64_RIP_REGNUM] -= cache->base;
23195796c8dcSSimon Schubert 	}
23205796c8dcSSimon Schubert       else
23215796c8dcSSimon Schubert 	{
23225796c8dcSSimon Schubert 	  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
23235796c8dcSSimon Schubert 	  cache->base = extract_unsigned_integer (buf, 8, byte_order)
23245796c8dcSSimon Schubert 			+ cache->sp_offset;
23255796c8dcSSimon Schubert 	}
23265796c8dcSSimon Schubert     }
23275796c8dcSSimon Schubert   else
23285796c8dcSSimon Schubert     {
23295796c8dcSSimon Schubert       get_frame_register (this_frame, AMD64_RBP_REGNUM, buf);
23305796c8dcSSimon Schubert       cache->base = extract_unsigned_integer (buf, 8, byte_order);
23315796c8dcSSimon Schubert     }
23325796c8dcSSimon Schubert 
23335796c8dcSSimon Schubert   /* Now that we have the base address for the stack frame we can
23345796c8dcSSimon Schubert      calculate the value of %rsp in the calling frame.  */
23355796c8dcSSimon Schubert   cache->saved_sp = cache->base + 16;
23365796c8dcSSimon Schubert 
23375796c8dcSSimon Schubert   /* For normal frames, %rip is stored at 8(%rbp).  If we don't have a
23385796c8dcSSimon Schubert      frame we find it at the same offset from the reconstructed base
23395796c8dcSSimon Schubert      address.  If we're halfway aligning the stack, %rip is handled
23405796c8dcSSimon Schubert      differently (see above).  */
23415796c8dcSSimon Schubert   if (!cache->frameless_p || cache->saved_sp_reg == -1)
23425796c8dcSSimon Schubert     cache->saved_regs[AMD64_RIP_REGNUM] = 8;
23435796c8dcSSimon Schubert 
23445796c8dcSSimon Schubert   /* Adjust all the saved registers such that they contain addresses
23455796c8dcSSimon Schubert      instead of offsets.  */
23465796c8dcSSimon Schubert   for (i = 0; i < AMD64_NUM_SAVED_REGS; i++)
23475796c8dcSSimon Schubert     if (cache->saved_regs[i] != -1)
23485796c8dcSSimon Schubert       cache->saved_regs[i] += cache->base;
23495796c8dcSSimon Schubert 
2350c50c785cSJohn Marino   cache->base_p = 1;
2351c50c785cSJohn Marino }
2352c50c785cSJohn Marino 
2353c50c785cSJohn Marino static struct amd64_frame_cache *
amd64_frame_cache(struct frame_info * this_frame,void ** this_cache)2354c50c785cSJohn Marino amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
2355c50c785cSJohn Marino {
2356c50c785cSJohn Marino   volatile struct gdb_exception ex;
2357c50c785cSJohn Marino   struct amd64_frame_cache *cache;
2358c50c785cSJohn Marino 
2359c50c785cSJohn Marino   if (*this_cache)
2360c50c785cSJohn Marino     return *this_cache;
2361c50c785cSJohn Marino 
2362c50c785cSJohn Marino   cache = amd64_alloc_frame_cache ();
2363c50c785cSJohn Marino   *this_cache = cache;
2364c50c785cSJohn Marino 
2365c50c785cSJohn Marino   TRY_CATCH (ex, RETURN_MASK_ERROR)
2366c50c785cSJohn Marino     {
2367c50c785cSJohn Marino       amd64_frame_cache_1 (this_frame, cache);
2368c50c785cSJohn Marino     }
2369c50c785cSJohn Marino   if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
2370c50c785cSJohn Marino     throw_exception (ex);
2371c50c785cSJohn Marino 
23725796c8dcSSimon Schubert   return cache;
23735796c8dcSSimon Schubert }
23745796c8dcSSimon Schubert 
2375c50c785cSJohn Marino static enum unwind_stop_reason
amd64_frame_unwind_stop_reason(struct frame_info * this_frame,void ** this_cache)2376c50c785cSJohn Marino amd64_frame_unwind_stop_reason (struct frame_info *this_frame,
2377c50c785cSJohn Marino 				void **this_cache)
2378c50c785cSJohn Marino {
2379c50c785cSJohn Marino   struct amd64_frame_cache *cache =
2380c50c785cSJohn Marino     amd64_frame_cache (this_frame, this_cache);
2381c50c785cSJohn Marino 
2382c50c785cSJohn Marino   if (!cache->base_p)
2383c50c785cSJohn Marino     return UNWIND_UNAVAILABLE;
2384c50c785cSJohn Marino 
2385c50c785cSJohn Marino   /* This marks the outermost frame.  */
2386c50c785cSJohn Marino   if (cache->base == 0)
2387c50c785cSJohn Marino     return UNWIND_OUTERMOST;
2388c50c785cSJohn Marino 
2389c50c785cSJohn Marino   return UNWIND_NO_REASON;
2390c50c785cSJohn Marino }
2391c50c785cSJohn Marino 
23925796c8dcSSimon Schubert static void
amd64_frame_this_id(struct frame_info * this_frame,void ** this_cache,struct frame_id * this_id)23935796c8dcSSimon Schubert amd64_frame_this_id (struct frame_info *this_frame, void **this_cache,
23945796c8dcSSimon Schubert 		     struct frame_id *this_id)
23955796c8dcSSimon Schubert {
23965796c8dcSSimon Schubert   struct amd64_frame_cache *cache =
23975796c8dcSSimon Schubert     amd64_frame_cache (this_frame, this_cache);
23985796c8dcSSimon Schubert 
2399c50c785cSJohn Marino   if (!cache->base_p)
2400c50c785cSJohn Marino     return;
2401c50c785cSJohn Marino 
24025796c8dcSSimon Schubert   /* This marks the outermost frame.  */
24035796c8dcSSimon Schubert   if (cache->base == 0)
24045796c8dcSSimon Schubert     return;
24055796c8dcSSimon Schubert 
24065796c8dcSSimon Schubert   (*this_id) = frame_id_build (cache->base + 16, cache->pc);
24075796c8dcSSimon Schubert }
24085796c8dcSSimon Schubert 
24095796c8dcSSimon Schubert static struct value *
amd64_frame_prev_register(struct frame_info * this_frame,void ** this_cache,int regnum)24105796c8dcSSimon Schubert amd64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
24115796c8dcSSimon Schubert 			   int regnum)
24125796c8dcSSimon Schubert {
24135796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (this_frame);
24145796c8dcSSimon Schubert   struct amd64_frame_cache *cache =
24155796c8dcSSimon Schubert     amd64_frame_cache (this_frame, this_cache);
24165796c8dcSSimon Schubert 
24175796c8dcSSimon Schubert   gdb_assert (regnum >= 0);
24185796c8dcSSimon Schubert 
24195796c8dcSSimon Schubert   if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
24205796c8dcSSimon Schubert     return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
24215796c8dcSSimon Schubert 
24225796c8dcSSimon Schubert   if (regnum < AMD64_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
24235796c8dcSSimon Schubert     return frame_unwind_got_memory (this_frame, regnum,
24245796c8dcSSimon Schubert 				    cache->saved_regs[regnum]);
24255796c8dcSSimon Schubert 
24265796c8dcSSimon Schubert   return frame_unwind_got_register (this_frame, regnum, regnum);
24275796c8dcSSimon Schubert }
24285796c8dcSSimon Schubert 
24295796c8dcSSimon Schubert static const struct frame_unwind amd64_frame_unwind =
24305796c8dcSSimon Schubert {
24315796c8dcSSimon Schubert   NORMAL_FRAME,
2432c50c785cSJohn Marino   amd64_frame_unwind_stop_reason,
24335796c8dcSSimon Schubert   amd64_frame_this_id,
24345796c8dcSSimon Schubert   amd64_frame_prev_register,
24355796c8dcSSimon Schubert   NULL,
24365796c8dcSSimon Schubert   default_frame_sniffer
24375796c8dcSSimon Schubert };
24385796c8dcSSimon Schubert 
2439a45ae5f8SJohn Marino /* Generate a bytecode expression to get the value of the saved PC.  */
2440a45ae5f8SJohn Marino 
2441a45ae5f8SJohn Marino static void
amd64_gen_return_address(struct gdbarch * gdbarch,struct agent_expr * ax,struct axs_value * value,CORE_ADDR scope)2442a45ae5f8SJohn Marino amd64_gen_return_address (struct gdbarch *gdbarch,
2443a45ae5f8SJohn Marino 			  struct agent_expr *ax, struct axs_value *value,
2444a45ae5f8SJohn Marino 			  CORE_ADDR scope)
2445a45ae5f8SJohn Marino {
2446a45ae5f8SJohn Marino   /* The following sequence assumes the traditional use of the base
2447a45ae5f8SJohn Marino      register.  */
2448a45ae5f8SJohn Marino   ax_reg (ax, AMD64_RBP_REGNUM);
2449a45ae5f8SJohn Marino   ax_const_l (ax, 8);
2450a45ae5f8SJohn Marino   ax_simple (ax, aop_add);
2451a45ae5f8SJohn Marino   value->type = register_type (gdbarch, AMD64_RIP_REGNUM);
2452a45ae5f8SJohn Marino   value->kind = axs_lvalue_memory;
2453a45ae5f8SJohn Marino }
2454a45ae5f8SJohn Marino 
24555796c8dcSSimon Schubert 
24565796c8dcSSimon Schubert /* Signal trampolines.  */
24575796c8dcSSimon Schubert 
24585796c8dcSSimon Schubert /* FIXME: kettenis/20030419: Perhaps, we can unify the 32-bit and
24595796c8dcSSimon Schubert    64-bit variants.  This would require using identical frame caches
24605796c8dcSSimon Schubert    on both platforms.  */
24615796c8dcSSimon Schubert 
24625796c8dcSSimon Schubert static struct amd64_frame_cache *
amd64_sigtramp_frame_cache(struct frame_info * this_frame,void ** this_cache)24635796c8dcSSimon Schubert amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
24645796c8dcSSimon Schubert {
24655796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (this_frame);
24665796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
24675796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2468c50c785cSJohn Marino   volatile struct gdb_exception ex;
24695796c8dcSSimon Schubert   struct amd64_frame_cache *cache;
24705796c8dcSSimon Schubert   CORE_ADDR addr;
24715796c8dcSSimon Schubert   gdb_byte buf[8];
24725796c8dcSSimon Schubert   int i;
24735796c8dcSSimon Schubert 
24745796c8dcSSimon Schubert   if (*this_cache)
24755796c8dcSSimon Schubert     return *this_cache;
24765796c8dcSSimon Schubert 
24775796c8dcSSimon Schubert   cache = amd64_alloc_frame_cache ();
24785796c8dcSSimon Schubert 
2479c50c785cSJohn Marino   TRY_CATCH (ex, RETURN_MASK_ERROR)
2480c50c785cSJohn Marino     {
24815796c8dcSSimon Schubert       get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
24825796c8dcSSimon Schubert       cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8;
24835796c8dcSSimon Schubert 
24845796c8dcSSimon Schubert       addr = tdep->sigcontext_addr (this_frame);
24855796c8dcSSimon Schubert       gdb_assert (tdep->sc_reg_offset);
24865796c8dcSSimon Schubert       gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS);
24875796c8dcSSimon Schubert       for (i = 0; i < tdep->sc_num_regs; i++)
24885796c8dcSSimon Schubert 	if (tdep->sc_reg_offset[i] != -1)
24895796c8dcSSimon Schubert 	  cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
24905796c8dcSSimon Schubert 
2491c50c785cSJohn Marino       cache->base_p = 1;
2492c50c785cSJohn Marino     }
2493c50c785cSJohn Marino   if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
2494c50c785cSJohn Marino     throw_exception (ex);
2495c50c785cSJohn Marino 
24965796c8dcSSimon Schubert   *this_cache = cache;
24975796c8dcSSimon Schubert   return cache;
24985796c8dcSSimon Schubert }
24995796c8dcSSimon Schubert 
2500c50c785cSJohn Marino static enum unwind_stop_reason
amd64_sigtramp_frame_unwind_stop_reason(struct frame_info * this_frame,void ** this_cache)2501c50c785cSJohn Marino amd64_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
2502c50c785cSJohn Marino 					 void **this_cache)
2503c50c785cSJohn Marino {
2504c50c785cSJohn Marino   struct amd64_frame_cache *cache =
2505c50c785cSJohn Marino     amd64_sigtramp_frame_cache (this_frame, this_cache);
2506c50c785cSJohn Marino 
2507c50c785cSJohn Marino   if (!cache->base_p)
2508c50c785cSJohn Marino     return UNWIND_UNAVAILABLE;
2509c50c785cSJohn Marino 
2510c50c785cSJohn Marino   return UNWIND_NO_REASON;
2511c50c785cSJohn Marino }
2512c50c785cSJohn Marino 
25135796c8dcSSimon Schubert static void
amd64_sigtramp_frame_this_id(struct frame_info * this_frame,void ** this_cache,struct frame_id * this_id)25145796c8dcSSimon Schubert amd64_sigtramp_frame_this_id (struct frame_info *this_frame,
25155796c8dcSSimon Schubert 			      void **this_cache, struct frame_id *this_id)
25165796c8dcSSimon Schubert {
25175796c8dcSSimon Schubert   struct amd64_frame_cache *cache =
25185796c8dcSSimon Schubert     amd64_sigtramp_frame_cache (this_frame, this_cache);
25195796c8dcSSimon Schubert 
2520c50c785cSJohn Marino   if (!cache->base_p)
2521c50c785cSJohn Marino     return;
2522c50c785cSJohn Marino 
25235796c8dcSSimon Schubert   (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
25245796c8dcSSimon Schubert }
25255796c8dcSSimon Schubert 
25265796c8dcSSimon Schubert static struct value *
amd64_sigtramp_frame_prev_register(struct frame_info * this_frame,void ** this_cache,int regnum)25275796c8dcSSimon Schubert amd64_sigtramp_frame_prev_register (struct frame_info *this_frame,
25285796c8dcSSimon Schubert 				    void **this_cache, int regnum)
25295796c8dcSSimon Schubert {
25305796c8dcSSimon Schubert   /* Make sure we've initialized the cache.  */
25315796c8dcSSimon Schubert   amd64_sigtramp_frame_cache (this_frame, this_cache);
25325796c8dcSSimon Schubert 
25335796c8dcSSimon Schubert   return amd64_frame_prev_register (this_frame, this_cache, regnum);
25345796c8dcSSimon Schubert }
25355796c8dcSSimon Schubert 
25365796c8dcSSimon Schubert static int
amd64_sigtramp_frame_sniffer(const struct frame_unwind * self,struct frame_info * this_frame,void ** this_cache)25375796c8dcSSimon Schubert amd64_sigtramp_frame_sniffer (const struct frame_unwind *self,
25385796c8dcSSimon Schubert 			      struct frame_info *this_frame,
25395796c8dcSSimon Schubert 			      void **this_cache)
25405796c8dcSSimon Schubert {
25415796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
25425796c8dcSSimon Schubert 
25435796c8dcSSimon Schubert   /* We shouldn't even bother if we don't have a sigcontext_addr
25445796c8dcSSimon Schubert      handler.  */
25455796c8dcSSimon Schubert   if (tdep->sigcontext_addr == NULL)
25465796c8dcSSimon Schubert     return 0;
25475796c8dcSSimon Schubert 
25485796c8dcSSimon Schubert   if (tdep->sigtramp_p != NULL)
25495796c8dcSSimon Schubert     {
25505796c8dcSSimon Schubert       if (tdep->sigtramp_p (this_frame))
25515796c8dcSSimon Schubert 	return 1;
25525796c8dcSSimon Schubert     }
25535796c8dcSSimon Schubert 
25545796c8dcSSimon Schubert   if (tdep->sigtramp_start != 0)
25555796c8dcSSimon Schubert     {
25565796c8dcSSimon Schubert       CORE_ADDR pc = get_frame_pc (this_frame);
25575796c8dcSSimon Schubert 
25585796c8dcSSimon Schubert       gdb_assert (tdep->sigtramp_end != 0);
25595796c8dcSSimon Schubert       if (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end)
25605796c8dcSSimon Schubert 	return 1;
25615796c8dcSSimon Schubert     }
25625796c8dcSSimon Schubert 
25635796c8dcSSimon Schubert   return 0;
25645796c8dcSSimon Schubert }
25655796c8dcSSimon Schubert 
25665796c8dcSSimon Schubert static const struct frame_unwind amd64_sigtramp_frame_unwind =
25675796c8dcSSimon Schubert {
25685796c8dcSSimon Schubert   SIGTRAMP_FRAME,
2569c50c785cSJohn Marino   amd64_sigtramp_frame_unwind_stop_reason,
25705796c8dcSSimon Schubert   amd64_sigtramp_frame_this_id,
25715796c8dcSSimon Schubert   amd64_sigtramp_frame_prev_register,
25725796c8dcSSimon Schubert   NULL,
25735796c8dcSSimon Schubert   amd64_sigtramp_frame_sniffer
25745796c8dcSSimon Schubert };
25755796c8dcSSimon Schubert 
25765796c8dcSSimon Schubert 
25775796c8dcSSimon Schubert static CORE_ADDR
amd64_frame_base_address(struct frame_info * this_frame,void ** this_cache)25785796c8dcSSimon Schubert amd64_frame_base_address (struct frame_info *this_frame, void **this_cache)
25795796c8dcSSimon Schubert {
25805796c8dcSSimon Schubert   struct amd64_frame_cache *cache =
25815796c8dcSSimon Schubert     amd64_frame_cache (this_frame, this_cache);
25825796c8dcSSimon Schubert 
25835796c8dcSSimon Schubert   return cache->base;
25845796c8dcSSimon Schubert }
25855796c8dcSSimon Schubert 
25865796c8dcSSimon Schubert static const struct frame_base amd64_frame_base =
25875796c8dcSSimon Schubert {
25885796c8dcSSimon Schubert   &amd64_frame_unwind,
25895796c8dcSSimon Schubert   amd64_frame_base_address,
25905796c8dcSSimon Schubert   amd64_frame_base_address,
25915796c8dcSSimon Schubert   amd64_frame_base_address
25925796c8dcSSimon Schubert };
25935796c8dcSSimon Schubert 
25945796c8dcSSimon Schubert /* Normal frames, but in a function epilogue.  */
25955796c8dcSSimon Schubert 
25965796c8dcSSimon Schubert /* The epilogue is defined here as the 'ret' instruction, which will
25975796c8dcSSimon Schubert    follow any instruction such as 'leave' or 'pop %ebp' that destroys
25985796c8dcSSimon Schubert    the function's stack frame.  */
25995796c8dcSSimon Schubert 
26005796c8dcSSimon Schubert static int
amd64_in_function_epilogue_p(struct gdbarch * gdbarch,CORE_ADDR pc)26015796c8dcSSimon Schubert amd64_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
26025796c8dcSSimon Schubert {
26035796c8dcSSimon Schubert   gdb_byte insn;
2604a45ae5f8SJohn Marino   struct symtab *symtab;
2605a45ae5f8SJohn Marino 
2606a45ae5f8SJohn Marino   symtab = find_pc_symtab (pc);
2607a45ae5f8SJohn Marino   if (symtab && symtab->epilogue_unwind_valid)
2608a45ae5f8SJohn Marino     return 0;
26095796c8dcSSimon Schubert 
26105796c8dcSSimon Schubert   if (target_read_memory (pc, &insn, 1))
26115796c8dcSSimon Schubert     return 0;   /* Can't read memory at pc.  */
26125796c8dcSSimon Schubert 
26135796c8dcSSimon Schubert   if (insn != 0xc3)     /* 'ret' instruction.  */
26145796c8dcSSimon Schubert     return 0;
26155796c8dcSSimon Schubert 
26165796c8dcSSimon Schubert   return 1;
26175796c8dcSSimon Schubert }
26185796c8dcSSimon Schubert 
26195796c8dcSSimon Schubert static int
amd64_epilogue_frame_sniffer(const struct frame_unwind * self,struct frame_info * this_frame,void ** this_prologue_cache)26205796c8dcSSimon Schubert amd64_epilogue_frame_sniffer (const struct frame_unwind *self,
26215796c8dcSSimon Schubert 			      struct frame_info *this_frame,
26225796c8dcSSimon Schubert 			      void **this_prologue_cache)
26235796c8dcSSimon Schubert {
26245796c8dcSSimon Schubert   if (frame_relative_level (this_frame) == 0)
26255796c8dcSSimon Schubert     return amd64_in_function_epilogue_p (get_frame_arch (this_frame),
26265796c8dcSSimon Schubert 					 get_frame_pc (this_frame));
26275796c8dcSSimon Schubert   else
26285796c8dcSSimon Schubert     return 0;
26295796c8dcSSimon Schubert }
26305796c8dcSSimon Schubert 
26315796c8dcSSimon Schubert static struct amd64_frame_cache *
amd64_epilogue_frame_cache(struct frame_info * this_frame,void ** this_cache)26325796c8dcSSimon Schubert amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
26335796c8dcSSimon Schubert {
26345796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (this_frame);
26355796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2636c50c785cSJohn Marino   volatile struct gdb_exception ex;
26375796c8dcSSimon Schubert   struct amd64_frame_cache *cache;
2638cf7f2e2dSJohn Marino   gdb_byte buf[8];
26395796c8dcSSimon Schubert 
26405796c8dcSSimon Schubert   if (*this_cache)
26415796c8dcSSimon Schubert     return *this_cache;
26425796c8dcSSimon Schubert 
26435796c8dcSSimon Schubert   cache = amd64_alloc_frame_cache ();
26445796c8dcSSimon Schubert   *this_cache = cache;
26455796c8dcSSimon Schubert 
2646c50c785cSJohn Marino   TRY_CATCH (ex, RETURN_MASK_ERROR)
2647c50c785cSJohn Marino     {
26485796c8dcSSimon Schubert       /* Cache base will be %esp plus cache->sp_offset (-8).  */
26495796c8dcSSimon Schubert       get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
26505796c8dcSSimon Schubert       cache->base = extract_unsigned_integer (buf, 8,
26515796c8dcSSimon Schubert 					      byte_order) + cache->sp_offset;
26525796c8dcSSimon Schubert 
26535796c8dcSSimon Schubert       /* Cache pc will be the frame func.  */
26545796c8dcSSimon Schubert       cache->pc = get_frame_pc (this_frame);
26555796c8dcSSimon Schubert 
26565796c8dcSSimon Schubert       /* The saved %esp will be at cache->base plus 16.  */
26575796c8dcSSimon Schubert       cache->saved_sp = cache->base + 16;
26585796c8dcSSimon Schubert 
26595796c8dcSSimon Schubert       /* The saved %eip will be at cache->base plus 8.  */
26605796c8dcSSimon Schubert       cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8;
26615796c8dcSSimon Schubert 
2662c50c785cSJohn Marino       cache->base_p = 1;
2663c50c785cSJohn Marino     }
2664c50c785cSJohn Marino   if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
2665c50c785cSJohn Marino     throw_exception (ex);
2666c50c785cSJohn Marino 
26675796c8dcSSimon Schubert   return cache;
26685796c8dcSSimon Schubert }
26695796c8dcSSimon Schubert 
2670c50c785cSJohn Marino static enum unwind_stop_reason
amd64_epilogue_frame_unwind_stop_reason(struct frame_info * this_frame,void ** this_cache)2671c50c785cSJohn Marino amd64_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
2672c50c785cSJohn Marino 					 void **this_cache)
2673c50c785cSJohn Marino {
2674c50c785cSJohn Marino   struct amd64_frame_cache *cache
2675c50c785cSJohn Marino     = amd64_epilogue_frame_cache (this_frame, this_cache);
2676c50c785cSJohn Marino 
2677c50c785cSJohn Marino   if (!cache->base_p)
2678c50c785cSJohn Marino     return UNWIND_UNAVAILABLE;
2679c50c785cSJohn Marino 
2680c50c785cSJohn Marino   return UNWIND_NO_REASON;
2681c50c785cSJohn Marino }
2682c50c785cSJohn Marino 
26835796c8dcSSimon Schubert static void
amd64_epilogue_frame_this_id(struct frame_info * this_frame,void ** this_cache,struct frame_id * this_id)26845796c8dcSSimon Schubert amd64_epilogue_frame_this_id (struct frame_info *this_frame,
26855796c8dcSSimon Schubert 			      void **this_cache,
26865796c8dcSSimon Schubert 			      struct frame_id *this_id)
26875796c8dcSSimon Schubert {
26885796c8dcSSimon Schubert   struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame,
26895796c8dcSSimon Schubert 							       this_cache);
26905796c8dcSSimon Schubert 
2691c50c785cSJohn Marino   if (!cache->base_p)
2692c50c785cSJohn Marino     return;
2693c50c785cSJohn Marino 
26945796c8dcSSimon Schubert   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
26955796c8dcSSimon Schubert }
26965796c8dcSSimon Schubert 
26975796c8dcSSimon Schubert static const struct frame_unwind amd64_epilogue_frame_unwind =
26985796c8dcSSimon Schubert {
26995796c8dcSSimon Schubert   NORMAL_FRAME,
2700c50c785cSJohn Marino   amd64_epilogue_frame_unwind_stop_reason,
27015796c8dcSSimon Schubert   amd64_epilogue_frame_this_id,
27025796c8dcSSimon Schubert   amd64_frame_prev_register,
27035796c8dcSSimon Schubert   NULL,
27045796c8dcSSimon Schubert   amd64_epilogue_frame_sniffer
27055796c8dcSSimon Schubert };
27065796c8dcSSimon Schubert 
27075796c8dcSSimon Schubert static struct frame_id
amd64_dummy_id(struct gdbarch * gdbarch,struct frame_info * this_frame)27085796c8dcSSimon Schubert amd64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
27095796c8dcSSimon Schubert {
27105796c8dcSSimon Schubert   CORE_ADDR fp;
27115796c8dcSSimon Schubert 
27125796c8dcSSimon Schubert   fp = get_frame_register_unsigned (this_frame, AMD64_RBP_REGNUM);
27135796c8dcSSimon Schubert 
27145796c8dcSSimon Schubert   return frame_id_build (fp + 16, get_frame_pc (this_frame));
27155796c8dcSSimon Schubert }
27165796c8dcSSimon Schubert 
27175796c8dcSSimon Schubert /* 16 byte align the SP per frame requirements.  */
27185796c8dcSSimon Schubert 
27195796c8dcSSimon Schubert static CORE_ADDR
amd64_frame_align(struct gdbarch * gdbarch,CORE_ADDR sp)27205796c8dcSSimon Schubert amd64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
27215796c8dcSSimon Schubert {
27225796c8dcSSimon Schubert   return sp & -(CORE_ADDR)16;
27235796c8dcSSimon Schubert }
27245796c8dcSSimon Schubert 
27255796c8dcSSimon Schubert 
27265796c8dcSSimon Schubert /* Supply register REGNUM from the buffer specified by FPREGS and LEN
27275796c8dcSSimon Schubert    in the floating-point register set REGSET to register cache
27285796c8dcSSimon Schubert    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
27295796c8dcSSimon Schubert 
27305796c8dcSSimon Schubert static void
amd64_supply_fpregset(const struct regset * regset,struct regcache * regcache,int regnum,const void * fpregs,size_t len)27315796c8dcSSimon Schubert amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
27325796c8dcSSimon Schubert 		       int regnum, const void *fpregs, size_t len)
27335796c8dcSSimon Schubert {
27345796c8dcSSimon Schubert   const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
27355796c8dcSSimon Schubert 
27365796c8dcSSimon Schubert   gdb_assert (len == tdep->sizeof_fpregset);
27375796c8dcSSimon Schubert   amd64_supply_fxsave (regcache, regnum, fpregs);
27385796c8dcSSimon Schubert }
27395796c8dcSSimon Schubert 
27405796c8dcSSimon Schubert /* Collect register REGNUM from the register cache REGCACHE and store
27415796c8dcSSimon Schubert    it in the buffer specified by FPREGS and LEN as described by the
27425796c8dcSSimon Schubert    floating-point register set REGSET.  If REGNUM is -1, do this for
27435796c8dcSSimon Schubert    all registers in REGSET.  */
27445796c8dcSSimon Schubert 
27455796c8dcSSimon Schubert static void
amd64_collect_fpregset(const struct regset * regset,const struct regcache * regcache,int regnum,void * fpregs,size_t len)27465796c8dcSSimon Schubert amd64_collect_fpregset (const struct regset *regset,
27475796c8dcSSimon Schubert 			const struct regcache *regcache,
27485796c8dcSSimon Schubert 			int regnum, void *fpregs, size_t len)
27495796c8dcSSimon Schubert {
27505796c8dcSSimon Schubert   const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
27515796c8dcSSimon Schubert 
27525796c8dcSSimon Schubert   gdb_assert (len == tdep->sizeof_fpregset);
27535796c8dcSSimon Schubert   amd64_collect_fxsave (regcache, regnum, fpregs);
27545796c8dcSSimon Schubert }
27555796c8dcSSimon Schubert 
2756cf7f2e2dSJohn Marino /* Similar to amd64_supply_fpregset, but use XSAVE extended state.  */
2757cf7f2e2dSJohn Marino 
2758cf7f2e2dSJohn Marino static void
amd64_supply_xstateregset(const struct regset * regset,struct regcache * regcache,int regnum,const void * xstateregs,size_t len)2759cf7f2e2dSJohn Marino amd64_supply_xstateregset (const struct regset *regset,
2760cf7f2e2dSJohn Marino 			   struct regcache *regcache, int regnum,
2761cf7f2e2dSJohn Marino 			   const void *xstateregs, size_t len)
2762cf7f2e2dSJohn Marino {
2763cf7f2e2dSJohn Marino   amd64_supply_xsave (regcache, regnum, xstateregs);
2764cf7f2e2dSJohn Marino }
2765cf7f2e2dSJohn Marino 
2766cf7f2e2dSJohn Marino /* Similar to amd64_collect_fpregset, but use XSAVE extended state.  */
2767cf7f2e2dSJohn Marino 
2768cf7f2e2dSJohn Marino static void
amd64_collect_xstateregset(const struct regset * regset,const struct regcache * regcache,int regnum,void * xstateregs,size_t len)2769cf7f2e2dSJohn Marino amd64_collect_xstateregset (const struct regset *regset,
2770cf7f2e2dSJohn Marino 			    const struct regcache *regcache,
2771cf7f2e2dSJohn Marino 			    int regnum, void *xstateregs, size_t len)
2772cf7f2e2dSJohn Marino {
2773cf7f2e2dSJohn Marino   amd64_collect_xsave (regcache, regnum, xstateregs, 1);
2774cf7f2e2dSJohn Marino }
2775cf7f2e2dSJohn Marino 
27765796c8dcSSimon Schubert /* Return the appropriate register set for the core section identified
27775796c8dcSSimon Schubert    by SECT_NAME and SECT_SIZE.  */
27785796c8dcSSimon Schubert 
27795796c8dcSSimon Schubert static const struct regset *
amd64_regset_from_core_section(struct gdbarch * gdbarch,const char * sect_name,size_t sect_size)27805796c8dcSSimon Schubert amd64_regset_from_core_section (struct gdbarch *gdbarch,
27815796c8dcSSimon Schubert 				const char *sect_name, size_t sect_size)
27825796c8dcSSimon Schubert {
27835796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
27845796c8dcSSimon Schubert 
27855796c8dcSSimon Schubert   if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
27865796c8dcSSimon Schubert     {
27875796c8dcSSimon Schubert       if (tdep->fpregset == NULL)
27885796c8dcSSimon Schubert 	tdep->fpregset = regset_alloc (gdbarch, amd64_supply_fpregset,
27895796c8dcSSimon Schubert 				       amd64_collect_fpregset);
27905796c8dcSSimon Schubert 
27915796c8dcSSimon Schubert       return tdep->fpregset;
27925796c8dcSSimon Schubert     }
27935796c8dcSSimon Schubert 
2794cf7f2e2dSJohn Marino   if (strcmp (sect_name, ".reg-xstate") == 0)
2795cf7f2e2dSJohn Marino     {
2796cf7f2e2dSJohn Marino       if (tdep->xstateregset == NULL)
2797cf7f2e2dSJohn Marino 	tdep->xstateregset = regset_alloc (gdbarch,
2798cf7f2e2dSJohn Marino 					   amd64_supply_xstateregset,
2799cf7f2e2dSJohn Marino 					   amd64_collect_xstateregset);
2800cf7f2e2dSJohn Marino 
2801cf7f2e2dSJohn Marino       return tdep->xstateregset;
2802cf7f2e2dSJohn Marino     }
2803cf7f2e2dSJohn Marino 
28045796c8dcSSimon Schubert   return i386_regset_from_core_section (gdbarch, sect_name, sect_size);
28055796c8dcSSimon Schubert }
28065796c8dcSSimon Schubert 
28075796c8dcSSimon Schubert 
28085796c8dcSSimon Schubert /* Figure out where the longjmp will land.  Slurp the jmp_buf out of
28095796c8dcSSimon Schubert    %rdi.  We expect its value to be a pointer to the jmp_buf structure
28105796c8dcSSimon Schubert    from which we extract the address that we will land at.  This
28115796c8dcSSimon Schubert    address is copied into PC.  This routine returns non-zero on
28125796c8dcSSimon Schubert    success.  */
28135796c8dcSSimon Schubert 
28145796c8dcSSimon Schubert static int
amd64_get_longjmp_target(struct frame_info * frame,CORE_ADDR * pc)28155796c8dcSSimon Schubert amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
28165796c8dcSSimon Schubert {
28175796c8dcSSimon Schubert   gdb_byte buf[8];
28185796c8dcSSimon Schubert   CORE_ADDR jb_addr;
28195796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_frame_arch (frame);
28205796c8dcSSimon Schubert   int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
28215796c8dcSSimon Schubert   int len = TYPE_LENGTH (builtin_type (gdbarch)->builtin_func_ptr);
28225796c8dcSSimon Schubert 
28235796c8dcSSimon Schubert   /* If JB_PC_OFFSET is -1, we have no way to find out where the
28245796c8dcSSimon Schubert      longjmp will land.	 */
28255796c8dcSSimon Schubert   if (jb_pc_offset == -1)
28265796c8dcSSimon Schubert     return 0;
28275796c8dcSSimon Schubert 
28285796c8dcSSimon Schubert   get_frame_register (frame, AMD64_RDI_REGNUM, buf);
28295796c8dcSSimon Schubert   jb_addr= extract_typed_address
28305796c8dcSSimon Schubert 	    (buf, builtin_type (gdbarch)->builtin_data_ptr);
28315796c8dcSSimon Schubert   if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
28325796c8dcSSimon Schubert     return 0;
28335796c8dcSSimon Schubert 
28345796c8dcSSimon Schubert   *pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
28355796c8dcSSimon Schubert 
28365796c8dcSSimon Schubert   return 1;
28375796c8dcSSimon Schubert }
28385796c8dcSSimon Schubert 
28395796c8dcSSimon Schubert static const int amd64_record_regmap[] =
28405796c8dcSSimon Schubert {
28415796c8dcSSimon Schubert   AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
28425796c8dcSSimon Schubert   AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
28435796c8dcSSimon Schubert   AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
28445796c8dcSSimon Schubert   AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
28455796c8dcSSimon Schubert   AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
28465796c8dcSSimon Schubert   AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
28475796c8dcSSimon Schubert };
28485796c8dcSSimon Schubert 
28495796c8dcSSimon Schubert void
amd64_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)28505796c8dcSSimon Schubert amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
28515796c8dcSSimon Schubert {
28525796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2853cf7f2e2dSJohn Marino   const struct target_desc *tdesc = info.target_desc;
28545796c8dcSSimon Schubert 
28555796c8dcSSimon Schubert   /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
28565796c8dcSSimon Schubert      floating-point registers.  */
28575796c8dcSSimon Schubert   tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE;
28585796c8dcSSimon Schubert 
2859cf7f2e2dSJohn Marino   if (! tdesc_has_registers (tdesc))
2860cf7f2e2dSJohn Marino     tdesc = tdesc_amd64;
2861cf7f2e2dSJohn Marino   tdep->tdesc = tdesc;
2862cf7f2e2dSJohn Marino 
2863cf7f2e2dSJohn Marino   tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
2864cf7f2e2dSJohn Marino   tdep->register_names = amd64_register_names;
2865cf7f2e2dSJohn Marino 
2866cf7f2e2dSJohn Marino   if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx") != NULL)
2867cf7f2e2dSJohn Marino     {
2868cf7f2e2dSJohn Marino       tdep->ymmh_register_names = amd64_ymmh_names;
2869cf7f2e2dSJohn Marino       tdep->num_ymm_regs = 16;
2870cf7f2e2dSJohn Marino       tdep->ymm0h_regnum = AMD64_YMM0H_REGNUM;
2871cf7f2e2dSJohn Marino     }
2872cf7f2e2dSJohn Marino 
2873cf7f2e2dSJohn Marino   tdep->num_byte_regs = 20;
2874cf7f2e2dSJohn Marino   tdep->num_word_regs = 16;
2875cf7f2e2dSJohn Marino   tdep->num_dword_regs = 16;
2876cf7f2e2dSJohn Marino   /* Avoid wiring in the MMX registers for now.  */
2877cf7f2e2dSJohn Marino   tdep->num_mmx_regs = 0;
2878cf7f2e2dSJohn Marino 
2879a45ae5f8SJohn Marino   set_gdbarch_pseudo_register_read_value (gdbarch,
2880a45ae5f8SJohn Marino 					  amd64_pseudo_register_read_value);
2881cf7f2e2dSJohn Marino   set_gdbarch_pseudo_register_write (gdbarch,
2882cf7f2e2dSJohn Marino 				     amd64_pseudo_register_write);
2883cf7f2e2dSJohn Marino 
2884cf7f2e2dSJohn Marino   set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name);
2885cf7f2e2dSJohn Marino 
28865796c8dcSSimon Schubert   /* AMD64 has an FPU and 16 SSE registers.  */
28875796c8dcSSimon Schubert   tdep->st0_regnum = AMD64_ST0_REGNUM;
28885796c8dcSSimon Schubert   tdep->num_xmm_regs = 16;
28895796c8dcSSimon Schubert 
28905796c8dcSSimon Schubert   /* This is what all the fuss is about.  */
28915796c8dcSSimon Schubert   set_gdbarch_long_bit (gdbarch, 64);
28925796c8dcSSimon Schubert   set_gdbarch_long_long_bit (gdbarch, 64);
28935796c8dcSSimon Schubert   set_gdbarch_ptr_bit (gdbarch, 64);
28945796c8dcSSimon Schubert 
28955796c8dcSSimon Schubert   /* In contrast to the i386, on AMD64 a `long double' actually takes
28965796c8dcSSimon Schubert      up 128 bits, even though it's still based on the i387 extended
28975796c8dcSSimon Schubert      floating-point format which has only 80 significant bits.  */
28985796c8dcSSimon Schubert   set_gdbarch_long_double_bit (gdbarch, 128);
28995796c8dcSSimon Schubert 
29005796c8dcSSimon Schubert   set_gdbarch_num_regs (gdbarch, AMD64_NUM_REGS);
29015796c8dcSSimon Schubert 
29025796c8dcSSimon Schubert   /* Register numbers of various important registers.  */
29035796c8dcSSimon Schubert   set_gdbarch_sp_regnum (gdbarch, AMD64_RSP_REGNUM); /* %rsp */
29045796c8dcSSimon Schubert   set_gdbarch_pc_regnum (gdbarch, AMD64_RIP_REGNUM); /* %rip */
29055796c8dcSSimon Schubert   set_gdbarch_ps_regnum (gdbarch, AMD64_EFLAGS_REGNUM); /* %eflags */
29065796c8dcSSimon Schubert   set_gdbarch_fp0_regnum (gdbarch, AMD64_ST0_REGNUM); /* %st(0) */
29075796c8dcSSimon Schubert 
29085796c8dcSSimon Schubert   /* The "default" register numbering scheme for AMD64 is referred to
29095796c8dcSSimon Schubert      as the "DWARF Register Number Mapping" in the System V psABI.
29105796c8dcSSimon Schubert      The preferred debugging format for all known AMD64 targets is
29115796c8dcSSimon Schubert      actually DWARF2, and GCC doesn't seem to support DWARF (that is
29125796c8dcSSimon Schubert      DWARF-1), but we provide the same mapping just in case.  This
29135796c8dcSSimon Schubert      mapping is also used for stabs, which GCC does support.  */
29145796c8dcSSimon Schubert   set_gdbarch_stab_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum);
29155796c8dcSSimon Schubert   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum);
29165796c8dcSSimon Schubert 
29175796c8dcSSimon Schubert   /* We don't override SDB_REG_RO_REGNUM, since COFF doesn't seem to
29185796c8dcSSimon Schubert      be in use on any of the supported AMD64 targets.  */
29195796c8dcSSimon Schubert 
29205796c8dcSSimon Schubert   /* Call dummy code.  */
29215796c8dcSSimon Schubert   set_gdbarch_push_dummy_call (gdbarch, amd64_push_dummy_call);
29225796c8dcSSimon Schubert   set_gdbarch_frame_align (gdbarch, amd64_frame_align);
29235796c8dcSSimon Schubert   set_gdbarch_frame_red_zone_size (gdbarch, 128);
2924cf7f2e2dSJohn Marino   tdep->call_dummy_num_integer_regs =
2925cf7f2e2dSJohn Marino     ARRAY_SIZE (amd64_dummy_call_integer_regs);
2926cf7f2e2dSJohn Marino   tdep->call_dummy_integer_regs = amd64_dummy_call_integer_regs;
2927cf7f2e2dSJohn Marino   tdep->classify = amd64_classify;
29285796c8dcSSimon Schubert 
29295796c8dcSSimon Schubert   set_gdbarch_convert_register_p (gdbarch, i387_convert_register_p);
29305796c8dcSSimon Schubert   set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
29315796c8dcSSimon Schubert   set_gdbarch_value_to_register (gdbarch, i387_value_to_register);
29325796c8dcSSimon Schubert 
29335796c8dcSSimon Schubert   set_gdbarch_return_value (gdbarch, amd64_return_value);
29345796c8dcSSimon Schubert 
29355796c8dcSSimon Schubert   set_gdbarch_skip_prologue (gdbarch, amd64_skip_prologue);
29365796c8dcSSimon Schubert 
29375796c8dcSSimon Schubert   tdep->record_regmap = amd64_record_regmap;
29385796c8dcSSimon Schubert 
29395796c8dcSSimon Schubert   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
29405796c8dcSSimon Schubert 
29415796c8dcSSimon Schubert   /* Hook the function epilogue frame unwinder.  This unwinder is
29425796c8dcSSimon Schubert      appended to the list first, so that it supercedes the other
29435796c8dcSSimon Schubert      unwinders in function epilogues.  */
29445796c8dcSSimon Schubert   frame_unwind_prepend_unwinder (gdbarch, &amd64_epilogue_frame_unwind);
29455796c8dcSSimon Schubert 
29465796c8dcSSimon Schubert   /* Hook the prologue-based frame unwinders.  */
29475796c8dcSSimon Schubert   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
29485796c8dcSSimon Schubert   frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind);
29495796c8dcSSimon Schubert   frame_base_set_default (gdbarch, &amd64_frame_base);
29505796c8dcSSimon Schubert 
29515796c8dcSSimon Schubert   /* If we have a register mapping, enable the generic core file support.  */
29525796c8dcSSimon Schubert   if (tdep->gregset_reg_offset)
29535796c8dcSSimon Schubert     set_gdbarch_regset_from_core_section (gdbarch,
29545796c8dcSSimon Schubert 					  amd64_regset_from_core_section);
29555796c8dcSSimon Schubert 
29565796c8dcSSimon Schubert   set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target);
2957cf7f2e2dSJohn Marino 
2958cf7f2e2dSJohn Marino   set_gdbarch_relocate_instruction (gdbarch, amd64_relocate_instruction);
2959a45ae5f8SJohn Marino 
2960a45ae5f8SJohn Marino   set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address);
2961*ef5ccd6cSJohn Marino 
2962*ef5ccd6cSJohn Marino   /* SystemTap variables and functions.  */
2963*ef5ccd6cSJohn Marino   set_gdbarch_stap_integer_prefix (gdbarch, "$");
2964*ef5ccd6cSJohn Marino   set_gdbarch_stap_register_prefix (gdbarch, "%");
2965*ef5ccd6cSJohn Marino   set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
2966*ef5ccd6cSJohn Marino   set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
2967*ef5ccd6cSJohn Marino   set_gdbarch_stap_is_single_operand (gdbarch,
2968*ef5ccd6cSJohn Marino 				      i386_stap_is_single_operand);
2969*ef5ccd6cSJohn Marino   set_gdbarch_stap_parse_special_token (gdbarch,
2970*ef5ccd6cSJohn Marino 					i386_stap_parse_special_token);
2971*ef5ccd6cSJohn Marino }
2972*ef5ccd6cSJohn Marino 
2973*ef5ccd6cSJohn Marino 
2974*ef5ccd6cSJohn Marino static struct type *
amd64_x32_pseudo_register_type(struct gdbarch * gdbarch,int regnum)2975*ef5ccd6cSJohn Marino amd64_x32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
2976*ef5ccd6cSJohn Marino {
2977*ef5ccd6cSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2978*ef5ccd6cSJohn Marino 
2979*ef5ccd6cSJohn Marino   switch (regnum - tdep->eax_regnum)
2980*ef5ccd6cSJohn Marino     {
2981*ef5ccd6cSJohn Marino     case AMD64_RBP_REGNUM:	/* %ebp */
2982*ef5ccd6cSJohn Marino     case AMD64_RSP_REGNUM:	/* %esp */
2983*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_data_ptr;
2984*ef5ccd6cSJohn Marino     case AMD64_RIP_REGNUM:	/* %eip */
2985*ef5ccd6cSJohn Marino       return builtin_type (gdbarch)->builtin_func_ptr;
2986*ef5ccd6cSJohn Marino     }
2987*ef5ccd6cSJohn Marino 
2988*ef5ccd6cSJohn Marino   return i386_pseudo_register_type (gdbarch, regnum);
2989*ef5ccd6cSJohn Marino }
2990*ef5ccd6cSJohn Marino 
2991*ef5ccd6cSJohn Marino void
amd64_x32_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)2992*ef5ccd6cSJohn Marino amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2993*ef5ccd6cSJohn Marino {
2994*ef5ccd6cSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2995*ef5ccd6cSJohn Marino   const struct target_desc *tdesc = info.target_desc;
2996*ef5ccd6cSJohn Marino 
2997*ef5ccd6cSJohn Marino   amd64_init_abi (info, gdbarch);
2998*ef5ccd6cSJohn Marino 
2999*ef5ccd6cSJohn Marino   if (! tdesc_has_registers (tdesc))
3000*ef5ccd6cSJohn Marino     tdesc = tdesc_x32;
3001*ef5ccd6cSJohn Marino   tdep->tdesc = tdesc;
3002*ef5ccd6cSJohn Marino 
3003*ef5ccd6cSJohn Marino   tdep->num_dword_regs = 17;
3004*ef5ccd6cSJohn Marino   set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_type);
3005*ef5ccd6cSJohn Marino 
3006*ef5ccd6cSJohn Marino   set_gdbarch_long_bit (gdbarch, 32);
3007*ef5ccd6cSJohn Marino   set_gdbarch_ptr_bit (gdbarch, 32);
3008cf7f2e2dSJohn Marino }
3009cf7f2e2dSJohn Marino 
3010cf7f2e2dSJohn Marino /* Provide a prototype to silence -Wmissing-prototypes.  */
3011cf7f2e2dSJohn Marino void _initialize_amd64_tdep (void);
3012cf7f2e2dSJohn Marino 
3013cf7f2e2dSJohn Marino void
_initialize_amd64_tdep(void)3014cf7f2e2dSJohn Marino _initialize_amd64_tdep (void)
3015cf7f2e2dSJohn Marino {
3016cf7f2e2dSJohn Marino   initialize_tdesc_amd64 ();
3017cf7f2e2dSJohn Marino   initialize_tdesc_amd64_avx ();
3018*ef5ccd6cSJohn Marino   initialize_tdesc_x32 ();
3019*ef5ccd6cSJohn Marino   initialize_tdesc_x32_avx ();
30205796c8dcSSimon Schubert }
30215796c8dcSSimon Schubert 
30225796c8dcSSimon Schubert 
30235796c8dcSSimon Schubert /* The 64-bit FXSAVE format differs from the 32-bit format in the
30245796c8dcSSimon Schubert    sense that the instruction pointer and data pointer are simply
30255796c8dcSSimon Schubert    64-bit offsets into the code segment and the data segment instead
30265796c8dcSSimon Schubert    of a selector offset pair.  The functions below store the upper 32
30275796c8dcSSimon Schubert    bits of these pointers (instead of just the 16-bits of the segment
30285796c8dcSSimon Schubert    selector).  */
30295796c8dcSSimon Schubert 
30305796c8dcSSimon Schubert /* Fill register REGNUM in REGCACHE with the appropriate
30315796c8dcSSimon Schubert    floating-point or SSE register value from *FXSAVE.  If REGNUM is
30325796c8dcSSimon Schubert    -1, do this for all registers.  This function masks off any of the
30335796c8dcSSimon Schubert    reserved bits in *FXSAVE.  */
30345796c8dcSSimon Schubert 
30355796c8dcSSimon Schubert void
amd64_supply_fxsave(struct regcache * regcache,int regnum,const void * fxsave)30365796c8dcSSimon Schubert amd64_supply_fxsave (struct regcache *regcache, int regnum,
30375796c8dcSSimon Schubert 		     const void *fxsave)
30385796c8dcSSimon Schubert {
30395796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_regcache_arch (regcache);
30405796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
30415796c8dcSSimon Schubert 
30425796c8dcSSimon Schubert   i387_supply_fxsave (regcache, regnum, fxsave);
30435796c8dcSSimon Schubert 
3044*ef5ccd6cSJohn Marino   if (fxsave
3045*ef5ccd6cSJohn Marino       && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
30465796c8dcSSimon Schubert     {
30475796c8dcSSimon Schubert       const gdb_byte *regs = fxsave;
30485796c8dcSSimon Schubert 
30495796c8dcSSimon Schubert       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
30505796c8dcSSimon Schubert 	regcache_raw_supply (regcache, I387_FISEG_REGNUM (tdep), regs + 12);
30515796c8dcSSimon Schubert       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
30525796c8dcSSimon Schubert 	regcache_raw_supply (regcache, I387_FOSEG_REGNUM (tdep), regs + 20);
30535796c8dcSSimon Schubert     }
30545796c8dcSSimon Schubert }
30555796c8dcSSimon Schubert 
3056cf7f2e2dSJohn Marino /* Similar to amd64_supply_fxsave, but use XSAVE extended state.  */
3057cf7f2e2dSJohn Marino 
3058cf7f2e2dSJohn Marino void
amd64_supply_xsave(struct regcache * regcache,int regnum,const void * xsave)3059cf7f2e2dSJohn Marino amd64_supply_xsave (struct regcache *regcache, int regnum,
3060cf7f2e2dSJohn Marino 		    const void *xsave)
3061cf7f2e2dSJohn Marino {
3062cf7f2e2dSJohn Marino   struct gdbarch *gdbarch = get_regcache_arch (regcache);
3063cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3064cf7f2e2dSJohn Marino 
3065cf7f2e2dSJohn Marino   i387_supply_xsave (regcache, regnum, xsave);
3066cf7f2e2dSJohn Marino 
3067*ef5ccd6cSJohn Marino   if (xsave
3068*ef5ccd6cSJohn Marino       && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
3069cf7f2e2dSJohn Marino     {
3070cf7f2e2dSJohn Marino       const gdb_byte *regs = xsave;
3071cf7f2e2dSJohn Marino 
3072cf7f2e2dSJohn Marino       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
3073cf7f2e2dSJohn Marino 	regcache_raw_supply (regcache, I387_FISEG_REGNUM (tdep),
3074cf7f2e2dSJohn Marino 			     regs + 12);
3075cf7f2e2dSJohn Marino       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
3076cf7f2e2dSJohn Marino 	regcache_raw_supply (regcache, I387_FOSEG_REGNUM (tdep),
3077cf7f2e2dSJohn Marino 			     regs + 20);
3078cf7f2e2dSJohn Marino     }
3079cf7f2e2dSJohn Marino }
3080cf7f2e2dSJohn Marino 
30815796c8dcSSimon Schubert /* Fill register REGNUM (if it is a floating-point or SSE register) in
30825796c8dcSSimon Schubert    *FXSAVE with the value from REGCACHE.  If REGNUM is -1, do this for
30835796c8dcSSimon Schubert    all registers.  This function doesn't touch any of the reserved
30845796c8dcSSimon Schubert    bits in *FXSAVE.  */
30855796c8dcSSimon Schubert 
30865796c8dcSSimon Schubert void
amd64_collect_fxsave(const struct regcache * regcache,int regnum,void * fxsave)30875796c8dcSSimon Schubert amd64_collect_fxsave (const struct regcache *regcache, int regnum,
30885796c8dcSSimon Schubert 		      void *fxsave)
30895796c8dcSSimon Schubert {
30905796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_regcache_arch (regcache);
30915796c8dcSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
30925796c8dcSSimon Schubert   gdb_byte *regs = fxsave;
30935796c8dcSSimon Schubert 
30945796c8dcSSimon Schubert   i387_collect_fxsave (regcache, regnum, fxsave);
30955796c8dcSSimon Schubert 
3096*ef5ccd6cSJohn Marino   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
30975796c8dcSSimon Schubert     {
30985796c8dcSSimon Schubert       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
30995796c8dcSSimon Schubert 	regcache_raw_collect (regcache, I387_FISEG_REGNUM (tdep), regs + 12);
31005796c8dcSSimon Schubert       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
31015796c8dcSSimon Schubert 	regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep), regs + 20);
31025796c8dcSSimon Schubert     }
31035796c8dcSSimon Schubert }
3104cf7f2e2dSJohn Marino 
3105a45ae5f8SJohn Marino /* Similar to amd64_collect_fxsave, but use XSAVE extended state.  */
3106cf7f2e2dSJohn Marino 
3107cf7f2e2dSJohn Marino void
amd64_collect_xsave(const struct regcache * regcache,int regnum,void * xsave,int gcore)3108cf7f2e2dSJohn Marino amd64_collect_xsave (const struct regcache *regcache, int regnum,
3109cf7f2e2dSJohn Marino 		     void *xsave, int gcore)
3110cf7f2e2dSJohn Marino {
3111cf7f2e2dSJohn Marino   struct gdbarch *gdbarch = get_regcache_arch (regcache);
3112cf7f2e2dSJohn Marino   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3113cf7f2e2dSJohn Marino   gdb_byte *regs = xsave;
3114cf7f2e2dSJohn Marino 
3115cf7f2e2dSJohn Marino   i387_collect_xsave (regcache, regnum, xsave, gcore);
3116cf7f2e2dSJohn Marino 
3117*ef5ccd6cSJohn Marino   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
3118cf7f2e2dSJohn Marino     {
3119cf7f2e2dSJohn Marino       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
3120cf7f2e2dSJohn Marino 	regcache_raw_collect (regcache, I387_FISEG_REGNUM (tdep),
3121cf7f2e2dSJohn Marino 			      regs + 12);
3122cf7f2e2dSJohn Marino       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
3123cf7f2e2dSJohn Marino 	regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep),
3124cf7f2e2dSJohn Marino 			      regs + 20);
3125cf7f2e2dSJohn Marino     }
3126cf7f2e2dSJohn Marino }
3127