chiark / gitweb /
Initial revision
[ssr] / StraySrc / SDLS / cdll / c / cstub
1 /*
2  * cstub.c
3  *
4  * Create DLL stublib
5  *
6  * © 1994-1998 Straylight
7  */
8
9 /*----- Licensing note ----------------------------------------------------*
10  *
11  * This file is part of Straylight's Dynamic Linking System (SDLS)
12  *
13  * SDLS is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * SDLS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with SDLS.  If not, write to the Free Software Foundation,
25  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stddef.h>
32
33 #include "cstub.h"
34 #include "readdef.h"
35 #include "aof/aof.h"
36 #include "aof/chunk.h"
37 #include "hashtable.h"
38 #include "error.h"
39
40 typedef struct
41 {
42   aof_file f;
43   int areaname;
44   int abase;
45   hashtable osym;
46 }
47 cstub__thing;
48
49 #define cstub__MAGIC 0x004c4c44
50 #define cstub__VERSION 100
51
52 static int term;
53
54 static void cstub__enames(char *p,unsigned ord,void *handle)
55 {
56   cstub__thing *t=handle;
57   if (ord==0xFFFFFFFF && hash_find(t->osym,p))
58     aof_string(p,t->f.area);
59 }
60
61 static void cstub__entries(char *p,unsigned ord,void *handle)
62 {
63   cstub__thing *t=handle;
64   static int entry[1]={0xE3A0F000};             /* MOV  PC,#0           */
65   if (hash_find(t->osym,p))
66   {
67     aof_addsym(p,t->f.area->next-t->abase,0,t->areaname,&t->f);
68     if (ord==0xFFFFFFFF)
69     {
70       aof_add(entry,t->f.area);
71       term=1;
72     }
73     else
74       aof_add(ord,t->f.area);
75   }
76 }
77
78 void cstub(char *name,readdef_info *inf,hashtable osym)
79 {
80   FILE *fp;
81   char buffer[256];
82
83   if (!inf->apptbl)
84   {
85     /* --- Don't check if we're creating application stubs --- */
86
87     if (!inf->name[0])
88     {
89       if (!(inf->errored & rd_name))
90         error(NONAME);
91       inf->errored|=rd_name;
92     }
93     if (inf->version==-1)
94     {
95       if (!(inf->errored & rd_version))
96         error(NOVERSION);
97       inf->errored|=rd_version;
98       inf->version=100;
99     }
100     if (inf->errored & rd_name)
101       return;
102   }
103
104   fp=fopen(name,"wb");                  /* Open the output file         */
105   if (!fp)                              /* If the file wasn't opened    */
106     error(NOOPENOUT,name);              /* Better give an error         */
107   else
108   {
109     char _buf[sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry)];
110     chunk_header *h=(chunk_header *)&_buf; /* Allocate memory easily :-) */
111
112     aof_chunkinfo obj_idfn={0};
113     aof_chunkinfo obj_head={0};
114     aof_chunkinfo obj_area={0};
115     aof_chunkinfo obj_symt={0};
116     aof_chunkinfo obj_strt={0};
117     aof_chunkinfo reloc={0};
118     cstub__thing t;
119
120     int o;
121     int osize=0;
122     int orelocs=0;
123
124     int sym_dllName;
125     int sym_dllEntries;
126     int sym_dllStubs;
127     int tmp;
128
129     t.f.area=&obj_area;
130     t.osym=osym;
131     t.f.symt=&obj_symt;
132     t.f.strt=&obj_strt;
133     t.f.reloc=&reloc;
134
135     h->hdr.id=chunk_MAGIC;              /* Fill in magic thingy         */
136     h->hdr.maxChunks=h->hdr.numChunks=5; /* And number of chunks        */
137
138     aof_string("Straylight Dynamic Link Library building system 1.01",
139                  &obj_idfn);
140     aof_align(obj_idfn);
141
142     aof_int(0,&obj_strt);
143
144     aof_int((int)aof_RELOC,&obj_head);
145     aof_int(150,&obj_head);
146     aof_int((inf->apptbl ? 1 : 3),&obj_head);
147     aof_int(obj_symt.next/sizeof(aof_symbol),&obj_head);
148     aof_int(0,&obj_head);
149     aof_int(0,&obj_head);
150
151     /* --- Do entry names for dll table --- */
152
153     if (inf->apptbl)
154       t.areaname=aof_string("DLL$$AppEntry",&obj_strt);
155     else
156       t.areaname=aof_string("DLL$$Strings",&obj_strt);
157     t.abase=obj_area.next;
158
159     if (!inf->apptbl)
160     {
161       sym_dllName=obj_symt.next/16;
162       aof_addsym("_dll_name",
163                  obj_area.next-t.abase,
164                  1,
165                  t.areaname,
166                  &t.f);
167
168       if (inf->dllpath)
169       {
170         sprintf(buffer,"%s[%s]",inf->dllpath,inf->name);
171         aof_string(buffer,&obj_area);
172       }
173       else
174       {
175         sprintf(buffer,"[%s]",inf->name);
176         aof_string(buffer,&obj_area);
177       }
178
179       sym_dllEntries=obj_symt.next/16;
180       aof_addsym("_dll_entries",
181                  obj_area.next-t.abase,
182                  1,
183                  t.areaname,
184                  &t.f);
185
186       /* --- Hack for link v. 5.00 --- *
187        *
188        * We IMPORT the symbol _dll_findall in order to ensure that DLLLib
189        * gets linked in.
190        */
191
192       {
193         aof_symbol sym={0};
194         sym.name=aof_string("_dll_findall",&obj_strt);
195         sym.defined=0;
196         sym.export=1;
197         aof_add(sym,&obj_symt);
198       }
199     }
200     else
201     {
202       aof_addsym("DLL$$AppEntryNames",
203                  obj_area.next-t.abase,
204                  0,
205                  t.areaname,
206                  &t.f);
207     }
208
209     hash_enumOrdered(inf->sym,cstub__enames,&t);
210
211     { char c=0; aof_add(c,&obj_area); }
212
213     aof_align(obj_area);
214
215     if (!inf->apptbl)
216     {
217       aof_int(t.areaname,&obj_head);
218       aof_int(0x00002202,&obj_head);
219       aof_int(obj_area.next-osize,&obj_head);
220       aof_int(reloc.next/8-orelocs,&obj_head);
221       aof_int(0,&obj_head);
222       aof_addBlock(reloc.p,reloc.next,&obj_area);
223       osize=obj_area.next;
224       orelocs=reloc.next/8;
225
226       /* --- Do entry veneers table --- */
227
228       t.areaname=aof_string("DLL$$Stubs",&obj_strt);
229       t.abase=obj_area.next;
230
231       sym_dllStubs=obj_symt.next/16;
232       aof_addsym("_dll_stubs",
233                  obj_area.next-t.abase,
234                  1,
235                  t.areaname,
236                  &t.f);
237     }
238     else
239     {
240       aof_addsym("DLL$$AppEntryStubs",
241                  obj_area.next-t.abase,
242                  0,
243                  t.areaname,
244                  &t.f);
245     }
246
247     term=0;
248     hash_enumOrdered(inf->sym,cstub__entries,&t);
249     if (!term)
250       aof_int(-1,&obj_area);
251
252     aof_align(obj_area);
253
254     aof_int(t.areaname,&obj_head);
255     aof_int(0x00002202,&obj_head);
256     aof_int(obj_area.next-osize,&obj_head);
257     aof_int(reloc.next/8-orelocs,&obj_head);
258     aof_int(0,&obj_head);
259     aof_addBlock(reloc.p,reloc.next,&obj_area);
260     osize=obj_area.next;
261     orelocs=reloc.next/8;
262
263     /* --- Do external DLL table area --- */
264
265     if (!inf->apptbl)
266     {
267       t.areaname=aof_string("DLL$$ExternalTable",&obj_strt);
268       t.abase=obj_area.next;
269
270       tmp=aof_int(0,&obj_area)-t.abase;
271       aof_add(tmp,&reloc);
272       aof_int(0x000A0000 | sym_dllName,&reloc);
273
274       aof_int(inf->version,&obj_area);
275
276       tmp=aof_int(0,&obj_area)-t.abase;
277       aof_add(tmp,&reloc);
278       aof_int(0x000A0000 | sym_dllEntries,&reloc);
279
280       tmp=aof_int(0,&obj_area)-t.abase;
281       aof_add(tmp,&reloc);
282       aof_int(0x000A0000 | sym_dllStubs,&reloc);
283
284       aof_align(obj_area);
285
286       aof_int(t.areaname,&obj_head);
287       aof_int(0x00002202,&obj_head);
288       aof_int(obj_area.next-osize,&obj_head);
289       aof_int(reloc.next/8-orelocs,&obj_head);
290       aof_int(0,&obj_head);
291       aof_addBlock(reloc.p,reloc.next,&obj_area);
292       osize=obj_area.next;
293       orelocs=reloc.next/8;
294     }
295
296     aof_fill(obj_strt.next,0,&obj_strt);
297     aof_align(obj_strt);
298
299     o=obj_symt.next/sizeof(aof_symbol);
300     aof_fill(o,12,&obj_head);
301
302     memcpy(h->table[0].chunkName,"OBJ_IDFN",8);
303     memcpy(h->table[1].chunkName,"OBJ_HEAD",8);
304     memcpy(h->table[2].chunkName,"OBJ_AREA",8);
305     memcpy(h->table[3].chunkName,"OBJ_SYMT",8);
306     memcpy(h->table[4].chunkName,"OBJ_STRT",8);
307
308     o=sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry);
309
310     h->table[0].offset=o;
311     h->table[0].size=obj_idfn.next;
312     o+=obj_idfn.next;
313
314     h->table[1].offset=o;
315     h->table[1].size=obj_head.next;
316     o+=obj_head.next;
317
318     h->table[2].offset=o;
319     h->table[2].size=obj_area.next;
320     o+=obj_area.next;
321
322     h->table[3].offset=o;
323     h->table[3].size=obj_symt.next;
324     o+=obj_symt.next;
325
326     h->table[4].offset=o;
327     h->table[4].size=obj_strt.next;
328     o+=obj_strt.next;
329
330     fwrite(h,sizeof(chunk_fixedHeader)+5*sizeof(chunk_tableEntry),1,fp);
331     fwrite(obj_idfn.p,obj_idfn.next,1,fp);
332     fwrite(obj_head.p,obj_head.next,1,fp);
333     fwrite(obj_area.p,obj_area.next,1,fp);
334     fwrite(obj_symt.p,obj_symt.next,1,fp);
335     fwrite(obj_strt.p,obj_strt.next,1,fp);
336     fclose(fp);
337
338     free(obj_idfn.p);
339     free(obj_area.p);
340     free(obj_strt.p);
341     free(obj_head.p);
342     free(obj_symt.p);
343   }
344 }