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>
18 struct name_hash * next;
19 unsigned int * address;
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;
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;
43 new = (struct name_hash *) malloc(sizeof(struct name_hash));
44 new->address = address;
45 new->name = strdup(name);
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){
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;
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;
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)
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));
98 read_symboltable(char * filename){
107 symbolfile = fopen(filename, "r");
109 fprintf(stderr,"Unable to open symbol table %s\n", filename);
113 fprintf(stderr,"Reading symbols from file %s\n", filename);
118 fgets(buffer, sizeof(buffer), symbolfile);
119 if (feof(symbolfile)) break;
121 /* Strip any text after a # sign (i.e. comments) */
124 if(*cpnt == '#') {*cpnt = 0; break; };
128 /* Quietly ignore any lines that have just whitespace */
131 if(*cpnt != ' ' && *cpnt != '\t') break;
134 if (!(*cpnt) || *cpnt == '\n') {
138 nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
139 add_hash(name, (unsigned int *) addr);
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
155 unsigned int address;
157 struct w_files * wpnt;
158 for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
159 cpnt = wpnt->nrname_table;
161 if( ((int) cpnt) - ((int)wpnt->nrname_table) >
162 wpnt->ne_header->nrname_tab_length) break;
164 strncpy(buffer, cpnt, len);
166 ordinal = *((unsigned short *) (cpnt + len));
167 j = GetEntryPointFromOrdinal(wpnt, ordinal);
168 address = j & 0xffff;
170 address |= (wpnt->selector_table[j].selector) << 16;
171 fprintf(stderr,"%s -> %x\n", buffer, address);
172 add_hash(buffer, (unsigned int *) address);