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