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