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