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