/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.

   This file is part of GNU CC.

   GNU CC is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   GNU CC is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU CC; see the file COPYING.  If not, write to
   the Free Software Foundation, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* As a special exception, if you link this library with other files,
   some of which are compiled with GCC, to produce an executable,
   this library does not by itself cause the resulting executable
   to be covered by the GNU General Public License.
   This exception does not however invalidate any other reasons why
   the executable file might be covered by the GNU General Public License.  */

/* Locate the FDE entry for a given address, using Darwin's keymgr support.  */

#include "tconfig.h"
#include <string.h>
#include <stdlib.h>
#include "dwarf2.h"
#include "unwind.h"
#define NO_BASE_OF_ENCODED_VALUE
#define DWARF2_OBJECT_END_PTR_EXTENSION
#include "unwind-pe.h"
#include "unwind-dw2-fde.h"
/* Carefully don't include gthr.h.  */

typedef int __gthread_mutex_t;
#define __gthread_mutex_lock(x)  (void)(x)
#define __gthread_mutex_unlock(x) (void)(x)

static fde * _Unwind_Find_registered_FDE (void *pc, 
					  struct dwarf_eh_bases *bases);

#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
#include "unwind-dw2-fde.c"
#undef _Unwind_Find_FDE

/* KeyMgr stuff.  */
#define KEYMGR_GCC3_LIVE_IMAGE_LIST     301     /* loaded images  */
#define KEYMGR_GCC3_DW2_OBJ_LIST        302     /* Dwarf2 object list  */

extern void *_keymgr_get_and_lock_processwide_ptr (int);
extern void _keymgr_set_and_unlock_processwide_ptr (int, void *);
extern void _keymgr_unlock_processwide_ptr (int);

struct mach_header;
extern char *getsectdatafromheader (struct mach_header*, const char*,
			const char *, unsigned long *);

/* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST.  */
struct km_object_info {
  struct object *seen_objects;
  struct object *unseen_objects;
  unsigned spare[2];
};

/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST.  Info about each resident image.  */
struct live_images {
  unsigned long this_size;                      /* sizeof (live_images)  */
  struct mach_header *mh;                       /* the image info  */
  unsigned long vm_slide;
  void (*destructor)(struct live_images *);     /* destructor for this  */
  struct live_images *next;
  unsigned int examined_p;
  void *fde;
  void *object_info;
  unsigned long info[2];                        /* Future use.  */
};

/* Bits in the examined_p field of struct live_images.  */
enum {
  EXAMINED_IMAGE_MASK = 1,	/* We've seen this one.  */
  ALLOCED_IMAGE_MASK = 2,	/* The FDE entries were allocated by
				   malloc, and must be freed.  This isn't
				   used by newer libgcc versions.  */
  IMAGE_IS_TEXT_MASK = 4,	/* This image is in the TEXT segment.  */
  DESTRUCTOR_MAY_BE_CALLED_LIVE = 8  /* The destructor may be called on an
					object that's part of the live
					image list.  */
};

/* Delete any data we allocated on a live_images structure.  Either
   IMAGE has already been removed from the
   KEYMGR_GCC3_LIVE_IMAGE_LIST and the struct will be deleted
   after we return, or that list is locked and we're being called
   because this object might be about to be unloaded.  Called by
   KeyMgr.  */

static void 
live_image_destructor (struct live_images *image)
{
  if (image->object_info)
    {
      /* Free any sorted arrays.  */
      __deregister_frame_info_bases (image->fde);

      free (image->object_info);
      image->object_info = NULL;
      if (image->examined_p & ALLOCED_IMAGE_MASK)
	free (image->fde);
      image->fde = NULL;
    }
  image->examined_p = 0;
  image->destructor = NULL;
}

/* Run through the list of live images.  If we can allocate memory,
   give each unseen image a new `struct object'.  Even if we can't,
   check whether the PC is inside the FDE of each unseen image.
 */
 
static inline fde *
examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
{
  fde *result = NULL;
  struct live_images *image;

  image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);

  for (; image != NULL; image = image->next)
    if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0)
      {
	char *fde;
	unsigned long sz;
	
	fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
	if (fde == NULL)
	  {
	    fde = getsectdatafromheader (image->mh, "__TEXT",
					 "__eh_frame", &sz);
	    if (fde != NULL)
	      image->examined_p |= IMAGE_IS_TEXT_MASK;
	  }
	
	/* If .eh_frame is empty, don't register at all.  */
	if (fde != NULL && sz > 0)
	  {
	    char *real_fde = (fde + image->vm_slide);
	    struct object *ob = NULL;
	    struct object panicob;
	    
	    if (! dont_alloc)
	      ob = calloc (1, sizeof (struct object));
	    dont_alloc |= ob == NULL;
	    if (dont_alloc)
	      ob = &panicob;
	    
	    ob->pc_begin = (void *)-1;
	    ob->tbase = 0;
	    ob->dbase = 0;
	    ob->u.single = (struct dwarf_fde *)real_fde;
	    ob->s.i = 0;
	    ob->s.b.encoding = DW_EH_PE_omit;
	    ob->fde_end = real_fde + sz;
	    
	    if (! dont_alloc)
	      {
		ob->next = unseen_objects;
		unseen_objects = ob;
		
		image->destructor = live_image_destructor;
		image->object_info = ob;
		
		image->examined_p |= (EXAMINED_IMAGE_MASK 
				      | DESTRUCTOR_MAY_BE_CALLED_LIVE);
	      }
	    image->fde = real_fde;
	    
	    result = search_object (ob, pc);
	    if (result)
	      {
		int encoding;
		
		bases->tbase = ob->tbase;
		bases->dbase = ob->dbase;
		
		encoding = ob->s.b.encoding;
		if (ob->s.b.mixed_encoding)
		  encoding = get_fde_encoding (result);
		read_encoded_value_with_base (encoding, 
					      base_from_object (encoding, ob),
					      result->pc_begin, 
					      (_Unwind_Ptr *)&bases->func);
		break;
	      }
	  }
	else
	  image->examined_p |= EXAMINED_IMAGE_MASK;
      }

  _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);

  return result;
}

fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
  struct km_object_info *the_obj_info;
  fde *ret = NULL;

  the_obj_info = 
    _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
  if (! the_obj_info)
    the_obj_info = calloc (1, sizeof (*the_obj_info));
  
  if (the_obj_info != NULL)
    {
      seen_objects = the_obj_info->seen_objects;
      unseen_objects = the_obj_info->unseen_objects;
  
      ret = _Unwind_Find_registered_FDE (pc, bases);
    }
  
  /* OK, didn't find it in the list of FDEs we've seen before,
     so go through and look at the new ones.  */
  if (ret == NULL)
    ret = examine_objects (pc, bases, the_obj_info == NULL);

  if (the_obj_info != NULL)
    {
      the_obj_info->seen_objects = seen_objects;
      the_obj_info->unseen_objects = unseen_objects;
      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
					      the_obj_info);
    }
  return ret;
}
