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