- Added experimental parsing for C++ code (but winedbg doesn't support
[wine] / programs / winedbg / hash.c
1 /*
2  * File hash.c - generate hash tables for Wine debugger symbols
3  *
4  * Copyright (C) 1993, Eric Youngdale.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <sys/types.h>
28 #include "debugger.h"
29
30 #define NR_NAME_HASH 16384
31 #ifndef PATH_MAX
32 #define PATH_MAX MAX_PATH
33 #endif
34
35 #ifdef __i386__
36 static char * reg_name[] =
37 {
38   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
39 };
40
41 static unsigned reg_ofs[] =
42 {
43   FIELD_OFFSET(CONTEXT, Eax), FIELD_OFFSET(CONTEXT, Ecx),
44   FIELD_OFFSET(CONTEXT, Edx), FIELD_OFFSET(CONTEXT, Ebx),
45   FIELD_OFFSET(CONTEXT, Esp), FIELD_OFFSET(CONTEXT, Ebp),
46   FIELD_OFFSET(CONTEXT, Esi), FIELD_OFFSET(CONTEXT, Edi)
47 };
48 #else
49 static char * reg_name[] = { NULL };   /* FIXME */
50 static unsigned reg_ofs[] = { 0 };
51 #endif
52
53
54 struct name_hash
55 {
56     struct name_hash * next;            /* Used to look up within name hash */
57     char *             name;
58     char *             sourcefile;
59
60     int                n_locals;
61     int                locals_alloc;
62     WineLocals       * local_vars;
63
64     int                n_lines;
65     int                lines_alloc;
66     WineLineNo       * linetab;
67
68     DBG_VALUE          value;
69     unsigned short     flags;
70     unsigned short     breakpoint_offset;
71     unsigned int       symbol_size;
72 };
73
74
75 static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value );
76 static int sortlist_valid = FALSE;
77
78 static int sorttab_nsym;
79 static struct name_hash ** addr_sorttab = NULL;
80
81 static struct name_hash * name_hash_table[NR_NAME_HASH];
82
83 static unsigned int name_hash( const char * name )
84 {
85     unsigned int hash = 0;
86     unsigned int tmp;
87     const char * p;
88
89     p = name;
90
91     while (*p)
92       {
93         hash = (hash << 4) + *p++;
94
95         if( (tmp = (hash & 0xf0000000)) )
96           {
97             hash ^= tmp >> 24;
98           }
99         hash &= ~tmp;
100       }
101     return hash % NR_NAME_HASH;
102 }
103
104 int
105 DEBUG_cmp_sym(const void * p1, const void * p2)
106 {
107   struct name_hash ** name1 = (struct name_hash **) p1;
108   struct name_hash ** name2 = (struct name_hash **) p2;
109
110   if( ((*name1)->flags & SYM_INVALID) != 0 )
111     {
112       return -1;
113     }
114
115   if( ((*name2)->flags & SYM_INVALID) != 0 )
116     {
117       return 1;
118     }
119
120   if( (*name1)->value.addr.seg > (*name2)->value.addr.seg )
121     {
122       return 1;
123     }
124
125   if( (*name1)->value.addr.seg < (*name2)->value.addr.seg )
126     {
127       return -1;
128     }
129
130   if( (*name1)->value.addr.off > (*name2)->value.addr.off )
131     {
132       return 1;
133     }
134
135   if( (*name1)->value.addr.off < (*name2)->value.addr.off )
136     {
137       return -1;
138     }
139
140   return 0;
141 }
142
143 /***********************************************************************
144  *           DEBUG_ResortSymbols
145  *
146  * Rebuild sorted list of symbols.
147  */
148 static
149 void
150 DEBUG_ResortSymbols(void)
151 {
152     struct name_hash *nh;
153     int         nsym = 0;
154     int         i;
155
156     for(i=0; i<NR_NAME_HASH; i++)
157     {
158         for (nh = name_hash_table[i]; nh; nh = nh->next)
159           {
160             if( (nh->flags & SYM_INVALID) == 0 )
161                nsym++;
162             else
163                DEBUG_Printf( DBG_CHN_MESG, "Symbol %s is invalid\n", nh->name );
164           }
165     }
166
167     sorttab_nsym = nsym;
168     if( nsym == 0 )
169       {
170         return;
171       }
172
173     addr_sorttab = (struct name_hash **) DBG_realloc(addr_sorttab,
174                                          nsym * sizeof(struct name_hash *));
175
176     nsym = 0;
177     for(i=0; i<NR_NAME_HASH; i++)
178     {
179         for (nh = name_hash_table[i]; nh; nh = nh->next)
180           {
181             if( (nh->flags & SYM_INVALID) == 0 )
182                addr_sorttab[nsym++] = nh;
183           }
184     }
185
186     qsort(addr_sorttab, nsym,
187           sizeof(struct name_hash *), DEBUG_cmp_sym);
188     sortlist_valid = TRUE;
189
190 }
191
192 /***********************************************************************
193  *           DEBUG_AddSymbol
194  *
195  * Add a symbol to the table.
196  */
197 struct name_hash *
198 DEBUG_AddSymbol( const char * name, const DBG_VALUE *value,
199                  const char * source, int flags)
200 {
201     struct name_hash  * new;
202     struct name_hash *nh;
203     static char  prev_source[PATH_MAX] = {'\0', };
204     static char * prev_duped_source = NULL;
205     int hash;
206
207     assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
208
209     hash = name_hash(name);
210     for (nh = name_hash_table[hash]; nh; nh = nh->next)
211     {
212         if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
213         {
214 #if 0
215             DEBUG_Printf(DBG_CHN_MESG, "Changing address for symbol %s (%08lx:%08lx => %08lx:%08lx)\n",
216                          name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
217 #endif
218             nh->value.addr = value->addr;
219             if( nh->value.type == NULL && value->type != NULL )
220             {
221                 nh->value.type = value->type;
222                 nh->value.cookie = value->cookie;
223             }
224             /* it may happen that the same symbol is defined in several compilation
225              * units, but the linker decides to merge it into a single instance.
226              * in that case, we don't clear the invalid flag for all the compilation
227              * units (N_GSYM), and wait to get the symbol from the symtab
228              */
229             if ((flags & SYM_INVALID) == 0)
230                nh->flags &= ~SYM_INVALID;
231
232             return nh;
233         }
234         if (nh->value.addr.seg == value->addr.seg &&
235             nh->value.addr.off == value->addr.off &&
236             strcmp(name, nh->name) == 0 )
237         {
238             return nh;
239         }
240     }
241
242 #if 0
243     DEBUG_Printf(DBG_CHN_TRACE, "adding symbol (%s) from file '%s' at 0x%04lx:%08lx\n",
244                  name, source, value->addr.seg, value->addr.off);
245 #endif
246
247     /*
248      * First see if we already have an entry for this symbol.  If so
249      * return it, so we don't end up with duplicates.
250      */
251
252     new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash));
253     new->value = *value;
254     new->name = DBG_strdup(name);
255
256     if( source != NULL )
257       {
258         /*
259          * This is an enhancement to reduce memory consumption.  The idea
260          * is that we duplicate a given string only once.  This is a big
261          * win if there are lots of symbols defined in a given source file.
262          */
263         if( strcmp(source, prev_source) == 0 )
264           {
265             new->sourcefile = prev_duped_source;
266           }
267         else
268           {
269             strcpy(prev_source, source);
270             prev_duped_source = new->sourcefile = DBG_strdup(source);
271           }
272       }
273     else
274       {
275         new->sourcefile = NULL;
276       }
277
278     new->n_lines        = 0;
279     new->lines_alloc    = 0;
280     new->linetab        = NULL;
281
282     new->n_locals       = 0;
283     new->locals_alloc   = 0;
284     new->local_vars     = NULL;
285
286     new->flags          = flags;
287     new->next           = NULL;
288
289     /* Now insert into the hash table */
290     new->next = name_hash_table[hash];
291     name_hash_table[hash] = new;
292
293     /*
294      * Check some heuristics based upon the file name to see whether
295      * we want to step through this guy or not.  These are machine generated
296      * assembly files that are used to translate between the MS way of
297      * calling things and the GCC way of calling things.  In general we
298      * always want to step through.
299      */
300     if ( source != NULL ) {
301         int     len = strlen(source);
302
303         if (len > 2 && source[len-2] == '.' && source[len-1] == 's') {
304             char* c = strrchr(source - 2, '/');
305             if (c != NULL) {
306                 if (strcmp(c + 1, "asmrelay.s") == 0)
307                     new->flags |= SYM_TRAMPOLINE;
308             }
309         }
310     }
311
312     sortlist_valid = FALSE;
313     return new;
314 }
315
316 BOOL DEBUG_Normalize(struct name_hash * nh )
317 {
318
319   /*
320    * We aren't adding any more locals or linenumbers to this function.
321    * Free any spare memory that we might have allocated.
322    */
323   if( nh == NULL )
324     {
325       return TRUE;
326     }
327
328   if( nh->n_locals != nh->locals_alloc )
329     {
330       nh->locals_alloc = nh->n_locals;
331       nh->local_vars = DBG_realloc(nh->local_vars,
332                                   nh->locals_alloc * sizeof(WineLocals));
333     }
334
335   if( nh->n_lines != nh->lines_alloc )
336     {
337       nh->lines_alloc = nh->n_lines;
338       nh->linetab = DBG_realloc(nh->linetab,
339                               nh->lines_alloc * sizeof(WineLineNo));
340     }
341
342   return TRUE;
343 }
344
345 /***********************************************************************
346  *           DEBUG_GetSymbolValue
347  *
348  * Get the address of a named symbol.
349  * Return values:
350  *      gsv_found:   if the symbol is found
351  *      gsv_unknown: if the symbol isn't found
352  *      gsv_aborted: some error occured (likely, many symbols of same name exist, 
353  *          and user didn't pick one of them)
354  */
355 static int    DEBUG_GSV_Helper(const char* name, const int lineno,
356                                DBG_VALUE* value, int num, int bp_flag)
357 {
358    struct name_hash*    nh;
359    int                  i = 0;
360    DBG_ADDR             addr;
361
362    for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
363    {
364       if ((nh->flags & SYM_INVALID) != 0) continue;
365       if (!strcmp(nh->name, name) && DEBUG_GetLineNumberAddr( nh, lineno, &addr, bp_flag ))
366       {
367          if (i >= num) return num + 1;
368          value[i].addr = addr;
369          value[i].type = nh->value.type;
370          value[i].cookie = nh->value.cookie;
371          i++;
372       }
373    }
374    return i;
375 }
376
377 enum get_sym_val DEBUG_GetSymbolValue( const char * name, 
378                                        const int lineno,
379                                        DBG_VALUE *rtn, int bp_flag )
380 {
381 #define NUMDBGV 10
382    /* FIXME: NUMDBGV should be made variable */
383    DBG_VALUE    value[NUMDBGV];
384    DBG_VALUE    vtmp;
385    int          num, i, local = -1;
386
387    num = DEBUG_GSV_Helper(name, lineno, value, NUMDBGV, bp_flag);
388    if (!num && (name[0] != '_'))
389    {
390       char buffer[512];
391
392       if (strlen(name) < sizeof(buffer) - 2) /* one for '_', one for '\0' */
393       {
394           buffer[0] = '_';
395           strcpy(buffer + 1, name);
396           num = DEBUG_GSV_Helper(buffer, lineno, value, NUMDBGV, bp_flag);
397       }
398       else DEBUG_Printf(DBG_CHN_WARN, "Way too long symbol (%s)\n", name);
399    }
400
401    /* now get the local symbols if any */
402    if (DEBUG_GetStackSymbolValue(name, &vtmp) && num < NUMDBGV)
403    {
404       value[num] = vtmp;
405       local = num;
406       num++;
407    }
408
409    if (num == 0) {
410       return gsv_unknown;
411    } else if (!DEBUG_InteractiveP || num == 1) {
412       i = 0;
413    } else {
414       char      buffer[256];
415
416       if (num == NUMDBGV+1) {
417          DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
418          num = NUMDBGV;
419       }
420       DEBUG_Printf(DBG_CHN_MESG, "Many symbols with name '%s', choose the one you want (<cr> to abort):\n", name);
421       for (i = 0; i < num; i++) {
422          DEBUG_Printf(DBG_CHN_MESG, "[%d]: ", i + 1);
423          if (i == local) {
424              struct name_hash*func;
425              unsigned int     ebp;
426              unsigned int     eip;
427
428              if (DEBUG_GetCurrentFrame(&func, &eip, &ebp))
429                  DEBUG_Printf(DBG_CHN_MESG, "local variable of %s in %s\n", func->name, func->sourcefile);
430              else
431                  DEBUG_Printf(DBG_CHN_MESG, "local variable\n");
432          } else {
433              DEBUG_PrintAddress( &value[i].addr, DEBUG_GetSelectorType(value[i].addr.seg), TRUE);
434              DEBUG_Printf(DBG_CHN_MESG, "\n");
435          }
436       }
437       do {
438           i = 0;
439           if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer)))
440           {
441               if (buffer[0] == '\0') return gsv_aborted;
442               i = atoi(buffer);
443               if (i < 1 || i > num)
444                   DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i);
445           }
446       } while (i < 1 || i > num);
447
448       /* The array is 0-based, but the choices are 1..n, so we have to subtract one before returning. */
449       i--;
450    }
451    *rtn = value[i];
452    return gsv_found;
453 }
454
455 /***********************************************************************
456  *           DEBUG_GetLineNumberAddr
457  *
458  * Get the address of a named symbol.
459  */
460 BOOL DEBUG_GetLineNumberAddr( const struct name_hash * nh, const int lineno,
461                               DBG_ADDR *addr, int bp_flag )
462 {
463     int i;
464
465     if( lineno == -1 )
466       {
467         *addr = nh->value.addr;
468         if( bp_flag )
469           {
470             addr->off += nh->breakpoint_offset;
471           }
472       }
473     else
474       {
475         /*
476          * Search for the specific line number.  If we don't find it,
477          * then return FALSE.
478          */
479         if( nh->linetab == NULL )
480           {
481             return FALSE;
482           }
483
484         for(i=0; i < nh->n_lines; i++ )
485           {
486             if( nh->linetab[i].line_number == lineno )
487               {
488                 *addr = nh->linetab[i].pc_offset;
489                 return TRUE;
490               }
491           }
492
493         /*
494          * This specific line number not found.
495          */
496         return FALSE;
497       }
498
499     return TRUE;
500 }
501
502
503 /***********************************************************************
504  *           DEBUG_SetSymbolValue
505  *
506  * Set the address of a named symbol.
507  */
508 BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *value )
509 {
510     char buffer[256];
511     struct name_hash *nh;
512
513     assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
514
515     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
516         if (!strcmp(nh->name, name)) break;
517
518     if (!nh && (name[0] != '_'))
519     {
520         buffer[0] = '_';
521         strcpy(buffer+1, name);
522         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
523             if (!strcmp(nh->name, buffer)) break;
524     }
525
526     if (!nh) return FALSE;
527     nh->value = *value;
528     nh->flags &= ~SYM_INVALID;
529
530 #ifdef __i386__
531     DEBUG_FixAddress( &nh->value.addr, DEBUG_context.SegDs );
532 #endif
533
534     return TRUE;
535 }
536
537
538 /***********************************************************************
539  *           DEBUG_FindNearestSymbol
540  *
541  * Find the symbol nearest to a given address.
542  * If ebp is specified as non-zero, it means we should dump the argument
543  * list into the string we return as well.
544  */
545 const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
546                                       struct name_hash ** rtn,
547                                       unsigned int ebp,
548                                       struct list_id * source)
549 {
550     static char name_buffer[MAX_PATH + 256];
551     static char arglist[1024];
552     static char argtmp[256];
553     struct name_hash * nearest = NULL;
554     int mid, high, low;
555     unsigned    int * ptr;
556     int lineno;
557     char * lineinfo, *sourcefile;
558     int i;
559     char linebuff[16];
560     unsigned val;
561     DBG_MODULE* module;
562     char modbuf[256];
563
564     if( rtn != NULL )
565       {
566         *rtn = NULL;
567       }
568
569     if( source != NULL )
570       {
571         source->sourcefile = NULL;
572         source->line = -1;
573       }
574
575     if( sortlist_valid == FALSE )
576       {
577         DEBUG_ResortSymbols();
578       }
579
580     if( sortlist_valid == FALSE )
581       {
582         return NULL;
583       }
584
585     /*
586      * FIXME  - use the binary search that we added to
587      * the function DEBUG_CheckLinenoStatus.  Better yet, we should
588      * probably keep some notion of the current function so we don't
589      * have to search every time.
590      */
591     /*
592      * Binary search to find closest symbol.
593      */
594     low = 0;
595     high = sorttab_nsym;
596     if( addr_sorttab[0]->value.addr.seg > addr->seg
597         || (   addr_sorttab[0]->value.addr.seg == addr->seg
598             && addr_sorttab[0]->value.addr.off > addr->off) )
599       {
600         nearest = NULL;
601       }
602     else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
603         || (   addr_sorttab[high - 1]->value.addr.seg == addr->seg
604             && addr_sorttab[high - 1]->value.addr.off < addr->off) )
605       {
606         nearest = addr_sorttab[high - 1];
607       }
608     else
609       {
610         while(1==1)
611           {
612             mid = (high + low)/2;
613             if( mid == low )
614               {
615                 /*
616                  * See if there are any other entries that might also
617                  * have the same address, and would also have a line
618                  * number table.
619                  */
620                 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
621                   {
622                     if(    (addr_sorttab[mid - 1]->value.addr.seg ==
623                             addr_sorttab[mid]->value.addr.seg)
624                         && (addr_sorttab[mid - 1]->value.addr.off ==
625                             addr_sorttab[mid]->value.addr.off)
626                         && (addr_sorttab[mid - 1]->linetab != NULL) )
627                       {
628                         mid--;
629                       }
630                   }
631
632                 if(    (mid < sorttab_nsym - 1)
633                     && (addr_sorttab[mid]->linetab == NULL) )
634                   {
635                     if(    (addr_sorttab[mid + 1]->value.addr.seg ==
636                             addr_sorttab[mid]->value.addr.seg)
637                         && (addr_sorttab[mid + 1]->value.addr.off ==
638                             addr_sorttab[mid]->value.addr.off)
639                         && (addr_sorttab[mid + 1]->linetab != NULL) )
640                       {
641                         mid++;
642                       }
643                   }
644                 nearest = addr_sorttab[mid];
645 #if 0
646                 DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
647                              addr_sorttab[mid ]->value.addr.seg,
648                              addr_sorttab[mid ]->value.addr.off,
649                              addr->seg, addr->off,
650                              addr_sorttab[mid ]->linetab,
651                              addr_sorttab[mid ]->name);
652 #endif
653                 break;
654               }
655             if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
656                 || (   addr_sorttab[mid]->value.addr.seg == addr->seg
657                     && addr_sorttab[mid]->value.addr.off <= addr->off) )
658               {
659                 low = mid;
660               }
661             else
662               {
663                 high = mid;
664               }
665           }
666       }
667
668     if (!nearest) return NULL;
669
670     if( rtn != NULL )
671       {
672         *rtn = nearest;
673       }
674
675     /*
676      * Fill in the relevant bits to the structure so that we can
677      * locate the source and line for this bit of code.
678      */
679     if( source != NULL )
680       {
681         source->sourcefile = nearest->sourcefile;
682         if( nearest->linetab == NULL )
683           {
684             source->line = -1;
685           }
686         else
687           {
688             source->line = nearest->linetab[0].line_number;
689           }
690       }
691
692     lineinfo = "";
693     lineno = -1;
694
695     /*
696      * Prepare to display the argument list.  If ebp is specified, it is
697      * the framepointer for the function in question.  If not specified,
698      * we don't want the arglist.
699      */
700     memset(arglist, '\0', sizeof(arglist));
701     if( ebp != 0 )
702       {
703         for(i=0; i < nearest->n_locals; i++ )
704           {
705             /*
706              * If this is a register (offset == 0) or a local
707              * variable, we don't want to know about it.
708              */
709             if( nearest->local_vars[i].offset <= 0 )
710               {
711                 continue;
712               }
713
714             ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
715             if( arglist[0] == '\0' )
716               {
717                 arglist[0] = '(';
718               }
719             else
720               {
721                 strcat(arglist, ", ");
722               }
723             DEBUG_READ_MEM_VERBOSE(ptr, &val, sizeof(val));
724             sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name, val);
725
726             strcat(arglist, argtmp);
727           }
728         if( arglist[0] == '(' )
729           {
730             strcat(arglist, ")");
731           }
732       }
733
734     module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
735     if (module) {
736        char*    ptr = strrchr(module->module_name, '/');
737
738        if (!ptr++) ptr = module->module_name;
739        sprintf( modbuf, " in %s", ptr);
740     }
741     else
742        modbuf[0] = '\0';
743
744     if( (nearest->sourcefile != NULL) && (flag == TRUE)
745         && (addr->off - nearest->value.addr.off < 0x100000) )
746       {
747
748         /*
749          * Try and find the nearest line number to the current offset.
750          */
751         if( nearest->linetab != NULL )
752         {
753             low = 0;
754             high = nearest->n_lines;
755             while ((high - low) > 1)
756             {
757                 mid = (high + low) / 2;
758                 if (addr->off < nearest->linetab[mid].pc_offset.off)
759                     high = mid;
760                 else
761                     low = mid;
762             }
763             lineno = nearest->linetab[low].line_number;
764         }
765
766         if( lineno != -1 )
767           {
768             sprintf(linebuff, ":%d", lineno);
769             lineinfo = linebuff;
770             if( source != NULL )
771               {
772                 source->line = lineno;
773               }
774           }
775
776         /* Remove the path from the file name */
777         sourcefile = strrchr( nearest->sourcefile, '/' );
778         if (!sourcefile) sourcefile = nearest->sourcefile;
779         else sourcefile++;
780
781         if (addr->off == nearest->value.addr.off)
782           sprintf( name_buffer, "%s%s [%s%s]%s", nearest->name,
783                    arglist, sourcefile, lineinfo, modbuf);
784         else
785           sprintf( name_buffer, "%s+0x%lx%s [%s%s]%s", nearest->name,
786                    addr->off - nearest->value.addr.off,
787                    arglist, sourcefile, lineinfo, modbuf );
788       }
789     else
790       {
791         if (addr->off == nearest->value.addr.off)
792           sprintf( name_buffer, "%s%s%s", nearest->name, arglist, modbuf);
793         else {
794           if (addr->seg && (nearest->value.addr.seg!=addr->seg))
795               return NULL;
796           else
797               sprintf( name_buffer, "%s+0x%lx%s%s", nearest->name,
798                        addr->off - nearest->value.addr.off, arglist, modbuf);
799         }
800       }
801     return name_buffer;
802 }
803
804
805 /***********************************************************************
806  *           DEBUG_ReadSymbolTable
807  *
808  * Read a symbol file into the hash table.
809  */
810 void DEBUG_ReadSymbolTable( const char* filename, unsigned long offset )
811 {
812     FILE * symbolfile;
813     DBG_VALUE value;
814     char type;
815     char * cpnt;
816     char buffer[256];
817     char name[256];
818
819     if (!(symbolfile = fopen(filename, "r")))
820     {
821         DEBUG_Printf( DBG_CHN_WARN, "Unable to open symbol table %s\n", filename );
822         return;
823     }
824
825     DEBUG_Printf( DBG_CHN_MESG, "Reading symbols from file %s\n", filename );
826
827     value.type = NULL;
828     value.addr.seg = 0;
829     value.addr.off = 0;
830     value.cookie = DV_TARGET;
831
832     while (1)
833     {
834         fgets( buffer, sizeof(buffer), symbolfile );
835         if (feof(symbolfile)) break;
836
837         /* Strip any text after a # sign (i.e. comments) */
838         cpnt = buffer;
839         while (*cpnt)
840             if(*cpnt++ == '#') { *cpnt = 0; break; }
841
842         /* Quietly ignore any lines that have just whitespace */
843         cpnt = buffer;
844         while(*cpnt)
845         {
846             if(*cpnt != ' ' && *cpnt != '\t') break;
847             cpnt++;
848         }
849         if (!(*cpnt) || *cpnt == '\n') continue;
850
851         if (sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name) == 3)
852         {
853            if (value.addr.off + offset < value.addr.off)
854               DEBUG_Printf( DBG_CHN_WARN, "Address wrap around\n");
855            value.addr.off += offset;
856            DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
857         }
858     }
859     fclose(symbolfile);
860 }
861
862
863 void
864 DEBUG_AddLineNumber( struct name_hash * func, int line_num,
865                      unsigned long offset )
866 {
867   if( func == NULL )
868     {
869       return;
870     }
871
872   if( func->n_lines + 1 >= func->lines_alloc )
873     {
874       func->lines_alloc += 64;
875       func->linetab = DBG_realloc(func->linetab,
876                               func->lines_alloc * sizeof(WineLineNo));
877     }
878
879   func->linetab[func->n_lines].line_number = line_num;
880   func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
881   func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
882   func->n_lines++;
883 }
884
885
886 struct wine_locals *
887 DEBUG_AddLocal( struct name_hash * func, int regno,
888                 int offset,
889                 int pc_start,
890                 int pc_end,
891                 char * name)
892 {
893   if( func == NULL )
894     {
895       return NULL;
896     }
897
898   if( func->n_locals + 1 >= func->locals_alloc )
899     {
900       func->locals_alloc += 32;
901       func->local_vars = DBG_realloc(func->local_vars,
902                               func->locals_alloc * sizeof(WineLocals));
903     }
904
905   func->local_vars[func->n_locals].regno = regno;
906   func->local_vars[func->n_locals].offset = offset;
907   func->local_vars[func->n_locals].pc_start = pc_start;
908   func->local_vars[func->n_locals].pc_end = pc_end;
909   func->local_vars[func->n_locals].name = DBG_strdup(name);
910   func->local_vars[func->n_locals].type = NULL;
911   func->n_locals++;
912
913   return &func->local_vars[func->n_locals - 1];
914 }
915
916 void
917 DEBUG_DumpHashInfo(void)
918 {
919   int i;
920   int depth;
921   struct name_hash *nh;
922
923   /*
924    * Utility function to dump stats about the hash table.
925    */
926     for(i=0; i<NR_NAME_HASH; i++)
927     {
928       depth = 0;
929       for (nh = name_hash_table[i]; nh; nh = nh->next)
930         {
931           depth++;
932         }
933       DEBUG_Printf(DBG_CHN_MESG, "Bucket %d: %d\n", i, depth);
934     }
935 }
936
937 /***********************************************************************
938  *           DEBUG_CheckLinenoStatus
939  *
940  * Find the symbol nearest to a given address.
941  * If ebp is specified as non-zero, it means we should dump the argument
942  * list into the string we return as well.
943  */
944 int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
945 {
946     struct name_hash * nearest = NULL;
947     int mid, high, low;
948
949     if( sortlist_valid == FALSE )
950       {
951         DEBUG_ResortSymbols();
952       }
953
954     /*
955      * Binary search to find closest symbol.
956      */
957     low = 0;
958     high = sorttab_nsym;
959     if( addr_sorttab[0]->value.addr.seg > addr->seg
960         || (   addr_sorttab[0]->value.addr.seg == addr->seg
961             && addr_sorttab[0]->value.addr.off > addr->off) )
962       {
963         nearest = NULL;
964       }
965     else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
966         || (   addr_sorttab[high - 1]->value.addr.seg == addr->seg
967             && addr_sorttab[high - 1]->value.addr.off < addr->off) )
968       {
969         nearest = addr_sorttab[high - 1];
970       }
971     else
972       {
973         while(1==1)
974           {
975             mid = (high + low)/2;
976             if( mid == low )
977               {
978                 /*
979                  * See if there are any other entries that might also
980                  * have the same address, and would also have a line
981                  * number table.
982                  */
983                 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
984                   {
985                     if(    (addr_sorttab[mid - 1]->value.addr.seg ==
986                             addr_sorttab[mid]->value.addr.seg)
987                         && (addr_sorttab[mid - 1]->value.addr.off ==
988                             addr_sorttab[mid]->value.addr.off)
989                         && (addr_sorttab[mid - 1]->linetab != NULL) )
990                       {
991                         mid--;
992                       }
993                   }
994
995                 if(    (mid < sorttab_nsym - 1)
996                     && (addr_sorttab[mid]->linetab == NULL) )
997                   {
998                     if(    (addr_sorttab[mid + 1]->value.addr.seg ==
999                             addr_sorttab[mid]->value.addr.seg)
1000                         && (addr_sorttab[mid + 1]->value.addr.off ==
1001                             addr_sorttab[mid]->value.addr.off)
1002                         && (addr_sorttab[mid + 1]->linetab != NULL) )
1003                       {
1004                         mid++;
1005                       }
1006                   }
1007                 nearest = addr_sorttab[mid];
1008 #if 0
1009                 DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
1010                              addr_sorttab[mid ]->value.addr.seg,
1011                              addr_sorttab[mid ]->value.addr.off,
1012                              addr->seg, addr->off,
1013                              addr_sorttab[mid ]->linetab,
1014                              addr_sorttab[mid ]->name);
1015 #endif
1016                 break;
1017               }
1018             if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
1019                 || (   addr_sorttab[mid]->value.addr.seg == addr->seg
1020                     && addr_sorttab[mid]->value.addr.off <= addr->off) )
1021               {
1022                 low = mid;
1023               }
1024             else
1025               {
1026                 high = mid;
1027               }
1028           }
1029       }
1030
1031     if (!nearest) return FUNC_HAS_NO_LINES;
1032
1033     if( nearest->flags & SYM_STEP_THROUGH )
1034       {
1035         /*
1036          * This will cause us to keep single stepping until
1037          * we get to the other side somewhere.
1038          */
1039         return NOT_ON_LINENUMBER;
1040       }
1041
1042     if( (nearest->flags & SYM_TRAMPOLINE) )
1043       {
1044         /*
1045          * This will cause us to keep single stepping until
1046          * we get to the other side somewhere.
1047          */
1048         return FUNC_IS_TRAMPOLINE;
1049       }
1050
1051     if( nearest->linetab == NULL )
1052       {
1053         return FUNC_HAS_NO_LINES;
1054       }
1055
1056
1057     /*
1058      * We never want to stop on the first instruction of a function
1059      * even if it has it's own linenumber.  Let the thing keep running
1060      * until it gets past the function prologue.  We only do this if there
1061      * is more than one line number for the function, of course.
1062      */
1063     if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
1064       {
1065         return NOT_ON_LINENUMBER;
1066       }
1067
1068     if( (nearest->sourcefile != NULL)
1069         && (addr->off - nearest->value.addr.off < 0x100000) )
1070       {
1071           low = 0;
1072           high = nearest->n_lines;
1073           while ((high - low) > 1)
1074           {
1075               mid = (high + low) / 2;
1076               if (addr->off < nearest->linetab[mid].pc_offset.off) high = mid;
1077               else low = mid;
1078           }
1079           if (addr->off == nearest->linetab[low].pc_offset.off)
1080               return AT_LINENUMBER;
1081           else
1082               return NOT_ON_LINENUMBER;
1083       }
1084
1085     return FUNC_HAS_NO_LINES;
1086 }
1087
1088 /***********************************************************************
1089  *           DEBUG_GetFuncInfo
1090  *
1091  * Find the symbol nearest to a given address.
1092  * Returns sourcefile name and line number in a format that the listing
1093  * handler can deal with.
1094  */
1095 void
1096 DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
1097                    const char * name)
1098 {
1099     char buffer[256];
1100     char * pnt;
1101     struct name_hash *nh;
1102
1103     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
1104       {
1105         if( filename != NULL )
1106           {
1107
1108             if( nh->sourcefile == NULL )
1109               {
1110                 continue;
1111               }
1112
1113             pnt = strrchr(nh->sourcefile, '/');
1114             if( strcmp(nh->sourcefile, filename) != 0
1115                 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1116               {
1117                 continue;
1118               }
1119           }
1120         if (!strcmp(nh->name, name)) break;
1121       }
1122
1123     if (!nh && (name[0] != '_'))
1124     {
1125         buffer[0] = '_';
1126         strcpy(buffer+1, name);
1127         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
1128           {
1129             if( filename != NULL )
1130               {
1131                 if( nh->sourcefile == NULL )
1132                   {
1133                     continue;
1134                   }
1135
1136                 pnt = strrchr(nh->sourcefile, '/');
1137                 if( strcmp(nh->sourcefile, filename) != 0
1138                     && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1139                   {
1140                     continue;
1141                   }
1142               }
1143             if (!strcmp(nh->name, buffer)) break;
1144           }
1145     }
1146
1147     if( !nh )
1148       {
1149         if( filename != NULL )
1150           {
1151             DEBUG_Printf(DBG_CHN_MESG, "No such function %s in %s\n", name, filename);
1152           }
1153         else
1154           {
1155             DEBUG_Printf(DBG_CHN_MESG, "No such function %s\n", name);
1156           }
1157         ret->sourcefile = NULL;
1158         ret->line = -1;
1159         return;
1160       }
1161
1162     ret->sourcefile = nh->sourcefile;
1163
1164     /*
1165      * Search for the specific line number.  If we don't find it,
1166      * then return FALSE.
1167      */
1168     if( nh->linetab == NULL )
1169       {
1170         ret->line = -1;
1171       }
1172     else
1173       {
1174         ret->line = nh->linetab[0].line_number;
1175       }
1176 }
1177
1178 /***********************************************************************
1179  *           DEBUG_GetStackSymbolValue
1180  *
1181  * Get the address of a named symbol from the current stack frame.
1182  */
1183 static
1184 BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
1185 {
1186   struct name_hash * curr_func;
1187   unsigned int       ebp;
1188   unsigned int       eip;
1189   int                i;
1190
1191   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1192     {
1193       return FALSE;
1194     }
1195
1196   for(i=0; i < curr_func->n_locals; i++ )
1197     {
1198       /*
1199        * Test the range of validity of the local variable.  This
1200        * comes up with RBRAC/LBRAC stabs in particular.
1201        */
1202       if(    (curr_func->local_vars[i].pc_start != 0)
1203           && ((eip - curr_func->value.addr.off)
1204               < curr_func->local_vars[i].pc_start) )
1205         {
1206           continue;
1207         }
1208
1209       if(    (curr_func->local_vars[i].pc_end != 0)
1210           && ((eip - curr_func->value.addr.off)
1211               > curr_func->local_vars[i].pc_end) )
1212         {
1213           continue;
1214         }
1215
1216       if( strcmp(name, curr_func->local_vars[i].name) == 0 )
1217         {
1218           /*
1219            * OK, we found it.  Now figure out what to do with this.
1220            */
1221           if( curr_func->local_vars[i].regno != 0 )
1222             {
1223               /*
1224                * Register variable.  Point to DEBUG_context field.
1225                */
1226               assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
1227               value->addr.off = ((DWORD)&DEBUG_context) +
1228                  reg_ofs[curr_func->local_vars[i].regno - 1];
1229               value->cookie = DV_HOST;
1230             }
1231           else
1232             {
1233               value->addr.off = ebp + curr_func->local_vars[i].offset;
1234               value->cookie = DV_TARGET;
1235             }
1236           value->addr.seg = 0;
1237           value->type = curr_func->local_vars[i].type;
1238
1239           return TRUE;
1240         }
1241     }
1242
1243   return FALSE;
1244 }
1245
1246 int
1247 DEBUG_InfoLocals(void)
1248 {
1249   struct name_hash  * curr_func;
1250   unsigned int        ebp;
1251   unsigned int        eip;
1252   int                 i;
1253   unsigned int      * ptr;
1254   unsigned int        val;
1255
1256   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1257     {
1258       return FALSE;
1259     }
1260
1261   DEBUG_Printf(DBG_CHN_MESG, "%s:\n", curr_func->name);
1262
1263   for(i=0; i < curr_func->n_locals; i++ )
1264     {
1265       /*
1266        * Test the range of validity of the local variable.  This
1267        * comes up with RBRAC/LBRAC stabs in particular.
1268        */
1269       if(    (curr_func->local_vars[i].pc_start != 0)
1270           && ((eip - curr_func->value.addr.off)
1271               < curr_func->local_vars[i].pc_start) )
1272         {
1273           continue;
1274         }
1275
1276       if(    (curr_func->local_vars[i].pc_end != 0)
1277           && ((eip - curr_func->value.addr.off)
1278               > curr_func->local_vars[i].pc_end) )
1279         {
1280           continue;
1281         }
1282
1283       DEBUG_PrintTypeCast(curr_func->local_vars[i].type);
1284
1285       if( curr_func->local_vars[i].regno != 0 )
1286         {
1287           ptr = (unsigned int *)(((DWORD)&DEBUG_context)
1288                                  + reg_ofs[curr_func->local_vars[i].regno - 1]);
1289           DEBUG_Printf(DBG_CHN_MESG, " %s (optimized into register $%s) == 0x%8.8x\n",
1290                        curr_func->local_vars[i].name,
1291                        reg_name[curr_func->local_vars[i].regno - 1],
1292                        *ptr);
1293         }
1294       else
1295         {
1296           DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset),
1297                                  &val, sizeof(val));
1298           DEBUG_Printf(DBG_CHN_MESG, " %s == 0x%8.8x\n",
1299                        curr_func->local_vars[i].name, val);
1300         }
1301     }
1302
1303   return TRUE;
1304 }
1305
1306 int
1307 DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
1308 {
1309   sym->symbol_size = len;
1310
1311   return TRUE;
1312 }
1313
1314 int
1315 DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
1316 {
1317   sym->breakpoint_offset = off;
1318
1319   return TRUE;
1320 }
1321
1322 int
1323 DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
1324 {
1325
1326   *addr = sym->value.addr;
1327
1328   return TRUE;
1329 }
1330
1331 int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
1332 {
1333   sym->type = type;
1334
1335   return TRUE;
1336 }
1337
1338 #ifdef HAVE_REGEX_H
1339
1340 static int cmp_sym_by_name(const void * p1, const void * p2)
1341 {
1342   struct name_hash ** name1 = (struct name_hash **) p1;
1343   struct name_hash ** name2 = (struct name_hash **) p2;
1344
1345   return strcmp( (*name1)->name, (*name2)->name );
1346 }
1347
1348 #include <regex.h>
1349
1350 void DEBUG_InfoSymbols(const char* str)
1351 {
1352     int                 i;
1353     struct name_hash*   nh;
1354     struct name_hash**  array = NULL;
1355     unsigned            num_used_array = 0;
1356     unsigned            num_alloc_array = 0;
1357     const char*         name;
1358     enum dbg_mode       mode;
1359     regex_t             preg;
1360
1361     regcomp(&preg, str, REG_NOSUB);
1362
1363     /* grab all symbols */
1364     for (i = 0; i < NR_NAME_HASH; i++)
1365     {
1366         for (nh = name_hash_table[i]; nh; nh = nh->next)
1367         {
1368             if (regexec(&preg, nh->name, 0, NULL, 0) == 0)
1369             {
1370                 if (num_used_array == num_alloc_array)
1371                 {
1372                     array = HeapReAlloc(GetProcessHeap(), 0, array, sizeof(*array) * (num_alloc_array += 32));
1373                     if (!array) return;
1374                 }
1375                 array[num_used_array++] = nh;
1376             }
1377         }
1378     }
1379     regfree(&preg);
1380
1381     /* now sort them by alphabetical order */
1382     qsort(array, num_used_array, sizeof(*array), cmp_sym_by_name);
1383
1384     /* and display them */
1385     for (i = 0; i < num_used_array; i++)
1386     {
1387         mode = DEBUG_GetSelectorType(array[i]->value.addr.seg);
1388         name = DEBUG_FindNearestSymbol( &array[i]->value.addr, TRUE, 
1389                                         NULL, 0, NULL );
1390
1391         if (mode != MODE_32) 
1392             DEBUG_Printf( DBG_CHN_MESG, "%04lx:%04lx :", 
1393                           array[i]->value.addr.seg & 0xFFFF,
1394                           array[i]->value.addr.off );
1395         else
1396             DEBUG_Printf( DBG_CHN_MESG, "%08lx  :", array[i]->value.addr.off );
1397         if (name) DEBUG_Printf( DBG_CHN_MESG, " %s\n", name );
1398     }
1399     HeapFree(GetProcessHeap(), 0, array);
1400 }
1401
1402 #else /* HAVE_REGEX_H */
1403
1404 void DEBUG_InfoSymbols(const char* str)
1405 {
1406     DEBUG_Printf( DBG_CHN_MESG, "FIXME: needs regex support\n" );
1407 }
1408
1409 #endif /* HAVE_REGEX_H */