/* * Copyright (C) 1996-1998 Ilya Ryzhenkov (orangy@inetlab.com) * This file maintains symbol management. * It uses hash tables to manipulate symbols. */ #include "helpdefs.h" #include "dlm_sym.h" #include "hash.h" static THashTab *Export,*Import,*DLM; static TExportSym FindExport; static TImportSym FindImport; unsigned long FExportHash(void *data) { return FHashString(((TExportSym*)data)->name); } unsigned long FImportHash(void *data) { return FHashString(((TImportSym*)data)->name); } int FExportCmp(void *data1,void *data2) { TExportSym *p1,*p2; int retval=1; p1=(TExportSym*)data1; p2=(TExportSym*)data2; if (p1->dlm && p2->dlm) retval=retval&&(p1->dlm==p2->dlm); return retval && (!strcmp(p1->name,p2->name)); } int FImportCmp(void *data1,void *data2) { return !strcmp((((TImportSym*)data1)->name),(((TImportSym*)data2)->name)); } int _sym_init_tables(void) { Export=_hash_createtab(256,FExportHash,FExportCmp); DLM =_hash_createtab(256,FExportHash,FExportCmp); Import=_hash_createtab(256,FImportHash,FImportCmp); if (!Export || !Import || !DLM) return 0; else return 1; } int _sym_add_export(char *name,void *address,TDlm *dlm) { TExportSym *sym; if (!name) return 0; sym=NEW(TExportSym); if (!sym) return 0; sym->name=strdup(name); sym->address=address; sym->dlm=dlm; return _hash_addsym(Export,sym); } int _sym_del_export(char *name,TDlm *dlm) { void *data; if (!name) return 0; FindExport.name=name; FindExport.dlm=dlm; data=_hash_delsym(Export, &FindExport); if (!data) return 0; else { FREE(((TExportSym *)data)->name); FREE(data); } return 1; } void *_sym_find_export(char *name,TDlm *dlm) { TExportSym *data; if (!name) return 0; FindExport.name=name; FindExport.dlm=dlm; data=(TExportSym *)_hash_findsym(Export, &FindExport); if (!data) return 0; else return data->address; } int _sym_add_import(char *name,TDlm *dlm) { TImportSym *sym; TImportDlmLst *idlm; if (!dlm || !name) return 0; // printf("add import %s for %s ",name,dlm->filename); idlm=NEW(TImportDlmLst); if (!idlm) return 0; idlm->dlm=dlm; idlm->next=idlm->prev=0; FindImport.name=name; sym=_hash_findsym(Import,&FindImport); if (!sym) { // printf("(new)"); sym=NEW(TImportSym); if (!sym) { free(idlm); return 0; } sym->name=strdup(name); sym->dlmlist=0; if (!_hash_addsym(Import,sym)) { free(sym->name); free(sym); free(idlm); // printf(" failed!\n"); return 0; } } if ((idlm->next=sym->dlmlist)) idlm->next->prev=idlm; sym->dlmlist=idlm; // printf("\n"); return 1; } int _sym_del_import(char *name,TDlm *dlm) { TImportSym *sym; TImportDlmLst *idlm; if (!dlm || !name) return 0; FindImport.name=name; sym=_hash_findsym(Import,&FindImport); if (!sym) return 0; idlm=sym->dlmlist; while (idlm) { if (idlm->dlm==dlm) { if (sym->dlmlist==idlm) sym->dlmlist=idlm->next; else idlm->prev->next=idlm->next; if (idlm->next) idlm->next->prev=idlm->prev; free(idlm); if (!sym->dlmlist) { _hash_delsym(Import,&FindImport); free(sym); } return 1; } idlm=idlm->next; } return 0; } TImportDlmLst *_sym_find_import(char *name) { TImportSym *data; if (!name) return 0; FindImport.name=name; data=(TImportSym *)_hash_findsym(Import, &FindImport); if (!data) return 0; else return data->dlmlist; } int _sym_add_dlm(char *name,TDlm *address) { TExportSym *sym; if (!name) return 0; sym=NEW(TExportSym); if (!sym) return 0; sym->name=strdup(name); sym->address=address; return _hash_addsym(DLM,sym); } int _sym_del_dlm(char *name) { void *data; TExportSym *sym; if (!name) return 0; FindExport.name=name; FindExport.dlm=0; data=_hash_delsym(DLM, &FindExport); if (!data) return 0; sym=(TExportSym *)data; free(sym->name); free(sym); return 1; } TDlm *_sym_find_dlm(char *name) { TExportSym *data; if (!name) return 0; FindExport.name=name; FindExport.dlm=0; data=(TExportSym *)_hash_findsym(DLM, &FindExport); if (!data) return 0; else return (TDlm *)data->address; } int _sym_dlmsearch(void) { return _hash_iter_init(DLM); } TDlm *_sym_dlmnext(void) { void *next=_hash_iter_next(); if (!next) return 0; return (TDlm *)(((TExportSym*)next)->address); }