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