Gregs.c revision be2bed2712097dae6d44bb1a9d46da2b0c17db4a
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/* libunwind - a platform-independent unwind library
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P.
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)This file is part of libunwind.
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Permission is hereby granted, free of charge, to any person obtaining
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)a copy of this software and associated documentation files (the
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)"Software"), to deal in the Software without restriction, including
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)without limitation the rights to use, copy, modify, merge, publish,
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)distribute, sublicense, and/or sell copies of the Software, and to
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)permit persons to whom the Software is furnished to do so, subject to
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)the following conditions:
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)The above copyright notice and this permission notice shall be
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochincluded in all copies or substantial portions of the Software.
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "offsets.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "unwind_i.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static inline dwarf_loc_t
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)linux_scratch_loc (struct cursor *c, unw_regnum_t reg)
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles){
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  unw_word_t addr = c->sigcontext_addr, fpstate_addr, off;
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int ret, is_fpstate = 0;
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (c->sigcontext_format)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case X86_SCF_NONE:
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return DWARF_REG_LOC (&c->dwarf, reg);
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case X86_SCF_LINUX_SIGFRAME:
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case X86_SCF_LINUX_RT_SIGFRAME:
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      addr += LINUX_UC_MCONTEXT_OFF;
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (reg)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_GS: off = LINUX_SC_GS_OFF; break;
51a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case UNW_X86_FS: off = LINUX_SC_FS_OFF; break;
52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case UNW_X86_ES: off = LINUX_SC_ES_OFF; break;
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_DS: off = LINUX_SC_DS_OFF; break;
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EDI: off = LINUX_SC_EDI_OFF; break;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case UNW_X86_ESI: off = LINUX_SC_ESI_OFF; break;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case UNW_X86_EBP: off = LINUX_SC_EBP_OFF; break;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case UNW_X86_ESP: off = LINUX_SC_ESP_OFF; break;
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case UNW_X86_EBX: off = LINUX_SC_EBX_OFF; break;
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EDX: off = LINUX_SC_EDX_OFF; break;
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_ECX: off = LINUX_SC_ECX_OFF; break;
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EAX: off = LINUX_SC_EAX_OFF; break;
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_TRAPNO: off = LINUX_SC_TRAPNO_OFF; break;
6358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    case UNW_X86_EIP: off = LINUX_SC_EIP_OFF; break;
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case UNW_X86_CS: off = LINUX_SC_CS_OFF; break;
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_EFLAGS: off = LINUX_SC_EFLAGS_OFF; break;
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_SS: off = LINUX_SC_SS_OFF; break;
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      /* The following is probably not correct for all possible cases.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 Somebody who understands this better should review this for
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	 correctness.  */
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case UNW_X86_FCW: is_fpstate = 1; off = LINUX_FPSTATE_CW_OFF; break;
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_FSW: is_fpstate = 1; off = LINUX_FPSTATE_SW_OFF; break;
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_FTW: is_fpstate = 1; off = LINUX_FPSTATE_TAG_OFF; break;
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case UNW_X86_FCS: is_fpstate = 1; off = LINUX_FPSTATE_CSSEL_OFF; break;
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case UNW_X86_FIP: is_fpstate = 1; off = LINUX_FPSTATE_IPOFF_OFF; break;
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_FEA: is_fpstate = 1; off = LINUX_FPSTATE_DATAOFF_OFF; break;
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_FDS: is_fpstate = 1; off = LINUX_FPSTATE_DATASEL_OFF; break;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_MXCSR: is_fpstate = 1; off = LINUX_FPSTATE_MXCSR_OFF; break;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      /* stacked fp registers */
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3:
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7:
84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      is_fpstate = 1;
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      off = LINUX_FPSTATE_ST0_OFF + 10*(reg - UNW_X86_ST0);
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)     /* SSE fp registers */
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi:
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi:
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi:
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi:
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi:
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi:
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi:
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi:
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      is_fpstate = 1;
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      off = LINUX_FPSTATE_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo);
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_FOP:
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_TSS:
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNW_X86_LDT:
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    default:
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return DWARF_REG_LOC (&c->dwarf, reg);
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (is_fpstate)
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    {
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if ((ret = dwarf_get (&c->dwarf,
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)			    DWARF_MEM_LOC (&c->dwarf,
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)					   addr + LINUX_SC_FPSTATE_OFF),
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)			    &fpstate_addr)) < 0)
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	return DWARF_NULL_LOC;
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (!fpstate_addr)
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	return DWARF_NULL_LOC;
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return DWARF_MEM_LOC (c, fpstate_addr + off);
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return DWARF_MEM_LOC (c, addr + off);
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)HIDDEN dwarf_loc_t
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)x86_scratch_loc (struct cursor *c, unw_regnum_t reg)
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (c->sigcontext_addr)
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return linux_scratch_loc (c, reg);
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return DWARF_REG_LOC (&c->dwarf, reg);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)HIDDEN int
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)		 int write)
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  dwarf_loc_t loc = DWARF_NULL_LOC;
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (reg)
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EIP:
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (write)
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	c->dwarf.ip = *valp;		/* also update the EIP cache */
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      loc = c->dwarf.loc[EIP];
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_CFA:
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (write)
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	return -UNW_EREADONLYREG;
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *valp = c->dwarf.cfa;
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return 0;
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break;
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break;
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break;
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_ESP:
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (c->dwarf.cfa_is_sp)
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	{
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	  if (write)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	    return -UNW_EREADONLYREG;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	  *valp = c->dwarf.cfa;
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	  return 0;
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	}
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      loc = c->dwarf.loc[ESP];
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break;
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break;
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break;
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break;
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break;
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_FCW:
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_FSW:
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_FTW:
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case UNW_X86_FOP:
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_FCS:
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_FIP:
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_FEA:
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case UNW_X86_FDS:
183    case UNW_X86_MXCSR:
184    case UNW_X86_GS:
185    case UNW_X86_FS:
186    case UNW_X86_ES:
187    case UNW_X86_DS:
188    case UNW_X86_SS:
189    case UNW_X86_CS:
190    case UNW_X86_TSS:
191    case UNW_X86_LDT:
192      loc = x86_scratch_loc (c, reg);
193      break;
194
195    default:
196      Debug (1, "bad register number %u\n", reg);
197      return -UNW_EBADREG;
198    }
199
200  if (write)
201    return dwarf_put (&c->dwarf, loc, *valp);
202  else
203    return dwarf_get (&c->dwarf, loc, valp);
204}
205
206HIDDEN int
207tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
208		   int write)
209{
210  struct dwarf_loc loc = DWARF_NULL_LOC;
211
212  switch (reg)
213    {
214    case UNW_X86_ST0:
215      loc = c->dwarf.loc[ST0];
216      break;
217
218      /* stacked fp registers */
219    case UNW_X86_ST1:
220    case UNW_X86_ST2:
221    case UNW_X86_ST3:
222    case UNW_X86_ST4:
223    case UNW_X86_ST5:
224    case UNW_X86_ST6:
225    case UNW_X86_ST7:
226      /* SSE fp registers */
227    case UNW_X86_XMM0_lo:
228    case UNW_X86_XMM0_hi:
229    case UNW_X86_XMM1_lo:
230    case UNW_X86_XMM1_hi:
231    case UNW_X86_XMM2_lo:
232    case UNW_X86_XMM2_hi:
233    case UNW_X86_XMM3_lo:
234    case UNW_X86_XMM3_hi:
235    case UNW_X86_XMM4_lo:
236    case UNW_X86_XMM4_hi:
237    case UNW_X86_XMM5_lo:
238    case UNW_X86_XMM5_hi:
239    case UNW_X86_XMM6_lo:
240    case UNW_X86_XMM6_hi:
241    case UNW_X86_XMM7_lo:
242    case UNW_X86_XMM7_hi:
243      loc = x86_scratch_loc (c, reg);
244      break;
245
246    default:
247      Debug (1, "bad register number %u\n", reg);
248      return -UNW_EBADREG;
249    }
250
251  if (write)
252    return dwarf_putfp (&c->dwarf, loc, *valp);
253  else
254    return dwarf_getfp (&c->dwarf, loc, valp);
255}
256