Release 940510
[wine] / debugger / hash.c
1 /*
2  * File hash.c - generate hash tables for Wine debugger symbols
3  *
4  * Copyright (C) 1993, Eric Youngdale.
5  */
6
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <neexe.h>
13 #include <segmem.h>
14 #include <prototypes.h>
15 #include <wine.h>
16
17 struct  name_hash{
18         struct name_hash * next;
19         unsigned int * address;
20         char * name;
21 };
22
23 #define NR_NAME_HASH 128
24
25 static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
26
27 static  unsigned int name_hash(const char * name){
28         unsigned int hash = 0;
29         const char * p;
30
31         p = name;
32
33         while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
34         return hash % NR_NAME_HASH;
35
36 }
37
38
39 void add_hash(char * name, unsigned int * address){
40         struct name_hash  * new;
41         int hash;
42
43         new = (struct  name_hash *) malloc(sizeof(struct name_hash));
44         new->address = address;
45         new->name = strdup(name);
46         new->next = NULL;
47         hash = name_hash(name);
48
49         /* Now insert into the hash table */
50         new->next = name_hash_table[hash];
51         name_hash_table[hash] = new;
52 }
53
54 unsigned int * find_hash(char * name){
55         char buffer[256];
56         struct name_hash  * nh;
57
58         for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
59                 if(strcmp(nh->name, name) == 0) return nh->address;
60
61         if(name[0] != '_'){
62                 buffer[0] = '_';
63                 strcpy(buffer+1, name);
64                 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
65                         if(strcmp(nh->name, buffer) == 0) return nh->address;
66         };
67
68
69         return (unsigned int *) 0xffffffff;
70 }
71
72
73 static char name_buffer[256];
74
75 char * find_nearest_symbol(unsigned int * address){
76         struct name_hash * nearest;
77         struct name_hash start;
78         struct name_hash  * nh;
79         int i;
80         
81         nearest = &start;
82         start.address = (unsigned int *) 0;
83         
84         for(i=0; i<NR_NAME_HASH; i++) {
85                 for(nh = name_hash_table[i]; nh; nh = nh->next)
86                         if(nh->address <= address && nh->address > nearest->address)
87                                 nearest = nh;
88         };
89         if((unsigned int) nearest->address == 0) return NULL;
90
91         sprintf(name_buffer, "%s+0x%x", nearest->name, ((unsigned int) address) - 
92                 ((unsigned int) nearest->address));
93         return name_buffer;
94 }
95
96
97 void
98 read_symboltable(char * filename){
99         FILE * symbolfile;
100         unsigned int addr;
101         int nargs;
102         char type;
103         char * cpnt;
104         char buffer[256];
105         char name[256];
106
107         symbolfile = fopen(filename, "r");
108         if(!symbolfile) {
109                 fprintf(stderr,"Unable to open symbol table %s\n", filename);
110                 return;
111         };
112
113         fprintf(stderr,"Reading symbols from file %s\n", filename);
114
115
116         while (1)
117         {
118                 fgets(buffer, sizeof(buffer),  symbolfile);
119                 if (feof(symbolfile)) break;
120                 
121                 /* Strip any text after a # sign (i.e. comments) */
122                 cpnt = buffer;
123                 while(*cpnt){
124                         if(*cpnt == '#') {*cpnt = 0; break; };
125                         cpnt++;
126                 };
127                 
128                 /* Quietly ignore any lines that have just whitespace */
129                 cpnt = buffer;
130                 while(*cpnt){
131                         if(*cpnt != ' ' && *cpnt != '\t') break;
132                         cpnt++;
133                 };
134                 if (!(*cpnt) || *cpnt == '\n') {
135                         continue;
136                 };
137                 
138                 nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
139                 add_hash(name, (unsigned int *) addr);
140       };
141       fclose(symbolfile);
142 }
143
144
145 /* Load the entry points from the dynamic linking into the hash tables. 
146  * This does not work yet - something needs to be added before it scans the
147  * tables correctly 
148  */
149
150 void
151 load_entrypoints(){
152         char buffer[256];
153         char * cpnt;
154         int j, ordinal, len;
155         unsigned int address;
156
157         struct w_files * wpnt;
158         for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
159                 cpnt  = wpnt->nrname_table;
160                 while(1==1){
161                         if( ((int) cpnt)  - ((int)wpnt->nrname_table) >  
162                            wpnt->ne_header->nrname_tab_length)  break;
163                         len = *cpnt++;
164                         strncpy(buffer, cpnt, len);
165                         buffer[len] = 0;
166                         ordinal =  *((unsigned short *)  (cpnt +  len));
167                         j = GetEntryPointFromOrdinal(wpnt, ordinal);            
168                         address  = j & 0xffff;
169                         j = j >> 16;
170                         address |= (wpnt->selector_table[j].selector) << 16;
171                         fprintf(stderr,"%s -> %x\n", buffer, address);
172                         add_hash(buffer, (unsigned int *) address);
173                         cpnt += len + 2;
174                 };
175         };
176         return;
177 }