Пример #1
0
PROTECTED void
unw_map_local_cursor_get (unw_map_cursor_t *map_cursor)
{
  intrmask_t saved_mask;

  lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
  map_cursor->map_list = local_map_list;
  map_cursor->cur_map = local_map_list;
  lock_rdwr_release (&local_rdwr_lock, saved_mask);
}
Пример #2
0
PROTECTED void
unw_map_local_destroy (void)
{
  intrmask_t saved_mask;

  lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
  if (local_map_list != NULL && --local_map_list_refs == 0)
    {
      map_destroy_list (local_map_list);
      local_map_list = NULL;
    }
  lock_rdwr_release (&local_rdwr_lock, saved_mask);
}
Пример #3
0
PROTECTED int
unw_map_local_create (void)
{
  intrmask_t saved_mask;
  int ret_value = 0;

  lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
  if (local_map_list_refs == 0)
    {
      local_map_list = map_create_list (getpid());
      if (local_map_list != NULL)
        local_map_list_refs = 1;
      else
        ret_value = -1;
    }
  else
    local_map_list_refs++;
  lock_rdwr_release (&local_rdwr_lock, saved_mask);
  return ret_value;
}
Пример #4
0
/* In order to cache as much as possible while unwinding the local process,
   we gather a map of the process before starting. If the cache is missing
   a map, or a map exists but doesn't have the "expected_flags" set, then
   check if the cache needs to be regenerated.
   While regenerating the list, grab a write lock to avoid any readers using
   the list while it's being modified. */
static int
rebuild_if_necessary (unw_word_t addr, int expected_flags, size_t bytes)
{
  struct map_info *map;
  struct map_info *new_list;
  int ret_value = -1;
  intrmask_t saved_mask;

  new_list = map_create_list (UNW_MAP_CREATE_LOCAL, getpid());
  map = map_find_from_addr (new_list, addr);
  if (map && (map->end - addr >= bytes) && (expected_flags == 0 || (map->flags & expected_flags)))
    {
      /* Get a write lock on local_map_list since it's going to be modified. */
      lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);

      /* Just in case another thread rebuilt the map, check to see if the
         ip with expected_flags is in local_map_list. If not, the assumption
         is that new_list is newer than local_map_list because the map only
         gets new maps with new permissions. If this is not true, then it
         would be necessary to regenerate the list one more time. */
      ret_value = 0;
      map = map_find_from_addr (local_map_list, addr);
      if (!map || (map->end - addr < bytes) || (expected_flags != 0 && !(map->flags & expected_flags)))
        {
          /* Move any cached items to the new list. */
          move_cached_elf_data (local_map_list, new_list);
          map = local_map_list;
          local_map_list = new_list;
          new_list = map;
        }

      lock_rdwr_release (&local_rdwr_lock, saved_mask);
    }

  map_destroy_list (new_list);

  return ret_value;
}