2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
13 #include <sys/types.h>
16 #define NR_NAME_HASH 16384
18 #define PATH_MAX _MAX_PATH
22 static char * reg_name
[] =
24 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
27 static unsigned reg_ofs
[] =
29 FIELD_OFFSET(CONTEXT
, Eax
), FIELD_OFFSET(CONTEXT
, Ecx
),
30 FIELD_OFFSET(CONTEXT
, Edx
), FIELD_OFFSET(CONTEXT
, Ebx
),
31 FIELD_OFFSET(CONTEXT
, Esp
), FIELD_OFFSET(CONTEXT
, Ebp
),
32 FIELD_OFFSET(CONTEXT
, Esi
), FIELD_OFFSET(CONTEXT
, Edi
)
35 static char * reg_name
[] = { NULL
}; /* FIXME */
36 static unsigned reg_ofs
[] = { 0 };
42 struct name_hash
* next
; /* Used to look up within name hash */
48 WineLocals
* local_vars
;
56 unsigned short breakpoint_offset
;
57 unsigned int symbol_size
;
61 static BOOL
DEBUG_GetStackSymbolValue( const char * name
, DBG_VALUE
*value
);
62 static int sortlist_valid
= FALSE
;
64 static int sorttab_nsym
;
65 static struct name_hash
** addr_sorttab
= NULL
;
67 static struct name_hash
* name_hash_table
[NR_NAME_HASH
];
69 static unsigned int name_hash( const char * name
)
71 unsigned int hash
= 0;
79 hash
= (hash
<< 4) + *p
++;
81 if( (tmp
= (hash
& 0xf0000000)) )
87 return hash
% NR_NAME_HASH
;
91 DEBUG_cmp_sym(const void * p1
, const void * p2
)
93 struct name_hash
** name1
= (struct name_hash
**) p1
;
94 struct name_hash
** name2
= (struct name_hash
**) p2
;
96 if( ((*name1
)->flags
& SYM_INVALID
) != 0 )
101 if( ((*name2
)->flags
& SYM_INVALID
) != 0 )
106 if( (*name1
)->value
.addr
.seg
> (*name2
)->value
.addr
.seg
)
111 if( (*name1
)->value
.addr
.seg
< (*name2
)->value
.addr
.seg
)
116 if( (*name1
)->value
.addr
.off
> (*name2
)->value
.addr
.off
)
121 if( (*name1
)->value
.addr
.off
< (*name2
)->value
.addr
.off
)
129 /***********************************************************************
130 * DEBUG_ResortSymbols
132 * Rebuild sorted list of symbols.
136 DEBUG_ResortSymbols(void)
138 struct name_hash
*nh
;
142 for(i
=0; i
<NR_NAME_HASH
; i
++)
144 for (nh
= name_hash_table
[i
]; nh
; nh
= nh
->next
)
146 if( (nh
->flags
& SYM_INVALID
) == 0 )
149 fprintf( stderr
, "Symbol %s is invalid\n", nh
->name
);
159 addr_sorttab
= (struct name_hash
**) DBG_realloc(addr_sorttab
,
160 nsym
* sizeof(struct name_hash
*));
163 for(i
=0; i
<NR_NAME_HASH
; i
++)
165 for (nh
= name_hash_table
[i
]; nh
; nh
= nh
->next
)
167 if( (nh
->flags
& SYM_INVALID
) == 0 )
168 addr_sorttab
[nsym
++] = nh
;
172 qsort(addr_sorttab
, nsym
,
173 sizeof(struct name_hash
*), DEBUG_cmp_sym
);
174 sortlist_valid
= TRUE
;
178 /***********************************************************************
181 * Add a symbol to the table.
184 DEBUG_AddSymbol( const char * name
, const DBG_VALUE
*value
, const char * source
,
187 struct name_hash
* new;
188 struct name_hash
*nh
;
189 static char prev_source
[PATH_MAX
] = {'\0', };
190 static char * prev_duped_source
= NULL
;
194 assert(value
->cookie
== DV_TARGET
|| value
->cookie
== DV_HOST
);
196 hash
= name_hash(name
);
197 for (nh
= name_hash_table
[hash
]; nh
; nh
= nh
->next
)
199 if( ((nh
->flags
& SYM_INVALID
) != 0) && strcmp(name
, nh
->name
) == 0 )
201 nh
->value
.addr
= value
->addr
;
203 if( nh
->value
.type
== NULL
&& value
->type
!= NULL
)
205 nh
->value
.type
= value
->type
;
206 nh
->value
.cookie
= value
->cookie
;
208 /* it may happen that the same symbol is defined in several compilation
209 * units, but the linker decides to merge it into a single instance.
210 * in that case, we don't clear the invalid flag for all the compilation
211 * units (N_GSYM), and wait to get the symbol from the symtab
213 if ((flags
& SYM_INVALID
) == 0)
214 nh
->flags
&= ~SYM_INVALID
;
218 if (nh
->value
.addr
.seg
== value
->addr
.seg
&&
219 nh
->value
.addr
.off
== value
->addr
.off
&&
220 strcmp(name
, nh
->name
) == 0 )
227 * First see if we already have an entry for this symbol. If so
228 * return it, so we don't end up with duplicates.
231 new = (struct name_hash
*) DBG_alloc(sizeof(struct name_hash
));
233 new->name
= DBG_strdup(name
);
238 * This is an enhancement to reduce memory consumption. The idea
239 * is that we duplicate a given string only once. This is a big
240 * win if there are lots of symbols defined in a given source file.
242 if( strcmp(source
, prev_source
) == 0 )
244 new->sourcefile
= prev_duped_source
;
248 strcpy(prev_source
, source
);
249 prev_duped_source
= new->sourcefile
= DBG_strdup(source
);
254 new->sourcefile
= NULL
;
258 new->lines_alloc
= 0;
262 new->locals_alloc
= 0;
263 new->local_vars
= NULL
;
268 /* Now insert into the hash table */
269 new->next
= name_hash_table
[hash
];
270 name_hash_table
[hash
] = new;
273 * Check some heuristics based upon the file name to see whether
274 * we want to step through this guy or not. These are machine generated
275 * assembly files that are used to translate between the MS way of
276 * calling things and the GCC way of calling things. In general we
277 * always want to step through.
281 c
= strrchr(source
, '.');
282 if( c
!= NULL
&& strcmp(c
, ".s") == 0 )
284 c
= strrchr(source
, '/');
288 if( (strcmp(c
, "callfrom16.s") == 0)
289 || (strcmp(c
, "callto16.s") == 0)
290 || (strcmp(c
, "call32.s") == 0) )
292 new->flags
|= SYM_TRAMPOLINE
;
298 sortlist_valid
= FALSE
;
302 BOOL
DEBUG_Normalize(struct name_hash
* nh
)
306 * We aren't adding any more locals or linenumbers to this function.
307 * Free any spare memory that we might have allocated.
314 if( nh
->n_locals
!= nh
->locals_alloc
)
316 nh
->locals_alloc
= nh
->n_locals
;
317 nh
->local_vars
= DBG_realloc(nh
->local_vars
,
318 nh
->locals_alloc
* sizeof(WineLocals
));
321 if( nh
->n_lines
!= nh
->lines_alloc
)
323 nh
->lines_alloc
= nh
->n_lines
;
324 nh
->linetab
= DBG_realloc(nh
->linetab
,
325 nh
->lines_alloc
* sizeof(WineLineNo
));
331 /***********************************************************************
332 * DEBUG_GetSymbolValue
334 * Get the address of a named symbol.
336 BOOL
DEBUG_GetSymbolValue( const char * name
, const int lineno
,
337 DBG_VALUE
*value
, int bp_flag
)
340 struct name_hash
*nh
;
342 for(nh
= name_hash_table
[name_hash(name
)]; nh
; nh
= nh
->next
)
344 if( (nh
->flags
& SYM_INVALID
) != 0 )
349 if (!strcmp(nh
->name
, name
)) break;
352 if (!nh
&& (name
[0] != '_'))
355 strcpy(buffer
+1, name
);
356 for(nh
= name_hash_table
[name_hash(buffer
)]; nh
; nh
= nh
->next
)
358 if( (nh
->flags
& SYM_INVALID
) != 0 )
362 if (!strcmp(nh
->name
, buffer
)) break;
367 * If we don't have anything here, then try and see if this
368 * is a local symbol to the current stack frame. No matter
369 * what, we have nothing more to do, so we let that function
370 * decide what we ultimately return.
374 return DEBUG_GetStackSymbolValue(name
, value
);
377 value
->type
= nh
->value
.type
;
378 value
->cookie
= nh
->value
.cookie
;
379 return DEBUG_GetLineNumberAddr( nh
, lineno
, &value
->addr
, bp_flag
);
382 /***********************************************************************
383 * DEBUG_GetLineNumberAddr
385 * Get the address of a named symbol.
387 BOOL
DEBUG_GetLineNumberAddr( struct name_hash
* nh
, const int lineno
,
388 DBG_ADDR
*addr
, int bp_flag
)
394 *addr
= nh
->value
.addr
;
397 addr
->off
+= nh
->breakpoint_offset
;
403 * Search for the specific line number. If we don't find it,
406 if( nh
->linetab
== NULL
)
411 for(i
=0; i
< nh
->n_lines
; i
++ )
413 if( nh
->linetab
[i
].line_number
== lineno
)
415 *addr
= nh
->linetab
[i
].pc_offset
;
421 * This specific line number not found.
430 /***********************************************************************
431 * DEBUG_SetSymbolValue
433 * Set the address of a named symbol.
435 BOOL
DEBUG_SetSymbolValue( const char * name
, const DBG_VALUE
*value
)
438 struct name_hash
*nh
;
440 assert(value
->cookie
== DV_TARGET
|| value
->cookie
== DV_HOST
);
442 for(nh
= name_hash_table
[name_hash(name
)]; nh
; nh
= nh
->next
)
443 if (!strcmp(nh
->name
, name
)) break;
445 if (!nh
&& (name
[0] != '_'))
448 strcpy(buffer
+1, name
);
449 for(nh
= name_hash_table
[name_hash(buffer
)]; nh
; nh
= nh
->next
)
450 if (!strcmp(nh
->name
, buffer
)) break;
453 if (!nh
) return FALSE
;
455 nh
->flags
&= ~SYM_INVALID
;
456 DEBUG_FixAddress( &nh
->value
.addr
, DEBUG_context
.SegDs
);
461 /***********************************************************************
462 * DEBUG_FindNearestSymbol
464 * Find the symbol nearest to a given address.
465 * If ebp is specified as non-zero, it means we should dump the argument
466 * list into the string we return as well.
468 const char * DEBUG_FindNearestSymbol( const DBG_ADDR
*addr
, int flag
,
469 struct name_hash
** rtn
,
471 struct list_id
* source
)
473 static char name_buffer
[MAX_PATH
+ 256];
474 static char arglist
[1024];
475 static char argtmp
[256];
476 struct name_hash
* nearest
= NULL
;
480 char * lineinfo
, *sourcefile
;
492 source
->sourcefile
= NULL
;
496 if( sortlist_valid
== FALSE
)
498 DEBUG_ResortSymbols();
501 if( sortlist_valid
== FALSE
)
507 * FIXME - use the binary search that we added to
508 * the function DEBUG_CheckLinenoStatus. Better yet, we should
509 * probably keep some notion of the current function so we don't
510 * have to search every time.
513 * Binary search to find closest symbol.
517 if( addr_sorttab
[0]->value
.addr
.seg
> addr
->seg
518 || ( addr_sorttab
[0]->value
.addr
.seg
== addr
->seg
519 && addr_sorttab
[0]->value
.addr
.off
> addr
->off
) )
523 else if( addr_sorttab
[high
- 1]->value
.addr
.seg
< addr
->seg
524 || ( addr_sorttab
[high
- 1]->value
.addr
.seg
== addr
->seg
525 && addr_sorttab
[high
- 1]->value
.addr
.off
< addr
->off
) )
527 nearest
= addr_sorttab
[high
- 1];
533 mid
= (high
+ low
)/2;
537 * See if there are any other entries that might also
538 * have the same address, and would also have a line
541 if( mid
> 0 && addr_sorttab
[mid
]->linetab
== NULL
)
543 if( (addr_sorttab
[mid
- 1]->value
.addr
.seg
==
544 addr_sorttab
[mid
]->value
.addr
.seg
)
545 && (addr_sorttab
[mid
- 1]->value
.addr
.off
==
546 addr_sorttab
[mid
]->value
.addr
.off
)
547 && (addr_sorttab
[mid
- 1]->linetab
!= NULL
) )
553 if( (mid
< sorttab_nsym
- 1)
554 && (addr_sorttab
[mid
]->linetab
== NULL
) )
556 if( (addr_sorttab
[mid
+ 1]->value
.addr
.seg
==
557 addr_sorttab
[mid
]->value
.addr
.seg
)
558 && (addr_sorttab
[mid
+ 1]->value
.addr
.off
==
559 addr_sorttab
[mid
]->value
.addr
.off
)
560 && (addr_sorttab
[mid
+ 1]->linetab
!= NULL
) )
565 nearest
= addr_sorttab
[mid
];
567 fprintf(stderr
, "Found %x:%x when looking for %x:%x %x %s\n",
568 addr_sorttab
[mid
]->value
.addr
.seg
,
569 addr_sorttab
[mid
]->value
.addr
.off
,
570 addr
->seg
, addr
->off
,
571 addr_sorttab
[mid
]->linetab
,
572 addr_sorttab
[mid
]->name
);
576 if( (addr_sorttab
[mid
]->value
.addr
.seg
< addr
->seg
)
577 || ( addr_sorttab
[mid
]->value
.addr
.seg
== addr
->seg
578 && addr_sorttab
[mid
]->value
.addr
.off
<= addr
->off
) )
589 if (!nearest
) return NULL
;
597 * Fill in the relevant bits to the structure so that we can
598 * locate the source and line for this bit of code.
602 source
->sourcefile
= nearest
->sourcefile
;
603 if( nearest
->linetab
== NULL
)
609 source
->line
= nearest
->linetab
[0].line_number
;
617 * Prepare to display the argument list. If ebp is specified, it is
618 * the framepointer for the function in question. If not specified,
619 * we don't want the arglist.
621 memset(arglist
, '\0', sizeof(arglist
));
624 for(i
=0; i
< nearest
->n_locals
; i
++ )
627 * If this is a register (offset == 0) or a local
628 * variable, we don't want to know about it.
630 if( nearest
->local_vars
[i
].offset
<= 0 )
635 ptr
= (unsigned int *) (ebp
+ nearest
->local_vars
[i
].offset
);
636 if( arglist
[0] == '\0' )
642 strcat(arglist
, ", ");
644 DEBUG_READ_MEM_VERBOSE(ptr
, &val
, sizeof(val
));
645 sprintf(argtmp
, "%s=0x%x", nearest
->local_vars
[i
].name
, val
);
647 strcat(arglist
, argtmp
);
649 if( arglist
[0] == '(' )
651 strcat(arglist
, ")");
655 if( (nearest
->sourcefile
!= NULL
) && (flag
== TRUE
)
656 && (addr
->off
- nearest
->value
.addr
.off
< 0x100000) )
660 * Try and find the nearest line number to the current offset.
662 if( nearest
->linetab
!= NULL
)
665 high
= nearest
->n_lines
;
666 while ((high
- low
) > 1)
668 mid
= (high
+ low
) / 2;
669 if (addr
->off
< nearest
->linetab
[mid
].pc_offset
.off
)
674 lineno
= nearest
->linetab
[low
].line_number
;
679 sprintf(linebuff
, ":%d", lineno
);
683 source
->line
= lineno
;
687 /* Remove the path from the file name */
688 sourcefile
= strrchr( nearest
->sourcefile
, '/' );
689 if (!sourcefile
) sourcefile
= nearest
->sourcefile
;
692 if (addr
->off
== nearest
->value
.addr
.off
)
693 sprintf( name_buffer
, "%s%s [%s%s]", nearest
->name
,
694 arglist
, sourcefile
, lineinfo
);
696 sprintf( name_buffer
, "%s+0x%lx%s [%s%s]", nearest
->name
,
697 addr
->off
- nearest
->value
.addr
.off
,
698 arglist
, sourcefile
, lineinfo
);
702 if (addr
->off
== nearest
->value
.addr
.off
)
703 sprintf( name_buffer
, "%s%s", nearest
->name
, arglist
);
705 if (addr
->seg
&& (nearest
->value
.addr
.seg
!=addr
->seg
))
708 sprintf( name_buffer
, "%s+0x%lx%s", nearest
->name
,
709 addr
->off
- nearest
->value
.addr
.off
, arglist
);
716 /***********************************************************************
717 * DEBUG_ReadSymbolTable
719 * Read a symbol file into the hash table.
721 void DEBUG_ReadSymbolTable( const char * filename
)
731 if (!(symbolfile
= fopen(filename
, "r")))
733 fprintf( stderr
, "Unable to open symbol table %s\n", filename
);
737 fprintf( stderr
, "Reading symbols from file %s\n", filename
);
742 value
.cookie
= DV_TARGET
;
746 fgets( buffer
, sizeof(buffer
), symbolfile
);
747 if (feof(symbolfile
)) break;
749 /* Strip any text after a # sign (i.e. comments) */
752 if(*cpnt
++ == '#') { *cpnt
= 0; break; }
754 /* Quietly ignore any lines that have just whitespace */
758 if(*cpnt
!= ' ' && *cpnt
!= '\t') break;
761 if (!(*cpnt
) || *cpnt
== '\n') continue;
763 nargs
= sscanf(buffer
, "%lx %c %s", &value
.addr
.off
, &type
, name
);
764 DEBUG_AddSymbol( name
, &value
, NULL
, SYM_WINE
);
771 DEBUG_AddLineNumber( struct name_hash
* func
, int line_num
,
772 unsigned long offset
)
779 if( func
->n_lines
+ 1 >= func
->lines_alloc
)
781 func
->lines_alloc
+= 64;
782 func
->linetab
= DBG_realloc(func
->linetab
,
783 func
->lines_alloc
* sizeof(WineLineNo
));
786 func
->linetab
[func
->n_lines
].line_number
= line_num
;
787 func
->linetab
[func
->n_lines
].pc_offset
.seg
= func
->value
.addr
.seg
;
788 func
->linetab
[func
->n_lines
].pc_offset
.off
= func
->value
.addr
.off
+ offset
;
794 DEBUG_AddLocal( struct name_hash
* func
, int regno
,
805 if( func
->n_locals
+ 1 >= func
->locals_alloc
)
807 func
->locals_alloc
+= 32;
808 func
->local_vars
= DBG_realloc(func
->local_vars
,
809 func
->locals_alloc
* sizeof(WineLocals
));
812 func
->local_vars
[func
->n_locals
].regno
= regno
;
813 func
->local_vars
[func
->n_locals
].offset
= offset
;
814 func
->local_vars
[func
->n_locals
].pc_start
= pc_start
;
815 func
->local_vars
[func
->n_locals
].pc_end
= pc_end
;
816 func
->local_vars
[func
->n_locals
].name
= DBG_strdup(name
);
817 func
->local_vars
[func
->n_locals
].type
= NULL
;
820 return &func
->local_vars
[func
->n_locals
- 1];
824 DEBUG_DumpHashInfo(void)
828 struct name_hash
*nh
;
831 * Utility function to dump stats about the hash table.
833 for(i
=0; i
<NR_NAME_HASH
; i
++)
836 for (nh
= name_hash_table
[i
]; nh
; nh
= nh
->next
)
840 fprintf(stderr
, "Bucket %d: %d\n", i
, depth
);
844 /***********************************************************************
845 * DEBUG_CheckLinenoStatus
847 * Find the symbol nearest to a given address.
848 * If ebp is specified as non-zero, it means we should dump the argument
849 * list into the string we return as well.
851 int DEBUG_CheckLinenoStatus( const DBG_ADDR
*addr
)
853 struct name_hash
* nearest
= NULL
;
856 if( sortlist_valid
== FALSE
)
858 DEBUG_ResortSymbols();
862 * Binary search to find closest symbol.
866 if( addr_sorttab
[0]->value
.addr
.seg
> addr
->seg
867 || ( addr_sorttab
[0]->value
.addr
.seg
== addr
->seg
868 && addr_sorttab
[0]->value
.addr
.off
> addr
->off
) )
872 else if( addr_sorttab
[high
- 1]->value
.addr
.seg
< addr
->seg
873 || ( addr_sorttab
[high
- 1]->value
.addr
.seg
== addr
->seg
874 && addr_sorttab
[high
- 1]->value
.addr
.off
< addr
->off
) )
876 nearest
= addr_sorttab
[high
- 1];
882 mid
= (high
+ low
)/2;
886 * See if there are any other entries that might also
887 * have the same address, and would also have a line
890 if( mid
> 0 && addr_sorttab
[mid
]->linetab
== NULL
)
892 if( (addr_sorttab
[mid
- 1]->value
.addr
.seg
==
893 addr_sorttab
[mid
]->value
.addr
.seg
)
894 && (addr_sorttab
[mid
- 1]->value
.addr
.off
==
895 addr_sorttab
[mid
]->value
.addr
.off
)
896 && (addr_sorttab
[mid
- 1]->linetab
!= NULL
) )
902 if( (mid
< sorttab_nsym
- 1)
903 && (addr_sorttab
[mid
]->linetab
== NULL
) )
905 if( (addr_sorttab
[mid
+ 1]->value
.addr
.seg
==
906 addr_sorttab
[mid
]->value
.addr
.seg
)
907 && (addr_sorttab
[mid
+ 1]->value
.addr
.off
==
908 addr_sorttab
[mid
]->value
.addr
.off
)
909 && (addr_sorttab
[mid
+ 1]->linetab
!= NULL
) )
914 nearest
= addr_sorttab
[mid
];
916 fprintf(stderr
, "Found %x:%x when looking for %x:%x %x %s\n",
917 addr_sorttab
[mid
]->value
.addr
.seg
,
918 addr_sorttab
[mid
]->value
.addr
.off
,
919 addr
->seg
, addr
->off
,
920 addr_sorttab
[mid
]->linetab
,
921 addr_sorttab
[mid
]->name
);
925 if( (addr_sorttab
[mid
]->value
.addr
.seg
< addr
->seg
)
926 || ( addr_sorttab
[mid
]->value
.addr
.seg
== addr
->seg
927 && addr_sorttab
[mid
]->value
.addr
.off
<= addr
->off
) )
938 if (!nearest
) return FUNC_HAS_NO_LINES
;
940 if( nearest
->flags
& SYM_STEP_THROUGH
)
943 * This will cause us to keep single stepping until
944 * we get to the other side somewhere.
946 return NOT_ON_LINENUMBER
;
949 if( (nearest
->flags
& SYM_TRAMPOLINE
) )
952 * This will cause us to keep single stepping until
953 * we get to the other side somewhere.
955 return FUNC_IS_TRAMPOLINE
;
958 if( nearest
->linetab
== NULL
)
960 return FUNC_HAS_NO_LINES
;
965 * We never want to stop on the first instruction of a function
966 * even if it has it's own linenumber. Let the thing keep running
967 * until it gets past the function prologue. We only do this if there
968 * is more than one line number for the function, of course.
970 if( nearest
->value
.addr
.off
== addr
->off
&& nearest
->n_lines
> 1 )
972 return NOT_ON_LINENUMBER
;
975 if( (nearest
->sourcefile
!= NULL
)
976 && (addr
->off
- nearest
->value
.addr
.off
< 0x100000) )
979 high
= nearest
->n_lines
;
980 while ((high
- low
) > 1)
982 mid
= (high
+ low
) / 2;
983 if (addr
->off
< nearest
->linetab
[mid
].pc_offset
.off
) high
= mid
;
986 if (addr
->off
== nearest
->linetab
[low
].pc_offset
.off
)
987 return AT_LINENUMBER
;
989 return NOT_ON_LINENUMBER
;
992 return FUNC_HAS_NO_LINES
;
995 /***********************************************************************
998 * Find the symbol nearest to a given address.
999 * Returns sourcefile name and line number in a format that the listing
1000 * handler can deal with.
1003 DEBUG_GetFuncInfo( struct list_id
* ret
, const char * filename
,
1008 struct name_hash
*nh
;
1010 for(nh
= name_hash_table
[name_hash(name
)]; nh
; nh
= nh
->next
)
1012 if( filename
!= NULL
)
1015 if( nh
->sourcefile
== NULL
)
1020 pnt
= strrchr(nh
->sourcefile
, '/');
1021 if( strcmp(nh
->sourcefile
, filename
) != 0
1022 && (pnt
== NULL
|| strcmp(pnt
+ 1, filename
) != 0) )
1027 if (!strcmp(nh
->name
, name
)) break;
1030 if (!nh
&& (name
[0] != '_'))
1033 strcpy(buffer
+1, name
);
1034 for(nh
= name_hash_table
[name_hash(buffer
)]; nh
; nh
= nh
->next
)
1036 if( filename
!= NULL
)
1038 if( nh
->sourcefile
== NULL
)
1043 pnt
= strrchr(nh
->sourcefile
, '/');
1044 if( strcmp(nh
->sourcefile
, filename
) != 0
1045 && (pnt
== NULL
|| strcmp(pnt
+ 1, filename
) != 0) )
1050 if (!strcmp(nh
->name
, buffer
)) break;
1056 if( filename
!= NULL
)
1058 fprintf(stderr
, "No such function %s in %s\n", name
, filename
);
1062 fprintf(stderr
, "No such function %s\n", name
);
1064 ret
->sourcefile
= NULL
;
1069 ret
->sourcefile
= nh
->sourcefile
;
1072 * Search for the specific line number. If we don't find it,
1073 * then return FALSE.
1075 if( nh
->linetab
== NULL
)
1081 ret
->line
= nh
->linetab
[0].line_number
;
1085 /***********************************************************************
1086 * DEBUG_GetStackSymbolValue
1088 * Get the address of a named symbol from the current stack frame.
1091 BOOL
DEBUG_GetStackSymbolValue( const char * name
, DBG_VALUE
*value
)
1093 struct name_hash
* curr_func
;
1098 if( DEBUG_GetCurrentFrame(&curr_func
, &eip
, &ebp
) == FALSE
)
1103 for(i
=0; i
< curr_func
->n_locals
; i
++ )
1106 * Test the range of validity of the local variable. This
1107 * comes up with RBRAC/LBRAC stabs in particular.
1109 if( (curr_func
->local_vars
[i
].pc_start
!= 0)
1110 && ((eip
- curr_func
->value
.addr
.off
)
1111 < curr_func
->local_vars
[i
].pc_start
) )
1116 if( (curr_func
->local_vars
[i
].pc_end
!= 0)
1117 && ((eip
- curr_func
->value
.addr
.off
)
1118 > curr_func
->local_vars
[i
].pc_end
) )
1123 if( strcmp(name
, curr_func
->local_vars
[i
].name
) == 0 )
1126 * OK, we found it. Now figure out what to do with this.
1128 if( curr_func
->local_vars
[i
].regno
!= 0 )
1131 * Register variable. Point to DEBUG_context field.
1133 value
->addr
.off
= ((DWORD
)&DEBUG_context
) +
1134 reg_ofs
[curr_func
->local_vars
[i
].regno
- 1];
1135 value
->cookie
= DV_HOST
;
1139 value
->addr
.off
= ebp
+ curr_func
->local_vars
[i
].offset
;
1140 value
->cookie
= DV_TARGET
;
1142 value
->addr
.seg
= 0;
1143 value
->type
= curr_func
->local_vars
[i
].type
;
1153 DEBUG_InfoLocals(void)
1155 struct name_hash
* curr_func
;
1162 if( DEBUG_GetCurrentFrame(&curr_func
, &eip
, &ebp
) == FALSE
)
1167 for(i
=0; i
< curr_func
->n_locals
; i
++ )
1170 * Test the range of validity of the local variable. This
1171 * comes up with RBRAC/LBRAC stabs in particular.
1173 if( (curr_func
->local_vars
[i
].pc_start
!= 0)
1174 && ((eip
- curr_func
->value
.addr
.off
)
1175 < curr_func
->local_vars
[i
].pc_start
) )
1180 if( (curr_func
->local_vars
[i
].pc_end
!= 0)
1181 && ((eip
- curr_func
->value
.addr
.off
)
1182 > curr_func
->local_vars
[i
].pc_end
) )
1187 if( curr_func
->local_vars
[i
].regno
!= 0 )
1189 ptr
= (unsigned int *)(((DWORD
)&DEBUG_context
)
1190 + reg_ofs
[curr_func
->local_vars
[i
].regno
- 1]);
1191 fprintf(stderr
, "%s:%s (optimized into register $%s) == 0x%8.8x\n",
1192 curr_func
->name
, curr_func
->local_vars
[i
].name
,
1193 reg_name
[curr_func
->local_vars
[i
].regno
- 1],
1198 DEBUG_READ_MEM_VERBOSE((void*)(ebp
+ curr_func
->local_vars
[i
].offset
),
1200 fprintf(stderr
, "%s:%s == 0x%8.8x\n",
1201 curr_func
->name
, curr_func
->local_vars
[i
].name
, val
);
1209 DEBUG_SetSymbolSize(struct name_hash
* sym
, unsigned int len
)
1211 sym
->symbol_size
= len
;
1217 DEBUG_SetSymbolBPOff(struct name_hash
* sym
, unsigned int off
)
1219 sym
->breakpoint_offset
= off
;
1225 DEBUG_GetSymbolAddr(struct name_hash
* sym
, DBG_ADDR
* addr
)
1228 *addr
= sym
->value
.addr
;
1233 int DEBUG_SetLocalSymbolType(struct wine_locals
* sym
, struct datatype
* type
)