2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
11 #include <sys/types.h>
14 #include <prototypes.h>
15 #include "selectors.h"
20 struct name_hash
* next
;
21 unsigned int * address
;
25 #define NR_NAME_HASH 128
27 static struct name_hash
* name_hash_table
[NR_NAME_HASH
] = {0,};
29 static unsigned int name_hash(const char * name
){
30 unsigned int hash
= 0;
35 while (*p
) hash
= (hash
<< 15) + (hash
<< 3) + (hash
>> 3) + *p
++;
36 return hash
% NR_NAME_HASH
;
41 void add_hash(char * name
, unsigned int * address
){
42 struct name_hash
* new;
45 new = (struct name_hash
*) malloc(sizeof(struct name_hash
));
46 new->address
= address
;
47 new->name
= strdup(name
);
49 hash
= name_hash(name
);
51 /* Now insert into the hash table */
52 new->next
= name_hash_table
[hash
];
53 name_hash_table
[hash
] = new;
56 unsigned int * find_hash(char * name
){
58 struct name_hash
* nh
;
60 for(nh
= name_hash_table
[name_hash(name
)]; nh
; nh
= nh
->next
)
61 if(strcmp(nh
->name
, name
) == 0) return nh
->address
;
65 strcpy(buffer
+1, name
);
66 for(nh
= name_hash_table
[name_hash(buffer
)]; nh
; nh
= nh
->next
)
67 if(strcmp(nh
->name
, buffer
) == 0) return nh
->address
;
71 return (unsigned int *) 0xffffffff;
75 static char name_buffer
[256];
77 char * find_nearest_symbol(unsigned int * address
){
78 struct name_hash
* nearest
;
79 struct name_hash start
;
80 struct name_hash
* nh
;
84 start
.address
= (unsigned int *) 0;
86 for(i
=0; i
<NR_NAME_HASH
; i
++) {
87 for(nh
= name_hash_table
[i
]; nh
; nh
= nh
->next
)
88 if(nh
->address
<= address
&& nh
->address
> nearest
->address
)
91 if((unsigned int) nearest
->address
== 0) return NULL
;
93 sprintf(name_buffer
, "%s+0x%x", nearest
->name
, ((unsigned int) address
) -
94 ((unsigned int) nearest
->address
));
100 read_symboltable(char * filename
){
109 symbolfile
= fopen(filename
, "r");
111 fprintf(stderr
,"Unable to open symbol table %s\n", filename
);
115 fprintf(stderr
,"Reading symbols from file %s\n", filename
);
120 fgets(buffer
, sizeof(buffer
), symbolfile
);
121 if (feof(symbolfile
)) break;
123 /* Strip any text after a # sign (i.e. comments) */
126 if(*cpnt
== '#') {*cpnt
= 0; break; };
130 /* Quietly ignore any lines that have just whitespace */
133 if(*cpnt
!= ' ' && *cpnt
!= '\t') break;
136 if (!(*cpnt
) || *cpnt
== '\n') {
140 nargs
= sscanf(buffer
, "%x %c %s", &addr
, &type
, name
);
141 add_hash(name
, (unsigned int *) addr
);
147 /* Load the entry points from the dynamic linking into the hash tables.
148 * This does not work yet - something needs to be added before it scans the
157 unsigned int address
;
159 struct w_files
* wpnt
;
160 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
){
161 cpnt
= wpnt
->ne
->nrname_table
;
163 if( ((int) cpnt
) - ((int)wpnt
->ne
->nrname_table
) >
164 wpnt
->ne
->ne_header
->nrname_tab_length
) break;
166 strncpy(buffer
, cpnt
, len
);
168 ordinal
= *((unsigned short *) (cpnt
+ len
));
169 j
= GetEntryPointFromOrdinal(wpnt
, ordinal
);
170 address
= j
& 0xffff;
172 address
|= (wpnt
->ne
->selector_table
[j
].selector
) << 16;
173 fprintf(stderr
,"%s -> %x\n", buffer
, address
);
174 add_hash(buffer
, (unsigned int *) address
);