Moved a number of 16-bit functions to file16.c.
[wine.git] / programs / winedbg / hash.c
blob266a0251bcb2a296c0d56c39ce4a62de3ea3fde1
1 /*
2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <sys/types.h>
28 #include "debugger.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
32 WINE_DECLARE_DEBUG_CHANNEL(winedbg_sym);
34 #define NR_NAME_HASH 16384
35 #ifndef PATH_MAX
36 #define PATH_MAX MAX_PATH
37 #endif
39 #ifdef __i386__
40 static const char * reg_name[] =
42 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
45 static unsigned reg_ofs[] =
47 FIELD_OFFSET(CONTEXT, Eax), FIELD_OFFSET(CONTEXT, Ecx),
48 FIELD_OFFSET(CONTEXT, Edx), FIELD_OFFSET(CONTEXT, Ebx),
49 FIELD_OFFSET(CONTEXT, Esp), FIELD_OFFSET(CONTEXT, Ebp),
50 FIELD_OFFSET(CONTEXT, Esi), FIELD_OFFSET(CONTEXT, Edi)
52 #else
53 static char * reg_name[] = { NULL }; /* FIXME */
54 static unsigned reg_ofs[] = { 0 };
55 #endif
58 struct name_hash
60 struct name_hash * next; /* Used to look up within name hash */
61 char * name;
62 char * sourcefile;
64 int n_locals;
65 int locals_alloc;
66 WineLocals * local_vars;
68 int n_lines;
69 int lines_alloc;
70 WineLineNo * linetab;
72 DBG_VALUE value;
73 unsigned short flags;
74 unsigned short breakpoint_offset;
75 unsigned int symbol_size;
79 static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value );
80 static int sortlist_valid = FALSE;
82 static int sorttab_nsym;
83 static struct name_hash ** addr_sorttab = NULL;
85 static struct name_hash * name_hash_table[NR_NAME_HASH];
87 static unsigned int name_hash( const char * name )
89 unsigned int hash = 0;
90 unsigned int tmp;
91 const char * p;
93 p = name;
95 while (*p)
97 hash = (hash << 4) + *p++;
99 if( (tmp = (hash & 0xf0000000)) )
101 hash ^= tmp >> 24;
103 hash &= ~tmp;
105 return hash % NR_NAME_HASH;
109 DEBUG_cmp_sym(const void * p1, const void * p2)
111 struct name_hash * name1 = *(struct name_hash **) p1;
112 struct name_hash * name2 = *(struct name_hash **) p2;
114 if( (name1->flags & SYM_INVALID) != 0 )
115 return -1;
117 if( (name2->flags & SYM_INVALID) != 0 )
118 return 1;
120 if( name1->value.addr.seg > name2->value.addr.seg )
121 return 1;
123 if( name1->value.addr.seg < name2->value.addr.seg )
124 return -1;
126 if( name1->value.addr.off > name2->value.addr.off )
127 return 1;
129 if( name1->value.addr.off < name2->value.addr.off )
130 return -1;
132 return 0;
135 /***********************************************************************
136 * DEBUG_ResortSymbols
138 * Rebuild sorted list of symbols.
140 static
141 void
142 DEBUG_ResortSymbols(void)
144 struct name_hash *nh;
145 int nsym = 0;
146 int i;
148 for(i=0; i<NR_NAME_HASH; i++)
150 for (nh = name_hash_table[i]; nh; nh = nh->next)
152 if( (nh->flags & SYM_INVALID) == 0 )
153 nsym++;
154 else
155 DEBUG_Printf("Symbol %s (%04lx:%08lx) is invalid\n",
156 nh->name, nh->value.addr.seg, nh->value.addr.off );
160 sorttab_nsym = nsym;
161 if( nsym == 0 )
163 return;
166 addr_sorttab = (struct name_hash **) DBG_realloc(addr_sorttab,
167 nsym * sizeof(struct name_hash *));
169 nsym = 0;
170 for(i=0; i<NR_NAME_HASH; i++)
172 for (nh = name_hash_table[i]; nh; nh = nh->next)
174 if( (nh->flags & SYM_INVALID) == 0 )
175 addr_sorttab[nsym++] = nh;
179 qsort(addr_sorttab, nsym,
180 sizeof(struct name_hash *), DEBUG_cmp_sym);
181 sortlist_valid = TRUE;
185 /***********************************************************************
186 * DEBUG_AddSymbol
188 * Add a symbol to the table.
190 struct name_hash *
191 DEBUG_AddSymbol( const char * name, const DBG_VALUE *value,
192 const char * source, int flags)
194 struct name_hash * new;
195 struct name_hash *nh;
196 static char prev_source[PATH_MAX] = {'\0', };
197 static char * prev_duped_source = NULL;
198 int hash;
200 assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
202 hash = name_hash(name);
203 for (nh = name_hash_table[hash]; nh; nh = nh->next)
205 if (name[0] == nh->name[0] && strcmp(name, nh->name) == 0)
207 int c = memcmp(&nh->value.addr, &value->addr, sizeof(value->addr));
209 if ((nh->flags & SYM_INVALID) != 0)
211 /* this case happens in ELF files, where we don't get the
212 * address of a symbol for the stabs part, but rather from
213 * the ELF sections. in this case, we'll call this function
214 * twice:
215 * - a first time while parsing the stabs, with a NULL
216 * address
217 * - a second time with the correct address
218 * SYM_INVALID is set for the first pass, and cleared in the second
219 * the code below gets most of information for both passes
221 * some GCC versions may provide the correct address in the first pass
222 * but it does not seem to be sensible to rely on that.
224 if (nh->value.addr.seg == 0 && nh->value.addr.off == 0 && c != 0)
226 WINE_TRACE_(winedbg_sym)(
227 "Changing address for symbol %s (%04lx:%08lx => %04lx:%08lx)\n",
228 name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
229 nh->value.addr = value->addr;
231 if (nh->value.type == NULL && value->type != NULL)
233 nh->value.type = value->type;
234 nh->value.cookie = value->cookie;
236 /* it may happen that the same symbol is defined in several compilation
237 * units, but the linker decides to merge it into a single instance.
238 * in that case, we don't clear the invalid flag for all the compilation
239 * units (N_GSYM), and wait to get the symbol from the symtab
241 if ((flags & SYM_INVALID) == 0)
242 nh->flags &= ~SYM_INVALID;
243 return nh;
245 /* don't define a symbol twice */
246 if (c == 0 && (flags & SYM_INVALID) == 0) return nh;
250 WINE_TRACE_(winedbg_sym)(
251 "adding %s symbol (%s) from file '%s' at %04lx:%08lx\n",
252 (flags & SYM_INVALID) ? "invalid" : " valid", name, source, value->addr.seg, value->addr.off);
255 * First see if we already have an entry for this symbol. If so
256 * return it, so we don't end up with duplicates.
259 new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash));
260 new->value = *value;
261 new->name = DBG_strdup(name);
263 if( source != NULL )
266 * This is an enhancement to reduce memory consumption. The idea
267 * is that we duplicate a given string only once. This is a big
268 * win if there are lots of symbols defined in a given source file.
270 if( strcmp(source, prev_source) == 0 )
272 new->sourcefile = prev_duped_source;
274 else
276 strcpy(prev_source, source);
277 prev_duped_source = new->sourcefile = DBG_strdup(source);
280 else
282 new->sourcefile = NULL;
285 new->n_lines = 0;
286 new->lines_alloc = 0;
287 new->linetab = NULL;
289 new->n_locals = 0;
290 new->locals_alloc = 0;
291 new->local_vars = NULL;
293 new->flags = flags;
294 new->next = NULL;
296 /* Now insert into the hash table */
297 new->next = name_hash_table[hash];
298 name_hash_table[hash] = new;
301 * Check some heuristics based upon the file name to see whether
302 * we want to step through this guy or not. These are machine generated
303 * assembly files that are used to translate between the MS way of
304 * calling things and the GCC way of calling things. In general we
305 * always want to step through.
307 if ( source != NULL ) {
308 int len = strlen(source);
310 if (len > 2 && source[len-2] == '.' && source[len-1] == 's') {
311 char* c = strrchr(source - 2, '/');
312 if (c != NULL) {
313 if (strcmp(c + 1, "asmrelay.s") == 0)
314 new->flags |= SYM_TRAMPOLINE;
319 sortlist_valid = FALSE;
320 return new;
323 BOOL DEBUG_Normalize(struct name_hash * nh )
327 * We aren't adding any more locals or linenumbers to this function.
328 * Free any spare memory that we might have allocated.
330 if( nh == NULL )
332 return TRUE;
335 if( nh->n_locals != nh->locals_alloc )
337 nh->locals_alloc = nh->n_locals;
338 nh->local_vars = DBG_realloc(nh->local_vars,
339 nh->locals_alloc * sizeof(WineLocals));
342 if( nh->n_lines != nh->lines_alloc )
344 nh->lines_alloc = nh->n_lines;
345 nh->linetab = DBG_realloc(nh->linetab,
346 nh->lines_alloc * sizeof(WineLineNo));
349 return TRUE;
352 /***********************************************************************
353 * DEBUG_GetSymbolValue
355 * Get the address of a named symbol.
356 * Return values:
357 * gsv_found: if the symbol is found
358 * gsv_unknown: if the symbol isn't found
359 * gsv_aborted: some error occurred (likely, many symbols of same name exist,
360 * and user didn't pick one of them)
362 static int DEBUG_GSV_Helper(const char* name, const int lineno,
363 DBG_VALUE* value, int num, int bp_flag)
365 struct name_hash* nh;
366 int i = 0;
367 DBG_ADDR addr;
369 for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
371 if ((nh->flags & SYM_INVALID) != 0) continue;
372 if (!strcmp(nh->name, name) && DEBUG_GetLineNumberAddr( nh, lineno, &addr, bp_flag ))
374 if (i >= num) return num + 1;
375 value[i].addr = addr;
376 value[i].type = nh->value.type;
377 value[i].cookie = nh->value.cookie;
378 i++;
381 return i;
384 enum get_sym_val DEBUG_GetSymbolValue( const char * name,
385 const int lineno,
386 DBG_VALUE *rtn, int bp_flag )
388 #define NUMDBGV 100
389 /* FIXME: NUMDBGV should be made variable */
390 DBG_VALUE value[NUMDBGV];
391 DBG_VALUE vtmp;
392 int num, i, local = -1;
394 num = DEBUG_GSV_Helper(name, lineno, value, NUMDBGV, bp_flag);
395 if (!num && (name[0] != '_'))
397 char buffer[512];
399 if (strlen(name) < sizeof(buffer) - 2) /* one for '_', one for '\0' */
401 buffer[0] = '_';
402 strcpy(buffer + 1, name);
403 num = DEBUG_GSV_Helper(buffer, lineno, value, NUMDBGV, bp_flag);
405 else WINE_WARN("Way too long symbol (%s)\n", name);
408 /* now get the local symbols if any */
409 if (DEBUG_GetStackSymbolValue(name, &vtmp) && num < NUMDBGV)
411 value[num] = vtmp;
412 local = num;
413 num++;
416 if (num == 0) {
417 return gsv_unknown;
418 } else if (!DEBUG_InteractiveP || num == 1) {
419 i = 0;
420 } else {
421 char buffer[256];
423 if (num == NUMDBGV+1) {
424 DEBUG_Printf("Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
425 num = NUMDBGV;
427 DEBUG_Printf("Many symbols with name '%s', choose the one you want (<cr> to abort):\n", name);
428 for (i = 0; i < num; i++) {
429 DEBUG_Printf("[%d]: ", i + 1);
430 if (i == local) {
431 struct name_hash*func;
432 unsigned int ebp;
433 unsigned int eip;
435 if (DEBUG_GetCurrentFrame(&func, &eip, &ebp))
436 DEBUG_Printf("local variable of %s in %s\n", func->name, func->sourcefile);
437 else
438 DEBUG_Printf("local variable\n");
439 } else {
440 DEBUG_PrintAddress( &value[i].addr, DEBUG_GetSelectorType(value[i].addr.seg), TRUE);
441 DEBUG_Printf("\n");
444 do {
445 i = 0;
446 if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer)))
448 if (buffer[0] == '\0') return gsv_aborted;
449 i = atoi(buffer);
450 if (i < 1 || i > num)
451 DEBUG_Printf("Invalid choice %d\n", i);
453 } while (i < 1 || i > num);
455 /* The array is 0-based, but the choices are 1..n, so we have to subtract one before returning. */
456 i--;
458 *rtn = value[i];
459 return gsv_found;
462 /***********************************************************************
463 * DEBUG_GetLineNumberAddr
465 * Get the address of a named symbol.
467 BOOL DEBUG_GetLineNumberAddr( const struct name_hash * nh, const int lineno,
468 DBG_ADDR *addr, int bp_flag )
470 int i;
472 if( lineno == -1 )
474 *addr = nh->value.addr;
475 if( bp_flag )
477 addr->off += nh->breakpoint_offset;
480 else
483 * Search for the specific line number. If we don't find it,
484 * then return FALSE.
486 if( nh->linetab == NULL )
488 return FALSE;
491 for(i=0; i < nh->n_lines; i++ )
493 if( nh->linetab[i].line_number == lineno )
495 *addr = nh->linetab[i].pc_offset;
496 return TRUE;
501 * This specific line number not found.
503 return FALSE;
506 return TRUE;
509 /***********************************************************************
510 * DEBUG_FindNearestSymbol
512 * Find the symbol nearest to a given address.
513 * If ebp is specified as non-zero, it means we should dump the argument
514 * list into the string we return as well.
516 const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
517 struct name_hash ** rtn,
518 unsigned int ebp,
519 struct list_id * source)
521 static char name_buffer[MAX_PATH + 256];
522 static char arglist[1024];
523 static char argtmp[256];
524 struct name_hash * nearest = NULL;
525 int mid, high, low;
526 unsigned int * ptr;
527 int lineno;
528 const char * lineinfo;
529 char *sourcefile;
530 int i;
531 char linebuff[16];
532 unsigned val;
533 DBG_MODULE* module;
534 char modbuf[256];
536 if( rtn != NULL )
538 *rtn = NULL;
541 if( source != NULL )
543 source->sourcefile = NULL;
544 source->line = -1;
547 if( sortlist_valid == FALSE )
549 DEBUG_ResortSymbols();
552 if( sortlist_valid == FALSE )
554 return NULL;
558 * FIXME - use the binary search that we added to
559 * the function DEBUG_CheckLinenoStatus. Better yet, we should
560 * probably keep some notion of the current function so we don't
561 * have to search every time.
564 * Binary search to find closest symbol.
566 low = 0;
567 high = sorttab_nsym;
568 if( addr_sorttab[0]->value.addr.seg > addr->seg
569 || ( addr_sorttab[0]->value.addr.seg == addr->seg
570 && addr_sorttab[0]->value.addr.off > addr->off) )
572 nearest = NULL;
574 else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
575 || ( addr_sorttab[high - 1]->value.addr.seg == addr->seg
576 && addr_sorttab[high - 1]->value.addr.off < addr->off) )
578 nearest = addr_sorttab[high - 1];
580 else
582 while(1==1)
584 mid = (high + low)/2;
585 if( mid == low )
588 * See if there are any other entries that might also
589 * have the same address, and would also have a line
590 * number table.
592 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
594 if( (addr_sorttab[mid - 1]->value.addr.seg ==
595 addr_sorttab[mid]->value.addr.seg)
596 && (addr_sorttab[mid - 1]->value.addr.off ==
597 addr_sorttab[mid]->value.addr.off)
598 && (addr_sorttab[mid - 1]->linetab != NULL) )
600 mid--;
604 if( (mid < sorttab_nsym - 1)
605 && (addr_sorttab[mid]->linetab == NULL) )
607 if( (addr_sorttab[mid + 1]->value.addr.seg ==
608 addr_sorttab[mid]->value.addr.seg)
609 && (addr_sorttab[mid + 1]->value.addr.off ==
610 addr_sorttab[mid]->value.addr.off)
611 && (addr_sorttab[mid + 1]->linetab != NULL) )
613 mid++;
616 nearest = addr_sorttab[mid];
617 WINE_TRACE_(winedbg_sym)(
618 "Found %lx:%lx when looking for %lx:%lx %p %s\n",
619 addr_sorttab[mid ]->value.addr.seg,
620 addr_sorttab[mid ]->value.addr.off,
621 addr->seg, addr->off,
622 addr_sorttab[mid ]->linetab,
623 addr_sorttab[mid ]->name);
624 break;
626 if( (addr_sorttab[mid]->value.addr.seg < addr->seg)
627 || ( addr_sorttab[mid]->value.addr.seg == addr->seg
628 && addr_sorttab[mid]->value.addr.off <= addr->off) )
630 low = mid;
632 else
634 high = mid;
639 if (!nearest) return NULL;
641 if( rtn != NULL )
643 *rtn = nearest;
647 * Fill in the relevant bits to the structure so that we can
648 * locate the source and line for this bit of code.
650 if( source != NULL )
652 source->sourcefile = nearest->sourcefile;
653 if( nearest->linetab == NULL )
655 source->line = -1;
657 else
659 source->line = nearest->linetab[0].line_number;
663 lineinfo = "";
664 lineno = -1;
667 * Prepare to display the argument list. If ebp is specified, it is
668 * the framepointer for the function in question. If not specified,
669 * we don't want the arglist.
671 memset(arglist, '\0', sizeof(arglist));
672 if( ebp != 0 )
674 for(i=0; i < nearest->n_locals; i++ )
677 * If this is a register (offset == 0) or a local
678 * variable, we don't want to know about it.
680 if( nearest->local_vars[i].offset <= 0 )
682 continue;
685 ptr = (unsigned int *) (ebp + nearest->local_vars[i].offset);
686 if( arglist[0] == '\0' )
688 arglist[0] = '(';
690 else
692 strcat(arglist, ", ");
694 DEBUG_READ_MEM_VERBOSE(ptr, &val, sizeof(val));
695 snprintf(argtmp, sizeof(argtmp), "%s=0x%x", nearest->local_vars[i].name, val);
697 strcat(arglist, argtmp);
699 if( arglist[0] == '(' )
701 strcat(arglist, ")");
705 module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
706 if (module) {
707 const char *p, *name = module->module_name;
708 if ((p = strrchr(name, '/'))) name = p + 1;
709 if ((p = strrchr(name, '\\'))) name = p + 1;
710 snprintf( modbuf, sizeof(modbuf), " in %s", name);
712 else
713 modbuf[0] = '\0';
715 if( (nearest->sourcefile != NULL) && (flag == TRUE)
716 && (addr->off - nearest->value.addr.off < 0x100000) )
720 * Try and find the nearest line number to the current offset.
722 if( nearest->linetab != NULL )
724 low = 0;
725 high = nearest->n_lines;
726 while ((high - low) > 1)
728 mid = (high + low) / 2;
729 if (addr->off < nearest->linetab[mid].pc_offset.off)
730 high = mid;
731 else
732 low = mid;
734 lineno = nearest->linetab[low].line_number;
737 if( lineno != -1 )
739 snprintf(linebuff, sizeof(linebuff), ":%d", lineno);
740 lineinfo = linebuff;
741 if( source != NULL )
743 source->line = lineno;
747 /* Remove the path from the file name */
748 sourcefile = strrchr( nearest->sourcefile, '/' );
749 if (!sourcefile) sourcefile = nearest->sourcefile;
750 else sourcefile++;
752 if (addr->off == nearest->value.addr.off)
753 snprintf( name_buffer, sizeof(name_buffer), "%s%s [%s%s]%s", nearest->name,
754 arglist, sourcefile, lineinfo, modbuf);
755 else
756 snprintf( name_buffer, sizeof(name_buffer), "%s+0x%lx%s [%s%s]%s", nearest->name,
757 addr->off - nearest->value.addr.off,
758 arglist, sourcefile, lineinfo, modbuf );
760 else
762 if (addr->off == nearest->value.addr.off)
763 snprintf( name_buffer, sizeof(name_buffer), "%s%s%s", nearest->name, arglist, modbuf);
764 else {
765 if (addr->seg && (nearest->value.addr.seg!=addr->seg))
766 return NULL;
767 else
768 snprintf( name_buffer, sizeof(name_buffer), "%s+0x%lx%s%s", nearest->name,
769 addr->off - nearest->value.addr.off, arglist, modbuf);
772 return name_buffer;
776 /***********************************************************************
777 * DEBUG_ReadSymbolTable
779 * Read a symbol file into the hash table.
781 void DEBUG_ReadSymbolTable( const char* filename, unsigned long offset )
783 FILE * symbolfile;
784 DBG_VALUE value;
785 char type;
786 char * cpnt;
787 char buffer[256];
788 char name[256];
790 if (!(symbolfile = fopen(filename, "r")))
792 WINE_WARN("Unable to open symbol table %s\n", filename);
793 return;
796 DEBUG_Printf("Reading symbols from file %s\n", filename);
798 value.type = NULL;
799 value.addr.seg = 0;
800 value.addr.off = 0;
801 value.cookie = DV_TARGET;
803 while (1)
805 fgets( buffer, sizeof(buffer), symbolfile );
806 if (feof(symbolfile)) break;
808 /* Strip any text after a # sign (i.e. comments) */
809 cpnt = buffer;
810 while (*cpnt)
811 if(*cpnt++ == '#') { *cpnt = 0; break; }
813 /* Quietly ignore any lines that have just whitespace */
814 cpnt = buffer;
815 while(*cpnt)
817 if(*cpnt != ' ' && *cpnt != '\t') break;
818 cpnt++;
820 if (!(*cpnt) || *cpnt == '\n') continue;
822 if (sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name) == 3)
824 if (value.addr.off + offset < value.addr.off)
825 WINE_WARN("Address wrap around\n");
826 value.addr.off += offset;
827 DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
830 fclose(symbolfile);
834 void
835 DEBUG_AddLineNumber( struct name_hash * func, int line_num,
836 unsigned long offset )
838 if( func == NULL )
840 return;
843 if( func->n_lines + 1 >= func->lines_alloc )
845 func->lines_alloc += 64;
846 func->linetab = DBG_realloc(func->linetab,
847 func->lines_alloc * sizeof(WineLineNo));
850 func->linetab[func->n_lines].line_number = line_num;
851 func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
852 func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
853 func->n_lines++;
857 struct wine_locals *
858 DEBUG_AddLocal( struct name_hash * func, int regno,
859 int offset,
860 int pc_start,
861 int pc_end,
862 char * name)
864 if( func == NULL )
866 return NULL;
869 if( func->n_locals + 1 >= func->locals_alloc )
871 func->locals_alloc += 32;
872 func->local_vars = DBG_realloc(func->local_vars,
873 func->locals_alloc * sizeof(WineLocals));
876 func->local_vars[func->n_locals].regno = regno;
877 func->local_vars[func->n_locals].offset = offset;
878 func->local_vars[func->n_locals].pc_start = pc_start;
879 func->local_vars[func->n_locals].pc_end = pc_end;
880 func->local_vars[func->n_locals].name = DBG_strdup(name);
881 func->local_vars[func->n_locals].type = NULL;
882 func->n_locals++;
884 return &func->local_vars[func->n_locals - 1];
887 void
888 DEBUG_DumpHashInfo(void)
890 int i;
891 int depth;
892 struct name_hash *nh;
895 * Utility function to dump stats about the hash table.
897 for(i=0; i<NR_NAME_HASH; i++)
899 depth = 0;
900 for (nh = name_hash_table[i]; nh; nh = nh->next)
902 depth++;
904 DEBUG_Printf("Bucket %d: %d\n", i, depth);
908 /***********************************************************************
909 * DEBUG_CheckLinenoStatus
911 * Find the symbol nearest to a given address.
912 * If ebp is specified as non-zero, it means we should dump the argument
913 * list into the string we return as well.
915 int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
917 struct name_hash * nearest = NULL;
918 int mid, high, low;
920 if( sortlist_valid == FALSE )
922 DEBUG_ResortSymbols();
926 * Binary search to find closest symbol.
928 low = 0;
929 high = sorttab_nsym;
930 if( addr_sorttab[0]->value.addr.seg > addr->seg
931 || ( addr_sorttab[0]->value.addr.seg == addr->seg
932 && addr_sorttab[0]->value.addr.off > addr->off) )
934 nearest = NULL;
936 else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
937 || ( addr_sorttab[high - 1]->value.addr.seg == addr->seg
938 && addr_sorttab[high - 1]->value.addr.off < addr->off) )
940 nearest = addr_sorttab[high - 1];
942 else
944 while(1==1)
946 mid = (high + low)/2;
947 if( mid == low )
950 * See if there are any other entries that might also
951 * have the same address, and would also have a line
952 * number table.
954 if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
956 if( (addr_sorttab[mid - 1]->value.addr.seg ==
957 addr_sorttab[mid]->value.addr.seg)
958 && (addr_sorttab[mid - 1]->value.addr.off ==
959 addr_sorttab[mid]->value.addr.off)
960 && (addr_sorttab[mid - 1]->linetab != NULL) )
962 mid--;
966 if( (mid < sorttab_nsym - 1)
967 && (addr_sorttab[mid]->linetab == NULL) )
969 if( (addr_sorttab[mid + 1]->value.addr.seg ==
970 addr_sorttab[mid]->value.addr.seg)
971 && (addr_sorttab[mid + 1]->value.addr.off ==
972 addr_sorttab[mid]->value.addr.off)
973 && (addr_sorttab[mid + 1]->linetab != NULL) )
975 mid++;
978 nearest = addr_sorttab[mid];
979 WINE_TRACE_(winedbg_sym)(
980 "Found %lx:%lx when looking for %lx:%lx %p %s\n",
981 addr_sorttab[mid ]->value.addr.seg,
982 addr_sorttab[mid ]->value.addr.off,
983 addr->seg, addr->off,
984 addr_sorttab[mid ]->linetab,
985 addr_sorttab[mid ]->name);
986 break;
988 if( (addr_sorttab[mid]->value.addr.seg < addr->seg)
989 || ( addr_sorttab[mid]->value.addr.seg == addr->seg
990 && addr_sorttab[mid]->value.addr.off <= addr->off) )
992 low = mid;
994 else
996 high = mid;
1001 if (!nearest) return FUNC_HAS_NO_LINES;
1003 if( nearest->flags & SYM_STEP_THROUGH )
1006 * This will cause us to keep single stepping until
1007 * we get to the other side somewhere.
1009 return NOT_ON_LINENUMBER;
1012 if( (nearest->flags & SYM_TRAMPOLINE) )
1015 * This will cause us to keep single stepping until
1016 * we get to the other side somewhere.
1018 return FUNC_IS_TRAMPOLINE;
1021 if( nearest->linetab == NULL )
1023 return FUNC_HAS_NO_LINES;
1028 * We never want to stop on the first instruction of a function
1029 * even if it has it's own linenumber. Let the thing keep running
1030 * until it gets past the function prologue. We only do this if there
1031 * is more than one line number for the function, of course.
1033 if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
1035 return NOT_ON_LINENUMBER;
1038 if( (nearest->sourcefile != NULL)
1039 && (addr->off - nearest->value.addr.off < 0x100000) )
1041 low = 0;
1042 high = nearest->n_lines;
1043 while ((high - low) > 1)
1045 mid = (high + low) / 2;
1046 if (addr->off < nearest->linetab[mid].pc_offset.off) high = mid;
1047 else low = mid;
1049 if (addr->off == nearest->linetab[low].pc_offset.off)
1050 return AT_LINENUMBER;
1051 else
1052 return NOT_ON_LINENUMBER;
1055 return FUNC_HAS_NO_LINES;
1058 /***********************************************************************
1059 * DEBUG_GetFuncInfo
1061 * Find the symbol nearest to a given address.
1062 * Returns sourcefile name and line number in a format that the listing
1063 * handler can deal with.
1065 void
1066 DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
1067 const char * name)
1069 char buffer[256];
1070 char * pnt;
1071 struct name_hash *nh;
1073 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
1075 if( filename != NULL )
1078 if( nh->sourcefile == NULL )
1080 continue;
1083 pnt = strrchr(nh->sourcefile, '/');
1084 if( strcmp(nh->sourcefile, filename) != 0
1085 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1087 continue;
1090 if (!strcmp(nh->name, name)) break;
1093 if (!nh && (name[0] != '_'))
1095 buffer[0] = '_';
1096 strcpy(buffer+1, name);
1097 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
1099 if( filename != NULL )
1101 if( nh->sourcefile == NULL )
1103 continue;
1106 pnt = strrchr(nh->sourcefile, '/');
1107 if( strcmp(nh->sourcefile, filename) != 0
1108 && (pnt == NULL || strcmp(pnt + 1, filename) != 0) )
1110 continue;
1113 if (!strcmp(nh->name, buffer)) break;
1117 if( !nh )
1119 if( filename != NULL )
1121 DEBUG_Printf("No such function %s in %s\n", name, filename);
1123 else
1125 DEBUG_Printf("No such function %s\n", name);
1127 ret->sourcefile = NULL;
1128 ret->line = -1;
1129 return;
1132 ret->sourcefile = nh->sourcefile;
1135 * Search for the specific line number. If we don't find it,
1136 * then return FALSE.
1138 if( nh->linetab == NULL )
1140 ret->line = -1;
1142 else
1144 ret->line = nh->linetab[0].line_number;
1148 /***********************************************************************
1149 * DEBUG_GetStackSymbolValue
1151 * Get the address of a named symbol from the current stack frame.
1153 static
1154 BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
1156 struct name_hash * curr_func;
1157 unsigned int ebp;
1158 unsigned int eip;
1159 int i;
1161 if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1163 return FALSE;
1166 for(i=0; i < curr_func->n_locals; i++ )
1169 * Test the range of validity of the local variable. This
1170 * comes up with RBRAC/LBRAC stabs in particular.
1172 if( (curr_func->local_vars[i].pc_start != 0)
1173 && ((eip - curr_func->value.addr.off)
1174 < curr_func->local_vars[i].pc_start) )
1176 continue;
1179 if( (curr_func->local_vars[i].pc_end != 0)
1180 && ((eip - curr_func->value.addr.off)
1181 > curr_func->local_vars[i].pc_end) )
1183 continue;
1186 if( strcmp(name, curr_func->local_vars[i].name) == 0 )
1189 * OK, we found it. Now figure out what to do with this.
1191 if( curr_func->local_vars[i].regno != 0 )
1194 * Register variable. Point to DEBUG_context field.
1196 assert(curr_func->local_vars[i].regno - 1 < sizeof(reg_ofs)/sizeof(reg_ofs[0]));
1197 value->addr.off = ((DWORD)&DEBUG_context) +
1198 reg_ofs[curr_func->local_vars[i].regno - 1];
1199 value->cookie = DV_HOST;
1201 else
1203 value->addr.off = ebp + curr_func->local_vars[i].offset;
1204 value->cookie = DV_TARGET;
1206 value->addr.seg = 0;
1207 value->type = curr_func->local_vars[i].type;
1209 return TRUE;
1213 return FALSE;
1217 DEBUG_InfoLocals(void)
1219 struct name_hash * curr_func;
1220 unsigned int ebp;
1221 unsigned int eip;
1222 int i;
1223 unsigned int * ptr;
1224 unsigned int val;
1226 if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
1228 return FALSE;
1231 DEBUG_Printf("%s:\n", curr_func->name);
1233 for(i=0; i < curr_func->n_locals; i++ )
1236 * Test the range of validity of the local variable. This
1237 * comes up with RBRAC/LBRAC stabs in particular.
1239 if( (curr_func->local_vars[i].pc_start != 0)
1240 && ((eip - curr_func->value.addr.off)
1241 < curr_func->local_vars[i].pc_start) )
1243 continue;
1246 if( (curr_func->local_vars[i].pc_end != 0)
1247 && ((eip - curr_func->value.addr.off)
1248 > curr_func->local_vars[i].pc_end) )
1250 continue;
1253 DEBUG_PrintTypeCast(curr_func->local_vars[i].type);
1255 if( curr_func->local_vars[i].regno != 0 )
1257 ptr = (unsigned int *)(((DWORD)&DEBUG_context)
1258 + reg_ofs[curr_func->local_vars[i].regno - 1]);
1259 DEBUG_Printf(" %s (optimized into register $%s) == 0x%8.8x\n",
1260 curr_func->local_vars[i].name,
1261 reg_name[curr_func->local_vars[i].regno - 1],
1262 *ptr);
1264 else
1266 DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset),
1267 &val, sizeof(val));
1268 DEBUG_Printf(" %s == 0x%8.8x\n",
1269 curr_func->local_vars[i].name, val);
1273 return TRUE;
1277 DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len)
1279 sym->symbol_size = len;
1281 return TRUE;
1285 DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int off)
1287 sym->breakpoint_offset = off;
1289 return TRUE;
1293 DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
1296 *addr = sym->value.addr;
1298 return TRUE;
1301 int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type)
1303 sym->type = type;
1305 return TRUE;
1308 const char *DEBUG_GetSymbolName(const struct name_hash * sym)
1310 return sym->name;
1313 #ifdef HAVE_REGEX_H
1315 static int cmp_sym_by_name(const void * p1, const void * p2)
1317 struct name_hash ** name1 = (struct name_hash **) p1;
1318 struct name_hash ** name2 = (struct name_hash **) p2;
1320 return strcmp( (*name1)->name, (*name2)->name );
1323 #include <regex.h>
1325 void DEBUG_InfoSymbols(const char* str)
1327 int i;
1328 struct name_hash* nh;
1329 struct name_hash** array = NULL;
1330 unsigned num_used_array = 0;
1331 unsigned num_alloc_array = 0;
1332 const char* name;
1333 enum dbg_mode mode;
1334 regex_t preg;
1336 regcomp(&preg, str, REG_NOSUB);
1338 /* grab all symbols */
1339 for (i = 0; i < NR_NAME_HASH; i++)
1341 for (nh = name_hash_table[i]; nh; nh = nh->next)
1343 if (regexec(&preg, nh->name, 0, NULL, 0) == 0)
1345 if (num_used_array == num_alloc_array)
1347 int size = sizeof(*array) * (num_alloc_array += 32);
1348 if (!array) array = HeapAlloc(GetProcessHeap(), 0, size);
1349 else array = HeapReAlloc(GetProcessHeap(), 0, array, size);
1350 if (!array) return;
1352 array[num_used_array++] = nh;
1356 regfree(&preg);
1358 /* now sort them by alphabetical order */
1359 qsort(array, num_used_array, sizeof(*array), cmp_sym_by_name);
1361 /* and display them */
1362 for (i = 0; i < num_used_array; i++)
1364 mode = DEBUG_GetSelectorType(array[i]->value.addr.seg);
1365 name = DEBUG_FindNearestSymbol( &array[i]->value.addr, TRUE,
1366 NULL, 0, NULL );
1368 if (mode != MODE_32)
1369 DEBUG_Printf("%04lx:%04lx :",
1370 array[i]->value.addr.seg & 0xFFFF,
1371 array[i]->value.addr.off);
1372 else
1373 DEBUG_Printf("%08lx :", array[i]->value.addr.off);
1374 if (array[i]->value.type)
1376 DEBUG_Printf(" (");
1377 DEBUG_PrintTypeCast(array[i]->value.type);
1378 DEBUG_Printf(")");
1380 if (name) DEBUG_Printf(" %s\n", name);
1382 HeapFree(GetProcessHeap(), 0, array);
1385 #else /* HAVE_REGEX_H */
1387 void DEBUG_InfoSymbols(const char* str)
1389 WINE_FIXME("Requires regex support\n");
1392 #endif /* HAVE_REGEX_H */