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