1a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock/* libunwind - a platform-independent unwind library
2fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov   Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
3a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
4a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockThis file is part of libunwind.
5a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
6a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockPermission is hereby granted, free of charge, to any person obtaining
7a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbocka copy of this software and associated documentation files (the
8a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock"Software"), to deal in the Software without restriction, including
9a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockwithout limitation the rights to use, copy, modify, merge, publish,
10a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockdistribute, sublicense, and/or sell copies of the Software, and to
11a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockpermit persons to whom the Software is furnished to do so, subject to
12a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockthe following conditions:
13a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
14a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockThe above copyright notice and this permission notice shall be
15a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockincluded in all copies or substantial portions of the Software.
16a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
17a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
24a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
25fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#ifdef HAVE_CONFIG_H
26fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include "config.h"
27fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#endif
28a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
29fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include <sys/ucontext.h>
30fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include <machine/sigframe.h>
31fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include <signal.h>
32fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include <stddef.h>
33fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include "unwind_i.h"
34fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov#include "ucontext_i.h"
35a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock
361ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin BelousovPROTECTED int
371ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin Belousovunw_is_signal_frame (unw_cursor_t *cursor)
381ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin Belousov{
391ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin Belousov  /* XXXKIB */
4081f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  struct cursor *c = (struct cursor *) cursor;
41752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov  unw_word_t w0, w1, w2, b0, ip;
4281f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  unw_addr_space_t as;
4381f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  unw_accessors_t *a;
4481f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  void *arg;
4581f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  int ret;
4681f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov
4781f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  as = c->dwarf.as;
4881f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  a = unw_get_accessors (as);
4981f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  arg = c->dwarf.as_arg;
5081f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov
5181f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  /* Check if RIP points at sigreturn sequence.
5281f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov48 8d 7c 24 10		lea	SIGF_UC(%rsp),%rdi
5381f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov6a 00			pushq	$0
5481f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov48 c7 c0 a1 01 00 00	movq	$SYS_sigreturn,%rax
5581f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov0f 05			syscall
5681f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousovf4		0:	hlt
5781f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousoveb fd			jmp	0b
5881f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  */
5981f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov
6081f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  ip = c->dwarf.ip;
61fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  c->sigcontext_format = X86_64_SCF_NONE;
6281f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
6381f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov      || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0
6481f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov      || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0)
6581f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov    return 0;
6681f2de00830e7d68add0c12b68a3c67778acaf6dKonstantin Belousov  w2 &= 0xffffff;
67752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov  if (w0 == 0x48006a10247c8d48 &&
68752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov      w1 == 0x050f000001a1c0c7 &&
69752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov      w2 == 0x0000000000fdebf4)
70fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov   {
71fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov     c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME;
72fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov     return (c->sigcontext_format);
73fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov   }
74752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov  /* Check if RIP points at standard syscall sequence.
75752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov49 89 ca	mov    %rcx,%r10
76752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov0f 05		syscall
77752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov  */
78752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov  if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0)
79752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov    return (0);
803bb74aae3da540865b1208f78936c8975929cb11Konstantin Belousov  Debug (12, "b0 0x%lx\n", b0);
813bb74aae3da540865b1208f78936c8975929cb11Konstantin Belousov  if ((b0 & 0xffffffffffffff) == 0x050fca89490000 ||
823bb74aae3da540865b1208f78936c8975929cb11Konstantin Belousov      (b0 & 0xffffffffff) == 0x050fca8949)
83fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov   {
84fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov    c->sigcontext_format = X86_64_SCF_FREEBSD_SYSCALL;
85fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov    return (c->sigcontext_format);
86fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov   }
87fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  return (X86_64_SCF_NONE);
881ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin Belousov}
891ba7599250d8bb2be1a4a21c1181d6a87db5e597Konstantin Belousov
90a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbockPROTECTED int
91fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousovunw_handle_signal_frame (unw_cursor_t *cursor)
92a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock{
93fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  struct cursor *c = (struct cursor *) cursor;
94fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  unw_word_t ucontext;
95fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  int ret;
96fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov
97fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  if (c->sigcontext_format == X86_64_SCF_FREEBSD_SIGFRAME)
98ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov   {
99fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov    ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc);
10021f0e90ce85da99c2897d5e2163e8183436becdcKonstantin Belousov    c->sigcontext_addr = c->dwarf.cfa;
101ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    Debug(1, "signal frame, skip over trampoline\n");
102ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov
103ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
104ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa);
105ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    if (ret < 0)
106ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov     {
107ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov       Debug (2, "returning %d\n", ret);
108ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov       return ret;
109ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov     }
110ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov
111ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0);
112ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0);
113ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0);
114ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0);
115ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0);
116ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0);
117ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
118ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
119ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
120ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
121ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
122ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
123ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
124ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
125ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
126ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
127ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);
128ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov
129ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    return 0;
130ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov   }
131ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov  else if (c->sigcontext_format == X86_64_SCF_FREEBSD_SYSCALL)
132ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov   {
133ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RCX] = c->dwarf.loc[R10];
134ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    /*  rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0);	*/
135ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    /*	rbp_loc = c->dwarf.loc[RBP];			*/
136ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0);
137ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip);
138ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",
139ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov	   (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]),
140ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov	   (unsigned long long) c->dwarf.ip);
141ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    if (ret < 0)
142ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov     {
143ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov       Debug (2, "returning %d\n", ret);
144ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov       return ret;
145ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov     }
146ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    c->dwarf.cfa += 8;
147ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov    return 1;
148ccc0ae665baa67ae3df8595ab7bb0ef8cbc0e5c4Konstantin Belousov   }
149fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov  else
150fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov    return -UNW_EBADFRAME;
151fd88f418184b82ea5dc191e16ae9f3705c865f68Konstantin Belousov
152a766efd844260866e0d216f6eeef87f4593f60b2ibm.com!masbock}
1530dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov
1540dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov#ifndef UNW_REMOTE_ONLY
1550dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin BelousovHIDDEN void *
1560dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousovx86_64_r_uc_addr (ucontext_t *uc, int reg)
1570dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov{
158ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura  /* NOTE: common_init() in init.h inlines these for fast path access. */
1590dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov  void *addr;
1600dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov
1610dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov  switch (reg)
1620dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    {
1630dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R8: addr = &uc->uc_mcontext.mc_r8; break;
1640dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R9: addr = &uc->uc_mcontext.mc_r9; break;
1650dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R10: addr = &uc->uc_mcontext.mc_r10; break;
1660dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R11: addr = &uc->uc_mcontext.mc_r11; break;
1670dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R12: addr = &uc->uc_mcontext.mc_r12; break;
1680dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R13: addr = &uc->uc_mcontext.mc_r13; break;
1690dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R14: addr = &uc->uc_mcontext.mc_r14; break;
1700dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_R15: addr = &uc->uc_mcontext.mc_r15; break;
1710dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RDI: addr = &uc->uc_mcontext.mc_rdi; break;
1720dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RSI: addr = &uc->uc_mcontext.mc_rsi; break;
1730dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RBP: addr = &uc->uc_mcontext.mc_rbp; break;
1740dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RBX: addr = &uc->uc_mcontext.mc_rbx; break;
1750dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RDX: addr = &uc->uc_mcontext.mc_rdx; break;
1760dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RAX: addr = &uc->uc_mcontext.mc_rax; break;
1770dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RCX: addr = &uc->uc_mcontext.mc_rcx; break;
1780dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RSP: addr = &uc->uc_mcontext.mc_rsp; break;
1790dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    case UNW_X86_64_RIP: addr = &uc->uc_mcontext.mc_rip; break;
1800dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov
1810dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    default:
1820dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov      addr = NULL;
1830dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov    }
1840dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov  return addr;
1850dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov}
186979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov
187979af4502fe19b0d98459633731d004a4a010a0eKonstantin BelousovHIDDEN NORETURN void
188979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousovx86_64_sigreturn (unw_cursor_t *cursor)
189979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov{
190979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov  struct cursor *c = (struct cursor *) cursor;
1911e77c66a51102090f429087fccc28cb6c383cce5Konstantin Belousov  ucontext_t *uc = (ucontext_t *)(c->sigcontext_addr +
1921e77c66a51102090f429087fccc28cb6c383cce5Konstantin Belousov    offsetof(struct sigframe, sf_uc));
193979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov
194979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov  Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
195979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov	     (unsigned long long) c->dwarf.ip, uc);
196979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov  sigreturn(uc);
197f01a04371287037ca884ec16b4316edc2a08458cKonstantin Belousov  abort();
198979af4502fe19b0d98459633731d004a4a010a0eKonstantin Belousov}
1990dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov#endif
200