mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-26 09:07:38 +01:00
(unw_search_ia64_unwind_table): Always return unwind_info in the
local case since it's trivial to do so and saves us time if later on we need to build a script for that procedure. 2005/02/23 14:40:44-08:00 mostang.com!davidm Adjust for sigset_t to intrmask_t renaming. 2004/10/25 05:21:51-07:00 hp.com!davidm (unw_search_ia64_unwind_table): Clarify comment and add a Debug() statement for the case where we find a bad unwind-header version. (Logical change 1.290)
This commit is contained in:
parent
f9b8ba0d47
commit
6fc50d4ed6
1 changed files with 25 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
||||||
/* libunwind - a platform-independent unwind library
|
/* libunwind - a platform-independent unwind library
|
||||||
Copyright (c) 2001-2004 Hewlett-Packard Development Company, L.P.
|
Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P.
|
||||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
This file is part of libunwind.
|
This file is part of libunwind.
|
||||||
|
@ -255,7 +255,7 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||||
unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
|
unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
|
||||||
const struct ia64_table_entry *e = NULL;
|
const struct ia64_table_entry *e = NULL;
|
||||||
unw_word_t handler_offset, segbase = 0;
|
unw_word_t handler_offset, segbase = 0;
|
||||||
int ret;
|
int ret, is_local;
|
||||||
|
|
||||||
assert ((di->format == UNW_INFO_FORMAT_TABLE
|
assert ((di->format == UNW_INFO_FORMAT_TABLE
|
||||||
|| di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
|
|| di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
|
||||||
|
@ -305,20 +305,33 @@ unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||||
hdr_addr = e->info_offset + segbase;
|
hdr_addr = e->info_offset + segbase;
|
||||||
info_addr = hdr_addr + 8;
|
info_addr = hdr_addr + 8;
|
||||||
|
|
||||||
/* read the header word: */
|
/* Read the header word. Note: the actual unwind-info is always
|
||||||
|
assumed to reside in memory, independent of whether di->format is
|
||||||
|
UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE. */
|
||||||
|
|
||||||
if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0)
|
if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (IA64_UNW_VER (hdr) != 1)
|
if (IA64_UNW_VER (hdr) != 1)
|
||||||
return -UNW_EBADVERSION;
|
{
|
||||||
|
Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n",
|
||||||
|
IA64_UNW_VER (hdr), (unsigned long) hdr,
|
||||||
|
(unsigned long) hdr_addr);
|
||||||
|
return -UNW_EBADVERSION;
|
||||||
|
}
|
||||||
|
|
||||||
info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr);
|
info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr);
|
||||||
|
|
||||||
if (need_unwind_info)
|
is_local = is_local_addr_space (as);
|
||||||
|
|
||||||
|
/* If we must have the unwind-info, return it. Also, if we are in
|
||||||
|
the local address-space, return the unwind-info because it's so
|
||||||
|
cheap to do so and it may come in handy later on. */
|
||||||
|
if (need_unwind_info || is_local)
|
||||||
{
|
{
|
||||||
pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr);
|
pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr);
|
||||||
|
|
||||||
if (is_local_addr_space (as))
|
if (is_local)
|
||||||
pi->unwind_info = (void *) (uintptr_t) info_addr;
|
pi->unwind_info = (void *) (uintptr_t) info_addr;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -606,12 +619,12 @@ check_callback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||||
static inline int
|
static inline int
|
||||||
validate_cache (unw_addr_space_t as)
|
validate_cache (unw_addr_space_t as)
|
||||||
{
|
{
|
||||||
sigset_t saved_sigmask;
|
intrmask_t saved_mask;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
|
sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
|
||||||
ret = dl_iterate_phdr (check_callback, as);
|
ret = dl_iterate_phdr (check_callback, as);
|
||||||
sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
|
sigprocmask (SIG_SETMASK, &saved_mask, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,14 +648,14 @@ tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
|
||||||
{
|
{
|
||||||
# if defined(HAVE_DL_ITERATE_PHDR)
|
# if defined(HAVE_DL_ITERATE_PHDR)
|
||||||
unw_dyn_info_t di, *dip = &di;
|
unw_dyn_info_t di, *dip = &di;
|
||||||
sigset_t saved_sigmask;
|
intrmask_t saved_mask;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
di.u.ti.segbase = ip; /* this is cheap... */
|
di.u.ti.segbase = ip; /* this is cheap... */
|
||||||
|
|
||||||
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, &saved_sigmask);
|
sigprocmask (SIG_SETMASK, &unwi_full_mask, &saved_mask);
|
||||||
ret = dl_iterate_phdr (callback, &di);
|
ret = dl_iterate_phdr (callback, &di);
|
||||||
sigprocmask (SIG_SETMASK, &saved_sigmask, NULL);
|
sigprocmask (SIG_SETMASK, &saved_mask, NULL);
|
||||||
|
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue