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