/* * cstub.c * * Create DLL stublib * * © 1994-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Dynamic Linking System (SDLS) * * SDLS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * SDLS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SDLS. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "cstub.h" #include "readdef.h" #include "aof/aof.h" #include "aof/chunk.h" #include "hashtable.h" #include "error.h" typedef struct { aof_file f; int areaname; int abase; hashtable osym; } cstub__thing; #define cstub__MAGIC 0x004c4c44 #define cstub__VERSION 100 static int term; static void cstub__enames(char *p,unsigned ord,void *handle) { cstub__thing *t=handle; if (ord==0xFFFFFFFF && hash_find(t->osym,p)) aof_string(p,t->f.area); } static void cstub__entries(char *p,unsigned ord,void *handle) { cstub__thing *t=handle; static int entry[1]={0xE3A0F000}; /* MOV PC,#0 */ if (hash_find(t->osym,p)) { aof_addsym(p,t->f.area->next-t->abase,0,t->areaname,&t->f); if (ord==0xFFFFFFFF) { aof_add(entry,t->f.area); term=1; } else aof_add(ord,t->f.area); } } void cstub(char *name,readdef_info *inf,hashtable osym) { FILE *fp; char buffer[256]; if (!inf->apptbl) { /* --- Don't check if we're creating application stubs --- */ if (!inf->name[0]) { if (!(inf->errored & rd_name)) error(NONAME); inf->errored|=rd_name; } if (inf->version==-1) { if (!(inf->errored & rd_version)) error(NOVERSION); inf->errored|=rd_version; inf->version=100; } if (inf->errored & rd_name) return; } fp=fopen(name,"wb"); /* Open the output file */ if (!fp) /* If the file wasn't opened */ error(NOOPENOUT,name); /* Better give an error */ else { char _buf[sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry)]; chunk_header *h=(chunk_header *)&_buf; /* Allocate memory easily :-) */ aof_chunkinfo obj_idfn={0}; aof_chunkinfo obj_head={0}; aof_chunkinfo obj_area={0}; aof_chunkinfo obj_symt={0}; aof_chunkinfo obj_strt={0}; aof_chunkinfo reloc={0}; cstub__thing t; int o; int osize=0; int orelocs=0; int sym_dllName; int sym_dllEntries; int sym_dllStubs; int tmp; t.f.area=&obj_area; t.osym=osym; t.f.symt=&obj_symt; t.f.strt=&obj_strt; t.f.reloc=&reloc; h->hdr.id=chunk_MAGIC; /* Fill in magic thingy */ h->hdr.maxChunks=h->hdr.numChunks=5; /* And number of chunks */ aof_string("Straylight Dynamic Link Library building system 1.01", &obj_idfn); aof_align(obj_idfn); aof_int(0,&obj_strt); aof_int((int)aof_RELOC,&obj_head); aof_int(150,&obj_head); aof_int((inf->apptbl ? 1 : 3),&obj_head); aof_int(obj_symt.next/sizeof(aof_symbol),&obj_head); aof_int(0,&obj_head); aof_int(0,&obj_head); /* --- Do entry names for dll table --- */ if (inf->apptbl) t.areaname=aof_string("DLL$$AppEntry",&obj_strt); else t.areaname=aof_string("DLL$$Strings",&obj_strt); t.abase=obj_area.next; if (!inf->apptbl) { sym_dllName=obj_symt.next/16; aof_addsym("_dll_name", obj_area.next-t.abase, 1, t.areaname, &t.f); if (inf->dllpath) { sprintf(buffer,"%s[%s]",inf->dllpath,inf->name); aof_string(buffer,&obj_area); } else { sprintf(buffer,"[%s]",inf->name); aof_string(buffer,&obj_area); } sym_dllEntries=obj_symt.next/16; aof_addsym("_dll_entries", obj_area.next-t.abase, 1, t.areaname, &t.f); /* --- Hack for link v. 5.00 --- * * * We IMPORT the symbol _dll_findall in order to ensure that DLLLib * gets linked in. */ { aof_symbol sym={0}; sym.name=aof_string("_dll_findall",&obj_strt); sym.defined=0; sym.export=1; aof_add(sym,&obj_symt); } } else { aof_addsym("DLL$$AppEntryNames", obj_area.next-t.abase, 0, t.areaname, &t.f); } hash_enumOrdered(inf->sym,cstub__enames,&t); { char c=0; aof_add(c,&obj_area); } aof_align(obj_area); if (!inf->apptbl) { aof_int(t.areaname,&obj_head); aof_int(0x00002202,&obj_head); aof_int(obj_area.next-osize,&obj_head); aof_int(reloc.next/8-orelocs,&obj_head); aof_int(0,&obj_head); aof_addBlock(reloc.p,reloc.next,&obj_area); osize=obj_area.next; orelocs=reloc.next/8; /* --- Do entry veneers table --- */ t.areaname=aof_string("DLL$$Stubs",&obj_strt); t.abase=obj_area.next; sym_dllStubs=obj_symt.next/16; aof_addsym("_dll_stubs", obj_area.next-t.abase, 1, t.areaname, &t.f); } else { aof_addsym("DLL$$AppEntryStubs", obj_area.next-t.abase, 0, t.areaname, &t.f); } term=0; hash_enumOrdered(inf->sym,cstub__entries,&t); if (!term) aof_int(-1,&obj_area); aof_align(obj_area); aof_int(t.areaname,&obj_head); aof_int(0x00002202,&obj_head); aof_int(obj_area.next-osize,&obj_head); aof_int(reloc.next/8-orelocs,&obj_head); aof_int(0,&obj_head); aof_addBlock(reloc.p,reloc.next,&obj_area); osize=obj_area.next; orelocs=reloc.next/8; /* --- Do external DLL table area --- */ if (!inf->apptbl) { t.areaname=aof_string("DLL$$ExternalTable",&obj_strt); t.abase=obj_area.next; tmp=aof_int(0,&obj_area)-t.abase; aof_add(tmp,&reloc); aof_int(0x000A0000 | sym_dllName,&reloc); aof_int(inf->version,&obj_area); tmp=aof_int(0,&obj_area)-t.abase; aof_add(tmp,&reloc); aof_int(0x000A0000 | sym_dllEntries,&reloc); tmp=aof_int(0,&obj_area)-t.abase; aof_add(tmp,&reloc); aof_int(0x000A0000 | sym_dllStubs,&reloc); aof_align(obj_area); aof_int(t.areaname,&obj_head); aof_int(0x00002202,&obj_head); aof_int(obj_area.next-osize,&obj_head); aof_int(reloc.next/8-orelocs,&obj_head); aof_int(0,&obj_head); aof_addBlock(reloc.p,reloc.next,&obj_area); osize=obj_area.next; orelocs=reloc.next/8; } aof_fill(obj_strt.next,0,&obj_strt); aof_align(obj_strt); o=obj_symt.next/sizeof(aof_symbol); aof_fill(o,12,&obj_head); memcpy(h->table[0].chunkName,"OBJ_IDFN",8); memcpy(h->table[1].chunkName,"OBJ_HEAD",8); memcpy(h->table[2].chunkName,"OBJ_AREA",8); memcpy(h->table[3].chunkName,"OBJ_SYMT",8); memcpy(h->table[4].chunkName,"OBJ_STRT",8); o=sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry); h->table[0].offset=o; h->table[0].size=obj_idfn.next; o+=obj_idfn.next; h->table[1].offset=o; h->table[1].size=obj_head.next; o+=obj_head.next; h->table[2].offset=o; h->table[2].size=obj_area.next; o+=obj_area.next; h->table[3].offset=o; h->table[3].size=obj_symt.next; o+=obj_symt.next; h->table[4].offset=o; h->table[4].size=obj_strt.next; o+=obj_strt.next; fwrite(h,sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry),1,fp); fwrite(obj_idfn.p,obj_idfn.next,1,fp); fwrite(obj_head.p,obj_head.next,1,fp); fwrite(obj_area.p,obj_area.next,1,fp); fwrite(obj_symt.p,obj_symt.next,1,fp); fwrite(obj_strt.p,obj_strt.next,1,fp); fclose(fp); free(obj_idfn.p); free(obj_area.p); free(obj_strt.p); free(obj_head.p); free(obj_symt.p); } }