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