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 }