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