Improved internal module handling (module now have a size, map of
[wine] / debugger / hash.c
1 /*
2  * File hash.c - generate hash tables for Wine debugger symbols
3  *
4  * Copyright (C) 1993, Eric Youngdale.
5  */
6
7
8 #include "config.h"
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <sys/types.h>
14 #include "debugger.h"
15
16 #define NR_NAME_HASH 16384
17 #ifndef PATH_MAX
18 #define PATH_MAX _MAX_PATH
19 #endif
20
21 #ifdef __i386__
22 static char * reg_name[] =
23 {
24   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
25 };
26
27 static unsigned reg_ofs[] =
28 {
29   FIELD_OFFSET(CONTEXT, Eax), FIELD_OFFSET(CONTEXT, Ecx),
30   FIELD_OFFSET(CONTEXT, Edx), FIELD_OFFSET(CONTEXT, Ebx),
31   FIELD_OFFSET(CONTEXT, Esp), FIELD_OFFSET(CONTEXT, Ebp),
32   FIELD_OFFSET(CONTEXT, Esi), FIELD_OFFSET(CONTEXT, Edi)
33 };
34 #else
35 static char * reg_name[] = { NULL };   /* FIXME */
36 static unsigned reg_ofs[] = { 0 };
37 #endif
38
39
40 struct name_hash
41 {
42     struct name_hash * next;            /* Used to look up within name hash */
43     char *             name;
44     char *             sourcefile;
45
46     int                n_locals;
47     int                locals_alloc;
48     WineLocals       * local_vars;
49   
50     int                n_lines;
51     int                lines_alloc;
52     WineLineNo       * linetab;
53
54     DBG_VALUE          value;
55     unsigned short     flags;
56     unsigned short     breakpoint_offset;
57     unsigned int       symbol_size;
58 };
59
60
61 static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value );
62 static int sortlist_valid = FALSE;
63
64 static int sorttab_nsym;
65 static struct name_hash ** addr_sorttab = NULL;
66
67 static struct name_hash * name_hash_table[NR_NAME_HASH];
68
69 static unsigned int name_hash( const char * name )
70 {
71     unsigned int hash = 0;
72     unsigned int tmp;
73     const char * p;
74
75     p = name;
76
77     while (*p) 
78       {
79         hash = (hash << 4) + *p++;
80
81         if( (tmp = (hash & 0xf0000000)) )
82           {
83             hash ^= tmp >> 24;
84           }
85         hash &= ~tmp;
86       }
87     return hash % NR_NAME_HASH;
88 }
89
90 int
91 DEBUG_cmp_sym(const void * p1, const void * p2)
92 {
93   struct name_hash ** name1 = (struct name_hash **) p1;
94   struct name_hash ** name2 = (struct name_hash **) p2;
95
96   if( ((*name1)->flags & SYM_INVALID) != 0 )
97     {
98       return -1;
99     }
100
101   if( ((*name2)->flags & SYM_INVALID) != 0 )
102     {
103       return 1;
104     }
105
106   if( (*name1)->value.addr.seg > (*name2)->value.addr.seg )
107     {
108       return 1;
109     }
110
111   if( (*name1)->value.addr.seg < (*name2)->value.addr.seg )
112     {
113       return -1;
114     }
115
116   if( (*name1)->value.addr.off > (*name2)->value.addr.off )
117     {
118       return 1;
119     }
120
121   if( (*name1)->value.addr.off < (*name2)->value.addr.off )
122     {
123       return -1;
124     }
125
126   return 0;
127 }
128
129 /***********************************************************************
130  *           DEBUG_ResortSymbols
131  *
132  * Rebuild sorted list of symbols.
133  */
134 static
135 void
136 DEBUG_ResortSymbols(void)
137 {
138     struct name_hash *nh;
139     int         nsym = 0;
140     int         i;
141
142     for(i=0; i<NR_NAME_HASH; i++)
143     {
144         for (nh = name_hash_table[i]; nh; nh = nh->next)
145           {
146             if( (nh->flags & SYM_INVALID) == 0 )
147                nsym++;
148             else
149                DEBUG_Printf( DBG_CHN_MESG, "Symbol %s is invalid\n", nh->name );
150           }
151     }
152
153     sorttab_nsym = nsym;
154     if( nsym == 0 )
155       {
156         return;
157       }
158
159     addr_sorttab = (struct name_hash **) DBG_realloc(addr_sorttab, 
160                                          nsym * sizeof(struct name_hash *));
161
162     nsym = 0;
163     for(i=0; i<NR_NAME_HASH; i++)
164     {
165         for (nh = name_hash_table[i]; nh; nh = nh->next)
166           {
167             if( (nh->flags & SYM_INVALID) == 0 )
168                addr_sorttab[nsym++] = nh;
169           }
170     }
171
172     qsort(addr_sorttab, nsym,
173           sizeof(struct name_hash *), DEBUG_cmp_sym);
174     sortlist_valid = TRUE;
175
176 }
177
178 /***********************************************************************
179  *           DEBUG_AddSymbol
180  *
181  * Add a symbol to the table.
182  */
183 struct name_hash *
184 DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
185                  int flags)
186 {
187     struct name_hash  * new;
188     struct name_hash *nh;
189     static char  prev_source[PATH_MAX] = {'\0', };
190     static char * prev_duped_source = NULL;
191     char * c;
192     int hash;
193
194     assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
195
196     hash = name_hash(name);
197     for (nh = name_hash_table[hash]; nh; nh = nh->next)
198     {
199         if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
200         {
201 #if 0
202             DEBUG_Printf(DBG_CHN_MESG, "Changing address for symbol %s (%08lx:%08lx => %08lx:%08lx)\n",
203                          name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
204 #endif
205             nh->value.addr = value->addr;
206             if( nh->value.type == NULL && value->type != NULL )
207             {
208                 nh->value.type = value->type;
209                 nh->value.cookie = value->cookie;
210             }
211             /* it may happen that the same symbol is defined in several compilation
212              * units, but the linker decides to merge it into a single instance.
213              * in that case, we don't clear the invalid flag for all the compilation
214              * units (N_GSYM), and wait to get the symbol from the symtab
215              */
216             if ((flags & SYM_INVALID) == 0)
217                nh->flags &= ~SYM_INVALID;
218
219             return nh;
220         }
221         if (nh->value.addr.seg == value->addr.seg &&
222             nh->value.addr.off == value->addr.off &&
223             strcmp(name, nh->name) == 0 )
224         {
225             return nh;
226         }
227     }
228
229 #if 0
230     DEBUG_Printf(DBG_CHN_TRACE, "adding symbol (%s) from file '%s' at 0x%04lx:%08lx\n",
231                  name, source, value->addr.seg, value->addr.off);
232 #endif
233
234     /*
235      * First see if we already have an entry for this symbol.  If so
236      * return it, so we don't end up with duplicates.
237      */
238     
239     new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash));
240     new->value = *value;
241     new->name = DBG_strdup(name);
242
243     if( source != NULL )
244       {
245         /*
246          * This is an enhancement to reduce memory consumption.  The idea
247          * is that we duplicate a given string only once.  This is a big
248          * win if there are lots of symbols defined in a given source file.
249          */
250         if( strcmp(source, prev_source) == 0 )
251           {
252             new->sourcefile = prev_duped_source;
253           }
254         else
255           {
256             strcpy(prev_source, source);
257             prev_duped_source = new->sourcefile = DBG_strdup(source);
258           }
259       }
260     else
261       {
262         new->sourcefile = NULL;
263       }
264
265     new->n_lines        = 0;
266     new->lines_alloc    = 0;
267     new->linetab        = NULL;
268
269     new->n_locals       = 0;
270     new->locals_alloc   = 0;
271     new->local_vars     = NULL;
272
273     new->flags          = flags;
274     new->next           = NULL;
275
276     /* Now insert into the hash table */
277     new->next = name_hash_table[hash];
278     name_hash_table[hash] = new;
279
280     /*
281      * Check some heuristics based upon the file name to see whether
282      * we want to step through this guy or not.  These are machine generated
283      * assembly files that are used to translate between the MS way of
284      * calling things and the GCC way of calling things.  In general we
285      * always want to step through.
286      */
287     if( source != NULL )
288       {
289         c = strrchr(source, '.');
290         if( c != NULL && strcmp(c, ".s") == 0 )
291           {
292             c = strrchr(source, '/');
293             if( c != NULL )
294               {
295                 c++;
296                 if(    (strcmp(c, "callfrom16.s") == 0)
297                     || (strcmp(c, "callto16.s") == 0)
298                     || (strcmp(c, "call32.s") == 0) )
299                   {
300                     new->flags |= SYM_TRAMPOLINE;
301                   }
302               }
303           }
304       }
305
306     sortlist_valid = FALSE;
307     return new;
308 }
309
310 BOOL DEBUG_Normalize(struct name_hash * nh )
311 {
312
313   /*
314    * We aren't adding any more locals or linenumbers to this function.
315    * Free any spare memory that we might have allocated.
316    */
317   if( nh == NULL )
318     {
319       return TRUE;
320     }
321
322   if( nh->n_locals != nh->locals_alloc )
323     {
324       nh->locals_alloc = nh->n_locals;
325       nh->local_vars = DBG_realloc(nh->local_vars,
326                                   nh->locals_alloc * sizeof(WineLocals));
327     }
328
329   if( nh->n_lines != nh->lines_alloc )
330     {
331       nh->lines_alloc = nh->n_lines;
332       nh->linetab = DBG_realloc(nh->linetab,
333                               nh->lines_alloc * sizeof(WineLineNo));
334     }
335
336   return TRUE;
337 }
338
339 /***********************************************************************
340  *           DEBUG_GetSymbolValue
341  *
342  * Get the address of a named symbol.
343  */
344 BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, 
345                            DBG_VALUE *value, int bp_flag )
346 {
347     struct name_hash *nh;
348
349     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
350       {
351         if( (nh->flags & SYM_INVALID) != 0 )
352           {
353             continue;
354           }
355
356         if (!strcmp(nh->name, name)) break;
357       }
358
359     if (!nh && (name[0] != '_'))
360     {
361         char buffer[256];
362         
363         assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
364         buffer[0] = '_';
365         strcpy(buffer+1, name);
366         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
367           {
368             if( (nh->flags & SYM_INVALID) != 0 )
369               {
370                 continue;
371               }
372             if (!strcmp(nh->name, buffer)) break;
373           }
374     }
375
376     /*
377      * If we don't have anything here, then try and see if this
378      * is a local symbol to the current stack frame.  No matter
379      * what, we have nothing more to do, so we let that function
380      * decide what we ultimately return.
381      */
382     if (!nh) 
383       {
384         return DEBUG_GetStackSymbolValue(name, value);
385       }
386
387     value->type = nh->value.type;
388     value->cookie = nh->value.cookie;
389     return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag );
390 }
391
392 /***********************************************************************
393  *           DEBUG_GetLineNumberAddr
394  *
395  * Get the address of a named symbol.
396  */
397 BOOL DEBUG_GetLineNumberAddr( const struct name_hash * nh, const int lineno, 
398                               DBG_ADDR *addr, int bp_flag )
399 {
400     int i;
401
402     if( lineno == -1 )
403       {
404         *addr = nh->value.addr;
405         if( bp_flag )
406           {
407             addr->off += nh->breakpoint_offset;
408           }
409       }
410     else
411       {
412         /*
413          * Search for the specific line number.  If we don't find it,
414          * then return FALSE.
415          */
416         if( nh->linetab == NULL )
417           {
418             return FALSE;
419           }
420
421         for(i=0; i < nh->n_lines; i++ )
422           {
423             if( nh->linetab[i].line_number == lineno )
424               {
425                 *addr = nh->linetab[i].pc_offset;
426                 return TRUE;
427               }
428           }
429
430         /*
431          * This specific line number not found.
432          */
433         return FALSE;
434       }
435
436     return TRUE;
437 }
438
439
440 /***********************************************************************
441  *           DEBUG_SetSymbolValue
442  *
443  * Set the address of a named symbol.
444  */
445 BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *value )
446 {
447     char buffer[256];
448     struct name_hash *nh;
449
450     assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
451
452     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
453         if (!strcmp(nh->name, name)) break;
454
455     if (!nh && (name[0] != '_'))
456     {
457         buffer[0] = '_';
458         strcpy(buffer+1, name);
459         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
460             if (!strcmp(nh->name, buffer)) break;
461     }
462
463     if (!nh) return FALSE;
464     nh->value = *value;
465     nh->flags &= ~SYM_INVALID;
466
467 #ifdef __i386__
468     DEBUG_FixAddress( &nh->value.addr, DEBUG_context.SegDs );
469 #endif
470
471     return TRUE;
472 }
473
474
475 /***********************************************************************
476  *           DEBUG_FindNearestSymbol
477  *
478  * Find the symbol nearest to a given address.
479  * If ebp is specified as non-zero, it means we should dump the argument
480  * list into the string we return as well.
481  */
482 const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
483                                       struct name_hash ** rtn,
484                                       unsigned int ebp,
485                                       struct list_id * source)
486 {
487     static char name_buffer[MAX_PATH + 256];
488     static char arglist[1024];
489     static char argtmp[256];
490     struct name_hash * nearest = NULL;
491     int mid, high, low;
492     unsigned    int * ptr;
493     int lineno;
494     char * lineinfo, *sourcefile;
495     int i;
496     char linebuff[16];
497     unsigned val;
498
499     if( rtn != NULL )
500       {
501         *rtn = NULL;
502       }
503
504     if( source != NULL )
505       {
506         source->sourcefile = NULL;
507         source->line = -1;
508       }
509
510     if( sortlist_valid == FALSE )
511       {
512         DEBUG_ResortSymbols();
513       }
514
515     if( sortlist_valid == FALSE )
516       {
517         return NULL;
518       }
519
520     /*
521      * FIXME  - use the binary search that we added to
522      * the function DEBUG_CheckLinenoStatus.  Better yet, we should
523      * probably keep some notion of the current function so we don't
524      * have to search every time.
525      */
526     /*
527      * Binary search to find closest symbol.
528      */
529     low = 0;
530     high = sorttab_nsym;
531     if( addr_sorttab[0]->value.addr.seg > addr->seg
532         || (   addr_sorttab[0]->value.addr.seg == addr->seg 
533             && addr_sorttab[0]->value.addr.off > addr->off) )
534       {
535         nearest = NULL;
536       }
537     else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
538         || (   addr_sorttab[high - 1]->value.addr.seg == addr->seg 
539             && addr_sorttab[high - 1]->value.addr.off < addr->off) )
540       {
541         nearest = addr_sorttab[high - 1];
542       }
543     else
544       {
545         while(1==1)
546           {
547             mid = (high + low)/2;
548             if( mid == low )
549               {
550                 /* 
551                  * See if there are any other entries that might also
552                  * have the same address, and would also have a line
553                  * number table.  
554                  */
555                 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
556                   {
557                     if(    (addr_sorttab[mid - 1]->value.addr.seg ==
558                             addr_sorttab[mid]->value.addr.seg)
559                         && (addr_sorttab[mid - 1]->value.addr.off ==
560                             addr_sorttab[mid]->value.addr.off)
561                         && (addr_sorttab[mid - 1]->linetab != NULL) )
562                       {
563                         mid--;
564                       }
565                   }
566
567                 if(    (mid < sorttab_nsym - 1)
568                     && (addr_sorttab[mid]->linetab == NULL) )
569                   {
570                     if(    (addr_sorttab[mid + 1]->value.addr.seg ==
571                             addr_sorttab[mid]->value.addr.seg)
572                         && (addr_sorttab[mid + 1]->value.addr.off ==
573                             addr_sorttab[mid]->value.addr.off)
574                         && (addr_sorttab[mid + 1]->linetab != NULL) )
575                       {
576                         mid++;
577                       }
578                   }
579                 nearest = addr_sorttab[mid];
580 #if 0
581                 DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
582                              addr_sorttab[mid ]->value.addr.seg,
583                              addr_sorttab[mid ]->value.addr.off,
584                              addr->seg, addr->off,
585                              addr_sorttab[mid ]->linetab,
586                              addr_sorttab[mid ]->name);
587 #endif
588                 break;
589               }
590             if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
591                 || (   addr_sorttab[mid]->value.addr.seg == addr->seg 
592                     && addr_sorttab[mid]->value.addr.off <= addr->off) )
593               {
594                 low = mid;
595               }
596             else
597               {
598                 high = mid;
599               }
600           }
601       }
602
603     if (!nearest) return NULL;
604
605     if( rtn != NULL )
606       {
607         *rtn = nearest;
608       }
609
610     /*
611      * Fill in the relevant bits to the structure so that we can
612      * locate the source and line for this bit of code.
613      */
614     if( source != NULL )
615       {
616         source->sourcefile = nearest->sourcefile;
617         if( nearest->linetab == NULL )
618           {
619             source->line = -1;
620           }
621         else
622           {
623             source->line = nearest->linetab[0].line_number;
624           }
625       }
626
627     lineinfo = "";
628     lineno = -1;
629
630     /*
631      * Prepare to display the argument list.  If ebp is specified, it is
632      * the framepointer for the function in question.  If not specified,
633      * we don't want the arglist.
634      */
635     memset(arglist, '\0', sizeof(arglist));
636     if( ebp != 0 )
637       {
638         for(i=0; i < nearest->n_locals; i++ )
639           {
640             /*
641              * If this is a register (offset == 0) or a local
642              * variable, we don't want to know about it.
643              */
644             if( nearest->local_vars[i].offset <= 0 )
645               {
646                 continue;
647               }
648
649             ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
650             if( arglist[0] == '\0' )
651               {
652                 arglist[0] = '(';
653               }
654             else
655               {
656                 strcat(arglist, ", ");
657               }
658             DEBUG_READ_MEM_VERBOSE(ptr, &val, sizeof(val));
659             sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name, val);
660
661             strcat(arglist, argtmp);
662           }
663         if( arglist[0] == '(' )
664           {
665             strcat(arglist, ")");
666           }
667       }
668
669     if( (nearest->sourcefile != NULL) && (flag == TRUE)
670         && (addr->off - nearest->value.addr.off < 0x100000) )
671       {
672
673         /*
674          * Try and find the nearest line number to the current offset.
675          */
676         if( nearest->linetab != NULL )
677         {
678             low = 0;
679             high = nearest->n_lines;
680             while ((high - low) > 1)
681             {
682                 mid = (high + low) / 2;
683                 if (addr->off < nearest->linetab[mid].pc_offset.off)
684                     high = mid;
685                 else
686                     low = mid;
687             }
688             lineno = nearest->linetab[low].line_number;
689         }
690
691         if( lineno != -1 )
692           {
693             sprintf(linebuff, ":%d", lineno);
694             lineinfo = linebuff;
695             if( source != NULL )
696               {
697                 source->line = lineno;
698               }
699           }
700
701         /* Remove the path from the file name */
702         sourcefile = strrchr( nearest->sourcefile, '/' );
703         if (!sourcefile) sourcefile = nearest->sourcefile;
704         else sourcefile++;
705
706         if (addr->off == nearest->value.addr.off)
707           sprintf( name_buffer, "%s%s [%s%s]", nearest->name, 
708                    arglist, sourcefile, lineinfo);
709         else
710           sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
711                    addr->off - nearest->value.addr.off, 
712                    arglist, sourcefile, lineinfo );
713       }
714     else
715       {
716         if (addr->off == nearest->value.addr.off)
717           sprintf( name_buffer, "%s%s", nearest->name, arglist);
718         else {
719           if (addr->seg && (nearest->value.addr.seg!=addr->seg))
720               return NULL;
721           else
722               sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
723                        addr->off - nearest->value.addr.off, arglist);
724         }
725       }
726     return name_buffer;
727 }
728
729
730 /***********************************************************************
731  *           DEBUG_ReadSymbolTable
732  *
733  * Read a symbol file into the hash table.
734  */
735 void DEBUG_ReadSymbolTable( const char * filename )
736 {
737     FILE * symbolfile;
738     DBG_VALUE value;
739     char type;
740     char * cpnt;
741     char buffer[256];
742     char name[256];
743
744     if (!(symbolfile = fopen(filename, "r")))
745     {
746         DEBUG_Printf( DBG_CHN_WARN, "Unable to open symbol table %s\n", filename );
747         return;
748     }
749
750     DEBUG_Printf( DBG_CHN_MESG, "Reading symbols from file %s\n", filename );
751
752     value.type = NULL;
753     value.addr.seg = 0;
754     value.addr.off = 0;
755     value.cookie = DV_TARGET;
756  
757     while (1)
758     {
759         fgets( buffer, sizeof(buffer), symbolfile );
760         if (feof(symbolfile)) break;
761                 
762         /* Strip any text after a # sign (i.e. comments) */
763         cpnt = buffer;
764         while (*cpnt)
765             if(*cpnt++ == '#') { *cpnt = 0; break; }
766                 
767         /* Quietly ignore any lines that have just whitespace */
768         cpnt = buffer;
769         while(*cpnt)
770         {
771             if(*cpnt != ' ' && *cpnt != '\t') break;
772             cpnt++;
773         }
774         if (!(*cpnt) || *cpnt == '\n') continue;
775                 
776         if (sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name) == 3)
777            DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
778     }
779     fclose(symbolfile);
780 }
781
782
783 void
784 DEBUG_AddLineNumber( struct name_hash * func, int line_num, 
785                      unsigned long offset )
786 {
787   if( func == NULL )
788     {
789       return;
790     }
791
792   if( func->n_lines + 1 >= func->lines_alloc )
793     {
794       func->lines_alloc += 64;
795       func->linetab = DBG_realloc(func->linetab,
796                               func->lines_alloc * sizeof(WineLineNo));
797     }
798
799   func->linetab[func->n_lines].line_number = line_num;
800   func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
801   func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
802   func->n_lines++;
803 }
804
805
806 struct wine_locals *
807 DEBUG_AddLocal( struct name_hash * func, int regno, 
808                 int offset,
809                 int pc_start,
810                 int pc_end,
811                 char * name)
812 {
813   if( func == NULL )
814     {
815       return NULL;
816     }
817
818   if( func->n_locals + 1 >= func->locals_alloc )
819     {
820       func->locals_alloc += 32;
821       func->local_vars = DBG_realloc(func->local_vars,
822                               func->locals_alloc * sizeof(WineLocals));
823     }
824
825   func->local_vars[func->n_locals].regno = regno;
826   func->local_vars[func->n_locals].offset = offset;
827   func->local_vars[func->n_locals].pc_start = pc_start;
828   func->local_vars[func->n_locals].pc_end = pc_end;
829   func->local_vars[func->n_locals].name = DBG_strdup(name);
830   func->local_vars[func->n_locals].type = NULL;
831   func->n_locals++;
832
833   return &func->local_vars[func->n_locals - 1];
834 }
835
836 void
837 DEBUG_DumpHashInfo(void)
838 {
839   int i;
840   int depth;
841   struct name_hash *nh;
842
843   /*
844    * Utility function to dump stats about the hash table.
845    */
846     for(i=0; i<NR_NAME_HASH; i++)
847     {
848       depth = 0;
849       for (nh = name_hash_table[i]; nh; nh = nh->next)
850         {
851           depth++;
852         }
853       DEBUG_Printf(DBG_CHN_MESG, "Bucket %d: %d\n", i, depth);
854     }
855 }
856
857 /***********************************************************************
858  *           DEBUG_CheckLinenoStatus
859  *
860  * Find the symbol nearest to a given address.
861  * If ebp is specified as non-zero, it means we should dump the argument
862  * list into the string we return as well.
863  */
864 int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
865 {
866     struct name_hash * nearest = NULL;
867     int mid, high, low;
868
869     if( sortlist_valid == FALSE )
870       {
871         DEBUG_ResortSymbols();
872       }
873
874     /*
875      * Binary search to find closest symbol.
876      */
877     low = 0;
878     high = sorttab_nsym;
879     if( addr_sorttab[0]->value.addr.seg > addr->seg
880         || (   addr_sorttab[0]->value.addr.seg == addr->seg 
881             && addr_sorttab[0]->value.addr.off > addr->off) )
882       {
883         nearest = NULL;
884       }
885     else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
886         || (   addr_sorttab[high - 1]->value.addr.seg == addr->seg 
887             && addr_sorttab[high - 1]->value.addr.off < addr->off) )
888       {
889         nearest = addr_sorttab[high - 1];
890       }
891     else
892       {
893         while(1==1)
894           {
895             mid = (high + low)/2;
896             if( mid == low )
897               {
898                 /* 
899                  * See if there are any other entries that might also
900                  * have the same address, and would also have a line
901                  * number table.  
902                  */
903                 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
904                   {
905                     if(    (addr_sorttab[mid - 1]->value.addr.seg ==
906                             addr_sorttab[mid]->value.addr.seg)
907                         && (addr_sorttab[mid - 1]->value.addr.off ==
908                             addr_sorttab[mid]->value.addr.off)
909                         && (addr_sorttab[mid - 1]->linetab != NULL) )
910                       {
911                         mid--;
912                       }
913                   }
914
915                 if(    (mid < sorttab_nsym - 1)
916                     && (addr_sorttab[mid]->linetab == NULL) )
917                   {
918                     if(    (addr_sorttab[mid + 1]->value.addr.seg ==
919                             addr_sorttab[mid]->value.addr.seg)
920                         && (addr_sorttab[mid + 1]->value.addr.off ==
921                             addr_sorttab[mid]->value.addr.off)
922                         && (addr_sorttab[mid + 1]->linetab != NULL) )
923                       {
924                         mid++;
925                       }
926                   }
927                 nearest = addr_sorttab[mid];
928 #if 0
929                 DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
930                              addr_sorttab[mid ]->value.addr.seg,
931                              addr_sorttab[mid ]->value.addr.off,
932                              addr->seg, addr->off,
933                              addr_sorttab[mid ]->linetab,
934                              addr_sorttab[mid ]->name);
935 #endif
936                 break;
937               }
938             if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
939                 || (   addr_sorttab[mid]->value.addr.seg == addr->seg 
940                     && addr_sorttab[mid]->value.addr.off <= addr->off) )
941               {
942                 low = mid;
943               }
944             else
945               {
946                 high = mid;
947               }
948           }
949       }
950
951     if (!nearest) return FUNC_HAS_NO_LINES;
952
953     if( nearest->flags & SYM_STEP_THROUGH )
954       {
955         /*
956          * This will cause us to keep single stepping until
957          * we get to the other side somewhere.
958          */
959         return NOT_ON_LINENUMBER;
960       }
961
962     if( (nearest->flags & SYM_TRAMPOLINE) )
963       {
964         /*
965          * This will cause us to keep single stepping until
966          * we get to the other side somewhere.
967          */
968         return FUNC_IS_TRAMPOLINE;
969       }
970
971     if( nearest->linetab == NULL )
972       {
973         return FUNC_HAS_NO_LINES;
974       }
975
976
977     /*
978      * We never want to stop on the first instruction of a function
979      * even if it has it's own linenumber.  Let the thing keep running
980      * until it gets past the function prologue.  We only do this if there
981      * is more than one line number for the function, of course.
982      */
983     if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
984       {
985         return NOT_ON_LINENUMBER;
986       }
987
988     if( (nearest->sourcefile != NULL)
989         && (addr->off - nearest->value.addr.off < 0x100000) )
990       {
991           low = 0;
992           high = nearest->n_lines;
993           while ((high - low) > 1)
994           {
995               mid = (high + low) / 2;
996               if (addr->off < nearest->linetab[mid].pc_offset.off) high = mid;
997               else low = mid;
998           }
999           if (addr->off == nearest->linetab[low].pc_offset.off)
1000               return AT_LINENUMBER;
1001           else
1002               return NOT_ON_LINENUMBER;
1003       }
1004
1005     return FUNC_HAS_NO_LINES;
1006 }
1007
1008 /***********************************************************************
1009  *           DEBUG_GetFuncInfo
1010  *
1011  * Find the symbol nearest to a given address.
1012  * Returns sourcefile name and line number in a format that the listing
1013  * handler can deal with.
1014  */
1015 void
1016 DEBUG_GetFuncInfo( struct list_id * ret, const char * filename, 
1017                    const char * name)
1018 {
1019     char buffer[256];
1020     char * pnt;
1021     struct name_hash *nh;
1022
1023     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
1024       {
1025         if( filename != NULL )
1026           {
1027
1028             if( nh->sourcefile == NULL )
1029               {
1030                 continue;
1031               }
1032
1033             pnt = strrchr(nh->sourcefile, '/');
1034             if( strcmp(nh->sourcefile, filename) != 0
1035                 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1036               {
1037                 continue;
1038               }
1039           }
1040         if (!strcmp(nh->name, name)) break;
1041       }
1042
1043     if (!nh && (name[0] != '_'))
1044     {
1045         buffer[0] = '_';
1046         strcpy(buffer+1, name);
1047         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
1048           {
1049             if( filename != NULL )
1050               {
1051                 if( nh->sourcefile == NULL )
1052                   {
1053                     continue;
1054                   }
1055
1056                 pnt = strrchr(nh->sourcefile, '/');
1057                 if( strcmp(nh->sourcefile, filename) != 0
1058                     && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1059                   {
1060                     continue;
1061                   }
1062               }
1063             if (!strcmp(nh->name, buffer)) break;
1064           }
1065     }
1066
1067     if( !nh )
1068       {
1069         if( filename != NULL )
1070           {
1071             DEBUG_Printf(DBG_CHN_MESG, "No such function %s in %s\n", name, filename);
1072           }
1073         else
1074           {
1075             DEBUG_Printf(DBG_CHN_MESG, "No such function %s\n", name);
1076           }
1077         ret->sourcefile = NULL;
1078         ret->line = -1;
1079         return;
1080       }
1081
1082     ret->sourcefile = nh->sourcefile;
1083
1084     /*
1085      * Search for the specific line number.  If we don't find it,
1086      * then return FALSE.
1087      */
1088     if( nh->linetab == NULL )
1089       {
1090         ret->line = -1;
1091       }
1092     else
1093       {
1094         ret->line = nh->linetab[0].line_number;
1095       }
1096 }
1097
1098 /***********************************************************************
1099  *           DEBUG_GetStackSymbolValue
1100  *
1101  * Get the address of a named symbol from the current stack frame.
1102  */
1103 static
1104 BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
1105 {
1106   struct name_hash * curr_func;
1107   unsigned int       ebp;
1108   unsigned int       eip;
1109   int                i;
1110
1111   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1112     {
1113       return FALSE;
1114     }
1115
1116   for(i=0; i < curr_func->n_locals; i++ )
1117     {
1118       /*
1119        * Test the range of validity of the local variable.  This
1120        * comes up with RBRAC/LBRAC stabs in particular.
1121        */
1122       if(    (curr_func->local_vars[i].pc_start != 0)
1123           && ((eip - curr_func->value.addr.off) 
1124               < curr_func->local_vars[i].pc_start) )
1125         {
1126           continue;
1127         }
1128
1129       if(    (curr_func->local_vars[i].pc_end != 0)
1130           && ((eip - curr_func->value.addr.off) 
1131               > curr_func->local_vars[i].pc_end) )
1132         {
1133           continue;
1134         }
1135
1136       if( strcmp(name, curr_func->local_vars[i].name) == 0 )
1137         {
1138           /*
1139            * OK, we found it.  Now figure out what to do with this.
1140            */
1141           if( curr_func->local_vars[i].regno != 0 )
1142             {
1143               /*
1144                * Register variable.  Point to DEBUG_context field.
1145                */
1146               assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
1147               value->addr.off = ((DWORD)&DEBUG_context) + 
1148                  reg_ofs[curr_func->local_vars[i].regno - 1];
1149               value->cookie = DV_HOST;
1150             }
1151           else 
1152             {
1153               value->addr.off = ebp + curr_func->local_vars[i].offset;
1154               value->cookie = DV_TARGET;
1155             }
1156           value->addr.seg = 0;
1157           value->type = curr_func->local_vars[i].type;
1158
1159           return TRUE;
1160         }
1161     }
1162
1163   return FALSE;
1164 }
1165
1166 int
1167 DEBUG_InfoLocals(void)
1168 {
1169   struct name_hash  * curr_func;
1170   unsigned int        ebp;
1171   unsigned int        eip;
1172   int                 i;
1173   unsigned int      * ptr;
1174   unsigned int        val;
1175
1176   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1177     {
1178       return FALSE;
1179     }
1180
1181   for(i=0; i < curr_func->n_locals; i++ )
1182     {
1183       /*
1184        * Test the range of validity of the local variable.  This
1185        * comes up with RBRAC/LBRAC stabs in particular.
1186        */
1187       if(    (curr_func->local_vars[i].pc_start != 0)
1188           && ((eip - curr_func->value.addr.off) 
1189               < curr_func->local_vars[i].pc_start) )
1190         {
1191           continue;
1192         }
1193
1194       if(    (curr_func->local_vars[i].pc_end != 0)
1195           && ((eip - curr_func->value.addr.off) 
1196               > curr_func->local_vars[i].pc_end) )
1197         {
1198           continue;
1199         }
1200       
1201       if( curr_func->local_vars[i].regno != 0 )
1202         {
1203           ptr = (unsigned int *)(((DWORD)&DEBUG_context)
1204                                  + reg_ofs[curr_func->local_vars[i].regno - 1]);
1205           DEBUG_Printf(DBG_CHN_MESG, "%s:%s (optimized into register $%s) == 0x%8.8x\n",
1206                        curr_func->name, curr_func->local_vars[i].name,
1207                        reg_name[curr_func->local_vars[i].regno - 1],
1208                        *ptr);
1209         }
1210       else
1211         {
1212           DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset), 
1213                                  &val, sizeof(val));
1214           DEBUG_Printf(DBG_CHN_MESG, "%s:%s == 0x%8.8x\n",
1215                        curr_func->name, curr_func->local_vars[i].name, val);
1216         }
1217     }
1218
1219   return TRUE;
1220 }
1221
1222 int
1223 DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
1224 {
1225   sym->symbol_size = len;
1226
1227   return TRUE;
1228 }
1229
1230 int
1231 DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
1232 {
1233   sym->breakpoint_offset = off;
1234
1235   return TRUE;
1236 }
1237
1238 int
1239 DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
1240 {
1241
1242   *addr = sym->value.addr;
1243
1244   return TRUE;
1245 }
1246
1247 int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
1248 {
1249   sym->type = type;
1250
1251   return TRUE;
1252 }