|
|
1.1 root 1: #include <u.h>
2: #include <libc.h>
3: #include <bio.h>
4: #include <bootexec.h>
5: #include <mach.h>
6:
7: /*
8: * All a.out header types. The dummy entry allows canonical
9: * processing of the union as a sequence of longs
10: */
11:
12: typedef struct {
13: union{
14: Exec; /* in a.out.h */
15: struct mipsexec; /* Hobbit uses this header too */
16: struct mips4kexec;
17: struct sparcexec;
18: struct nextexec;
19: struct i960exec;
20: } e;
21: long dummy; /* padding to ensure extra long */
22: } ExecHdr;
23:
24: static void i960boot(Fhdr *, ExecHdr *);
25: static void nextboot(Fhdr *, ExecHdr *);
26: static void sparcboot(Fhdr *, ExecHdr *);
27: static void mipsboot(Fhdr *, ExecHdr *);
28: static void mips4kboot(Fhdr *, ExecHdr *);
29: static void common(Fhdr *, ExecHdr *);
30: static void adotout(Fhdr *, ExecHdr *);
31: static void setsym(Fhdr *, long, long, long, long);
32: static void setdata(Fhdr *, long, long, long, long);
33: static void settext(Fhdr *, long, long, long, long);
34: static void hswal(long *, int, long (*) (long));
35: static long _round(long, long);
36:
37: /*
38: * definition of per-executable file type structures
39: */
40:
41: typedef struct Exectable{
42: long magic; /* big-endian magic number of file */
43: char *name; /* executable identifier */
44: int type; /* Internal code */
45: Mach *mach; /* Per-machine data */
46: ulong hsize; /* header size */
47: long (*swal)(long); /* beswal or leswal */
48: void (*hparse)(Fhdr *, ExecHdr *);
49: } ExecTable;
50:
51: extern Mach mmips;
52: extern Mach msparc;
53: extern Mach m68020;
54: extern Mach mi386;
55: extern Mach mi960;
56: extern Mach m3210;
57:
58: ExecTable exectab[] =
59: {
60: { V_MAGIC, /* Mips v.out */
61: "mips plan 9 executable",
62: FMIPS,
63: &mmips,
64: sizeof(Exec),
65: beswal,
66: adotout },
67: { 0x160<<16, /* Mips boot image */
68: "mips plan 9 boot image",
69: FMIPSB,
70: &mmips,
71: sizeof(struct mipsexec),
72: beswal,
73: mipsboot },
74: { (0x160<<16)|3, /* Mips boot image */
75: "mips 4k plan 9 boot image",
76: FMIPSB,
77: &mmips,
78: sizeof(struct mips4kexec),
79: beswal,
80: mips4kboot },
81: { K_MAGIC, /* Sparc k.out */
82: "sparc plan 9 executable",
83: FSPARC,
84: &msparc,
85: sizeof(Exec),
86: beswal,
87: adotout },
88: { 0x01030107, /* Sparc boot image */
89: "sparc plan 9 boot image",
90: FSPARCB,
91: &msparc,
92: sizeof(struct sparcexec),
93: beswal,
94: sparcboot },
95: { A_MAGIC, /* 68020 2.out & boot image */
96: "68020 plan 9 executable",
97: F68020,
98: &m68020,
99: sizeof(Exec),
100: beswal,
101: common },
102: { 0xFEEDFACE, /* Next boot image */
103: "next plan 9 boot image",
104: FNEXTB,
105: &m68020,
106: sizeof(struct nextexec),
107: beswal,
108: nextboot },
109: { I_MAGIC, /* I386 8.out & boot image */
110: "386 plan 9 executable",
111: FI386,
112: &mi386,
113: sizeof(Exec),
114: beswal,
115: common },
116: { J_MAGIC, /* I960 6.out (big-endian) */
117: "960 plan 9 executable",
118: FI960,
119: &mi960,
120: sizeof(Exec),
121: beswal,
122: adotout },
123: { 0x61010200, /* I960 boot image (little endian) */
124: "960 plan 9 boot image",
125: FI960B,
126: &mi960,
127: sizeof(struct i960exec),
128: leswal,
129: i960boot },
130: { X_MAGIC, /* 3210 x.out */
131: "3210 plan 9 executable",
132: F3210,
133: &m3210,
134: sizeof(Exec),
135: beswal,
136: adotout },
137: { 0 },
138: };
139:
140: Mach *mach = &mmips; /* Global current machine table */
141:
142: int
143: crackhdr(int fd, Fhdr *fp)
144: {
145: ExecTable *mp;
146: ExecHdr d;
147: int nb, magic;
148:
149: fp->type = FNONE;
150: if ((nb = read(fd, (char *)&d.e, sizeof(d.e))) <= 0)
151: return 0;
152: fp->magic = magic = beswal(d.e.magic); /* big-endian */
153: for (mp = exectab; mp->magic; mp++) {
154: if (mp->magic == magic && nb >= mp->hsize) {
155: hswal((long *) &d, sizeof(d.e)/sizeof(long), mp->swal);
156: fp->type = mp->type;
157: fp->name = mp->name;
158: fp->hdrsz = mp->hsize; /* zero on bootables */
159: mach = mp->mach;
160: mp->hparse(fp, &d);
161: seek(fd, mp->hsize, 0); /* seek to end of header */
162: return 1;
163: }
164: }
165: return 0;
166: }
167: /*
168: * Convert header to canonical form
169: */
170: static void
171: hswal(long *lp, int n, long (*swap) (long))
172: {
173: while (n--) {
174: *lp = (*swap) (*lp);
175: lp++;
176: }
177: }
178: /*
179: * Crack a normal a.out-type header
180: */
181: static void
182: adotout(Fhdr *fp, ExecHdr *hp)
183: {
184: long pgsize = mach->pgsize;
185:
186: settext(fp, hp->e.entry, pgsize+sizeof(Exec),
187: hp->e.text, sizeof(Exec));
188: setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
189: hp->e.data, fp->txtsz+sizeof(Exec), hp->e.bss);
190: setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);
191: }
192:
193: /*
194: * 68020 2.out and 68020 bootable images
195: * 386I 8.out and 386I bootable images
196: *
197: */
198: static void
199: common(Fhdr *fp, ExecHdr *hp)
200: {
201: long kbase = mach->kbase;
202:
203: adotout(fp, hp);
204: if (fp->entry & kbase) { /* Boot image */
205: switch(fp->type) {
206: case F68020:
207: fp->type = F68020B;
208: fp->name = "68020 plan 9 boot image";
209: fp->hdrsz = 0; /* header stripped */
210: break;
211: case FI386:
212: fp->type = FI386B;
213: fp->txtaddr = sizeof(Exec);
214: fp->name = "386 plan 9 boot image";
215: fp->hdrsz = 0; /* header stripped */
216: fp->dataddr = fp->txtaddr+fp->txtsz;
217: break;
218: default:
219: break;
220: }
221: fp->txtaddr |= kbase;
222: fp->entry |= kbase;
223: fp->dataddr |= kbase;
224: }
225: }
226:
227: /*
228: * mips bootable image.
229: */
230: static void
231: mipsboot(Fhdr *fp, ExecHdr *hp)
232: {
233: switch(hp->e.amagic) {
234: default:
235: case 0407: /* some kind of mips */
236: fp->type = FMIPSB;
237: settext(fp, hp->e.mentry, hp->e.text_start, hp->e.tsize,
238: sizeof(struct mipsexec)+4);
239: setdata(fp, hp->e.data_start, hp->e.dsize,
240: fp->txtoff+hp->e.tsize, hp->e.bsize);
241: break;
242: case 0413: /* some kind of mips */
243: fp->type = FMIPSB;
244: settext(fp, hp->e.mentry, hp->e.text_start, hp->e.tsize, 0);
245: setdata(fp, hp->e.data_start, hp->e.dsize, hp->e.tsize,
246: hp->e.bsize);
247: break;
248: }
249: setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
250: fp->hdrsz = 0; /* header stripped */
251: }
252:
253: /*
254: * mips4k bootable image.
255: */
256: static void
257: mips4kboot(Fhdr *fp, ExecHdr *hp)
258: {
259: switch(hp->e.h.amagic) {
260: default:
261: case 0407: /* some kind of mips */
262: fp->type = FMIPSB;
263: settext(fp, hp->e.h.mentry, hp->e.h.text_start, hp->e.h.tsize,
264: sizeof(struct mips4kexec));
265: setdata(fp, hp->e.h.data_start, hp->e.h.dsize,
266: fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
267: break;
268: case 0413: /* some kind of mips */
269: fp->type = FMIPSB;
270: settext(fp, hp->e.h.mentry, hp->e.h.text_start, hp->e.h.tsize, 0);
271: setdata(fp, hp->e.h.data_start, hp->e.h.dsize, hp->e.h.tsize,
272: hp->e.h.bsize);
273: break;
274: }
275: setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
276: fp->hdrsz = 0; /* header stripped */
277: }
278:
279: /*
280: * sparc bootable image
281: */
282: static void
283: sparcboot(Fhdr *fp, ExecHdr *hp)
284: {
285: fp->type = FSPARCB;
286: settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
287: sizeof(struct sparcexec));
288: setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
289: fp->txtoff+hp->e.stext, hp->e.sbss);
290: setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
291: fp->hdrsz = 0; /* header stripped */
292: }
293:
294: /*
295: * next bootable image
296: */
297: static void
298: nextboot(Fhdr *fp, ExecHdr *hp)
299: {
300: fp->type = FNEXTB;
301: settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
302: hp->e.texts.size, hp->e.texts.offset);
303: setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
304: hp->e.datas.offset, hp->e.bsss.size);
305: setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
306: hp->e.symc.symoff);
307: fp->hdrsz = 0; /* header stripped */
308: }
309:
310: /*
311: * I960 bootable image
312: */
313: static void
314: i960boot(Fhdr *fp, ExecHdr *hp)
315: {
316: /* long n = hp->e.i6comments.fptrlineno-hp->e.i6comments.fptrreloc; */
317:
318: settext(fp, hp->e.i6entry, hp->e.i6texts.virt, hp->e.i6texts.size,
319: hp->e.i6texts.fptr);
320: setdata(fp, hp->e.i6datas.virt, hp->e.i6datas.size,
321: hp->e.i6datas.fptr, hp->e.i6bsssize);
322: setsym(fp, 0, 0, 0, 0);
323: /*setsym(fp, n, 0, hp->e.i6comments.size-n, hp->e.i6comments.fptr); */
324: fp->hdrsz = 0; /* header stripped */
325: }
326:
327:
328: static void
329: settext(Fhdr *fp, long e, long a, long s, long off)
330: {
331: fp->txtaddr = a;
332: fp->entry = e;
333: fp->txtsz = s;
334: fp->txtoff = off;
335: }
336: static void
337: setdata(Fhdr *fp, long a, long s, long off, long bss)
338: {
339: fp->dataddr = a;
340: fp->datsz = s;
341: fp->datoff = off;
342: fp->bsssz = bss;
343: }
344: static void
345: setsym(Fhdr *fp, long sy, long sppc, long lnpc, long symoff)
346: {
347: fp->symsz = sy;
348: fp->symoff = symoff;
349: fp->sppcsz = sppc;
350: fp->sppcoff = fp->symoff+fp->symsz;
351: fp->lnpcsz = lnpc;
352: fp->lnpcoff = fp->sppcoff+fp->sppcsz;
353: }
354:
355:
356: static long
357: _round(long a, long b)
358: {
359: long w;
360:
361: w = (a/b)*b;
362: if (a!=w)
363: w += b;
364: return(w);
365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.