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"
19 struct name_hash * next;
20 unsigned int * address;
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 * address){
41 struct name_hash * new;
44 new = (struct name_hash *) malloc(sizeof(struct name_hash));
45 new->address = address;
46 new->name = strdup(name);
48 hash = name_hash(name);
50 /* Now insert into the hash table */
51 new->next = name_hash_table[hash];
52 name_hash_table[hash] = new;
55 unsigned int * find_hash(char * name){
57 struct name_hash * nh;
59 for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
60 if(strcmp(nh->name, name) == 0) return nh->address;
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;
70 return (unsigned int *) 0xffffffff;
74 static char name_buffer[256];
76 char * find_nearest_symbol(unsigned int * address){
77 struct name_hash * nearest;
78 struct name_hash start;
79 struct name_hash * nh;
83 start.address = (unsigned int *) 0;
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)
90 if((unsigned int) nearest->address == 0) return NULL;
92 sprintf(name_buffer, "%s+0x%x", nearest->name, ((unsigned int) address) -
93 ((unsigned int) nearest->address));
99 read_symboltable(char * filename){
108 symbolfile = fopen(filename, "r");
110 fprintf(stderr,"Unable to open symbol table %s\n", filename);
114 fprintf(stderr,"Reading symbols from file %s\n", filename);
119 fgets(buffer, sizeof(buffer), symbolfile);
120 if (feof(symbolfile)) break;
122 /* Strip any text after a # sign (i.e. comments) */
125 if(*cpnt == '#') {*cpnt = 0; break; };
129 /* Quietly ignore any lines that have just whitespace */
132 if(*cpnt != ' ' && *cpnt != '\t') break;
135 if (!(*cpnt) || *cpnt == '\n') {
139 nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
140 add_hash(name, (unsigned int *) addr);
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
156 unsigned int address;
158 struct w_files * wpnt;
159 for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
160 cpnt = wpnt->ne->nrname_table;
162 if( ((int) cpnt) - ((int)wpnt->ne->nrname_table) >
163 wpnt->ne->ne_header->nrname_tab_length) break;
165 strncpy(buffer, cpnt, len);
167 ordinal = *((unsigned short *) (cpnt + len));
168 j = GetEntryPointFromOrdinal(wpnt, ordinal);
169 address = j & 0xffff;
171 address |= (wpnt->ne->selector_table[j].selector) << 16;
172 fprintf(stderr,"%s -> %x\n", buffer, address);
173 add_hash(buffer, (unsigned int *) address);