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