|
|
1.1 root 1: /* Copyright 1989 by AT&T Bell Laboratories */
2: #include "tags.h"
3: #ifdef NeXT
4: #include <sys/loader.h>
5: #else
6: #include <a.out.h>
7: #endif NeXT
8:
9: #define CEIL(x,quantum) ((((int)(x))+(quantum)-1)&~((quantum)-1))
10:
11: #ifdef NS32
12: #define N_DATADDR(x) 0x400000
13: #endif NS32
14:
15: #ifndef N_DATADDR
16: #define N_DATADDR(x) CEIL((x).a_text,getpagesize())
17: #endif
18:
19: #ifndef N_TXTADDR
20: #ifdef NeXT
21: #include <machine/vm_param.h>
22: #ifdef USRTEXT
23: #define N_TXTADDR(x) USRTEXT
24: #endif USRTEXT
25: #endif
26: #ifdef VAX
27: #define N_TXTADDR(x) 0
28: #endif
29: #ifdef NS32
30: #define N_TXTADDR(x) 0
31: #define exec aouthdr
32: #define a_magic magic
33: #define a_text tsize
34: #define a_data dsize
35: #define a_bss bsize
36: #define a_entry entry
37: #define a_trsize text_start
38: #define a_drsize data_start
39: #endif NS32
40: #ifndef sony_news
41: #ifdef M68
42: #define N_TXTADDR(x) getpagesize()
43: #endif
44: #else sony_news
45: #define N_TXTADDR(x) 0
46: #endif sony_news
47: #ifdef SPARC
48: #include <machine/vmparam.h>
49: #define N_TXTADDR(x) USRTEXT
50: #endif
51: #endif
52:
53:
54:
55: /* Garbage collection is already done.
56: * Data to be saved is:
57: * 0 -> ceil(etext) text
58: * ceil(etext) -> arenabase data
59: * arenabase -> old_high heap
60: *
61: * > set a_entry as address of start procedure
62: */
63:
64: extern int etext; /* &etext is just beyond the end of the text segment */
65: extern int old_high;
66:
67: static int textstart,datastart;
68:
69: extern int startptr;
70:
71: #ifdef V9
72: getpagesize(){return 1024;}
73: #endif
74:
75: #ifndef NeXT
76: export (filid)
77: int filid;
78: {
79: int bytcount;
80: static struct exec E; /* make it static so all fields=0 */
81:
82: #if SUN3 || SPARC
83: E.a_magic = NMAGIC;
84: #else
85: #ifdef NS32
86: E.a_magic = NS32GMAGIC;
87: #else
88: E.a_magic = ZMAGIC;
89: #endif
90: #endif
91: #ifdef M68
92: #ifndef sony_news
93: E.a_machtype = 2; /* M_68020 */
94: #endif sony_news
95: E.a_machtype = M_68020; /* M_68020 */
96: #endif
97: #ifdef SPARC
98: E.a_toolversion = 1;
99: E.a_machtype = M_SPARC;
100: #endif
101:
102: textstart = N_TXTADDR(E);
103: E.a_text = (int) CEIL(((int)&etext),getpagesize())-textstart;
104: datastart = N_DATADDR(E);
105: E.a_bss = 0;
106: #ifndef NS32
107: E.a_syms = 0;
108: #endif NS32
109: E.a_entry = startptr;
110: E.a_trsize = 0;
111: E.a_drsize = 0;
112: E.a_data = CEIL(old_high-datastart, getpagesize());
113:
114: filid >>= 1;
115: fchmod(filid,0755);
116: #ifdef NS32
117: coff_cough(filid,&bytcount,E.a_text,E.a_data,E.a_entry);
118: #else
119: bulletproofWrite(filid,&E,sizeof(E));
120: bytcount = sizeof(E);
121: #endif NS32
122: #if VAX || NS32
123: {int i, nzeros = getpagesize()-sizeof(E);
124: char zeros[1024];
125: for(i=0;i<nzeros;i++) zeros[i]=0;
126: bulletproofWrite(filid,zeros,nzeros);
127:
128: }
129: #endif
130: #ifdef sony_news
131: {int i, nzeros = getpagesize()-bytcount;
132: char zeros[4096];
133: for(i=0;i<nzeros;i++) zeros[i]=0;
134: bulletproofWrite(filid,zeros,nzeros);
135: }
136: #endif sony_news
137: bulletproofWrite(filid,textstart,E.a_text);
138: bulletproofWrite(filid,datastart,E.a_data);
139: }
140: #ifdef NS32
141: coff_cough(fd,countp,tsize,dsize,entry)
142: int fd, *countp, tsize, dsize, entry;
143: {
144: static struct filehdr fhdr;
145: static struct aouthdr ahdr;
146: static struct scnhdr thdr;
147: static struct scnhdr dhdr;
148: static struct scnhdr bhdr;
149: int allhdrsize = sizeof(fhdr) + sizeof(ahdr) + 3*sizeof(thdr);
150: int pagesize = getpagesize();
151:
152: fhdr.f_magic = NS32GMAGIC;
153: fhdr.f_nscns = 3;
154: fhdr.f_timdat = /* don't care */ 0;
155: fhdr.f_symptr = /* null? */ 0;
156: fhdr.f_nsyms = 0;
157: fhdr.f_opthdr = sizeof(struct aouthdr);
158: fhdr.f_flags = F_RELFLG|F_EXEC|F_LNNO|F_LSYMS|F_AR32WR;
159:
160: ahdr.magic = /* OOPS */ 0x010b;
161: ahdr.vstamp = /* don't care */ 0;
162: ahdr.tsize = tsize;
163: ahdr.dsize = dsize;
164: ahdr.bsize = 0;
165: ahdr.msize = /* OOPS */ 0x10;
166: ahdr.mod_start = /* OOPS */ 0x20;
167: ahdr.entry = entry;
168: ahdr.text_start = 0;
169: ahdr.data_start = 0x400000;
170: ahdr.entry_mod = /* unused? */ 0;
171: ahdr.flags = U_SYS_42|U_AL_4096;
172:
173: strncpy(thdr.s_name,_TEXT,8);
174: thdr.s_paddr = thdr.s_vaddr = ahdr.data_start;
175: thdr.s_size = ahdr.tsize;
176: thdr.s_scnptr = CEIL(allhdrsize,pagesize);
177: thdr.s_relptr = /* null? */ 0;
178: thdr.s_lnnoptr = /* null? */ 0;
179: thdr.s_nreloc = 0;
180: thdr.s_nlnno = 0;
181: thdr.s_flags = STYP_TEXT;
182: thdr.s_symptr = /* null? */ 0;
183: thdr.s_modno = /* OOPS */ 0;
184: thdr.s_pad = /* don't care */ 0;
185:
186: strncpy(dhdr.s_name,_DATA,8);
187: dhdr.s_paddr = dhdr.s_vaddr = ahdr.data_start;
188: dhdr.s_size = ahdr.dsize;
189: dhdr.s_scnptr = thdr.s_scnptr + CEIL(thdr.s_size,pagesize);
190: dhdr.s_relptr = /* null? */ 0;
191: dhdr.s_lnnoptr = /* null? */ 0;
192: dhdr.s_nreloc = 0;
193: dhdr.s_nlnno = 0;
194: dhdr.s_flags = STYP_DATA;
195: dhdr.s_symptr = /* null? */ 0;
196: dhdr.s_modno = /* OOPS */ 0;
197: dhdr.s_pad = /* don't care */ 0;
198:
199: strncpy(bhdr.s_name,_BSS,8);
200: bhdr.s_paddr = bhdr.s_vaddr = ahdr.data_start + ahdr.dsize;
201: bhdr.s_size = /* none */ 0;
202: bhdr.s_scnptr = /* null */ 0;
203: bhdr.s_relptr = /* null? */ 0;
204: bhdr.s_lnnoptr = /* null? */ 0;
205: bhdr.s_nreloc = 0;
206: bhdr.s_nlnno = 0;
207: bhdr.s_flags = STYP_BSS;
208: bhdr.s_symptr = /* null? */ 0;
209: bhdr.s_modno = /* OOPS */ 0;
210: bhdr.s_pad = /* don't care */ 0;
211: bulletproofWrite(fd,&fhdr,sizeof(fhdr));
212: bulletproofWrite(fd,&ahdr,sizeof(ahdr));
213: bulletproofWrite(fd,&thdr,sizeof(thdr));
214: bulletproofWrite(fd,&dhdr,sizeof(dhdr));
215: bulletproofWrite(fd,&bhdr,sizeof(bhdr));
216: *countp = allhdrsize;
217: }
218: #endif NS32
219: #else NeXT
220: extern int mach_maplimit;
221: export(filid) int filid;
222: {static struct mach_header E; /* make it static so all fields=0 */
223: static struct segment_command tcmd;
224: static struct section tsectn;
225: static struct segment_command dcmd;
226: static struct section dsectn;
227: static struct section bsectn;
228: static struct thread_command uthr;
229: static unsigned long thflavor;
230: static unsigned long thcount;
231: static struct NeXT_thread_state_regs ntregs;
232: static unsigned int hdrsize;
233: int datasize, bsssize;
234:
235: E.magic = MH_MAGIC;
236: E.cputype = CPU_TYPE_MC68030;
237: E.cpusubtype = CPU_SUBTYPE_NeXT;
238: E.filetype = MH_EXECUTE;
239: E.ncmds = 3;
240: E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
241: + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn)
242: + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
243: E.flags = MH_NOUNDEFS;
244:
245: hdrsize = E.sizeofcmds + sizeof(E);
246: textstart = N_TXTADDR(E);
247:
248:
249: tcmd.cmd = LC_SEGMENT;
250: tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
251: strcpy(tcmd.segname,SEG_TEXT);
252: tcmd.vmaddr = textstart;
253: tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart;
254: tcmd.fileoff = 0;
255: tcmd.filesize = tcmd.vmsize;
256: tcmd.maxprot = VM_PROT_ALL;
257: tcmd.initprot = VM_PROT_READ|VM_PROT_EXECUTE;
258: tcmd.nsects = 1;
259: tcmd.flags = 0;
260:
261: strcpy(tsectn.sectname,SECT_TEXT);
262: strcpy(tsectn.segname,tcmd.segname);
263: tsectn.addr = tcmd.vmaddr + hdrsize;
264: tsectn.size = tcmd.vmsize - hdrsize;
265: tsectn.offset = hdrsize;
266: tsectn.align = 2;
267: tsectn.reloff = 0;
268: tsectn.nreloc = 0;
269: tsectn.flags = 0;
270: tsectn.reserved1 = tsectn.reserved2 = 0;
271:
272:
273: dcmd.cmd = LC_SEGMENT;
274: dcmd.cmdsize = sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn);
275: strcpy(dcmd.segname,SEG_DATA);
276: dcmd.vmaddr = tcmd.vmaddr + tcmd.vmsize;
277: datasize = CEIL(old_high-dcmd.vmaddr, getpagesize());
278: bsssize = mach_maplimit-old_high;
279: dcmd.vmsize = bsssize+datasize;
280: dcmd.fileoff = tcmd.fileoff + tcmd.filesize;
281: dcmd.filesize = datasize;
282: dcmd.maxprot = VM_PROT_ALL;
283: dcmd.initprot = VM_PROT_ALL;
284: dcmd.nsects = 2;
285: dcmd.flags = 0;
286:
287: strcpy(dsectn.sectname,SECT_DATA);
288: strcpy(dsectn.segname,dcmd.segname);
289: dsectn.addr = dcmd.vmaddr;
290: dsectn.size = datasize;
291: dsectn.offset = dcmd.fileoff;
292: dsectn.align = 2;
293: dsectn.reloff = 0;
294: dsectn.nreloc = 0;
295: dsectn.flags = 0;
296: dsectn.reserved1 = dsectn.reserved2 = 0;
297:
298: strcpy(bsectn.sectname,SECT_BSS);
299: strcpy(bsectn.segname,dcmd.segname);
300: bsectn.addr = dsectn.addr + dsectn.size;
301: bsectn.size = bsssize;
302: bsectn.offset = 0;
303: bsectn.align = 2;
304: bsectn.reloff = 0;
305: bsectn.nreloc = 0;
306: bsectn.flags = S_ZEROFILL;
307: bsectn.reserved1 = bsectn.reserved2 = 0;
308:
309: uthr.cmd = LC_UNIXTHREAD;
310: uthr.cmdsize = sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
311:
312: thflavor = NeXT_THREAD_STATE_REGS;
313:
314: thcount = NeXT_THREAD_STATE_REGS_COUNT;
315:
316: ntregs.areg[0] = 0xfeadface;
317: ntregs.pc = startptr;
318:
319: filid >>= 1;
320: fchmod(filid,0755);
321: bulletproofWrite(filid,&E,sizeof(E));
322: bulletproofWrite(filid,&tcmd,sizeof(tcmd));
323: bulletproofWrite(filid,&tsectn,sizeof(tsectn));
324: bulletproofWrite(filid,&dcmd,sizeof(dcmd));
325: bulletproofWrite(filid,&dsectn,sizeof(dsectn));
326: bulletproofWrite(filid,&bsectn,sizeof(bsectn));
327: bulletproofWrite(filid,&uthr,sizeof(uthr));
328: bulletproofWrite(filid,&thflavor,sizeof(thflavor));
329: bulletproofWrite(filid,&thcount,sizeof(thcount));
330: bulletproofWrite(filid,&ntregs,sizeof(ntregs));
331: bulletproofWrite(filid,tsectn.addr,tsectn.size);
332: bulletproofWrite(filid,dsectn.addr,dsectn.size);
333: }
334: #endif NeXT
335:
336:
337: /* NICK: A Bullet-proof write to retry on NFS systems */
338: /* JHR: Added retry for NFS timeout errors. */
339: #include <errno.h>
340: bulletproofWrite(fid, buf, total)
341: int fid;
342: char *buf;
343: int total;
344: {
345: int bytesWritten = 0;
346: #ifdef M68
347: int retries = 0;
348: #endif
349: int i;
350: do
351: { i = write(fid, buf, total-bytesWritten);
352: #ifdef M68
353: #ifndef sony_news
354: if (i < 0) {
355: if (errno == ETIMEDOUT) {
356: /* NFS timeout error, so try again. */
357: if (retries++ > 5)
358: die("export, NFS timeout");
359: chatting("[Write timeout, retrying]\n");
360: continue;
361: }
362: else die("export");
363: }
364: else retries = 0;
365: #else sony_news
366: if (i < 0) die("export");
367: #endif sony_news
368: #else
369: if (i < 0) die("export");
370: #endif
371: bytesWritten += i;
372: buf += i;
373: if (bytesWritten < total)
374: chatting("[Write incomplete (%d/%d), retrying]\n",
375: bytesWritten, total);
376: }
377: while (bytesWritten < total);
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.