mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-23 20:03:43 +01:00
(x86_64_local_resume): Fix missing "H" typo.
2004/11/30 22:44:47-08:00 mostang.com!davidm (my_rt_sigreturn): New function. (x86_64_local_resume): Use my_rt_sigreturn(). The normal sigreturn() does nothing (returns with an error). 2004/11/23 18:01:09-08:00 mostang.com!davidm (x86_64_local_resume): Provide a minimal implementation (a la x86). (establish_machine_state): Fix off-by-one error. (Logical change 1.290)
This commit is contained in:
parent
5d8b2e3415
commit
a9cad72ed4
1 changed files with 44 additions and 2 deletions
|
@ -31,10 +31,52 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
#ifndef UNW_REMOTE_ONLY
|
#ifndef UNW_REMOTE_ONLY
|
||||||
|
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
/* sigreturn() is a no-op on x86_64 glibc. */
|
||||||
|
|
||||||
|
static NORETURN inline long
|
||||||
|
my_rt_sigreturn (void *new_sp)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__ ("mov %0, %%rsp;"
|
||||||
|
"mov %1, %%rax;"
|
||||||
|
"syscall"
|
||||||
|
:: "r"(new_sp), "i"(SYS_rt_sigreturn)
|
||||||
|
: "memory");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
HIDDEN inline int
|
HIDDEN inline int
|
||||||
x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||||
{
|
{
|
||||||
|
#if defined(__linux)
|
||||||
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
|
ucontext_t *uc = c->dwarf.as_arg;
|
||||||
|
|
||||||
|
/* Ensure c->pi is up-to-date. On x86-64, it's relatively common to
|
||||||
|
be missing DWARF unwind info. We don't want to fail in that
|
||||||
|
case, because the frame-chain still would let us do a backtrace
|
||||||
|
at least. */
|
||||||
|
dwarf_make_proc_info (&c->dwarf);
|
||||||
|
|
||||||
|
if (unlikely (c->sigcontext_format != X86_64_SCF_NONE))
|
||||||
|
{
|
||||||
|
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||||
|
|
||||||
|
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||||
|
(unsigned long long) c->dwarf.ip, sc);
|
||||||
|
my_rt_sigreturn (sc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug (8, "resuming at ip=%llx via setcontext()\n",
|
||||||
|
(unsigned long long) c->dwarf.ip);
|
||||||
|
setcontext (uc);
|
||||||
|
}
|
||||||
|
#else
|
||||||
# warning Implement me!
|
# warning Implement me!
|
||||||
|
#endif
|
||||||
|
return -UNW_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !UNW_REMOTE_ONLY */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -60,9 +102,9 @@ establish_machine_state (struct cursor *c)
|
||||||
|
|
||||||
Debug (8, "copying out cursor state\n");
|
Debug (8, "copying out cursor state\n");
|
||||||
|
|
||||||
for (reg = 0; reg < UNW_REG_LAST; ++reg)
|
for (reg = 0; reg <= UNW_REG_LAST; ++reg)
|
||||||
{
|
{
|
||||||
Debug (8, "copying %s %d\n", unw_regname (reg), reg);
|
Debug (16, "copying %s %d\n", unw_regname (reg), reg);
|
||||||
if (unw_is_fpreg (reg))
|
if (unw_is_fpreg (reg))
|
||||||
{
|
{
|
||||||
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
|
if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0)
|
||||||
|
|
Loading…
Reference in a new issue