Release 970509
[wine/multimedia.git] / debugger / hash.c
blob610785f127e6b44fbb311ee1367261dfe63e0047
1 /*
2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
5 */
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 "selectors.h"
16 #include "debugger.h"
17 #include "toolhelp.h"
18 #include "xmalloc.h"
20 #define NR_NAME_HASH 16384
21 #ifndef PATH_MAX
22 #define PATH_MAX _MAX_PATH
23 #endif
25 static char * reg_name[] =
27 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
31 struct name_hash
33 struct name_hash * next; /* Used to look up within name hash */
34 char * name;
35 char * sourcefile;
37 int n_locals;
38 int locals_alloc;
39 WineLocals * local_vars;
41 int n_lines;
42 int lines_alloc;
43 WineLineNo * linetab;
45 DBG_ADDR addr;
46 unsigned short flags;
47 unsigned short breakpoint_offset;
48 unsigned int symbol_size;
52 static BOOL32 DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr );
53 static int sortlist_valid = FALSE;
55 static int sorttab_nsym;
56 static struct name_hash ** addr_sorttab = NULL;
58 static struct name_hash * name_hash_table[NR_NAME_HASH];
60 static unsigned int name_hash( const char * name )
62 unsigned int hash = 0;
63 unsigned int tmp;
64 const char * p;
66 p = name;
68 while (*p)
70 hash = (hash << 4) + *p++;
72 if( (tmp = (hash & 0xf0000000)) )
74 hash ^= tmp >> 24;
76 hash &= ~tmp;
78 return hash % NR_NAME_HASH;
81 int
82 DEBUG_cmp_sym(const void * p1, const void * p2)
84 struct name_hash ** name1 = (struct name_hash **) p1;
85 struct name_hash ** name2 = (struct name_hash **) p2;
87 if( ((*name1)->flags & SYM_INVALID) != 0 )
89 return -1;
92 if( ((*name2)->flags & SYM_INVALID) != 0 )
94 return 1;
97 if( (*name1)->addr.seg > (*name2)->addr.seg )
99 return 1;
102 if( (*name1)->addr.seg < (*name2)->addr.seg )
104 return -1;
107 if( (*name1)->addr.off > (*name2)->addr.off )
109 return 1;
112 if( (*name1)->addr.off < (*name2)->addr.off )
114 return -1;
117 return 0;
120 /***********************************************************************
121 * DEBUG_ResortSymbols
123 * Rebuild sorted list of symbols.
125 static
126 void
127 DEBUG_ResortSymbols()
129 struct name_hash *nh;
130 int nsym = 0;
131 int i;
133 for(i=0; i<NR_NAME_HASH; i++)
135 for (nh = name_hash_table[i]; nh; nh = nh->next)
137 nsym++;
141 sorttab_nsym = nsym;
142 if( nsym == 0 )
144 return;
147 addr_sorttab = (struct name_hash **) xrealloc(addr_sorttab,
148 nsym * sizeof(struct name_hash *));
150 nsym = 0;
151 for(i=0; i<NR_NAME_HASH; i++)
153 for (nh = name_hash_table[i]; nh; nh = nh->next)
155 addr_sorttab[nsym++] = nh;
159 qsort(addr_sorttab, nsym,
160 sizeof(struct name_hash *), DEBUG_cmp_sym);
161 sortlist_valid = TRUE;
165 /***********************************************************************
166 * DEBUG_AddSymbol
168 * Add a symbol to the table.
170 struct name_hash *
171 DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source,
172 int flags)
174 struct name_hash * new;
175 struct name_hash *nh;
176 static char prev_source[PATH_MAX] = {'\0', };
177 static char * prev_duped_source = NULL;
178 char * c;
179 int hash;
181 hash = name_hash(name);
182 for (nh = name_hash_table[hash]; nh; nh = nh->next)
184 if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
186 nh->addr.off = addr->off;
187 nh->addr.seg = addr->seg;
188 if( nh->addr.type == NULL && addr->type != NULL )
190 nh->addr.type = addr->type;
192 nh->flags &= ~SYM_INVALID;
193 return nh;
195 if (nh->addr.seg == addr->seg &&
196 nh->addr.off == addr->off &&
197 strcmp(name, nh->name) == 0 )
199 return nh;
204 * First see if we already have an entry for this symbol. If so
205 * return it, so we don't end up with duplicates.
208 new = (struct name_hash *) xmalloc(sizeof(struct name_hash));
209 new->addr = *addr;
210 new->name = xstrdup(name);
212 if( source != NULL )
215 * This is an enhancement to reduce memory consumption. The idea
216 * is that we duplicate a given string only once. This is a big
217 * win if there are lots of symbols defined in a given source file.
219 if( strcmp(source, prev_source) == 0 )
221 new->sourcefile = prev_duped_source;
223 else
225 strcpy(prev_source, source);
226 prev_duped_source = new->sourcefile = xstrdup(source);
229 else
231 new->sourcefile = NULL;
234 new->n_lines = 0;
235 new->lines_alloc = 0;
236 new->linetab = NULL;
238 new->n_locals = 0;
239 new->locals_alloc = 0;
240 new->local_vars = NULL;
242 new->flags = flags;
243 new->next = NULL;
245 /* Now insert into the hash table */
246 new->next = name_hash_table[hash];
247 name_hash_table[hash] = new;
250 * Check some heuristics based upon the file name to see whether
251 * we want to step through this guy or not. These are machine generated
252 * assembly files that are used to translate between the MS way of
253 * calling things and the GCC way of calling things. In general we
254 * always want to step through.
256 if( source != NULL )
258 c = strrchr(source, '.');
259 if( c != NULL && strcmp(c, ".s") == 0 )
261 c = strrchr(source, '/');
262 if( c != NULL )
264 c++;
265 if( (strcmp(c, "callfrom16.s") == 0)
266 || (strcmp(c, "callto16.s") == 0)
267 || (strcmp(c, "callfrom32.s") == 0)
268 || (strcmp(c, "callto32.s") == 0) )
270 new->flags |= SYM_TRAMPOLINE;
276 sortlist_valid = FALSE;
277 return new;
280 BOOL32 DEBUG_Normalize(struct name_hash * nh )
284 * We aren't adding any more locals or linenumbers to this function.
285 * Free any spare memory that we might have allocated.
287 if( nh == NULL )
289 return TRUE;
292 if( nh->n_locals != nh->locals_alloc )
294 nh->locals_alloc = nh->n_locals;
295 nh->local_vars = xrealloc(nh->local_vars,
296 nh->locals_alloc * sizeof(WineLocals));
299 if( nh->n_lines != nh->lines_alloc )
301 nh->lines_alloc = nh->n_lines;
302 nh->linetab = xrealloc(nh->linetab,
303 nh->lines_alloc * sizeof(WineLineNo));
306 return TRUE;
309 /***********************************************************************
310 * DEBUG_GetSymbolValue
312 * Get the address of a named symbol.
314 BOOL32 DEBUG_GetSymbolValue( const char * name, const int lineno,
315 DBG_ADDR *addr, int bp_flag )
317 char buffer[256];
318 struct name_hash *nh;
320 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
322 if( (nh->flags & SYM_INVALID) != 0 )
324 continue;
327 if (!strcmp(nh->name, name)) break;
330 if (!nh && (name[0] != '_'))
332 buffer[0] = '_';
333 strcpy(buffer+1, name);
334 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
336 if( (nh->flags & SYM_INVALID) != 0 )
338 continue;
340 if (!strcmp(nh->name, buffer)) break;
345 * If we don't have anything here, then try and see if this
346 * is a local symbol to the current stack frame. No matter
347 * what, we have nothing more to do, so we let that function
348 * decide what we ultimately return.
350 if (!nh)
352 return DEBUG_GetStackSymbolValue(name, addr);
355 return DEBUG_GetLineNumberAddr( nh, lineno, addr, bp_flag );
358 /***********************************************************************
359 * DEBUG_GetLineNumberAddr
361 * Get the address of a named symbol.
363 BOOL32 DEBUG_GetLineNumberAddr( struct name_hash * nh, const int lineno,
364 DBG_ADDR *addr, int bp_flag )
366 int i;
368 if( lineno == -1 )
370 *addr = nh->addr;
371 if( bp_flag )
373 addr->off += nh->breakpoint_offset;
376 else
379 * Search for the specific line number. If we don't find it,
380 * then return FALSE.
382 if( nh->linetab == NULL )
384 return FALSE;
387 for(i=0; i < nh->n_lines; i++ )
389 if( nh->linetab[i].line_number == lineno )
391 *addr = nh->linetab[i].pc_offset;
392 return TRUE;
397 * This specific line number not found.
399 return FALSE;
402 return TRUE;
406 /***********************************************************************
407 * DEBUG_SetSymbolValue
409 * Set the address of a named symbol.
411 BOOL32 DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
413 char buffer[256];
414 struct name_hash *nh;
416 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
417 if (!strcmp(nh->name, name)) break;
419 if (!nh && (name[0] != '_'))
421 buffer[0] = '_';
422 strcpy(buffer+1, name);
423 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
424 if (!strcmp(nh->name, buffer)) break;
427 if (!nh) return FALSE;
428 nh->addr = *addr;
429 nh->flags &= SYM_INVALID;
430 DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(&DEBUG_context) );
431 return TRUE;
435 /***********************************************************************
436 * DEBUG_FindNearestSymbol
438 * Find the symbol nearest to a given address.
439 * If ebp is specified as non-zero, it means we should dump the argument
440 * list into the string we return as well.
442 const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
443 struct name_hash ** rtn,
444 unsigned int ebp,
445 struct list_id * source)
447 static char name_buffer[MAX_PATH + 256];
448 static char arglist[1024];
449 static char argtmp[256];
450 struct name_hash * nearest = NULL;
451 int mid, high, low;
452 unsigned int * ptr;
453 int lineno;
454 char * lineinfo, *sourcefile;
455 int i;
456 char linebuff[16];
458 if( rtn != NULL )
460 *rtn = NULL;
463 if( source != NULL )
465 source->sourcefile = NULL;
466 source->line = -1;
469 if( sortlist_valid == FALSE )
471 DEBUG_ResortSymbols();
474 if( sortlist_valid == FALSE )
476 return NULL;
480 * FIXME - use the binary search that we added to
481 * the function DEBUG_CheckLinenoStatus. Better yet, we should
482 * probably keep some notion of the current function so we don't
483 * have to search every time.
486 * Binary search to find closest symbol.
488 low = 0;
489 high = sorttab_nsym;
490 if( addr_sorttab[0]->addr.seg > addr->seg
491 || ( addr_sorttab[0]->addr.seg == addr->seg
492 && addr_sorttab[0]->addr.off > addr->off) )
494 nearest = NULL;
496 else if( addr_sorttab[high - 1]->addr.seg < addr->seg
497 || ( addr_sorttab[high - 1]->addr.seg == addr->seg
498 && addr_sorttab[high - 1]->addr.off < addr->off) )
500 nearest = addr_sorttab[high - 1];
502 else
504 while(1==1)
506 mid = (high + low)/2;
507 if( mid == low )
510 * See if there are any other entries that might also
511 * have the same address, and would also have a line
512 * number table.
514 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
516 if( (addr_sorttab[mid - 1]->addr.seg ==
517 addr_sorttab[mid]->addr.seg)
518 && (addr_sorttab[mid - 1]->addr.off ==
519 addr_sorttab[mid]->addr.off)
520 && (addr_sorttab[mid - 1]->linetab != NULL) )
522 mid--;
526 if( (mid < sorttab_nsym - 1)
527 && (addr_sorttab[mid]->linetab == NULL) )
529 if( (addr_sorttab[mid + 1]->addr.seg ==
530 addr_sorttab[mid]->addr.seg)
531 && (addr_sorttab[mid + 1]->addr.off ==
532 addr_sorttab[mid]->addr.off)
533 && (addr_sorttab[mid + 1]->linetab != NULL) )
535 mid++;
538 nearest = addr_sorttab[mid];
539 #if 0
540 fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
541 addr_sorttab[mid ]->addr.seg,
542 addr_sorttab[mid ]->addr.off,
543 addr->seg, addr->off,
544 addr_sorttab[mid ]->linetab,
545 addr_sorttab[mid ]->name);
546 #endif
547 break;
549 if( (addr_sorttab[mid]->addr.seg < addr->seg)
550 || ( addr_sorttab[mid]->addr.seg == addr->seg
551 && addr_sorttab[mid]->addr.off <= addr->off) )
553 low = mid;
555 else
557 high = mid;
562 if (!nearest) return NULL;
564 if( rtn != NULL )
566 *rtn = nearest;
570 * Fill in the relevant bits to the structure so that we can
571 * locate the source and line for this bit of code.
573 if( source != NULL )
575 source->sourcefile = nearest->sourcefile;
576 if( nearest->linetab == NULL )
578 source->line = -1;
580 else
582 source->line = nearest->linetab[0].line_number;
586 lineinfo = "";
587 lineno = -1;
590 * Prepare to display the argument list. If ebp is specified, it is
591 * the framepointer for the function in question. If not specified,
592 * we don't want the arglist.
594 memset(arglist, '\0', sizeof(arglist));
595 if( ebp != 0 )
597 for(i=0; i < nearest->n_locals; i++ )
600 * If this is a register (offset == 0) or a local
601 * variable, we don't want to know about it.
603 if( nearest->local_vars[i].offset <= 0 )
605 continue;
608 ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
609 if( arglist[0] == '\0' )
611 arglist[0] = '(';
613 else
615 strcat(arglist, ", ");
618 sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name,
619 *ptr);
620 strcat(arglist, argtmp);
622 if( arglist[0] == '(' )
624 strcat(arglist, ")");
628 if( (nearest->sourcefile != NULL) && (flag == TRUE)
629 && (addr->off - nearest->addr.off < 0x100000) )
633 * Try and find the nearest line number to the current offset.
635 if( nearest->linetab != NULL )
638 * FIXME - this is an inefficient linear search. A binary
639 * search would be better if this gets to be a performance
640 * bottleneck.
642 for(i=0; i < nearest->n_lines; i++)
644 if( addr->off < nearest->linetab[i].pc_offset.off )
646 break;
648 lineno = nearest->linetab[i].line_number;
652 if( lineno != -1 )
654 sprintf(linebuff, ":%d", lineno);
655 lineinfo = linebuff;
656 if( source != NULL )
658 source->line = lineno;
662 /* Remove the path from the file name */
663 sourcefile = strrchr( nearest->sourcefile, '/' );
664 if (!sourcefile) sourcefile = nearest->sourcefile;
665 else sourcefile++;
667 if (addr->off == nearest->addr.off)
668 sprintf( name_buffer, "%s%s [%s%s]", nearest->name,
669 arglist, sourcefile, lineinfo);
670 else
671 sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
672 addr->off - nearest->addr.off,
673 arglist, sourcefile, lineinfo );
675 else
677 if (addr->off == nearest->addr.off)
678 sprintf( name_buffer, "%s%s", nearest->name, arglist);
679 else
680 sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
681 addr->off - nearest->addr.off, arglist);
683 return name_buffer;
687 /***********************************************************************
688 * DEBUG_ReadSymbolTable
690 * Read a symbol file into the hash table.
692 void DEBUG_ReadSymbolTable( const char * filename )
694 FILE * symbolfile;
695 DBG_ADDR addr = { 0, 0 };
696 int nargs;
697 char type;
698 char * cpnt;
699 char buffer[256];
700 char name[256];
702 if (!(symbolfile = fopen(filename, "r")))
704 fprintf( stderr, "Unable to open symbol table %s\n", filename );
705 return;
708 fprintf( stderr, "Reading symbols from file %s\n", filename );
710 while (1)
712 fgets( buffer, sizeof(buffer), symbolfile );
713 if (feof(symbolfile)) break;
715 /* Strip any text after a # sign (i.e. comments) */
716 cpnt = buffer;
717 while (*cpnt)
718 if(*cpnt++ == '#') { *cpnt = 0; break; }
720 /* Quietly ignore any lines that have just whitespace */
721 cpnt = buffer;
722 while(*cpnt)
724 if(*cpnt != ' ' && *cpnt != '\t') break;
725 cpnt++;
727 if (!(*cpnt) || *cpnt == '\n') continue;
729 nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name);
730 DEBUG_AddSymbol( name, &addr, NULL, SYM_WINE );
732 fclose(symbolfile);
736 /***********************************************************************
737 * DEBUG_LoadEntryPoints
739 * Load the entry points of all the modules into the hash table.
741 void DEBUG_LoadEntryPoints(void)
743 MODULEENTRY entry;
744 NE_MODULE *pModule;
745 DBG_ADDR addr;
746 char buffer[256];
747 unsigned char *cpnt, *name;
748 FARPROC16 address;
749 BOOL32 ok;
751 for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
753 if (!(pModule = MODULE_GetPtr( entry.hModule ))) continue;
754 if (pModule->flags & NE_FFLAGS_WIN32) continue;
756 name = (unsigned char *)pModule + pModule->name_table;
758 fprintf( stderr, " %.*s",*name, name + 1 );
760 /* First search the resident names */
762 cpnt = (unsigned char *)pModule + pModule->name_table;
763 while (*cpnt)
765 cpnt += *cpnt + 1 + sizeof(WORD);
766 sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
767 if ((address = MODULE_GetEntryPoint( entry.hModule,
768 *(WORD *)(cpnt + *cpnt + 1) )))
770 addr.seg = HIWORD(address);
771 addr.off = LOWORD(address);
772 addr.type = NULL;
773 DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
777 /* Now search the non-resident names table */
779 if (!pModule->nrname_handle) continue; /* No non-resident table */
780 cpnt = (char *)GlobalLock16( pModule->nrname_handle );
781 while (*cpnt)
783 cpnt += *cpnt + 1 + sizeof(WORD);
784 sprintf( buffer, "%.*s_%.*s", *name, name + 1, *cpnt, cpnt + 1 );
785 if ((address = MODULE_GetEntryPoint( entry.hModule,
786 *(WORD *)(cpnt + *cpnt + 1) )))
788 addr.seg = HIWORD(address);
789 addr.off = LOWORD(address);
790 addr.type = NULL;
791 DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32);
797 void
798 DEBUG_AddLineNumber( struct name_hash * func, int line_num,
799 unsigned long offset )
801 if( func == NULL )
803 return;
806 if( func->n_lines + 1 >= func->lines_alloc )
808 func->lines_alloc += 64;
809 func->linetab = xrealloc(func->linetab,
810 func->lines_alloc * sizeof(WineLineNo));
813 func->linetab[func->n_lines].line_number = line_num;
814 func->linetab[func->n_lines].pc_offset.seg = func->addr.seg;
815 func->linetab[func->n_lines].pc_offset.off = func->addr.off + offset;
816 func->linetab[func->n_lines].pc_offset.type = NULL;
817 func->n_lines++;
821 struct wine_locals *
822 DEBUG_AddLocal( struct name_hash * func, int regno,
823 int offset,
824 int pc_start,
825 int pc_end,
826 char * name)
828 if( func == NULL )
830 return NULL;
833 if( func->n_locals + 1 >= func->locals_alloc )
835 func->locals_alloc += 32;
836 func->local_vars = xrealloc(func->local_vars,
837 func->locals_alloc * sizeof(WineLocals));
840 func->local_vars[func->n_locals].regno = regno;
841 func->local_vars[func->n_locals].offset = offset;
842 func->local_vars[func->n_locals].pc_start = pc_start;
843 func->local_vars[func->n_locals].pc_end = pc_end;
844 func->local_vars[func->n_locals].name = xstrdup(name);
845 func->local_vars[func->n_locals].type = NULL;
846 func->n_locals++;
848 return &func->local_vars[func->n_locals - 1];
851 void
852 DEBUG_DumpHashInfo()
854 int i;
855 int depth;
856 struct name_hash *nh;
859 * Utility function to dump stats about the hash table.
861 for(i=0; i<NR_NAME_HASH; i++)
863 depth = 0;
864 for (nh = name_hash_table[i]; nh; nh = nh->next)
866 depth++;
868 fprintf(stderr, "Bucket %d: %d\n", i, depth);
872 /***********************************************************************
873 * DEBUG_CheckLinenoStatus
875 * Find the symbol nearest to a given address.
876 * If ebp is specified as non-zero, it means we should dump the argument
877 * list into the string we return as well.
879 int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
881 struct name_hash * nearest = NULL;
882 int mid, high, low;
883 int i;
885 if( sortlist_valid == FALSE )
887 DEBUG_ResortSymbols();
891 * Binary search to find closest symbol.
893 low = 0;
894 high = sorttab_nsym;
895 if( addr_sorttab[0]->addr.seg > addr->seg
896 || ( addr_sorttab[0]->addr.seg == addr->seg
897 && addr_sorttab[0]->addr.off > addr->off) )
899 nearest = NULL;
901 else if( addr_sorttab[high - 1]->addr.seg < addr->seg
902 || ( addr_sorttab[high - 1]->addr.seg == addr->seg
903 && addr_sorttab[high - 1]->addr.off < addr->off) )
905 nearest = addr_sorttab[high - 1];
907 else
909 while(1==1)
911 mid = (high + low)/2;
912 if( mid == low )
915 * See if there are any other entries that might also
916 * have the same address, and would also have a line
917 * number table.
919 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
921 if( (addr_sorttab[mid - 1]->addr.seg ==
922 addr_sorttab[mid]->addr.seg)
923 && (addr_sorttab[mid - 1]->addr.off ==
924 addr_sorttab[mid]->addr.off)
925 && (addr_sorttab[mid - 1]->linetab != NULL) )
927 mid--;
931 if( (mid < sorttab_nsym - 1)
932 && (addr_sorttab[mid]->linetab == NULL) )
934 if( (addr_sorttab[mid + 1]->addr.seg ==
935 addr_sorttab[mid]->addr.seg)
936 && (addr_sorttab[mid + 1]->addr.off ==
937 addr_sorttab[mid]->addr.off)
938 && (addr_sorttab[mid + 1]->linetab != NULL) )
940 mid++;
943 nearest = addr_sorttab[mid];
944 #if 0
945 fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
946 addr_sorttab[mid ]->addr.seg,
947 addr_sorttab[mid ]->addr.off,
948 addr->seg, addr->off,
949 addr_sorttab[mid ]->linetab,
950 addr_sorttab[mid ]->name);
951 #endif
952 break;
954 if( (addr_sorttab[mid]->addr.seg < addr->seg)
955 || ( addr_sorttab[mid]->addr.seg == addr->seg
956 && addr_sorttab[mid]->addr.off <= addr->off) )
958 low = mid;
960 else
962 high = mid;
967 if (!nearest) return FUNC_HAS_NO_LINES;
969 if( nearest->flags & SYM_STEP_THROUGH )
972 * This will cause us to keep single stepping until
973 * we get to the other side somewhere.
975 return NOT_ON_LINENUMBER;
978 if( (nearest->flags & SYM_TRAMPOLINE) )
981 * This will cause us to keep single stepping until
982 * we get to the other side somewhere.
984 return FUNC_IS_TRAMPOLINE;
987 if( nearest->linetab == NULL )
989 return FUNC_HAS_NO_LINES;
994 * We never want to stop on the first instruction of a function
995 * even if it has it's own linenumber. Let the thing keep running
996 * until it gets past the function prologue. We only do this if there
997 * is more than one line number for the function, of course.
999 if( nearest->addr.off == addr->off && nearest->n_lines > 1 )
1001 return NOT_ON_LINENUMBER;
1004 if( (nearest->sourcefile != NULL)
1005 && (addr->off - nearest->addr.off < 0x100000) )
1008 * FIXME - this is an inefficient linear search. A binary
1009 * search would be better if this gets to be a performance
1010 * bottleneck.
1012 for(i=0; i < nearest->n_lines; i++)
1014 if( addr->off == nearest->linetab[i].pc_offset.off )
1016 return AT_LINENUMBER;
1018 if( addr->off < nearest->linetab[i].pc_offset.off )
1020 break;
1024 return NOT_ON_LINENUMBER;
1027 return FUNC_HAS_NO_LINES;
1030 /***********************************************************************
1031 * DEBUG_GetFuncInfo
1033 * Find the symbol nearest to a given address.
1034 * Returns sourcefile name and line number in a format that the listing
1035 * handler can deal with.
1037 void
1038 DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
1039 const char * name)
1041 char buffer[256];
1042 char * pnt;
1043 struct name_hash *nh;
1045 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
1047 if( filename != NULL )
1050 if( nh->sourcefile == NULL )
1052 continue;
1055 pnt = strrchr(nh->sourcefile, '/');
1056 if( strcmp(nh->sourcefile, filename) != 0
1057 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1059 continue;
1062 if (!strcmp(nh->name, name)) break;
1065 if (!nh && (name[0] != '_'))
1067 buffer[0] = '_';
1068 strcpy(buffer+1, name);
1069 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
1071 if( filename != NULL )
1073 if( nh->sourcefile == NULL )
1075 continue;
1078 pnt = strrchr(nh->sourcefile, '/');
1079 if( strcmp(nh->sourcefile, filename) != 0
1080 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1082 continue;
1085 if (!strcmp(nh->name, buffer)) break;
1089 if( !nh )
1091 if( filename != NULL )
1093 fprintf(stderr, "No such function %s in %s\n", name, filename);
1095 else
1097 fprintf(stderr, "No such function %s\n", name);
1099 ret->sourcefile = NULL;
1100 ret->line = -1;
1101 return;
1104 ret->sourcefile = nh->sourcefile;
1107 * Search for the specific line number. If we don't find it,
1108 * then return FALSE.
1110 if( nh->linetab == NULL )
1112 ret->line = -1;
1114 else
1116 ret->line = nh->linetab[0].line_number;
1120 /***********************************************************************
1121 * DEBUG_GetStackSymbolValue
1123 * Get the address of a named symbol from the current stack frame.
1125 static
1126 BOOL32 DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr )
1128 struct name_hash * curr_func;
1129 unsigned int ebp;
1130 unsigned int eip;
1131 int i;
1133 if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1135 return FALSE;
1138 for(i=0; i < curr_func->n_locals; i++ )
1141 * Test the range of validity of the local variable. This
1142 * comes up with RBRAC/LBRAC stabs in particular.
1144 if( (curr_func->local_vars[i].pc_start != 0)
1145 && ((eip - curr_func->addr.off)
1146 < curr_func->local_vars[i].pc_start) )
1148 continue;
1151 if( (curr_func->local_vars[i].pc_end != 0)
1152 && ((eip - curr_func->addr.off)
1153 > curr_func->local_vars[i].pc_end) )
1155 continue;
1158 if( strcmp(name, curr_func->local_vars[i].name) == 0 )
1161 * OK, we found it. Now figure out what to do with this.
1163 if( curr_func->local_vars[i].regno != 0 )
1166 * Register variable. We don't know how to treat
1167 * this yet.
1169 return FALSE;
1172 addr->seg = 0;
1173 addr->off = ebp + curr_func->local_vars[i].offset;
1174 addr->type = curr_func->local_vars[i].type;
1176 return TRUE;
1179 return FALSE;
1183 DEBUG_InfoLocals()
1185 struct name_hash * curr_func;
1186 unsigned int ebp;
1187 unsigned int eip;
1188 int i;
1189 unsigned int * ptr;
1190 int rtn = FALSE;
1192 if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1194 return FALSE;
1197 for(i=0; i < curr_func->n_locals; i++ )
1200 * Test the range of validity of the local variable. This
1201 * comes up with RBRAC/LBRAC stabs in particular.
1203 if( (curr_func->local_vars[i].pc_start != 0)
1204 && ((eip - curr_func->addr.off)
1205 < curr_func->local_vars[i].pc_start) )
1207 continue;
1210 if( (curr_func->local_vars[i].pc_end != 0)
1211 && ((eip - curr_func->addr.off)
1212 > curr_func->local_vars[i].pc_end) )
1214 continue;
1217 if( curr_func->local_vars[i].offset == 0 )
1219 fprintf(stderr, "%s:%s optimized into register $%s \n",
1220 curr_func->name, curr_func->local_vars[i].name,
1221 reg_name[curr_func->local_vars[i].regno]);
1223 else
1225 ptr = (unsigned int *) (ebp + curr_func->local_vars[i].offset);
1226 fprintf(stderr, "%s:%s == 0x%8.8x\n",
1227 curr_func->name, curr_func->local_vars[i].name,
1228 *ptr);
1232 rtn = TRUE;
1234 return (rtn);
1238 DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
1240 sym->symbol_size = len;
1242 return TRUE;
1246 DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
1248 sym->breakpoint_offset = off;
1250 return TRUE;
1254 DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
1257 *addr = sym->addr;
1259 return TRUE;
1262 int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
1264 sym->type = type;
1266 return TRUE;