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