/*
 * File hash.c - generate hash tables for Wine debugger symbols
 *
 * Copyright (C) 1993, Eric Youngdale.
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <neexe.h>
#include "module.h"
#include "selectors.h"
#include "wine.h"

struct  name_hash{
	struct name_hash * next;
        unsigned int segment;
	unsigned int address;
	char * name;
};

#define NR_NAME_HASH 128

static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};

static  unsigned int name_hash(const char * name){
	unsigned int hash = 0;
	const char * p;

	p = name;

	while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
	return hash % NR_NAME_HASH;

}


void add_hash(char * name, unsigned int segment, unsigned int address)
{
	struct name_hash  * new;
	int hash;

	new = (struct  name_hash *) malloc(sizeof(struct name_hash));
        new->segment = segment;
	new->address = address;
	new->name = strdup(name);
	new->next = NULL;
	hash = name_hash(name);

	/* Now insert into the hash table */
	new->next = name_hash_table[hash];
	name_hash_table[hash] = new;
}

unsigned int find_hash(char * name)
{
	char buffer[256];
	struct name_hash  * nh;

	for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
		if(strcmp(nh->name, name) == 0) return nh->address;

	if(name[0] != '_'){
		buffer[0] = '_';
		strcpy(buffer+1, name);
		for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
			if(strcmp(nh->name, buffer) == 0) return nh->address;
	};


	return 0xffffffff;
}


static char name_buffer[256];

char * find_nearest_symbol(unsigned int segment, unsigned int address)
{
	struct name_hash * nearest;
	struct name_hash  * nh;
        unsigned int nearest_address;
	int i;
	
	nearest = NULL;
        nearest_address = 0;
	
	for(i=0; i<NR_NAME_HASH; i++) {
		for(nh = name_hash_table[i]; nh; nh = nh->next)
			if (nh->segment == segment &&
                            nh->address <= address &&
                            nh->address >= nearest_address)
                        {
                            nearest_address = nh->address;
                            nearest = nh;
                        }
	}
        if (!nearest) return NULL;

        if (address == nearest->address)
            sprintf( name_buffer, "%s", nearest->name );
	else
            sprintf( name_buffer, "%s+0x%x", nearest->name,
                     address - nearest->address );
	return name_buffer;
}


void
read_symboltable(char * filename){
	FILE * symbolfile;
	unsigned int addr;
	int nargs;
	char type;
	char * cpnt;
	char buffer[256];
	char name[256];

	symbolfile = fopen(filename, "r");
	if(!symbolfile) {
		fprintf(stderr,"Unable to open symbol table %s\n", filename);
		return;
	};

	fprintf(stderr,"Reading symbols from file %s\n", filename);


	while (1)
	{
		fgets(buffer, sizeof(buffer),  symbolfile);
		if (feof(symbolfile)) break;
		
		/* Strip any text after a # sign (i.e. comments) */
		cpnt = buffer;
		while(*cpnt){
			if(*cpnt == '#') {*cpnt = 0; break; };
			cpnt++;
		};
		
		/* Quietly ignore any lines that have just whitespace */
		cpnt = buffer;
		while(*cpnt){
			if(*cpnt != ' ' && *cpnt != '\t') break;
			cpnt++;
		};
		if (!(*cpnt) || *cpnt == '\n') {
			continue;
		};
		
		nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
		add_hash(name, 0, addr);
      };
      fclose(symbolfile);
}



void load_entrypoints( HMODULE hModule )
{
    char buffer[256];
    unsigned char *cpnt, *name;
    NE_MODULE *pModule;
    unsigned int address;

    if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
    name = (unsigned char *)pModule + pModule->name_table;

      /* First search the resident names */

    cpnt = (unsigned char *)pModule + pModule->name_table;
    while (*cpnt)
    {
        cpnt += *cpnt + 1 + sizeof(WORD);
        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
                 *cpnt, *cpnt, cpnt + 1 );
        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
        if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
    }

      /* Now search the non-resident names table */

    if (!pModule->nrname_handle) return;  /* No non-resident table */
    cpnt = (char *)GlobalLock( pModule->nrname_handle );
    while (*cpnt)
    {
        cpnt += *cpnt + 1 + sizeof(WORD);
        sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
                 *cpnt, *cpnt, cpnt + 1 );
        address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
        if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
    }
}
