mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-22 16:20:29 +01:00
(Logical change 1.43)
This commit is contained in:
parent
b064eb4574
commit
e9e4e5fb29
12 changed files with 1233 additions and 0 deletions
|
@ -0,0 +1,58 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
|
||||||
|
int write, void *arg)
|
||||||
|
{
|
||||||
|
unw_word_t *wp = (unsigned long *) val;
|
||||||
|
struct UPT_info *ui = arg;
|
||||||
|
pid_t pid = ui->pid;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((unsigned) reg >= sizeof (_UPT_reg_offset) / sizeof (_UPT_reg_offset[0]))
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (write)
|
||||||
|
for (i = 0; i < sizeof (*val) / sizeof (wp[i]); ++i)
|
||||||
|
{
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg] + i * sizeof(wp[i]),
|
||||||
|
wp[i]);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (i = 0; i < sizeof (*val) / sizeof (wp[i]); ++i)
|
||||||
|
{
|
||||||
|
wp[i] = ptrace (PTRACE_PEEKUSER, pid,
|
||||||
|
_UPT_reg_offset[reg] + i * sizeof(wp[i]), 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
|
||||||
|
int write, void *arg)
|
||||||
|
{
|
||||||
|
struct UPT_info *ui = arg;
|
||||||
|
pid_t pid = ui->pid;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
debug (100, "_UPT_mem[%lx] <- %lx\n", __FUNCTION__, addr, *val);
|
||||||
|
ptrace (PTRACE_POKEDATA, pid, addr, *val);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*val = ptrace (PTRACE_PEEKDATA, pid, addr, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EINVAL;
|
||||||
|
debug (100, "%s: mem[%lx] -> %lx\n", __FUNCTION__, addr, *val);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
# include <elf.h>
|
||||||
|
# include <asm/ptrace_offsets.h>
|
||||||
|
# include "ia64/rse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
|
int write, void *arg)
|
||||||
|
{
|
||||||
|
struct UPT_info *ui = arg;
|
||||||
|
pid_t pid = ui->pid;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (write)
|
||||||
|
debug (100, "%s: %s <- %lx\n", __FUNCTION__ unw_regname (reg), *val);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
if ((unsigned) reg - UNW_IA64_NAT < 32)
|
||||||
|
{
|
||||||
|
unsigned long nat_bits, mask;
|
||||||
|
|
||||||
|
/* The Linux ptrace represents the statc NaT bits as a single word. */
|
||||||
|
mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT);
|
||||||
|
errno = 0;
|
||||||
|
nat_bits = ptrace (PTRACE_PEEKUSER, pid, PT_NAT_BITS, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
if (*val)
|
||||||
|
nat_bits |= mask;
|
||||||
|
else
|
||||||
|
nat_bits &= ~mask;
|
||||||
|
errno = 0;
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_NAT_BITS, nat_bits);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case UNW_REG_IP:
|
||||||
|
{
|
||||||
|
unsigned long ip, psr;
|
||||||
|
|
||||||
|
/* distribute bundle-addr. & slot-number across PT_IIP & PT_IPSR. */
|
||||||
|
errno = 0;
|
||||||
|
psr = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IPSR, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
ip = *val & ~0xfUL;
|
||||||
|
psr = (psr & ~0x3UL << 41) | (*val & 0x3);
|
||||||
|
errno = 0;
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_CR_IIP, ip);
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_CR_IPSR, psr);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
ip = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IIP, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
*val = ip + ((psr >> 41) & 0x3);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
case UNW_IA64_AR_BSPSTORE:
|
||||||
|
reg = UNW_IA64_AR_BSP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UNW_IA64_AR_BSP:
|
||||||
|
case UNW_IA64_BSP:
|
||||||
|
{
|
||||||
|
unsigned long sof, cfm, bsp;
|
||||||
|
|
||||||
|
/* Account for the fact that ptrace() expects bsp to point
|
||||||
|
_after_ the current register frame. */
|
||||||
|
errno = 0;
|
||||||
|
cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
sof = (cfm & 0x7f);
|
||||||
|
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
bsp = ia64_rse_skip_regs (*val, sof);
|
||||||
|
errno = 0;
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, bsp);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
*val = ia64_rse_skip_regs (bsp, -sof);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
case UNW_IA64_CFM:
|
||||||
|
/* If we change CFM, we need to adjust ptrace's notion of bsp
|
||||||
|
accordingly, so that the real bsp remains unchanged. */
|
||||||
|
if (write)
|
||||||
|
{
|
||||||
|
unsigned long new_sof, old_sof, cfm, bsp;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0);
|
||||||
|
cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
old_sof = (cfm & 0x7f);
|
||||||
|
new_sof = (*val & 0x7f);
|
||||||
|
if (old_sof != new_sof)
|
||||||
|
{
|
||||||
|
bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
|
||||||
|
errno = 0;
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, PT_CFM, *val);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((unsigned) reg >= sizeof (_UPT_reg_offset) / sizeof (_UPT_reg_offset[0]))
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (write)
|
||||||
|
ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg], *val);
|
||||||
|
else
|
||||||
|
*val = ptrace (PTRACE_PEEKUSER, pid, _UPT_reg_offset[reg], 0);
|
||||||
|
if (errno)
|
||||||
|
return -UNW_EBADREG;
|
||||||
|
|
||||||
|
out:
|
||||||
|
#if DEBUG
|
||||||
|
if (!write)
|
||||||
|
debug (100, "%s: %s -> %lx\n", __FUNCTION__ unw_regname (reg), *val);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
unw_accessors_t _UPT_accessors =
|
||||||
|
{
|
||||||
|
.find_proc_info = _UPT_find_proc_info,
|
||||||
|
.put_unwind_info = _UPT_put_unwind_info,
|
||||||
|
.get_dyn_info_list_addr = _UPT_get_dyn_info_list_addr,
|
||||||
|
.access_mem = _UPT_access_mem,
|
||||||
|
.access_reg = _UPT_access_reg,
|
||||||
|
.access_fpreg = _UPT_access_fpreg,
|
||||||
|
#if 0
|
||||||
|
.resume = _UPT_resume_single_block
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
_UPT_create (pid_t pid)
|
||||||
|
{
|
||||||
|
struct UPT_info *ui = malloc (sizeof (struct UPT_info));
|
||||||
|
|
||||||
|
if (!ui)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset (ui, 0, sizeof (*ui));
|
||||||
|
ui->pid = pid;
|
||||||
|
return ui;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
_UPT_destroy (void *ui)
|
||||||
|
{
|
||||||
|
free (ui);
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include <elf.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
static unw_word_t
|
||||||
|
find_gp (struct UPT_info *ui, Elf64_Phdr *pdyn, Elf64_Addr load_base)
|
||||||
|
{
|
||||||
|
Elf64_Off soff, str_soff;
|
||||||
|
Elf64_Ehdr *ehdr = ui->image;
|
||||||
|
Elf64_Shdr *shdr;
|
||||||
|
Elf64_Shdr *str_shdr;
|
||||||
|
Elf64_Addr gp = 0;
|
||||||
|
char *strtab;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pdyn)
|
||||||
|
{
|
||||||
|
/* If we have a PT_DYNAMIC program header, fetch the gp-value
|
||||||
|
from the DT_PLTGOT entry. */
|
||||||
|
Elf64_Dyn *dyn = (Elf64_Dyn *) (pdyn->p_offset + ui->image);
|
||||||
|
for (; dyn->d_tag != DT_NULL; ++dyn)
|
||||||
|
if (dyn->d_tag == DT_PLTGOT)
|
||||||
|
{
|
||||||
|
gp = (Elf64_Addr) dyn->d_un.d_ptr + load_base;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Without a PT_DYAMIC header, lets try to look for a non-empty .opd
|
||||||
|
section. If there is such a section, we know it's full of
|
||||||
|
function descriptors, and we can simply pick up the gp from the
|
||||||
|
second word of the first entry in this table. */
|
||||||
|
|
||||||
|
soff = ehdr->e_shoff;
|
||||||
|
str_soff = soff + (ehdr->e_shstrndx * ehdr->e_shentsize);
|
||||||
|
|
||||||
|
if (soff + ehdr->e_shnum * ehdr->e_shentsize > ui->image_size)
|
||||||
|
{
|
||||||
|
debug (1, "%s: section table outside of image? (%lu > %lu)", __FUNCTION__,
|
||||||
|
soff + ehdr->e_shnum * ehdr->e_shentsize, ui->image_size);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
shdr = (Elf64_Shdr *) ((char *) ui->image + soff);
|
||||||
|
str_shdr = (Elf64_Shdr *) ((char *) ui->image + str_soff);
|
||||||
|
strtab = (char *) ui->image + str_shdr->sh_offset;
|
||||||
|
for (i = 0; i < ehdr->e_shnum; ++i)
|
||||||
|
{
|
||||||
|
if (strcmp (strtab + shdr->sh_name, ".opd") == 0
|
||||||
|
&& shdr->sh_size >= 16)
|
||||||
|
{
|
||||||
|
gp = ((Elf64_Addr *) (ui->image + shdr->sh_offset))[1];
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
shdr = (Elf64_Shdr *) (((char *) shdr) + ehdr->e_shentsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug (100, "%s: image at %lx, gp = %lx\n", ui->image, gp);
|
||||||
|
return gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
elf64_valid_object (struct UPT_info *ui)
|
||||||
|
{
|
||||||
|
return memcmp (ui->image, ELFMAG, SELFMAG) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HIDDEN unw_dyn_info_t *
|
||||||
|
_UPTi_find_unwind_table (struct UPT_info *ui, unw_addr_space_t as,
|
||||||
|
char *path, unw_word_t segbase, unw_word_t mapoff)
|
||||||
|
{
|
||||||
|
Elf64_Phdr *phdr, *ptxt = NULL, *punw = NULL, *pdyn = NULL;
|
||||||
|
struct stat stat;
|
||||||
|
Elf64_Ehdr *ehdr;
|
||||||
|
int fd, i;
|
||||||
|
|
||||||
|
if (ui->image)
|
||||||
|
{
|
||||||
|
munmap (ui->image, ui->image_size);
|
||||||
|
ui->image = NULL;
|
||||||
|
ui->image_size = 0;
|
||||||
|
|
||||||
|
/* invalidate the cache: */
|
||||||
|
ui->di_cache.start_ip = ui->di_cache.end_ip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open (path, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (fstat (fd, &stat) < 0)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->image_size = stat.st_size;
|
||||||
|
ui->image = mmap (NULL, ui->image_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
close (fd);
|
||||||
|
if (ui->image == MAP_FAILED)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!elf64_valid_object (ui))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ehdr = ui->image;
|
||||||
|
phdr = (Elf64_Phdr *) ((char *) ui->image + ehdr->e_phoff);
|
||||||
|
|
||||||
|
for (i = 0; i < ehdr->e_phnum; ++i)
|
||||||
|
{
|
||||||
|
switch (phdr[i].p_type)
|
||||||
|
{
|
||||||
|
case PT_LOAD:
|
||||||
|
if (phdr[i].p_offset == mapoff)
|
||||||
|
ptxt = phdr + i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PT_IA_64_UNWIND:
|
||||||
|
punw = phdr + i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PT_DYNAMIC:
|
||||||
|
pdyn = phdr + i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ptxt || !punw)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ui->di_cache.start_ip = segbase;
|
||||||
|
ui->di_cache.end_ip = ui->di_cache.start_ip + ptxt->p_memsz;
|
||||||
|
ui->di_cache.gp = find_gp (ui, pdyn, segbase - ptxt->p_vaddr);
|
||||||
|
ui->di_cache.format = UNW_INFO_FORMAT_TABLE;
|
||||||
|
ui->di_cache.u.ti.name_ptr = 0;
|
||||||
|
ui->di_cache.u.ti.segbase = segbase;
|
||||||
|
ui->di_cache.u.ti.table_len = punw->p_memsz / sizeof (unw_word_t);
|
||||||
|
ui->di_cache.u.ti.table_data = (unw_word_t *)
|
||||||
|
((char *) ui->image + (punw->p_vaddr - ptxt->p_vaddr));
|
||||||
|
return &ui->di_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unw_dyn_info_t *
|
||||||
|
get_unwind_info (struct UPT_info *ui, unw_addr_space_t as,
|
||||||
|
unw_word_t ip, unw_proc_info_t *pi,
|
||||||
|
int need_unwind_info)
|
||||||
|
{
|
||||||
|
unsigned long segbase, hi, mapoff;
|
||||||
|
struct map_iterator mi;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
if (!ui->ktab.start_ip)
|
||||||
|
{
|
||||||
|
int ret = _Uia64_get_kernel_table (&ui->ktab);
|
||||||
|
if (ret < 0)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (ip >= ui->ktab.start_ip && ip < ui->ktab.end_ip)
|
||||||
|
return &ui->ktab;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ip >= ui->di_cache.start_ip && ip < ui->di_cache.end_ip)
|
||||||
|
return &ui->di_cache;
|
||||||
|
|
||||||
|
maps_init (&mi, ui->pid);
|
||||||
|
while (maps_next (&mi, &segbase, &hi, &mapoff, path))
|
||||||
|
{
|
||||||
|
if (ip >= segbase && ip < hi)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
maps_close (&mi);
|
||||||
|
|
||||||
|
if (ip < segbase || ip >= hi)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return _UPTi_find_unwind_table (ui, as, path, segbase, mapoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_UPT_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
|
||||||
|
int need_unwind_info, void *arg)
|
||||||
|
{
|
||||||
|
struct UPT_info *ui = arg;
|
||||||
|
unw_dyn_info_t *di;
|
||||||
|
|
||||||
|
di = get_unwind_info (ui, as, ip, pi, need_unwind_info);
|
||||||
|
if (!di)
|
||||||
|
return -UNW_ENOINFO;
|
||||||
|
|
||||||
|
return _Uia64_search_unwind_table (as, ip, di, pi, need_unwind_info, arg);
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
_UPT_get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dil_addr,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
unsigned long lo, hi, off;
|
||||||
|
struct UPT_info *ui = arg;
|
||||||
|
struct map_iterator mi;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
unw_dyn_info_t *di;
|
||||||
|
unw_word_t res;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (ui->checked_dyn_info_list_addr)
|
||||||
|
{
|
||||||
|
*dil_addr = ui->dyn_info_list_addr;
|
||||||
|
return *dil_addr ? 0 : -UNW_ENOINFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->checked_dyn_info_list_addr = 1;
|
||||||
|
|
||||||
|
maps_init (&mi, ui->pid);
|
||||||
|
while (maps_next (&mi, &lo, &hi, &off, path))
|
||||||
|
{
|
||||||
|
di = _UPTi_find_unwind_table (ui, as, path, lo, off);
|
||||||
|
if (di)
|
||||||
|
{
|
||||||
|
res = _Uia64_find_dyn_list (as, di->u.ti.table_data,
|
||||||
|
(di->u.ti.table_len
|
||||||
|
* sizeof (di->u.ti.table_data[0])),
|
||||||
|
di->u.ti.segbase, arg);
|
||||||
|
if (res && ++count == 0)
|
||||||
|
ui->dyn_info_list_addr = *dil_addr = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maps_close (&mi);
|
||||||
|
|
||||||
|
/* If multiple dynamic-info list addresses are found, we would have
|
||||||
|
to determine which was is the one actually in use (since the
|
||||||
|
dynamic name resolution algorithm will pick one "winner").
|
||||||
|
Perhaps we'd have to track them all until we find one that's
|
||||||
|
non-empty. Hopefully, this case simply will never arise, since
|
||||||
|
only libunwind defines the dynamic info list head. */
|
||||||
|
assert (count <= 1);
|
||||||
|
|
||||||
|
return (count > 0) ? 0 : -UNW_ENOINFO;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
#ifndef _UPT_internal_h
|
||||||
|
#define _UPT_internal_h
|
||||||
|
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
struct UPT_info
|
||||||
|
{
|
||||||
|
pid_t pid; /* the process-id of the child we're unwinding */
|
||||||
|
void *image; /* mmap'ped image of the child's executable */
|
||||||
|
size_t image_size; /* size of the image */
|
||||||
|
unw_dyn_info_t di_cache;
|
||||||
|
unw_word_t dyn_info_list_addr;
|
||||||
|
unsigned int checked_dyn_info_list_addr : 1;
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
unw_dyn_info_t ktab;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct map_iterator
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
};
|
||||||
|
|
||||||
|
HIDDEN int _UPT_reg_offset[UNW_REG_LAST];
|
||||||
|
|
||||||
|
extern HIDDEN unw_dyn_info_t *_UPTi_find_unwind_table (struct UPT_info *ui,
|
||||||
|
unw_addr_space_t as,
|
||||||
|
char *path,
|
||||||
|
unw_word_t segbase,
|
||||||
|
unw_word_t mapoff);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
maps_init (struct map_iterator *mi, pid_t pid)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf (path, sizeof (path), "/proc/%d/maps", pid);
|
||||||
|
mi->fp = fopen (path, "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
maps_next (struct map_iterator *mi,
|
||||||
|
unsigned long *low, unsigned long *high, unsigned long *offset,
|
||||||
|
char *path)
|
||||||
|
{
|
||||||
|
char line[256+PATH_MAX];
|
||||||
|
|
||||||
|
if (!mi->fp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (fgets (line, sizeof (line), mi->fp))
|
||||||
|
{
|
||||||
|
if (sscanf (line, "%lx-%lx %*4c %lx %*x:%*x %*d %s\n",
|
||||||
|
low, high, offset, path) == 4)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
maps_close (struct map_iterator *mi)
|
||||||
|
{
|
||||||
|
fclose (mi->fp);
|
||||||
|
mi->fp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _UPT_internal_h */
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
_UPT_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg)
|
||||||
|
{
|
||||||
|
if (!pi->unwind_info)
|
||||||
|
return;
|
||||||
|
free (pi->unwind_info);
|
||||||
|
pi->unwind_info = NULL;
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
# include <asm/ptrace_offsets.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int _UPT_reg_offset[UNW_REG_LAST] =
|
||||||
|
{
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
# ifndef PT_AR_CSD
|
||||||
|
# define PT_AR_CSD -1 /* this was introduced with rev 2.1 of ia64 */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
[UNW_IA64_GR + 0] = -1, [UNW_IA64_GR + 1] = PT_R1,
|
||||||
|
[UNW_IA64_GR + 2] = PT_R2, [UNW_IA64_GR + 3] = PT_R3,
|
||||||
|
[UNW_IA64_GR + 4] = PT_R4, [UNW_IA64_GR + 5] = PT_R5,
|
||||||
|
[UNW_IA64_GR + 6] = PT_R6, [UNW_IA64_GR + 7] = PT_R7,
|
||||||
|
[UNW_IA64_GR + 8] = PT_R8, [UNW_IA64_GR + 9] = PT_R9,
|
||||||
|
[UNW_IA64_GR + 10] = PT_R10, [UNW_IA64_GR + 11] = PT_R11,
|
||||||
|
[UNW_IA64_GR + 12] = PT_R12, [UNW_IA64_GR + 13] = PT_R13,
|
||||||
|
[UNW_IA64_GR + 14] = PT_R14, [UNW_IA64_GR + 15] = PT_R15,
|
||||||
|
[UNW_IA64_GR + 16] = PT_R16, [UNW_IA64_GR + 17] = PT_R17,
|
||||||
|
[UNW_IA64_GR + 18] = PT_R18, [UNW_IA64_GR + 19] = PT_R19,
|
||||||
|
[UNW_IA64_GR + 20] = PT_R20, [UNW_IA64_GR + 21] = PT_R21,
|
||||||
|
[UNW_IA64_GR + 22] = PT_R22, [UNW_IA64_GR + 23] = PT_R23,
|
||||||
|
[UNW_IA64_GR + 24] = PT_R24, [UNW_IA64_GR + 25] = PT_R25,
|
||||||
|
[UNW_IA64_GR + 26] = PT_R26, [UNW_IA64_GR + 27] = PT_R27,
|
||||||
|
[UNW_IA64_GR + 28] = PT_R28, [UNW_IA64_GR + 29] = PT_R29,
|
||||||
|
[UNW_IA64_GR + 30] = PT_R30, [UNW_IA64_GR + 31] = PT_R31,
|
||||||
|
|
||||||
|
[UNW_IA64_NAT+ 0] = -1, [UNW_IA64_NAT+ 1] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 2] = PT_NAT_BITS, [UNW_IA64_NAT+ 3] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 4] = PT_NAT_BITS, [UNW_IA64_NAT+ 5] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 6] = PT_NAT_BITS, [UNW_IA64_NAT+ 7] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 8] = PT_NAT_BITS, [UNW_IA64_NAT+ 9] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 10] = PT_NAT_BITS, [UNW_IA64_NAT+ 11] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 12] = PT_NAT_BITS, [UNW_IA64_NAT+ 13] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 14] = PT_NAT_BITS, [UNW_IA64_NAT+ 15] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 16] = PT_NAT_BITS, [UNW_IA64_NAT+ 17] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 18] = PT_NAT_BITS, [UNW_IA64_NAT+ 19] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 20] = PT_NAT_BITS, [UNW_IA64_NAT+ 21] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 22] = PT_NAT_BITS, [UNW_IA64_NAT+ 23] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 24] = PT_NAT_BITS, [UNW_IA64_NAT+ 25] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 26] = PT_NAT_BITS, [UNW_IA64_NAT+ 27] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 28] = PT_NAT_BITS, [UNW_IA64_NAT+ 29] = PT_NAT_BITS,
|
||||||
|
[UNW_IA64_NAT+ 30] = PT_NAT_BITS, [UNW_IA64_NAT+ 31] = PT_NAT_BITS,
|
||||||
|
|
||||||
|
[UNW_IA64_FR + 0] = -1, [UNW_IA64_FR + 1] = -1,
|
||||||
|
[UNW_IA64_FR + 2] = PT_F2, [UNW_IA64_FR + 3] = PT_F3,
|
||||||
|
[UNW_IA64_FR + 4] = PT_F4, [UNW_IA64_FR + 5] = PT_F5,
|
||||||
|
[UNW_IA64_FR + 6] = PT_F6, [UNW_IA64_FR + 7] = PT_F7,
|
||||||
|
[UNW_IA64_FR + 8] = PT_F8, [UNW_IA64_FR + 9] = PT_F9,
|
||||||
|
[UNW_IA64_FR + 10] = PT_F10, [UNW_IA64_FR + 11] = PT_F11,
|
||||||
|
[UNW_IA64_FR + 12] = PT_F12, [UNW_IA64_FR + 13] = PT_F13,
|
||||||
|
[UNW_IA64_FR + 14] = PT_F14, [UNW_IA64_FR + 15] = PT_F15,
|
||||||
|
[UNW_IA64_FR + 16] = PT_F16, [UNW_IA64_FR + 17] = PT_F17,
|
||||||
|
[UNW_IA64_FR + 18] = PT_F18, [UNW_IA64_FR + 19] = PT_F19,
|
||||||
|
[UNW_IA64_FR + 20] = PT_F20, [UNW_IA64_FR + 21] = PT_F21,
|
||||||
|
[UNW_IA64_FR + 22] = PT_F22, [UNW_IA64_FR + 23] = PT_F23,
|
||||||
|
[UNW_IA64_FR + 24] = PT_F24, [UNW_IA64_FR + 25] = PT_F25,
|
||||||
|
[UNW_IA64_FR + 26] = PT_F26, [UNW_IA64_FR + 27] = PT_F27,
|
||||||
|
[UNW_IA64_FR + 28] = PT_F28, [UNW_IA64_FR + 29] = PT_F29,
|
||||||
|
[UNW_IA64_FR + 30] = PT_F30, [UNW_IA64_FR + 31] = PT_F31,
|
||||||
|
[UNW_IA64_FR + 32] = PT_F32, [UNW_IA64_FR + 33] = PT_F33,
|
||||||
|
[UNW_IA64_FR + 34] = PT_F34, [UNW_IA64_FR + 35] = PT_F35,
|
||||||
|
[UNW_IA64_FR + 36] = PT_F36, [UNW_IA64_FR + 37] = PT_F37,
|
||||||
|
[UNW_IA64_FR + 38] = PT_F38, [UNW_IA64_FR + 39] = PT_F39,
|
||||||
|
[UNW_IA64_FR + 40] = PT_F40, [UNW_IA64_FR + 41] = PT_F41,
|
||||||
|
[UNW_IA64_FR + 42] = PT_F42, [UNW_IA64_FR + 43] = PT_F43,
|
||||||
|
[UNW_IA64_FR + 44] = PT_F44, [UNW_IA64_FR + 45] = PT_F45,
|
||||||
|
[UNW_IA64_FR + 46] = PT_F46, [UNW_IA64_FR + 47] = PT_F47,
|
||||||
|
[UNW_IA64_FR + 48] = PT_F48, [UNW_IA64_FR + 49] = PT_F49,
|
||||||
|
[UNW_IA64_FR + 50] = PT_F50, [UNW_IA64_FR + 51] = PT_F51,
|
||||||
|
[UNW_IA64_FR + 52] = PT_F52, [UNW_IA64_FR + 53] = PT_F53,
|
||||||
|
[UNW_IA64_FR + 54] = PT_F54, [UNW_IA64_FR + 55] = PT_F55,
|
||||||
|
[UNW_IA64_FR + 56] = PT_F56, [UNW_IA64_FR + 57] = PT_F57,
|
||||||
|
[UNW_IA64_FR + 58] = PT_F58, [UNW_IA64_FR + 59] = PT_F59,
|
||||||
|
[UNW_IA64_FR + 60] = PT_F60, [UNW_IA64_FR + 61] = PT_F61,
|
||||||
|
[UNW_IA64_FR + 62] = PT_F62, [UNW_IA64_FR + 63] = PT_F63,
|
||||||
|
[UNW_IA64_FR + 64] = PT_F64, [UNW_IA64_FR + 65] = PT_F65,
|
||||||
|
[UNW_IA64_FR + 66] = PT_F66, [UNW_IA64_FR + 67] = PT_F67,
|
||||||
|
[UNW_IA64_FR + 68] = PT_F68, [UNW_IA64_FR + 69] = PT_F69,
|
||||||
|
[UNW_IA64_FR + 70] = PT_F70, [UNW_IA64_FR + 71] = PT_F71,
|
||||||
|
[UNW_IA64_FR + 72] = PT_F72, [UNW_IA64_FR + 73] = PT_F73,
|
||||||
|
[UNW_IA64_FR + 74] = PT_F74, [UNW_IA64_FR + 75] = PT_F75,
|
||||||
|
[UNW_IA64_FR + 76] = PT_F76, [UNW_IA64_FR + 77] = PT_F77,
|
||||||
|
[UNW_IA64_FR + 78] = PT_F78, [UNW_IA64_FR + 79] = PT_F79,
|
||||||
|
[UNW_IA64_FR + 80] = PT_F80, [UNW_IA64_FR + 81] = PT_F81,
|
||||||
|
[UNW_IA64_FR + 82] = PT_F82, [UNW_IA64_FR + 83] = PT_F83,
|
||||||
|
[UNW_IA64_FR + 84] = PT_F84, [UNW_IA64_FR + 85] = PT_F85,
|
||||||
|
[UNW_IA64_FR + 86] = PT_F86, [UNW_IA64_FR + 87] = PT_F87,
|
||||||
|
[UNW_IA64_FR + 88] = PT_F88, [UNW_IA64_FR + 89] = PT_F89,
|
||||||
|
[UNW_IA64_FR + 90] = PT_F90, [UNW_IA64_FR + 91] = PT_F91,
|
||||||
|
[UNW_IA64_FR + 92] = PT_F92, [UNW_IA64_FR + 93] = PT_F93,
|
||||||
|
[UNW_IA64_FR + 94] = PT_F94, [UNW_IA64_FR + 95] = PT_F95,
|
||||||
|
[UNW_IA64_FR + 96] = PT_F96, [UNW_IA64_FR + 97] = PT_F97,
|
||||||
|
[UNW_IA64_FR + 98] = PT_F98, [UNW_IA64_FR + 99] = PT_F99,
|
||||||
|
[UNW_IA64_FR +100] = PT_F100, [UNW_IA64_FR +101] = PT_F101,
|
||||||
|
[UNW_IA64_FR +102] = PT_F102, [UNW_IA64_FR +103] = PT_F103,
|
||||||
|
[UNW_IA64_FR +104] = PT_F104, [UNW_IA64_FR +105] = PT_F105,
|
||||||
|
[UNW_IA64_FR +106] = PT_F106, [UNW_IA64_FR +107] = PT_F107,
|
||||||
|
[UNW_IA64_FR +108] = PT_F108, [UNW_IA64_FR +109] = PT_F109,
|
||||||
|
[UNW_IA64_FR +110] = PT_F110, [UNW_IA64_FR +111] = PT_F111,
|
||||||
|
[UNW_IA64_FR +112] = PT_F112, [UNW_IA64_FR +113] = PT_F113,
|
||||||
|
[UNW_IA64_FR +114] = PT_F114, [UNW_IA64_FR +115] = PT_F115,
|
||||||
|
[UNW_IA64_FR +116] = PT_F116, [UNW_IA64_FR +117] = PT_F117,
|
||||||
|
[UNW_IA64_FR +118] = PT_F118, [UNW_IA64_FR +119] = PT_F119,
|
||||||
|
[UNW_IA64_FR +120] = PT_F120, [UNW_IA64_FR +121] = PT_F121,
|
||||||
|
[UNW_IA64_FR +122] = PT_F122, [UNW_IA64_FR +123] = PT_F123,
|
||||||
|
[UNW_IA64_FR +124] = PT_F124, [UNW_IA64_FR +125] = PT_F125,
|
||||||
|
[UNW_IA64_FR +126] = PT_F126, [UNW_IA64_FR +127] = PT_F127,
|
||||||
|
|
||||||
|
[UNW_IA64_AR + 0] = -1, [UNW_IA64_AR + 1] = -1,
|
||||||
|
[UNW_IA64_AR + 2] = -1, [UNW_IA64_AR + 3] = -1,
|
||||||
|
[UNW_IA64_AR + 4] = -1, [UNW_IA64_AR + 5] = -1,
|
||||||
|
[UNW_IA64_AR + 6] = -1, [UNW_IA64_AR + 7] = -1,
|
||||||
|
[UNW_IA64_AR + 8] = -1, [UNW_IA64_AR + 9] = -1,
|
||||||
|
[UNW_IA64_AR + 10] = -1, [UNW_IA64_AR + 11] = -1,
|
||||||
|
[UNW_IA64_AR + 12] = -1, [UNW_IA64_AR + 13] = -1,
|
||||||
|
[UNW_IA64_AR + 14] = -1, [UNW_IA64_AR + 15] = -1,
|
||||||
|
[UNW_IA64_AR + 16] = PT_AR_RSC, [UNW_IA64_AR + 17] = PT_AR_BSP,
|
||||||
|
[UNW_IA64_AR + 18] = PT_AR_BSPSTORE,[UNW_IA64_AR + 19] = PT_AR_RNAT,
|
||||||
|
[UNW_IA64_AR + 20] = -1, [UNW_IA64_AR + 21] = -1,
|
||||||
|
[UNW_IA64_AR + 22] = -1, [UNW_IA64_AR + 23] = -1,
|
||||||
|
[UNW_IA64_AR + 24] = -1, [UNW_IA64_AR + 25] = PT_AR_CSD,
|
||||||
|
[UNW_IA64_AR + 26] = -1, [UNW_IA64_AR + 27] = -1,
|
||||||
|
[UNW_IA64_AR + 28] = -1, [UNW_IA64_AR + 29] = -1,
|
||||||
|
[UNW_IA64_AR + 30] = -1, [UNW_IA64_AR + 31] = -1,
|
||||||
|
[UNW_IA64_AR + 32] = PT_AR_CCV, [UNW_IA64_AR + 33] = -1,
|
||||||
|
[UNW_IA64_AR + 34] = -1, [UNW_IA64_AR + 35] = -1,
|
||||||
|
[UNW_IA64_AR + 36] = PT_AR_UNAT, [UNW_IA64_AR + 37] = -1,
|
||||||
|
[UNW_IA64_AR + 38] = -1, [UNW_IA64_AR + 39] = -1,
|
||||||
|
[UNW_IA64_AR + 40] = PT_AR_FPSR, [UNW_IA64_AR + 41] = -1,
|
||||||
|
[UNW_IA64_AR + 42] = -1, [UNW_IA64_AR + 43] = -1,
|
||||||
|
[UNW_IA64_AR + 44] = -1, [UNW_IA64_AR + 45] = -1,
|
||||||
|
[UNW_IA64_AR + 46] = -1, [UNW_IA64_AR + 47] = -1,
|
||||||
|
[UNW_IA64_AR + 48] = -1, [UNW_IA64_AR + 49] = -1,
|
||||||
|
[UNW_IA64_AR + 50] = -1, [UNW_IA64_AR + 51] = -1,
|
||||||
|
[UNW_IA64_AR + 52] = -1, [UNW_IA64_AR + 53] = -1,
|
||||||
|
[UNW_IA64_AR + 54] = -1, [UNW_IA64_AR + 55] = -1,
|
||||||
|
[UNW_IA64_AR + 56] = -1, [UNW_IA64_AR + 57] = -1,
|
||||||
|
[UNW_IA64_AR + 58] = -1, [UNW_IA64_AR + 59] = -1,
|
||||||
|
[UNW_IA64_AR + 60] = -1, [UNW_IA64_AR + 61] = -1,
|
||||||
|
[UNW_IA64_AR + 62] = -1, [UNW_IA64_AR + 63] = -1,
|
||||||
|
[UNW_IA64_AR + 64] = PT_AR_PFS, [UNW_IA64_AR + 65] = PT_AR_LC,
|
||||||
|
[UNW_IA64_AR + 66] = PT_AR_EC, [UNW_IA64_AR + 67] = -1,
|
||||||
|
[UNW_IA64_AR + 68] = -1, [UNW_IA64_AR + 69] = -1,
|
||||||
|
[UNW_IA64_AR + 70] = -1, [UNW_IA64_AR + 71] = -1,
|
||||||
|
[UNW_IA64_AR + 72] = -1, [UNW_IA64_AR + 73] = -1,
|
||||||
|
[UNW_IA64_AR + 74] = -1, [UNW_IA64_AR + 75] = -1,
|
||||||
|
[UNW_IA64_AR + 76] = -1, [UNW_IA64_AR + 77] = -1,
|
||||||
|
[UNW_IA64_AR + 78] = -1, [UNW_IA64_AR + 79] = -1,
|
||||||
|
[UNW_IA64_AR + 80] = -1, [UNW_IA64_AR + 81] = -1,
|
||||||
|
[UNW_IA64_AR + 82] = -1, [UNW_IA64_AR + 83] = -1,
|
||||||
|
[UNW_IA64_AR + 84] = -1, [UNW_IA64_AR + 85] = -1,
|
||||||
|
[UNW_IA64_AR + 86] = -1, [UNW_IA64_AR + 87] = -1,
|
||||||
|
[UNW_IA64_AR + 88] = -1, [UNW_IA64_AR + 89] = -1,
|
||||||
|
[UNW_IA64_AR + 90] = -1, [UNW_IA64_AR + 91] = -1,
|
||||||
|
[UNW_IA64_AR + 92] = -1, [UNW_IA64_AR + 93] = -1,
|
||||||
|
[UNW_IA64_AR + 94] = -1, [UNW_IA64_AR + 95] = -1,
|
||||||
|
[UNW_IA64_AR + 96] = -1, [UNW_IA64_AR + 97] = -1,
|
||||||
|
[UNW_IA64_AR + 98] = -1, [UNW_IA64_AR + 99] = -1,
|
||||||
|
[UNW_IA64_AR +100] = -1, [UNW_IA64_AR +101] = -1,
|
||||||
|
[UNW_IA64_AR +102] = -1, [UNW_IA64_AR +103] = -1,
|
||||||
|
[UNW_IA64_AR +104] = -1, [UNW_IA64_AR +105] = -1,
|
||||||
|
[UNW_IA64_AR +106] = -1, [UNW_IA64_AR +107] = -1,
|
||||||
|
[UNW_IA64_AR +108] = -1, [UNW_IA64_AR +109] = -1,
|
||||||
|
[UNW_IA64_AR +110] = -1, [UNW_IA64_AR +111] = -1,
|
||||||
|
[UNW_IA64_AR +112] = -1, [UNW_IA64_AR +113] = -1,
|
||||||
|
[UNW_IA64_AR +114] = -1, [UNW_IA64_AR +115] = -1,
|
||||||
|
[UNW_IA64_AR +116] = -1, [UNW_IA64_AR +117] = -1,
|
||||||
|
[UNW_IA64_AR +118] = -1, [UNW_IA64_AR +119] = -1,
|
||||||
|
[UNW_IA64_AR +120] = -1, [UNW_IA64_AR +121] = -1,
|
||||||
|
[UNW_IA64_AR +122] = -1, [UNW_IA64_AR +123] = -1,
|
||||||
|
[UNW_IA64_AR +124] = -1, [UNW_IA64_AR +125] = -1,
|
||||||
|
[UNW_IA64_AR +126] = -1, [UNW_IA64_AR +127] = -1,
|
||||||
|
|
||||||
|
[UNW_IA64_BR + 0] = PT_B0, [UNW_IA64_BR + 1] = PT_B1,
|
||||||
|
[UNW_IA64_BR + 2] = PT_B2, [UNW_IA64_BR + 3] = PT_B3,
|
||||||
|
[UNW_IA64_BR + 4] = PT_B4, [UNW_IA64_BR + 5] = PT_B5,
|
||||||
|
[UNW_IA64_BR + 6] = PT_B6, [UNW_IA64_BR + 7] = PT_B7,
|
||||||
|
|
||||||
|
[UNW_IA64_PR] = PT_PR,
|
||||||
|
[UNW_IA64_CFM] = PT_CFM,
|
||||||
|
[UNW_IA64_IP] = PT_CR_IIP
|
||||||
|
#else
|
||||||
|
# error Fix me.
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -0,0 +1,178 @@
|
||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2003 Hewlett-Packard Co
|
||||||
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
int nerrors;
|
||||||
|
int verbose = 1;
|
||||||
|
|
||||||
|
#define panic(args...) \
|
||||||
|
do { fprintf (stderr, args); ++nerrors; } while (0)
|
||||||
|
|
||||||
|
static unw_addr_space_t as;
|
||||||
|
|
||||||
|
void
|
||||||
|
do_backtrace (pid_t target_pid)
|
||||||
|
{
|
||||||
|
unw_proc_info_t pi;
|
||||||
|
unw_word_t ip, sp;
|
||||||
|
unw_cursor_t c;
|
||||||
|
char buf[512];
|
||||||
|
int ret;
|
||||||
|
struct UPT_info *ui;
|
||||||
|
|
||||||
|
ui = _UPT_create (target_pid);
|
||||||
|
ret = unw_init_remote (&c, as, ui);
|
||||||
|
if (ret < 0)
|
||||||
|
panic ("unw_init_remote() failed: ret=%d\n", ret);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unw_get_reg (&c, UNW_REG_IP, &ip);
|
||||||
|
unw_get_reg (&c, UNW_REG_SP, &sp);
|
||||||
|
unw_get_proc_name (&c, buf, sizeof (buf));
|
||||||
|
|
||||||
|
printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
|
||||||
|
|
||||||
|
unw_get_proc_info (&c, &pi);
|
||||||
|
printf ("\tproc=%016lx-%016lx\n\thandler=%lx lsda=%lx",
|
||||||
|
(long) pi.start_ip, (long) pi.end_ip,
|
||||||
|
(long) pi.handler, (long) pi.lsda);
|
||||||
|
|
||||||
|
#if UNW_TARGET_IA64
|
||||||
|
{
|
||||||
|
unw_word_t bsp;
|
||||||
|
|
||||||
|
unw_get_reg (&c, UNW_IA64_BSP, &bsp);
|
||||||
|
printf (" bsp=%lx", bsp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
|
ret = unw_step (&c);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
unw_get_reg (&c, UNW_REG_IP, &ip);
|
||||||
|
printf ("FAILURE: unw_step() returned %d for ip=%lx\n",
|
||||||
|
ret, (long) ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ret > 0);
|
||||||
|
|
||||||
|
_UPT_destroy (ui);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
panic ("unwind failed with ret=%d\n", ret);
|
||||||
|
|
||||||
|
printf ("================\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int status, pid, state = 1;
|
||||||
|
pid_t target_pid;
|
||||||
|
|
||||||
|
as = unw_create_addr_space (&_UPT_accessors, 0);
|
||||||
|
if (!as)
|
||||||
|
panic ("unw_create_addr_space() failed");
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
char *args[] = { "self", "/bin/ls", "/usr", NULL };
|
||||||
|
|
||||||
|
/* automated test case */
|
||||||
|
verbose = 0;
|
||||||
|
argv = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_pid = fork ();
|
||||||
|
if (!target_pid)
|
||||||
|
{
|
||||||
|
/* child */
|
||||||
|
|
||||||
|
if (!verbose)
|
||||||
|
dup2 (open ("/dev/null", O_WRONLY), 1);
|
||||||
|
|
||||||
|
ptrace (PTRACE_TRACEME, 0, 0, 0);
|
||||||
|
execve (argv[1], argv + 1, environ);
|
||||||
|
_exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pid = wait4 (-1, &status, 0, 0);
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
panic ("wait4() failed (errno=%d)\n", errno);
|
||||||
|
}
|
||||||
|
if (WIFSIGNALED (status) || WIFEXITED (status)
|
||||||
|
|| (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP))
|
||||||
|
{
|
||||||
|
if (WIFEXITED (status))
|
||||||
|
{
|
||||||
|
if (WEXITSTATUS (status) != 0)
|
||||||
|
panic ("child's exit status %d\n", WEXITSTATUS (status));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (WIFSIGNALED (status))
|
||||||
|
panic ("child terminated by signal %d\n", WTERMSIG (status));
|
||||||
|
else
|
||||||
|
panic ("child got signal %d\n", WSTOPSIG (status));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (!state)
|
||||||
|
do_backtrace (target_pid);
|
||||||
|
|
||||||
|
state ^= 1;
|
||||||
|
ptrace (PTRACE_SYSCALL, target_pid, 0, 0); /* continue */
|
||||||
|
#else
|
||||||
|
do_backtrace (target_pid);
|
||||||
|
ptrace (PTRACE_SINGLESTEP, target_pid, 0, 0); /* continue */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nerrors)
|
||||||
|
{
|
||||||
|
printf ("FAILURE: detected %d errors\n", nerrors);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if (verbose)
|
||||||
|
printf ("SUCCESS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue