Fixed ptrace argument order for FreeBSD, NetBSD and Solaris.
[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)))
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, unsigned long offset )
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         {
843            if (value.addr.off + offset < value.addr.off)
844               DEBUG_Printf( DBG_CHN_WARN, "Address wrap around\n");
845            value.addr.off += offset;
846            DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
847         }
848     }
849     fclose(symbolfile);
850 }
851
852
853 void
854 DEBUG_AddLineNumber( struct name_hash * func, int line_num,
855                      unsigned long offset )
856 {
857   if( func == NULL )
858     {
859       return;
860     }
861
862   if( func->n_lines + 1 >= func->lines_alloc )
863     {
864       func->lines_alloc += 64;
865       func->linetab = DBG_realloc(func->linetab,
866                               func->lines_alloc * sizeof(WineLineNo));
867     }
868
869   func->linetab[func->n_lines].line_number = line_num;
870   func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
871   func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
872   func->n_lines++;
873 }
874
875
876 struct wine_locals *
877 DEBUG_AddLocal( struct name_hash * func, int regno,
878                 int offset,
879                 int pc_start,
880                 int pc_end,
881                 char * name)
882 {
883   if( func == NULL )
884     {
885       return NULL;
886     }
887
888   if( func->n_locals + 1 >= func->locals_alloc )
889     {
890       func->locals_alloc += 32;
891       func->local_vars = DBG_realloc(func->local_vars,
892                               func->locals_alloc * sizeof(WineLocals));
893     }
894
895   func->local_vars[func->n_locals].regno = regno;
896   func->local_vars[func->n_locals].offset = offset;
897   func->local_vars[func->n_locals].pc_start = pc_start;
898   func->local_vars[func->n_locals].pc_end = pc_end;
899   func->local_vars[func->n_locals].name = DBG_strdup(name);
900   func->local_vars[func->n_locals].type = NULL;
901   func->n_locals++;
902
903   return &func->local_vars[func->n_locals - 1];
904 }
905
906 void
907 DEBUG_DumpHashInfo(void)
908 {
909   int i;
910   int depth;
911   struct name_hash *nh;
912
913   /*
914    * Utility function to dump stats about the hash table.
915    */
916     for(i=0; i<NR_NAME_HASH; i++)
917     {
918       depth = 0;
919       for (nh = name_hash_table[i]; nh; nh = nh->next)
920         {
921           depth++;
922         }
923       DEBUG_Printf(DBG_CHN_MESG, "Bucket %d: %d\n", i, depth);
924     }
925 }
926
927 /***********************************************************************
928  *           DEBUG_CheckLinenoStatus
929  *
930  * Find the symbol nearest to a given address.
931  * If ebp is specified as non-zero, it means we should dump the argument
932  * list into the string we return as well.
933  */
934 int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
935 {
936     struct name_hash * nearest = NULL;
937     int mid, high, low;
938
939     if( sortlist_valid == FALSE )
940       {
941         DEBUG_ResortSymbols();
942       }
943
944     /*
945      * Binary search to find closest symbol.
946      */
947     low = 0;
948     high = sorttab_nsym;
949     if( addr_sorttab[0]->value.addr.seg > addr->seg
950         || (   addr_sorttab[0]->value.addr.seg == addr->seg
951             && addr_sorttab[0]->value.addr.off > addr->off) )
952       {
953         nearest = NULL;
954       }
955     else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
956         || (   addr_sorttab[high - 1]->value.addr.seg == addr->seg
957             && addr_sorttab[high - 1]->value.addr.off < addr->off) )
958       {
959         nearest = addr_sorttab[high - 1];
960       }
961     else
962       {
963         while(1==1)
964           {
965             mid = (high + low)/2;
966             if( mid == low )
967               {
968                 /*
969                  * See if there are any other entries that might also
970                  * have the same address, and would also have a line
971                  * number table.
972                  */
973                 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
974                   {
975                     if(    (addr_sorttab[mid - 1]->value.addr.seg ==
976                             addr_sorttab[mid]->value.addr.seg)
977                         && (addr_sorttab[mid - 1]->value.addr.off ==
978                             addr_sorttab[mid]->value.addr.off)
979                         && (addr_sorttab[mid - 1]->linetab != NULL) )
980                       {
981                         mid--;
982                       }
983                   }
984
985                 if(    (mid < sorttab_nsym - 1)
986                     && (addr_sorttab[mid]->linetab == NULL) )
987                   {
988                     if(    (addr_sorttab[mid + 1]->value.addr.seg ==
989                             addr_sorttab[mid]->value.addr.seg)
990                         && (addr_sorttab[mid + 1]->value.addr.off ==
991                             addr_sorttab[mid]->value.addr.off)
992                         && (addr_sorttab[mid + 1]->linetab != NULL) )
993                       {
994                         mid++;
995                       }
996                   }
997                 nearest = addr_sorttab[mid];
998 #if 0
999                 DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
1000                              addr_sorttab[mid ]->value.addr.seg,
1001                              addr_sorttab[mid ]->value.addr.off,
1002                              addr->seg, addr->off,
1003                              addr_sorttab[mid ]->linetab,
1004                              addr_sorttab[mid ]->name);
1005 #endif
1006                 break;
1007               }
1008             if(    (addr_sorttab[mid]->value.addr.seg < addr->seg)
1009                 || (   addr_sorttab[mid]->value.addr.seg == addr->seg
1010                     && addr_sorttab[mid]->value.addr.off <= addr->off) )
1011               {
1012                 low = mid;
1013               }
1014             else
1015               {
1016                 high = mid;
1017               }
1018           }
1019       }
1020
1021     if (!nearest) return FUNC_HAS_NO_LINES;
1022
1023     if( nearest->flags & SYM_STEP_THROUGH )
1024       {
1025         /*
1026          * This will cause us to keep single stepping until
1027          * we get to the other side somewhere.
1028          */
1029         return NOT_ON_LINENUMBER;
1030       }
1031
1032     if( (nearest->flags & SYM_TRAMPOLINE) )
1033       {
1034         /*
1035          * This will cause us to keep single stepping until
1036          * we get to the other side somewhere.
1037          */
1038         return FUNC_IS_TRAMPOLINE;
1039       }
1040
1041     if( nearest->linetab == NULL )
1042       {
1043         return FUNC_HAS_NO_LINES;
1044       }
1045
1046
1047     /*
1048      * We never want to stop on the first instruction of a function
1049      * even if it has it's own linenumber.  Let the thing keep running
1050      * until it gets past the function prologue.  We only do this if there
1051      * is more than one line number for the function, of course.
1052      */
1053     if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
1054       {
1055         return NOT_ON_LINENUMBER;
1056       }
1057
1058     if( (nearest->sourcefile != NULL)
1059         && (addr->off - nearest->value.addr.off < 0x100000) )
1060       {
1061           low = 0;
1062           high = nearest->n_lines;
1063           while ((high - low) > 1)
1064           {
1065               mid = (high + low) / 2;
1066               if (addr->off < nearest->linetab[mid].pc_offset.off) high = mid;
1067               else low = mid;
1068           }
1069           if (addr->off == nearest->linetab[low].pc_offset.off)
1070               return AT_LINENUMBER;
1071           else
1072               return NOT_ON_LINENUMBER;
1073       }
1074
1075     return FUNC_HAS_NO_LINES;
1076 }
1077
1078 /***********************************************************************
1079  *           DEBUG_GetFuncInfo
1080  *
1081  * Find the symbol nearest to a given address.
1082  * Returns sourcefile name and line number in a format that the listing
1083  * handler can deal with.
1084  */
1085 void
1086 DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
1087                    const char * name)
1088 {
1089     char buffer[256];
1090     char * pnt;
1091     struct name_hash *nh;
1092
1093     for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
1094       {
1095         if( filename != NULL )
1096           {
1097
1098             if( nh->sourcefile == NULL )
1099               {
1100                 continue;
1101               }
1102
1103             pnt = strrchr(nh->sourcefile, '/');
1104             if( strcmp(nh->sourcefile, filename) != 0
1105                 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1106               {
1107                 continue;
1108               }
1109           }
1110         if (!strcmp(nh->name, name)) break;
1111       }
1112
1113     if (!nh && (name[0] != '_'))
1114     {
1115         buffer[0] = '_';
1116         strcpy(buffer+1, name);
1117         for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
1118           {
1119             if( filename != NULL )
1120               {
1121                 if( nh->sourcefile == NULL )
1122                   {
1123                     continue;
1124                   }
1125
1126                 pnt = strrchr(nh->sourcefile, '/');
1127                 if( strcmp(nh->sourcefile, filename) != 0
1128                     && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1129                   {
1130                     continue;
1131                   }
1132               }
1133             if (!strcmp(nh->name, buffer)) break;
1134           }
1135     }
1136
1137     if( !nh )
1138       {
1139         if( filename != NULL )
1140           {
1141             DEBUG_Printf(DBG_CHN_MESG, "No such function %s in %s\n", name, filename);
1142           }
1143         else
1144           {
1145             DEBUG_Printf(DBG_CHN_MESG, "No such function %s\n", name);
1146           }
1147         ret->sourcefile = NULL;
1148         ret->line = -1;
1149         return;
1150       }
1151
1152     ret->sourcefile = nh->sourcefile;
1153
1154     /*
1155      * Search for the specific line number.  If we don't find it,
1156      * then return FALSE.
1157      */
1158     if( nh->linetab == NULL )
1159       {
1160         ret->line = -1;
1161       }
1162     else
1163       {
1164         ret->line = nh->linetab[0].line_number;
1165       }
1166 }
1167
1168 /***********************************************************************
1169  *           DEBUG_GetStackSymbolValue
1170  *
1171  * Get the address of a named symbol from the current stack frame.
1172  */
1173 static
1174 BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
1175 {
1176   struct name_hash * curr_func;
1177   unsigned int       ebp;
1178   unsigned int       eip;
1179   int                i;
1180
1181   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1182     {
1183       return FALSE;
1184     }
1185
1186   for(i=0; i < curr_func->n_locals; i++ )
1187     {
1188       /*
1189        * Test the range of validity of the local variable.  This
1190        * comes up with RBRAC/LBRAC stabs in particular.
1191        */
1192       if(    (curr_func->local_vars[i].pc_start != 0)
1193           && ((eip - curr_func->value.addr.off)
1194               < curr_func->local_vars[i].pc_start) )
1195         {
1196           continue;
1197         }
1198
1199       if(    (curr_func->local_vars[i].pc_end != 0)
1200           && ((eip - curr_func->value.addr.off)
1201               > curr_func->local_vars[i].pc_end) )
1202         {
1203           continue;
1204         }
1205
1206       if( strcmp(name, curr_func->local_vars[i].name) == 0 )
1207         {
1208           /*
1209            * OK, we found it.  Now figure out what to do with this.
1210            */
1211           if( curr_func->local_vars[i].regno != 0 )
1212             {
1213               /*
1214                * Register variable.  Point to DEBUG_context field.
1215                */
1216               assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
1217               value->addr.off = ((DWORD)&DEBUG_context) +
1218                  reg_ofs[curr_func->local_vars[i].regno - 1];
1219               value->cookie = DV_HOST;
1220             }
1221           else
1222             {
1223               value->addr.off = ebp + curr_func->local_vars[i].offset;
1224               value->cookie = DV_TARGET;
1225             }
1226           value->addr.seg = 0;
1227           value->type = curr_func->local_vars[i].type;
1228
1229           return TRUE;
1230         }
1231     }
1232
1233   return FALSE;
1234 }
1235
1236 int
1237 DEBUG_InfoLocals(void)
1238 {
1239   struct name_hash  * curr_func;
1240   unsigned int        ebp;
1241   unsigned int        eip;
1242   int                 i;
1243   unsigned int      * ptr;
1244   unsigned int        val;
1245
1246   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1247     {
1248       return FALSE;
1249     }
1250
1251   DEBUG_Printf(DBG_CHN_MESG, "%s:\n", curr_func->name);
1252
1253   for(i=0; i < curr_func->n_locals; i++ )
1254     {
1255       /*
1256        * Test the range of validity of the local variable.  This
1257        * comes up with RBRAC/LBRAC stabs in particular.
1258        */
1259       if(    (curr_func->local_vars[i].pc_start != 0)
1260           && ((eip - curr_func->value.addr.off)
1261               < curr_func->local_vars[i].pc_start) )
1262         {
1263           continue;
1264         }
1265
1266       if(    (curr_func->local_vars[i].pc_end != 0)
1267           && ((eip - curr_func->value.addr.off)
1268               > curr_func->local_vars[i].pc_end) )
1269         {
1270           continue;
1271         }
1272
1273       DEBUG_PrintTypeCast(curr_func->local_vars[i].type);
1274
1275       if( curr_func->local_vars[i].regno != 0 )
1276         {
1277           ptr = (unsigned int *)(((DWORD)&DEBUG_context)
1278                                  + reg_ofs[curr_func->local_vars[i].regno - 1]);
1279           DEBUG_Printf(DBG_CHN_MESG, " %s (optimized into register $%s) == 0x%8.8x\n",
1280                        curr_func->local_vars[i].name,
1281                        reg_name[curr_func->local_vars[i].regno - 1],
1282                        *ptr);
1283         }
1284       else
1285         {
1286           DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset),
1287                                  &val, sizeof(val));
1288           DEBUG_Printf(DBG_CHN_MESG, " %s == 0x%8.8x\n",
1289                        curr_func->local_vars[i].name, val);
1290         }
1291     }
1292
1293   return TRUE;
1294 }
1295
1296 int
1297 DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
1298 {
1299   sym->symbol_size = len;
1300
1301   return TRUE;
1302 }
1303
1304 int
1305 DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
1306 {
1307   sym->breakpoint_offset = off;
1308
1309   return TRUE;
1310 }
1311
1312 int
1313 DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
1314 {
1315
1316   *addr = sym->value.addr;
1317
1318   return TRUE;
1319 }
1320
1321 int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
1322 {
1323   sym->type = type;
1324
1325   return TRUE;
1326 }