mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-05 17:24:30 +01:00
(get_script_cache): Fix typo in Debug() statement (missing argument).
(put_script_cache): Fix typo in argument name. 2005/04/07 12:19:38-07:00 hp.com!davidm (ia64_get_cache_proc_info): Move it to near the end of the file. (script_init): Also call ia64_fetch_proc_info() if the script was found in the cache but it's empty (count == 0 and NULL unwind_info pointer). Also invoke build_script() if script has no instructions yet (count==0). Add assertion to ensure that build_script() never returns an empty script. (ia64_cache_proc_info): New function to cache the proc_info only. 2005/02/23 14:40:44-08:00 mostang.com!davidm Adjust for sigset_t to intrmask_t renaming. 2005/02/23 13:10:05-08:00 mostang.com!davidm Adjust for "ia64_rse" to "rse" prefix change. (Logical change 1.290)
This commit is contained in:
parent
847e0a4b18
commit
23405d02ec
1 changed files with 93 additions and 46 deletions
|
@ -1,5 +1,5 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2001-2004 Hewlett-Packard Co
|
||||
Copyright (C) 2001-2005 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of libunwind.
|
||||
|
@ -38,7 +38,7 @@ enum ia64_script_insn_opcode
|
|||
IA64_INSN_MOVE, /* s[dst] = s[val] */
|
||||
IA64_INSN_MOVE_NAT, /* like above, but with NaT info */
|
||||
IA64_INSN_MOVE_NO_NAT, /* like above, but clear NaT info */
|
||||
IA64_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp_loc, val) */
|
||||
IA64_INSN_MOVE_STACKED, /* s[dst] = rse_skip(*s.bsp_loc, val) */
|
||||
IA64_INSN_MOVE_STACKED_NAT, /* like above, but with NaT info */
|
||||
IA64_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */
|
||||
IA64_INSN_MOVE_SCRATCH_NAT, /* like above, but with NaT info */
|
||||
|
@ -93,7 +93,7 @@ flush_script_cache (struct ia64_script_cache *cache)
|
|||
}
|
||||
|
||||
static inline struct ia64_script_cache *
|
||||
get_script_cache (unw_addr_space_t as, sigset_t *saved_sigmaskp)
|
||||
get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
|
||||
{
|
||||
struct ia64_script_cache *cache = &as->global_cache;
|
||||
unw_caching_policy_t caching = as->caching_policy;
|
||||
|
@ -101,24 +101,28 @@ get_script_cache (unw_addr_space_t as, sigset_t *saved_sigmaskp)
|
|||
if (caching == UNW_CACHE_NONE)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE___THREAD
|
||||
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
||||
cache = &ia64_per_thread_cache;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATOMIC_OPS_H
|
||||
if (AO_test_and_set (&cache->busy) == AO_TS_SET)
|
||||
#if defined(__linux) && defined(__KERNEL__)
|
||||
if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
|
||||
return NULL;
|
||||
#else
|
||||
sigprocmask (SIG_SETMASK, &unwi_full_sigmask, saved_sigmaskp);
|
||||
# ifdef HAVE___THREAD
|
||||
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
||||
cache = &ia64_per_thread_cache;
|
||||
# endif
|
||||
# ifdef HAVE_ATOMIC_OPS_H
|
||||
if (AO_test_and_set (&cache->busy) == AO_TS_SET)
|
||||
return NULL;
|
||||
# else
|
||||
sigprocmask (SIG_SETMASK, &unwi_full_mask, saved_maskp);
|
||||
if (likely (caching == UNW_CACHE_GLOBAL))
|
||||
{
|
||||
Debug (16, "%s: acquiring lock\n");
|
||||
Debug (16, "%s: acquiring lock\n", __FUNCTION__);
|
||||
mutex_lock (&cache->lock);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (as->cache_generation != cache->generation)
|
||||
if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
|
||||
{
|
||||
flush_script_cache (cache);
|
||||
cache->generation = as->cache_generation;
|
||||
|
@ -128,17 +132,21 @@ get_script_cache (unw_addr_space_t as, sigset_t *saved_sigmaskp)
|
|||
|
||||
static inline void
|
||||
put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache,
|
||||
sigset_t *saved_sigmaskp)
|
||||
intrmask_t *saved_maskp)
|
||||
{
|
||||
assert (as->caching_policy != UNW_CACHE_NONE);
|
||||
|
||||
Debug (16, "unmasking signals/releasing lock\n");
|
||||
#ifdef HAVE_ATOMIC_OPS_H
|
||||
AO_CLEAR (&cache->busy);
|
||||
Debug (16, "unmasking signals/interrupts and releasing lock\n");
|
||||
#if defined(__linux) && defined(__KERNEL__)
|
||||
spin_unlock_irqrestore (&cache->busy, *saved_maskp);
|
||||
#else
|
||||
# ifdef HAVE_ATOMIC_OPS_H
|
||||
AO_CLEAR (&cache->busy);
|
||||
# else
|
||||
if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
|
||||
mutex_unlock (&cache->lock);
|
||||
sigprocmask (SIG_SETMASK, saved_sigmaskp, NULL);
|
||||
sigprocmask (SIG_SETMASK, saved_maskp, NULL);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -175,25 +183,6 @@ script_lookup (struct ia64_script_cache *cache, struct cursor *c)
|
|||
}
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
ia64_get_cached_proc_info (struct cursor *c)
|
||||
{
|
||||
struct ia64_script_cache *cache;
|
||||
struct ia64_script *script;
|
||||
sigset_t saved_sigmask;
|
||||
|
||||
cache = get_script_cache (c->as, &saved_sigmask);
|
||||
if (!cache)
|
||||
return -UNW_ENOINFO; /* cache is busy */
|
||||
{
|
||||
script = script_lookup (cache, c);
|
||||
if (script)
|
||||
c->pi = script->pi;
|
||||
}
|
||||
put_script_cache (c->as, cache, &saved_sigmask);
|
||||
return script ? 0 : -UNW_ENOINFO;
|
||||
}
|
||||
|
||||
static inline void
|
||||
script_init (struct ia64_script *script, unw_word_t ip)
|
||||
{
|
||||
|
@ -614,8 +603,7 @@ run_script (struct ia64_script *script, struct cursor *c)
|
|||
if ((ret = ia64_get_stacked (c, val, &loc, &nat_loc)) < 0)
|
||||
return ret;
|
||||
assert (!IA64_IS_REG_LOC (loc));
|
||||
set_nat_info (c, dst,
|
||||
nat_loc, ia64_rse_slot_num (IA64_GET_ADDR (loc)));
|
||||
set_nat_info (c, dst, nat_loc, rse_slot_num (IA64_GET_ADDR (loc)));
|
||||
break;
|
||||
|
||||
case IA64_INSN_MOVE_SCRATCH_NAT:
|
||||
|
@ -655,13 +643,13 @@ ia64_find_save_locs (struct cursor *c)
|
|||
{
|
||||
struct ia64_script_cache *cache = NULL;
|
||||
struct ia64_script *script = NULL;
|
||||
sigset_t saved_sigmask;
|
||||
intrmask_t saved_mask;
|
||||
int ret = 0;
|
||||
|
||||
if (c->as->caching_policy == UNW_CACHE_NONE)
|
||||
return uncached_find_save_locs (c);
|
||||
|
||||
cache = get_script_cache (c->as, &saved_sigmask);
|
||||
cache = get_script_cache (c->as, &saved_mask);
|
||||
if (!cache)
|
||||
{
|
||||
Debug (1, "contention on script-cache; doing uncached lookup\n");
|
||||
|
@ -671,11 +659,15 @@ ia64_find_save_locs (struct cursor *c)
|
|||
script = script_lookup (cache, c);
|
||||
Debug (8, "ip %lx %s in script cache\n", (long) c->ip,
|
||||
script ? "hit" : "missed");
|
||||
if (!script)
|
||||
|
||||
if (!script || (script->count == 0 && !script->pi.unwind_info))
|
||||
{
|
||||
if ((ret = ia64_fetch_proc_info (c, c->ip, 1)) < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!script)
|
||||
{
|
||||
script = script_new (cache, c->ip);
|
||||
if (!script)
|
||||
{
|
||||
|
@ -683,10 +675,14 @@ ia64_find_save_locs (struct cursor *c)
|
|||
ret = -UNW_EUNSPEC;
|
||||
goto out;
|
||||
}
|
||||
cache->buckets[c->prev_script].hint = script - cache->buckets;
|
||||
|
||||
ret = build_script (c, script);
|
||||
}
|
||||
cache->buckets[c->prev_script].hint = script - cache->buckets;
|
||||
|
||||
if (script->count == 0)
|
||||
ret = build_script (c, script);
|
||||
|
||||
assert (script->count > 0);
|
||||
|
||||
c->hint = script->hint;
|
||||
c->prev_script = script - cache->buckets;
|
||||
|
||||
|
@ -701,7 +697,7 @@ ia64_find_save_locs (struct cursor *c)
|
|||
ret = run_script (script, c);
|
||||
}
|
||||
out:
|
||||
put_script_cache (c->as, cache, &saved_sigmask);
|
||||
put_script_cache (c->as, cache, &saved_mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -718,3 +714,54 @@ ia64_validate_cache (unw_addr_space_t as, void *arg)
|
|||
unwi_dyn_validate_cache (as, arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
ia64_cache_proc_info (struct cursor *c)
|
||||
{
|
||||
struct ia64_script_cache *cache;
|
||||
struct ia64_script *script;
|
||||
intrmask_t saved_mask;
|
||||
int ret = 0;
|
||||
|
||||
cache = get_script_cache (c->as, &saved_mask);
|
||||
if (!cache)
|
||||
return ret; /* cache is busy */
|
||||
|
||||
/* Re-check to see if a cache entry has been added in the meantime: */
|
||||
script = script_lookup (cache, c);
|
||||
if (script)
|
||||
goto out;
|
||||
|
||||
script = script_new (cache, c->ip);
|
||||
if (!script)
|
||||
{
|
||||
dprintf ("%s: failed to create unwind script\n", __FUNCTION__);
|
||||
ret = -UNW_EUNSPEC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
script->pi = c->pi;
|
||||
|
||||
out:
|
||||
put_script_cache (c->as, cache, &saved_mask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
ia64_get_cached_proc_info (struct cursor *c)
|
||||
{
|
||||
struct ia64_script_cache *cache;
|
||||
struct ia64_script *script;
|
||||
intrmask_t saved_mask;
|
||||
|
||||
cache = get_script_cache (c->as, &saved_mask);
|
||||
if (!cache)
|
||||
return -UNW_ENOINFO; /* cache is busy */
|
||||
{
|
||||
script = script_lookup (cache, c);
|
||||
if (script)
|
||||
c->pi = script->pi;
|
||||
}
|
||||
put_script_cache (c->as, cache, &saved_mask);
|
||||
return script ? 0 : -UNW_ENOINFO;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue