/*
 * File hash.c - generate hash tables for Wine debugger symbols
 *
 * Copyright (C) 1993, Eric Youngdale.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include "debugger.h"

#define NR_NAME_HASH 16384
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif

#ifdef __i386__
static char * reg_name[] =
{
  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
};

static unsigned reg_ofs[] =
{
  FIELD_OFFSET(CONTEXT, Eax), FIELD_OFFSET(CONTEXT, Ecx),
  FIELD_OFFSET(CONTEXT, Edx), FIELD_OFFSET(CONTEXT, Ebx),
  FIELD_OFFSET(CONTEXT, Esp), FIELD_OFFSET(CONTEXT, Ebp),
  FIELD_OFFSET(CONTEXT, Esi), FIELD_OFFSET(CONTEXT, Edi)
};
#else
static char * reg_name[] = { NULL };   /* FIXME */
static unsigned reg_ofs[] = { 0 };
#endif


struct name_hash
{
    struct name_hash * next;		/* Used to look up within name hash */
    char *             name;
    char *             sourcefile;

    int		       n_locals;
    int		       locals_alloc;
    WineLocals       * local_vars;

    int		       n_lines;
    int		       lines_alloc;
    WineLineNo       * linetab;

    DBG_VALUE          value;
    unsigned short     flags;
    unsigned short     breakpoint_offset;
    unsigned int       symbol_size;
};


static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value );
static int sortlist_valid = FALSE;

static int sorttab_nsym;
static struct name_hash ** addr_sorttab = NULL;

static struct name_hash * name_hash_table[NR_NAME_HASH];

static unsigned int name_hash( const char * name )
{
    unsigned int hash = 0;
    unsigned int tmp;
    const char * p;

    p = name;

    while (*p)
      {
	hash = (hash << 4) + *p++;

	if( (tmp = (hash & 0xf0000000)) )
	  {
	    hash ^= tmp >> 24;
	  }
	hash &= ~tmp;
      }
    return hash % NR_NAME_HASH;
}

int
DEBUG_cmp_sym(const void * p1, const void * p2)
{
  struct name_hash ** name1 = (struct name_hash **) p1;
  struct name_hash ** name2 = (struct name_hash **) p2;

  if( ((*name1)->flags & SYM_INVALID) != 0 )
    {
      return -1;
    }

  if( ((*name2)->flags & SYM_INVALID) != 0 )
    {
      return 1;
    }

  if( (*name1)->value.addr.seg > (*name2)->value.addr.seg )
    {
      return 1;
    }

  if( (*name1)->value.addr.seg < (*name2)->value.addr.seg )
    {
      return -1;
    }

  if( (*name1)->value.addr.off > (*name2)->value.addr.off )
    {
      return 1;
    }

  if( (*name1)->value.addr.off < (*name2)->value.addr.off )
    {
      return -1;
    }

  return 0;
}

/***********************************************************************
 *           DEBUG_ResortSymbols
 *
 * Rebuild sorted list of symbols.
 */
static
void
DEBUG_ResortSymbols(void)
{
    struct name_hash *nh;
    int		nsym = 0;
    int		i;

    for(i=0; i<NR_NAME_HASH; i++)
    {
        for (nh = name_hash_table[i]; nh; nh = nh->next)
	  {
	    if( (nh->flags & SYM_INVALID) == 0 )
	       nsym++;
	    else
	       DEBUG_Printf( DBG_CHN_MESG, "Symbol %s is invalid\n", nh->name );
	  }
    }

    sorttab_nsym = nsym;
    if( nsym == 0 )
      {
	return;
      }

    addr_sorttab = (struct name_hash **) DBG_realloc(addr_sorttab,
					 nsym * sizeof(struct name_hash *));

    nsym = 0;
    for(i=0; i<NR_NAME_HASH; i++)
    {
        for (nh = name_hash_table[i]; nh; nh = nh->next)
	  {
	    if( (nh->flags & SYM_INVALID) == 0 )
	       addr_sorttab[nsym++] = nh;
	  }
    }

    qsort(addr_sorttab, nsym,
	  sizeof(struct name_hash *), DEBUG_cmp_sym);
    sortlist_valid = TRUE;

}

/***********************************************************************
 *           DEBUG_AddSymbol
 *
 * Add a symbol to the table.
 */
struct name_hash *
DEBUG_AddSymbol( const char * name, const DBG_VALUE *value,
		 const char * source, int flags)
{
    struct name_hash  * new;
    struct name_hash *nh;
    static char  prev_source[PATH_MAX] = {'\0', };
    static char * prev_duped_source = NULL;
    int hash;

    assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);

    hash = name_hash(name);
    for (nh = name_hash_table[hash]; nh; nh = nh->next)
    {
 	if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
        {
#if 0
	    DEBUG_Printf(DBG_CHN_MESG, "Changing address for symbol %s (%08lx:%08lx => %08lx:%08lx)\n",
			 name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
#endif
 	    nh->value.addr = value->addr;
 	    if( nh->value.type == NULL && value->type != NULL )
            {
 		nh->value.type = value->type;
		nh->value.cookie = value->cookie;
            }
	    /* it may happen that the same symbol is defined in several compilation
	     * units, but the linker decides to merge it into a single instance.
	     * in that case, we don't clear the invalid flag for all the compilation
	     * units (N_GSYM), and wait to get the symbol from the symtab
	     */
 	    if ((flags & SYM_INVALID) == 0)
	       nh->flags &= ~SYM_INVALID;

 	    return nh;
        }
 	if (nh->value.addr.seg == value->addr.seg &&
 	    nh->value.addr.off == value->addr.off &&
 	    strcmp(name, nh->name) == 0 )
        {
            return nh;
        }
    }

#if 0
    DEBUG_Printf(DBG_CHN_TRACE, "adding symbol (%s) from file '%s' at 0x%04lx:%08lx\n",
		 name, source, value->addr.seg, value->addr.off);
#endif

    /*
     * First see if we already have an entry for this symbol.  If so
     * return it, so we don't end up with duplicates.
     */

    new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash));
    new->value = *value;
    new->name = DBG_strdup(name);

    if( source != NULL )
      {
	/*
	 * This is an enhancement to reduce memory consumption.  The idea
	 * is that we duplicate a given string only once.  This is a big
	 * win if there are lots of symbols defined in a given source file.
	 */
	if( strcmp(source, prev_source) == 0 )
	  {
	    new->sourcefile = prev_duped_source;
	  }
	else
	  {
	    strcpy(prev_source, source);
	    prev_duped_source = new->sourcefile = DBG_strdup(source);
	  }
      }
    else
      {
	new->sourcefile = NULL;
      }

    new->n_lines	= 0;
    new->lines_alloc	= 0;
    new->linetab	= NULL;

    new->n_locals	= 0;
    new->locals_alloc	= 0;
    new->local_vars	= NULL;

    new->flags		= flags;
    new->next		= NULL;

    /* Now insert into the hash table */
    new->next = name_hash_table[hash];
    name_hash_table[hash] = new;

    /*
     * Check some heuristics based upon the file name to see whether
     * we want to step through this guy or not.  These are machine generated
     * assembly files that are used to translate between the MS way of
     * calling things and the GCC way of calling things.  In general we
     * always want to step through.
     */
    if ( source != NULL ) {
        int	len = strlen(source);

	if (len > 2 && source[len-2] == '.' && source[len-1] == 's') {
	    char* c = strrchr(source - 2, '/');
	    if (c != NULL) {
		if (strcmp(c + 1, "asmrelay.s") == 0)
		    new->flags |= SYM_TRAMPOLINE;
	    }
	}
    }

    sortlist_valid = FALSE;
    return new;
}

BOOL DEBUG_Normalize(struct name_hash * nh )
{

  /*
   * We aren't adding any more locals or linenumbers to this function.
   * Free any spare memory that we might have allocated.
   */
  if( nh == NULL )
    {
      return TRUE;
    }

  if( nh->n_locals != nh->locals_alloc )
    {
      nh->locals_alloc = nh->n_locals;
      nh->local_vars = DBG_realloc(nh->local_vars,
				  nh->locals_alloc * sizeof(WineLocals));
    }

  if( nh->n_lines != nh->lines_alloc )
    {
      nh->lines_alloc = nh->n_lines;
      nh->linetab = DBG_realloc(nh->linetab,
			      nh->lines_alloc * sizeof(WineLineNo));
    }

  return TRUE;
}

/***********************************************************************
 *           DEBUG_GetSymbolValue
 *
 * Get the address of a named symbol.
 */
static int    DEBUG_GSV_Helper(const char* name, const int lineno,
			       DBG_VALUE* value, int num, int bp_flag)
{
   struct name_hash*	nh;
   int			i = 0;
   DBG_ADDR		addr;

   for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
   {
      if ((nh->flags & SYM_INVALID) != 0) continue;
      if (!strcmp(nh->name, name) && DEBUG_GetLineNumberAddr( nh, lineno, &addr, bp_flag ))
      {
	 if (i >= num) return num + 1;
	 value[i].addr = addr;
	 value[i].type = nh->value.type;
	 value[i].cookie = nh->value.cookie;
	 i++;
      }
   }
   return i;
}

BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
			   DBG_VALUE *rtn, int bp_flag )
{
#define NUMDBGV 10
   /* FIXME: NUMDBGV should be made variable */
   DBG_VALUE 	value[NUMDBGV];
   DBG_VALUE	vtmp;
   int		num, i, local = -1;

   num = DEBUG_GSV_Helper(name, lineno, value, NUMDBGV, bp_flag);
   if (!num && (name[0] != '_'))
   {
      char buffer[512];

      assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
      buffer[0] = '_';
      strcpy(buffer + 1, name);
      num = DEBUG_GSV_Helper(buffer, lineno, value, NUMDBGV, bp_flag);
   }

   /* now get the local symbols if any */
   if (DEBUG_GetStackSymbolValue(name, &vtmp) && num < NUMDBGV)
   {
      value[num] = vtmp;
      local = num;
      num++;
   }

   if (num == 0) {
      return FALSE;
   } else if (!DEBUG_interactiveP || num == 1) {
      i = 0;
   } else {
      char	buffer[256];

      if (num == NUMDBGV+1) {
	 DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
	 num = NUMDBGV;
      }
      DEBUG_Printf(DBG_CHN_MESG, "Many symbols with name '%s', choose the one you want (<cr> to abort):\n", name);
      for (i = 0; i < num; i++) {
	 DEBUG_Printf(DBG_CHN_MESG, "[%d]: ", i + 1);
         if (i == local) {
             struct name_hash*func;
             unsigned int     ebp;
             unsigned int     eip;

             if (DEBUG_GetCurrentFrame(&func, &eip, &ebp))
                 DEBUG_Printf(DBG_CHN_MESG, "local variable of %s in %s\n", func->name, func->sourcefile);
             else
                 DEBUG_Printf(DBG_CHN_MESG, "local variable\n");
         } else {
             DEBUG_PrintAddress( &value[i].addr, DEBUG_GetSelectorType(value[i].addr.seg), TRUE);
             DEBUG_Printf(DBG_CHN_MESG, "\n");
         }
      }
      do {
	  i = 0;
	  if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer), FALSE, FALSE))
	  {
	      i = atoi(buffer);
	      if (i < 1 || i > num)
		  DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i);
	  }
      } while (i < 1 || i > num);

      /* The array is 0-based, but the choices are 1..n, so we have to subtract one before returning. */
      i--;
   }
   *rtn = value[i];
   return TRUE;
}

/***********************************************************************
 *           DEBUG_GetLineNumberAddr
 *
 * Get the address of a named symbol.
 */
BOOL DEBUG_GetLineNumberAddr( const struct name_hash * nh, const int lineno,
			      DBG_ADDR *addr, int bp_flag )
{
    int i;

    if( lineno == -1 )
      {
	*addr = nh->value.addr;
	if( bp_flag )
	  {
	    addr->off += nh->breakpoint_offset;
	  }
      }
    else
      {
	/*
	 * Search for the specific line number.  If we don't find it,
	 * then return FALSE.
	 */
	if( nh->linetab == NULL )
	  {
	    return FALSE;
	  }

	for(i=0; i < nh->n_lines; i++ )
	  {
	    if( nh->linetab[i].line_number == lineno )
	      {
		*addr = nh->linetab[i].pc_offset;
		return TRUE;
	      }
	  }

	/*
	 * This specific line number not found.
	 */
	return FALSE;
      }

    return TRUE;
}


/***********************************************************************
 *           DEBUG_SetSymbolValue
 *
 * Set the address of a named symbol.
 */
BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *value )
{
    char buffer[256];
    struct name_hash *nh;

    assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);

    for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
        if (!strcmp(nh->name, name)) break;

    if (!nh && (name[0] != '_'))
    {
        buffer[0] = '_';
        strcpy(buffer+1, name);
        for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
            if (!strcmp(nh->name, buffer)) break;
    }

    if (!nh) return FALSE;
    nh->value = *value;
    nh->flags &= ~SYM_INVALID;

#ifdef __i386__
    DEBUG_FixAddress( &nh->value.addr, DEBUG_context.SegDs );
#endif

    return TRUE;
}


/***********************************************************************
 *           DEBUG_FindNearestSymbol
 *
 * Find the symbol nearest to a given address.
 * If ebp is specified as non-zero, it means we should dump the argument
 * list into the string we return as well.
 */
const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
				      struct name_hash ** rtn,
				      unsigned int ebp,
				      struct list_id * source)
{
    static char name_buffer[MAX_PATH + 256];
    static char arglist[1024];
    static char argtmp[256];
    struct name_hash * nearest = NULL;
    int mid, high, low;
    unsigned	int * ptr;
    int lineno;
    char * lineinfo, *sourcefile;
    int i;
    char linebuff[16];
    unsigned val;
    DBG_MODULE*	module;
    char modbuf[256];

    if( rtn != NULL )
      {
	*rtn = NULL;
      }

    if( source != NULL )
      {
 	source->sourcefile = NULL;
	source->line = -1;
      }

    if( sortlist_valid == FALSE )
      {
	DEBUG_ResortSymbols();
      }

    if( sortlist_valid == FALSE )
      {
	return NULL;
      }

    /*
     * FIXME  - use the binary search that we added to
     * the function DEBUG_CheckLinenoStatus.  Better yet, we should
     * probably keep some notion of the current function so we don't
     * have to search every time.
     */
    /*
     * Binary search to find closest symbol.
     */
    low = 0;
    high = sorttab_nsym;
    if( addr_sorttab[0]->value.addr.seg > addr->seg
	|| (   addr_sorttab[0]->value.addr.seg == addr->seg
	    && addr_sorttab[0]->value.addr.off > addr->off) )
      {
	nearest = NULL;
      }
    else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
	|| (   addr_sorttab[high - 1]->value.addr.seg == addr->seg
	    && addr_sorttab[high - 1]->value.addr.off < addr->off) )
      {
	nearest = addr_sorttab[high - 1];
      }
    else
      {
	while(1==1)
	  {
	    mid = (high + low)/2;
	    if( mid == low )
	      {
		/*
		 * See if there are any other entries that might also
		 * have the same address, and would also have a line
		 * number table.
		 */
		if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
		  {
		    if(    (addr_sorttab[mid - 1]->value.addr.seg ==
			    addr_sorttab[mid]->value.addr.seg)
			&& (addr_sorttab[mid - 1]->value.addr.off ==
			    addr_sorttab[mid]->value.addr.off)
		        && (addr_sorttab[mid - 1]->linetab != NULL) )
		      {
			mid--;
		      }
		  }

		if(    (mid < sorttab_nsym - 1)
		    && (addr_sorttab[mid]->linetab == NULL) )
		  {
		    if(    (addr_sorttab[mid + 1]->value.addr.seg ==
			    addr_sorttab[mid]->value.addr.seg)
			&& (addr_sorttab[mid + 1]->value.addr.off ==
			    addr_sorttab[mid]->value.addr.off)
		        && (addr_sorttab[mid + 1]->linetab != NULL) )
		      {
			mid++;
		      }
		  }
		nearest = addr_sorttab[mid];
#if 0
		DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
			     addr_sorttab[mid ]->value.addr.seg,
			     addr_sorttab[mid ]->value.addr.off,
			     addr->seg, addr->off,
			     addr_sorttab[mid ]->linetab,
			     addr_sorttab[mid ]->name);
#endif
		break;
	      }
	    if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
		|| (   addr_sorttab[mid]->value.addr.seg == addr->seg
		    && addr_sorttab[mid]->value.addr.off <= addr->off) )
	      {
		low = mid;
	      }
	    else
	      {
		high = mid;
	      }
	  }
      }

    if (!nearest) return NULL;

    if( rtn != NULL )
      {
	*rtn = nearest;
      }

    /*
     * Fill in the relevant bits to the structure so that we can
     * locate the source and line for this bit of code.
     */
    if( source != NULL )
      {
	source->sourcefile = nearest->sourcefile;
	if( nearest->linetab == NULL )
	  {
	    source->line = -1;
	  }
	else
	  {
	    source->line = nearest->linetab[0].line_number;
	  }
      }

    lineinfo = "";
    lineno = -1;

    /*
     * Prepare to display the argument list.  If ebp is specified, it is
     * the framepointer for the function in question.  If not specified,
     * we don't want the arglist.
     */
    memset(arglist, '\0', sizeof(arglist));
    if( ebp != 0 )
      {
	for(i=0; i < nearest->n_locals; i++ )
	  {
	    /*
	     * If this is a register (offset == 0) or a local
	     * variable, we don't want to know about it.
	     */
	    if( nearest->local_vars[i].offset <= 0 )
	      {
		continue;
	      }

	    ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
	    if( arglist[0] == '\0' )
	      {
		arglist[0] = '(';
	      }
	    else
	      {
		strcat(arglist, ", ");
	      }
	    DEBUG_READ_MEM_VERBOSE(ptr, &val, sizeof(val));
	    sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name, val);

	    strcat(arglist, argtmp);
	  }
	if( arglist[0] == '(' )
	  {
	    strcat(arglist, ")");
	  }
      }

    module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
    if (module) {
       char*	ptr = strrchr(module->module_name, '/');

       if (!ptr++) ptr = module->module_name;
       sprintf( modbuf, " in %s", ptr);
    }
    else
       modbuf[0] = '\0';

    if( (nearest->sourcefile != NULL) && (flag == TRUE)
	&& (addr->off - nearest->value.addr.off < 0x100000) )
      {

	/*
	 * Try and find the nearest line number to the current offset.
	 */
	if( nearest->linetab != NULL )
        {
            low = 0;
            high = nearest->n_lines;
            while ((high - low) > 1)
            {
                mid = (high + low) / 2;
                if (addr->off < nearest->linetab[mid].pc_offset.off)
                    high = mid;
                else
                    low = mid;
            }
            lineno = nearest->linetab[low].line_number;
        }

	if( lineno != -1 )
	  {
	    sprintf(linebuff, ":%d", lineno);
	    lineinfo = linebuff;
	    if( source != NULL )
	      {
		source->line = lineno;
	      }
	  }

        /* Remove the path from the file name */
        sourcefile = strrchr( nearest->sourcefile, '/' );
        if (!sourcefile) sourcefile = nearest->sourcefile;
        else sourcefile++;

	if (addr->off == nearest->value.addr.off)
	  sprintf( name_buffer, "%s%s [%s%s]%s", nearest->name,
		   arglist, sourcefile, lineinfo, modbuf);
	else
	  sprintf( name_buffer, "%s+0x%lx%s [%s%s]%s", nearest->name,
		   addr->off - nearest->value.addr.off,
		   arglist, sourcefile, lineinfo, modbuf );
      }
    else
      {
	if (addr->off == nearest->value.addr.off)
	  sprintf( name_buffer, "%s%s%s", nearest->name, arglist, modbuf);
	else {
	  if (addr->seg && (nearest->value.addr.seg!=addr->seg))
	      return NULL;
	  else
	      sprintf( name_buffer, "%s+0x%lx%s%s", nearest->name,
		       addr->off - nearest->value.addr.off, arglist, modbuf);
 	}
      }
    return name_buffer;
}


/***********************************************************************
 *           DEBUG_ReadSymbolTable
 *
 * Read a symbol file into the hash table.
 */
void DEBUG_ReadSymbolTable( const char* filename )
{
    FILE * symbolfile;
    DBG_VALUE value;
    char type;
    char * cpnt;
    char buffer[256];
    char name[256];

    if (!(symbolfile = fopen(filename, "r")))
    {
        DEBUG_Printf( DBG_CHN_WARN, "Unable to open symbol table %s\n", filename );
        return;
    }

    DEBUG_Printf( DBG_CHN_MESG, "Reading symbols from file %s\n", filename );

    value.type = NULL;
    value.addr.seg = 0;
    value.addr.off = 0;
    value.cookie = DV_TARGET;

    while (1)
    {
        fgets( buffer, sizeof(buffer), symbolfile );
        if (feof(symbolfile)) break;

        /* Strip any text after a # sign (i.e. comments) */
        cpnt = buffer;
        while (*cpnt)
            if(*cpnt++ == '#') { *cpnt = 0; break; }

        /* Quietly ignore any lines that have just whitespace */
        cpnt = buffer;
        while(*cpnt)
        {
            if(*cpnt != ' ' && *cpnt != '\t') break;
            cpnt++;
        }
        if (!(*cpnt) || *cpnt == '\n') continue;

        if (sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name) == 3)
	   DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
    }
    fclose(symbolfile);
}


void
DEBUG_AddLineNumber( struct name_hash * func, int line_num,
		     unsigned long offset )
{
  if( func == NULL )
    {
      return;
    }

  if( func->n_lines + 1 >= func->lines_alloc )
    {
      func->lines_alloc += 64;
      func->linetab = DBG_realloc(func->linetab,
			      func->lines_alloc * sizeof(WineLineNo));
    }

  func->linetab[func->n_lines].line_number = line_num;
  func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
  func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
  func->n_lines++;
}


struct wine_locals *
DEBUG_AddLocal( struct name_hash * func, int regno,
		int offset,
		int pc_start,
		int pc_end,
		char * name)
{
  if( func == NULL )
    {
      return NULL;
    }

  if( func->n_locals + 1 >= func->locals_alloc )
    {
      func->locals_alloc += 32;
      func->local_vars = DBG_realloc(func->local_vars,
			      func->locals_alloc * sizeof(WineLocals));
    }

  func->local_vars[func->n_locals].regno = regno;
  func->local_vars[func->n_locals].offset = offset;
  func->local_vars[func->n_locals].pc_start = pc_start;
  func->local_vars[func->n_locals].pc_end = pc_end;
  func->local_vars[func->n_locals].name = DBG_strdup(name);
  func->local_vars[func->n_locals].type = NULL;
  func->n_locals++;

  return &func->local_vars[func->n_locals - 1];
}

void
DEBUG_DumpHashInfo(void)
{
  int i;
  int depth;
  struct name_hash *nh;

  /*
   * Utility function to dump stats about the hash table.
   */
    for(i=0; i<NR_NAME_HASH; i++)
    {
      depth = 0;
      for (nh = name_hash_table[i]; nh; nh = nh->next)
	{
	  depth++;
	}
      DEBUG_Printf(DBG_CHN_MESG, "Bucket %d: %d\n", i, depth);
    }
}

/***********************************************************************
 *           DEBUG_CheckLinenoStatus
 *
 * Find the symbol nearest to a given address.
 * If ebp is specified as non-zero, it means we should dump the argument
 * list into the string we return as well.
 */
