Release 0.6
[wine/multimedia.git] / debugger / hash.c
bloba6d640f0906762c91cd8b907880f3ae44bad2c05
1 /*
2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
5 */
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>
17 struct name_hash{
18 struct name_hash * next;
19 unsigned int * address;
20 char * name;
23 #define NR_NAME_HASH 128
25 static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
27 static unsigned int name_hash(const char * name){
28 unsigned int hash = 0;
29 const char * p;
31 p = name;
33 while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
34 return hash % NR_NAME_HASH;
39 void add_hash(char * name, unsigned int * address){
40 struct name_hash * new;
41 int hash;
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);
49 /* Now insert into the hash table */
50 new->next = name_hash_table[hash];
51 name_hash_table[hash] = new;
54 unsigned int * find_hash(char * name){
55 char buffer[256];
56 struct name_hash * nh;
58 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
59 if(strcmp(nh->name, name) == 0) return nh->address;
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;
69 return (unsigned int *) 0xffffffff;
73 static char name_buffer[256];
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;
81 nearest = &start;
82 start.address = (unsigned int *) 0;
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;
89 if((unsigned int) nearest->address == 0) return NULL;
91 sprintf(name_buffer, "%s+0x%x", nearest->name, ((unsigned int) address) -
92 ((unsigned int) nearest->address));
93 return name_buffer;
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];
107 symbolfile = fopen(filename, "r");
108 if(!symbolfile) {
109 fprintf(stderr,"Unable to open symbol table %s\n", filename);
110 return;
113 fprintf(stderr,"Reading symbols from file %s\n", filename);
116 while (1)
118 fgets(buffer, sizeof(buffer), symbolfile);
119 if (feof(symbolfile)) break;
121 /* Strip any text after a # sign (i.e. comments) */
122 cpnt = buffer;
123 while(*cpnt){
124 if(*cpnt == '#') {*cpnt = 0; break; };
125 cpnt++;
128 /* Quietly ignore any lines that have just whitespace */
129 cpnt = buffer;
130 while(*cpnt){
131 if(*cpnt != ' ' && *cpnt != '\t') break;
132 cpnt++;
134 if (!(*cpnt) || *cpnt == '\n') {
135 continue;
138 nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
139 add_hash(name, (unsigned int *) addr);
141 fclose(symbolfile);
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
150 void
151 load_entrypoints(){
152 char buffer[256];
153 char * cpnt;
154 int j, ordinal, len;
155 unsigned int address;
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;
176 return;