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