int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
{
    struct name_hash * nearest = NULL;
    int mid, high, low;

    if( sortlist_valid == FALSE )
      {
	DEBUG_ResortSymbols();
      }

    /*
     * Binary search to find closest symbol.
     */
    low = 0;
    high = sorttab_nsym;
    if( addr_sorttab[0]->value.addr.seg > addr->seg
	|| (   addr_sorttab[0]->value.addr.seg == addr->seg
	    && addr_sorttab[0]->value.addr.off > addr->off) )
      {
	nearest = NULL;
      }
    else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
	|| (   addr_sorttab[high - 1]->value.addr.seg == addr->seg
	    && addr_sorttab[high - 1]->value.addr.off < addr->off) )
      {
	nearest = addr_sorttab[high - 1];
      }
    else
      {
	while(1==1)
	  {
	    mid = (high + low)/2;
	    if( mid == low )
	      {
		/*
		 * See if there are any other entries that might also
		 * have the same address, and would also have a line
		 * number table.
		 */
		if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
		  {
		    if(    (addr_sorttab[mid - 1]->value.addr.seg ==
			    addr_sorttab[mid]->value.addr.seg)
			&& (addr_sorttab[mid - 1]->value.addr.off ==
			    addr_sorttab[mid]->value.addr.off)
		        && (addr_sorttab[mid - 1]->linetab != NULL) )
		      {
			mid--;
		      }
		  }

		if(    (mid < sorttab_nsym - 1)
		    && (addr_sorttab[mid]->linetab == NULL) )
		  {
		    if(    (addr_sorttab[mid + 1]->value.addr.seg ==
			    addr_sorttab[mid]->value.addr.seg)
			&& (addr_sorttab[mid + 1]->value.addr.off ==
			    addr_sorttab[mid]->value.addr.off)
		        && (addr_sorttab[mid + 1]->linetab != NULL) )
		      {
			mid++;
		      }
		  }
		nearest = addr_sorttab[mid];
#if 0
		DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
			     addr_sorttab[mid ]->value.addr.seg,
			     addr_sorttab[mid ]->value.addr.off,
			     addr->seg, addr->off,
			     addr_sorttab[mid ]->linetab,
			     addr_sorttab[mid ]->name);
#endif
		break;
	      }
	    if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
		|| (   addr_sorttab[mid]->value.addr.seg == addr->seg
		    && addr_sorttab[mid]->value.addr.off <= addr->off) )
	      {
		low = mid;
	      }
	    else
	      {
		high = mid;
	      }
	  }
      }

    if (!nearest) return FUNC_HAS_NO_LINES;

    if( nearest->flags & SYM_STEP_THROUGH )
      {
	/*
	 * This will cause us to keep single stepping until
	 * we get to the other side somewhere.
	 */
	return NOT_ON_LINENUMBER;
      }

    if( (nearest->flags & SYM_TRAMPOLINE) )
      {
	/*
	 * This will cause us to keep single stepping until
	 * we get to the other side somewhere.
	 */
	return FUNC_IS_TRAMPOLINE;
      }

    if( nearest->linetab == NULL )
      {
	return FUNC_HAS_NO_LINES;
      }


    /*
     * We never want to stop on the first instruction of a function
     * even if it has it's own linenumber.  Let the thing keep running
     * until it gets past the function prologue.  We only do this if there
     * is more than one line number for the function, of course.
     */
    if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
      {
	return NOT_ON_LINENUMBER;
      }

    if( (nearest->sourcefile != NULL)
	&& (addr->off - nearest->value.addr.off < 0x100000) )
      {
          low = 0;
          high = nearest->n_lines;
          while ((high - low) > 1)
          {
              mid = (high + low) / 2;
              if (addr->off < nearest->linetab[mid].pc_offset.off) high = mid;
              else low = mid;
          }
          if (addr->off == nearest->linetab[low].pc_offset.off)
              return AT_LINENUMBER;
          else
              return NOT_ON_LINENUMBER;
      }

    return FUNC_HAS_NO_LINES;
}

/***********************************************************************
 *           DEBUG_GetFuncInfo
 *
 * Find the symbol nearest to a given address.
 * Returns sourcefile name and line number in a format that the listing
 * handler can deal with.
 */
