2 * File hash.c - generate hash tables for Wine debugger symbols
4 * Copyright (C) 1993, Eric Youngdale.
11 #include <sys/types.h>
14 #include "selectors.h"
18 struct name_hash * next;
24 #define NR_NAME_HASH 128
26 static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
28 static unsigned int name_hash(const char * name){
29 unsigned int hash = 0;
34 while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
35 return hash % NR_NAME_HASH;
40 void add_hash(char * name, unsigned int segment, unsigned int address)
42 struct name_hash * new;
45 new = (struct name_hash *) malloc(sizeof(struct name_hash));
46 new->segment = segment;
47 new->address = address;
48 new->name = strdup(name);
50 hash = name_hash(name);
52 /* Now insert into the hash table */
53 new->next = name_hash_table[hash];
54 name_hash_table[hash] = new;
57 unsigned int find_hash(char * name)
60 struct name_hash * nh;
62 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
63 if(strcmp(nh->name, name) == 0) return nh->address;
67 strcpy(buffer+1, name);
68 for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
69 if(strcmp(nh->name, buffer) == 0) return nh->address;
77 static char name_buffer[256];
79 char * find_nearest_symbol(unsigned int segment, unsigned int address)
81 struct name_hash * nearest;
82 struct name_hash * nh;
83 unsigned int nearest_address;
89 for(i=0; i<NR_NAME_HASH; i++) {
90 for(nh = name_hash_table[i]; nh; nh = nh->next)
91 if (nh->segment == segment &&
92 nh->address <= address &&
93 nh->address >= nearest_address)
95 nearest_address = nh->address;
99 if (!nearest) return NULL;
101 if (address == nearest->address)
102 sprintf( name_buffer, "%s", nearest->name );
104 sprintf( name_buffer, "%s+0x%x", nearest->name,
105 address - nearest->address );
111 read_symboltable(char * filename){
120 symbolfile = fopen(filename, "r");
122 fprintf(stderr,"Unable to open symbol table %s\n", filename);
126 fprintf(stderr,"Reading symbols from file %s\n", filename);
131 fgets(buffer, sizeof(buffer), symbolfile);
132 if (feof(symbolfile)) break;
134 /* Strip any text after a # sign (i.e. comments) */
137 if(*cpnt == '#') {*cpnt = 0; break; };
141 /* Quietly ignore any lines that have just whitespace */
144 if(*cpnt != ' ' && *cpnt != '\t') break;
147 if (!(*cpnt) || *cpnt == '\n') {
151 nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
152 add_hash(name, 0, addr);
159 void load_entrypoints( HMODULE hModule )
162 unsigned char *cpnt, *name;
164 unsigned int address;
166 if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
167 name = (unsigned char *)pModule + pModule->name_table;
169 /* First search the resident names */
171 cpnt = (unsigned char *)pModule + pModule->name_table;
174 cpnt += *cpnt + 1 + sizeof(WORD);
175 sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
176 *cpnt, *cpnt, cpnt + 1 );
177 address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
178 if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
181 /* Now search the non-resident names table */
183 if (!pModule->nrname_handle) return; /* No non-resident table */
184 cpnt = (char *)GlobalLock( pModule->nrname_handle );
187 cpnt += *cpnt + 1 + sizeof(WORD);
188 sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
189 *cpnt, *cpnt, cpnt + 1 );
190 address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
191 if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );