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
27 #include <sys/types.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
36 #define PATH_MAX MAX_PATH
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
)
53 static char * reg_name
[] = { NULL
}; /* FIXME */
54 static unsigned reg_ofs
[] = { 0 };
60 struct name_hash
* next
; /* Used to look up within name hash */
66 WineLocals
* local_vars
;
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;
97 hash
= (hash
<< 4) + *p
++;
99 if( (tmp
= (hash
& 0xf0000000)) )
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 )
117 if( (name2
->flags
& SYM_INVALID
) != 0 )
120 if( name1
->value
.addr
.seg
> name2
->value
.addr
.seg
)
123 if( name1
->value
.addr
.seg
< name2
->value
.addr
.seg
)
126 if( name1
->value
.addr
.off
> name2
->value
.addr
.off
)
129 if( name1
->value
.addr
.off
< name2
->value
.addr
.off
)
135 /***********************************************************************
136 * DEBUG_ResortSymbols
138 * Rebuild sorted list of symbols.
142 DEBUG_ResortSymbols(void)
144 struct name_hash
*nh
;
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 )
155 DEBUG_Printf("Symbol %s (%04lx:%08lx) is invalid\n",
156 nh
->name
, nh
->value
.addr
.seg
, nh
->value
.addr
.off
);
166 addr_sorttab
= (struct name_hash
**) DBG_realloc(addr_sorttab
,
167 nsym
* sizeof(struct name_hash
*));
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 /***********************************************************************
188 * Add a symbol to the table.
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
;
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
215 * - a first time while parsing the stabs, with a NULL
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
;
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
));
261 new->name
= DBG_strdup(name
);
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
;
276 strcpy(prev_source
, source
);
277 prev_duped_source
= new->sourcefile
= DBG_strdup(source
);
282 new->sourcefile
= NULL
;
286 new->lines_alloc
= 0;
290 new->locals_alloc
= 0;
291 new->local_vars
= 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, '/');
313 if (strcmp(c
+ 1, "asmrelay.s") == 0)
314 new->flags
|= SYM_TRAMPOLINE
;
319 sortlist_valid
= FALSE
;
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.
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
));
352 /***********************************************************************
353 * DEBUG_GetSymbolValue
355 * Get the address of a named symbol.
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
;
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
;
384 enum get_sym_val
DEBUG_GetSymbolValue( const char * name
,
386 DBG_VALUE
*rtn
, int bp_flag
)
389 /* FIXME: NUMDBGV should be made variable */
390 DBG_VALUE value
[NUMDBGV
];
392 int num
, i
, local
= -1;
394 num
= DEBUG_GSV_Helper(name
, lineno
, value
, NUMDBGV
, bp_flag
);
395 if (!num
&& (name
[0] != '_'))
399 if (strlen(name
) < sizeof(buffer
) - 2) /* one for '_', one for '\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
)
418 } else if (!DEBUG_InteractiveP
|| num
== 1) {
423 if (num
== NUMDBGV
+1) {
424 DEBUG_Printf("Too many addresses for symbol '%s', limiting the first %d\n", name
, 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);
431 struct name_hash
*func
;
435 if (DEBUG_GetCurrentFrame(&func
, &eip
, &ebp
))
436 DEBUG_Printf("local variable of %s in %s\n", func
->name
, func
->sourcefile
);
438 DEBUG_Printf("local variable\n");
440 DEBUG_PrintAddress( &value
[i
].addr
, DEBUG_GetSelectorType(value
[i
].addr
.seg
), TRUE
);
446 if (DEBUG_ReadLine("=> ", buffer
, sizeof(buffer
)))
448 if (buffer
[0] == '\0') return gsv_aborted
;
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. */
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
)
474 *addr
= nh
->value
.addr
;
477 addr
->off
+= nh
->breakpoint_offset
;
483 * Search for the specific line number. If we don't find it,
486 if( nh
->linetab
== NULL
)
491 for(i
=0; i
< nh
->n_lines
; i
++ )
493 if( nh
->linetab
[i
].line_number
== lineno
)
495 *addr
= nh
->linetab
[i
].pc_offset
;
501 * This specific line number not found.
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
,
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
;
528 const char * lineinfo
;
543 source
->sourcefile
= NULL
;
547 if( sortlist_valid
== FALSE
)
549 DEBUG_ResortSymbols();
552 if( sortlist_valid
== FALSE
)
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.
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
) )
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];
584 mid
= (high
+ low
)/2;
588 * See if there are any other entries that might also
589 * have the same address, and would also have a line
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
) )
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
) )
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
);
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
) )
639 if (!nearest
) return NULL
;
647 * Fill in the relevant bits to the structure so that we can
648 * locate the source and line for this bit of code.
652 source
->sourcefile
= nearest
->sourcefile
;
653 if( nearest
->linetab
== NULL
)
659 source
->line
= nearest
->linetab
[0].line_number
;
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
));
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 )
685 ptr
= (unsigned int *) (ebp
+ nearest
->local_vars
[i
].offset
);
686 if( arglist
[0] == '\0' )
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
);
707 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
);
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
)
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
)
734 lineno
= nearest
->linetab
[low
].line_number
;
739 snprintf(linebuff
, sizeof(linebuff
), ":%d", lineno
);
743 source
->line
= lineno
;
747 /* Remove the path from the file name */
748 sourcefile
= strrchr( nearest
->sourcefile
, '/' );
749 if (!sourcefile
) sourcefile
= nearest
->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
);
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
);
762 if (addr
->off
== nearest
->value
.addr
.off
)
763 snprintf( name_buffer
, sizeof(name_buffer
), "%s%s%s", nearest
->name
, arglist
, modbuf
);
765 if (addr
->seg
&& (nearest
->value
.addr
.seg
!=addr
->seg
))
768 snprintf( name_buffer
, sizeof(name_buffer
), "%s+0x%lx%s%s", nearest
->name
,
769 addr
->off
- nearest
->value
.addr
.off
, arglist
, modbuf
);
776 /***********************************************************************
777 * DEBUG_ReadSymbolTable
779 * Read a symbol file into the hash table.
781 void DEBUG_ReadSymbolTable( const char* filename
, unsigned long offset
)
790 if (!(symbolfile
= fopen(filename
, "r")))
792 WINE_WARN("Unable to open symbol table %s\n", filename
);
796 DEBUG_Printf("Reading symbols from file %s\n", filename
);
801 value
.cookie
= DV_TARGET
;
805 fgets( buffer
, sizeof(buffer
), symbolfile
);
806 if (feof(symbolfile
)) break;
808 /* Strip any text after a # sign (i.e. comments) */
811 if(*cpnt
++ == '#') { *cpnt
= 0; break; }
813 /* Quietly ignore any lines that have just whitespace */
817 if(*cpnt
!= ' ' && *cpnt
!= '\t') break;
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
);
835 DEBUG_AddLineNumber( struct name_hash
* func
, int line_num
,
836 unsigned long offset
)
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
;
858 DEBUG_AddLocal( struct name_hash
* func
, int regno
,
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
;
884 return &func
->local_vars
[func
->n_locals
- 1];
888 DEBUG_DumpHashInfo(void)
892 struct name_hash
*nh
;
895 * Utility function to dump stats about the hash table.
897 for(i
=0; i
<NR_NAME_HASH
; i
++)
900 for (nh
= name_hash_table
[i
]; nh
; nh
= nh
->next
)
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
;
920 if( sortlist_valid
== FALSE
)
922 DEBUG_ResortSymbols();
926 * Binary search to find closest symbol.
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
) )
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];
946 mid
= (high
+ low
)/2;
950 * See if there are any other entries that might also
951 * have the same address, and would also have a line
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
) )
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
) )
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
);
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
) )
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) )
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
;
1049 if (addr
->off
== nearest
->linetab
[low
].pc_offset
.off
)
1050 return AT_LINENUMBER
;
1052 return NOT_ON_LINENUMBER
;
1055 return FUNC_HAS_NO_LINES
;
1058 /***********************************************************************
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.
1066 DEBUG_GetFuncInfo( struct list_id
* ret
, const char * filename
,
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
)
1083 pnt
= strrchr(nh
->sourcefile
, '/');
1084 if( strcmp(nh
->sourcefile
, filename
) != 0
1085 && (pnt
== NULL
|| strcmp(pnt
+ 1, filename
) != 0) )
1090 if (!strcmp(nh
->name
, name
)) break;
1093 if (!nh
&& (name
[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
)
1106 pnt
= strrchr(nh
->sourcefile
, '/');
1107 if( strcmp(nh
->sourcefile
, filename
) != 0
1108 && (pnt
== NULL
|| strcmp(pnt
+ 1, filename
) != 0) )
1113 if (!strcmp(nh
->name
, buffer
)) break;
1119 if( filename
!= NULL
)
1121 DEBUG_Printf("No such function %s in %s\n", name
, filename
);
1125 DEBUG_Printf("No such function %s\n", name
);
1127 ret
->sourcefile
= NULL
;
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
)
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.
1154 BOOL
DEBUG_GetStackSymbolValue( const char * name
, DBG_VALUE
*value
)
1156 struct name_hash
* curr_func
;
1161 if( DEBUG_GetCurrentFrame(&curr_func
, &eip
, &ebp
) == 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
) )
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
) )
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
;
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
;
1217 DEBUG_InfoLocals(void)
1219 struct name_hash
* curr_func
;
1226 if( DEBUG_GetCurrentFrame(&curr_func
, &eip
, &ebp
) == 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
) )
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
) )
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],
1266 DEBUG_READ_MEM_VERBOSE((void*)(ebp
+ curr_func
->local_vars
[i
].offset
),
1268 DEBUG_Printf(" %s == 0x%8.8x\n",
1269 curr_func
->local_vars
[i
].name
, val
);
1277 DEBUG_SetSymbolSize(struct name_hash
* sym
, unsigned int len
)
1279 sym
->symbol_size
= len
;
1285 DEBUG_SetSymbolBPOff(struct name_hash
* sym
, unsigned int off
)
1287 sym
->breakpoint_offset
= off
;
1293 DEBUG_GetSymbolAddr(struct name_hash
* sym
, DBG_ADDR
* addr
)
1296 *addr
= sym
->value
.addr
;
1301 int DEBUG_SetLocalSymbolType(struct wine_locals
* sym
, struct datatype
* type
)
1308 const char *DEBUG_GetSymbolName(const struct name_hash
* sym
)
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
);
1325 void DEBUG_InfoSymbols(const char* str
)
1328 struct name_hash
* nh
;
1329 struct name_hash
** array
= NULL
;
1330 unsigned num_used_array
= 0;
1331 unsigned num_alloc_array
= 0;
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
);
1352 array
[num_used_array
++] = nh
;
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
,
1368 if (mode
!= MODE_32
)
1369 DEBUG_Printf("%04lx:%04lx :",
1370 array
[i
]->value
.addr
.seg
& 0xFFFF,
1371 array
[i
]->value
.addr
.off
);
1373 DEBUG_Printf("%08lx :", array
[i
]->value
.addr
.off
);
1374 if (array
[i
]->value
.type
)
1377 DEBUG_PrintTypeCast(array
[i
]->value
.type
);
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 */