void
DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
		   const char * name)
{
    char buffer[256];
    char * pnt;
    struct name_hash *nh;

    for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
      {
	if( filename != NULL )
	  {

	    if( nh->sourcefile == NULL )
	      {
		continue;
	      }

	    pnt = strrchr(nh->sourcefile, '/');
	    if( strcmp(nh->sourcefile, filename) != 0
		&& (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
	      {
		continue;
	      }
	  }
        if (!strcmp(nh->name, name)) break;
      }

    if (!nh && (name[0] != '_'))
    {
        buffer[0] = '_';
        strcpy(buffer+1, name);
        for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
	  {
	    if( filename != NULL )
	      {
		if( nh->sourcefile == NULL )
		  {
		    continue;
		  }

		pnt = strrchr(nh->sourcefile, '/');
		if( strcmp(nh->sourcefile, filename) != 0
		    && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
		  {
		    continue;
		  }
	      }
            if (!strcmp(nh->name, buffer)) break;
	  }
    }

    if( !nh )
      {
	if( filename != NULL )
	  {
	    DEBUG_Printf(DBG_CHN_MESG, "No such function %s in %s\n", name, filename);
	  }
	else
	  {
	    DEBUG_Printf(DBG_CHN_MESG, "No such function %s\n", name);
	  }
	ret->sourcefile = NULL;
	ret->line = -1;
	return;
      }

    ret->sourcefile = nh->sourcefile;

    /*
     * Search for the specific line number.  If we don't find it,
     * then return FALSE.
     */
    if( nh->linetab == NULL )
      {
	ret->line = -1;
      }
    else
      {
	ret->line = nh->linetab[0].line_number;
      }
}

/***********************************************************************
 *           DEBUG_GetStackSymbolValue
 *
 * Get the address of a named symbol from the current stack frame.
 */
static
BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
{
  struct name_hash * curr_func;
  unsigned int	     ebp;
  unsigned int	     eip;
  int		     i;

  if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
    {
      return FALSE;
    }

  for(i=0; i < curr_func->n_locals; i++ )
    {
      /*
       * Test the range of validity of the local variable.  This
       * comes up with RBRAC/LBRAC stabs in particular.
       */
      if(    (curr_func->local_vars[i].pc_start != 0)
	  && ((eip - curr_func->value.addr.off)
	      < curr_func->local_vars[i].pc_start) )
	{
	  continue;
	}

      if(    (curr_func->local_vars[i].pc_end != 0)
	  && ((eip - curr_func->value.addr.off)
	      > curr_func->local_vars[i].pc_end) )
	{
	  continue;
	}

      if( strcmp(name, curr_func->local_vars[i].name) == 0 )
	{
	  /*
	   * OK, we found it.  Now figure out what to do with this.
	   */
	  if( curr_func->local_vars[i].regno != 0 )
	    {
	      /*
	       * Register variable.  Point to DEBUG_context field.
	       */
	      assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
	      value->addr.off = ((DWORD)&DEBUG_context) +
		 reg_ofs[curr_func->local_vars[i].regno - 1];
	      value->cookie = DV_HOST;
	    }
	  else
	    {
	      value->addr.off = ebp + curr_func->local_vars[i].offset;
	      value->cookie = DV_TARGET;
	    }
	  value->addr.seg = 0;
	  value->type = curr_func->local_vars[i].type;

	  return TRUE;
	}
    }

  return FALSE;
}

int
DEBUG_InfoLocals(void)
{
  struct name_hash  * curr_func;
  unsigned int	      ebp;
  unsigned int	      eip;
  int		      i;
  unsigned int      * ptr;
  unsigned int	      val;

  if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
    {
      return FALSE;
    }

  DEBUG_Printf(DBG_CHN_MESG, "%s:\n", curr_func->name);

  for(i=0; i < curr_func->n_locals; i++ )
    {
      /*
       * Test the range of validity of the local variable.  This
       * comes up with RBRAC/LBRAC stabs in particular.
       */
      if(    (curr_func->local_vars[i].pc_start != 0)
	  && ((eip - curr_func->value.addr.off)
	      < curr_func->local_vars[i].pc_start) )
	{
	  continue;
	}

      if(    (curr_func->local_vars[i].pc_end != 0)
	  && ((eip - curr_func->value.addr.off)
	      > curr_func->local_vars[i].pc_end) )
	{
	  continue;
	}

      DEBUG_PrintTypeCast(curr_func->local_vars[i].type);

      if( curr_func->local_vars[i].regno != 0 )
	{
	  ptr = (unsigned int *)(((DWORD)&DEBUG_context)
				 + reg_ofs[curr_func->local_vars[i].regno - 1]);
	  DEBUG_Printf(DBG_CHN_MESG, " %s (optimized into register $%s) == 0x%8.8x\n",
		       curr_func->local_vars[i].name,
		       reg_name[curr_func->local_vars[i].regno - 1],
		       *ptr);
	}
      else
	{
	  DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset),
				 &val, sizeof(val));
	  DEBUG_Printf(DBG_CHN_MESG, " %s == 0x%8.8x\n",
		       curr_func->local_vars[i].name, val);
	}
    }

  return TRUE;
}

int
DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
{
  sym->symbol_size = len;

  return TRUE;
}

int
DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
{
  sym->breakpoint_offset = off;

  return TRUE;
}

int
DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
{

  *addr = sym->value.addr;

  return TRUE;
}

int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
{
  sym->type = type;

  return TRUE;
}
