xref: /plan9-contrib/sys/src/libmach/8obj.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /*
2bd389b36SDavid du Colombier  * 8obj.c - identify and parse a 386 object file
33e12c5d1SDavid du Colombier  */
43e12c5d1SDavid du Colombier #include <u.h>
53e12c5d1SDavid du Colombier #include <libc.h>
63e12c5d1SDavid du Colombier #include <bio.h>
73e12c5d1SDavid du Colombier #include "8c/8.out.h"
83e12c5d1SDavid du Colombier #include "obj.h"
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier typedef struct Addr	Addr;
113e12c5d1SDavid du Colombier struct Addr
123e12c5d1SDavid du Colombier {
133e12c5d1SDavid du Colombier 	char	sym;
143e12c5d1SDavid du Colombier 	char	flags;
153e12c5d1SDavid du Colombier };
16bd389b36SDavid du Colombier static	Addr	addr(Biobuf*);
173e12c5d1SDavid du Colombier static	char	type2char(int);
18bd389b36SDavid du Colombier static	void	skip(Biobuf*, int);
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier int
213e12c5d1SDavid du Colombier _is8(char *t)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier 	uchar *s = (uchar*)t;
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier 	return  s[0] == (ANAME&0xff)			/* aslo = ANAME */
263e12c5d1SDavid du Colombier 		&& s[1] == ((ANAME>>8)&0xff)
273e12c5d1SDavid du Colombier 		&& s[2] == D_FILE			/* type */
283e12c5d1SDavid du Colombier 		&& s[3] == 1				/* sym */
293e12c5d1SDavid du Colombier 		&& s[4] == '<';				/* name of file */
303e12c5d1SDavid du Colombier }
313e12c5d1SDavid du Colombier 
32bd389b36SDavid du Colombier int
33bd389b36SDavid du Colombier _read8(Biobuf *bp, Prog* p)
343e12c5d1SDavid du Colombier {
35*219b2ee8SDavid du Colombier 	int as, n, c;
363e12c5d1SDavid du Colombier 	Addr a;
373e12c5d1SDavid du Colombier 
38bd389b36SDavid du Colombier 	as = Bgetc(bp);		/* as(low) */
393e12c5d1SDavid du Colombier 	if(as < 0)
403e12c5d1SDavid du Colombier 		return 0;
41bd389b36SDavid du Colombier 	c = Bgetc(bp);		/* as(high) */
423e12c5d1SDavid du Colombier 	if(c < 0)
433e12c5d1SDavid du Colombier 		return 0;
443e12c5d1SDavid du Colombier 	as |= ((c & 0xff) << 8);
453e12c5d1SDavid du Colombier 	p->kind = aNone;
463e12c5d1SDavid du Colombier 	if(as == ANAME){
473e12c5d1SDavid du Colombier 		p->kind = aName;
48bd389b36SDavid du Colombier 		p->type = type2char(Bgetc(bp));		/* type */
49bd389b36SDavid du Colombier 		p->sym = Bgetc(bp);			/* sym */
50*219b2ee8SDavid du Colombier 		n = 0;
51*219b2ee8SDavid du Colombier 		for(;;) {
52*219b2ee8SDavid du Colombier 			as = Bgetc(bp);
53*219b2ee8SDavid du Colombier 			if(as < 0)
54*219b2ee8SDavid du Colombier 				return 0;
55*219b2ee8SDavid du Colombier 			n++;
56*219b2ee8SDavid du Colombier 			if(as == 0)
57*219b2ee8SDavid du Colombier 				break;
583e12c5d1SDavid du Colombier 		}
59*219b2ee8SDavid du Colombier 		p->id = malloc(n);
60*219b2ee8SDavid du Colombier 		if(p->id == 0)
61*219b2ee8SDavid du Colombier 			return 0;
62*219b2ee8SDavid du Colombier 		Bseek(bp, -n, 1);
63*219b2ee8SDavid du Colombier 		if(Bread(bp, p->id, n) != n)
64*219b2ee8SDavid du Colombier 			return 0;
65bd389b36SDavid du Colombier 		return 1;
663e12c5d1SDavid du Colombier 	}
673e12c5d1SDavid du Colombier 	if(as == ATEXT)
683e12c5d1SDavid du Colombier 		p->kind = aText;
693e12c5d1SDavid du Colombier 	if(as == AGLOBL)
703e12c5d1SDavid du Colombier 		p->kind = aData;
71bd389b36SDavid du Colombier 	skip(bp, 4);		/* lineno(4) */
72bd389b36SDavid du Colombier 	a = addr(bp);
73bd389b36SDavid du Colombier 	addr(bp);
743e12c5d1SDavid du Colombier 	if(!(a.flags & T_SYM))
753e12c5d1SDavid du Colombier 		p->kind = aNone;
763e12c5d1SDavid du Colombier 	p->sym = a.sym;
77bd389b36SDavid du Colombier 	return 1;
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier 
803e12c5d1SDavid du Colombier static Addr
81bd389b36SDavid du Colombier addr(Biobuf *bp)
823e12c5d1SDavid du Colombier {
833e12c5d1SDavid du Colombier 	Addr a;
84bd389b36SDavid du Colombier 	int t;
853e12c5d1SDavid du Colombier 	long off;
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	off = 0;
88bd389b36SDavid du Colombier 	a.sym = -1;
89bd389b36SDavid du Colombier 	a.flags = Bgetc(bp);			/* flags */
90bd389b36SDavid du Colombier 	if(a.flags & T_INDEX)
91bd389b36SDavid du Colombier 		skip(bp, 2);
923e12c5d1SDavid du Colombier 	if(a.flags & T_OFFSET){
93bd389b36SDavid du Colombier 		off = Bgetc(bp);
94bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 8;
95bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 16;
96bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 24;
973e12c5d1SDavid du Colombier 		if(off < 0)
983e12c5d1SDavid du Colombier 			off = -off;
993e12c5d1SDavid du Colombier 	}
1003e12c5d1SDavid du Colombier 	if(a.flags & T_SYM)
101bd389b36SDavid du Colombier 		a.sym = Bgetc(bp);
1023e12c5d1SDavid du Colombier 	if(a.flags & T_FCONST)
103bd389b36SDavid du Colombier 		skip(bp, 8);
1043e12c5d1SDavid du Colombier 	else
1053e12c5d1SDavid du Colombier 	if(a.flags & T_SCONST)
106bd389b36SDavid du Colombier 		skip(bp, NSNAME);
107bd389b36SDavid du Colombier 	if(a.flags & T_TYPE) {
108bd389b36SDavid du Colombier 		t = Bgetc(bp);
1093e12c5d1SDavid du Colombier 		if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
110bd389b36SDavid du Colombier 			_offset(a.sym, off);
111bd389b36SDavid du Colombier 	}
1123e12c5d1SDavid du Colombier 	return a;
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier 
1153e12c5d1SDavid du Colombier static char
1163e12c5d1SDavid du Colombier type2char(int t)
1173e12c5d1SDavid du Colombier {
1183e12c5d1SDavid du Colombier 	switch(t){
1193e12c5d1SDavid du Colombier 	case D_EXTERN:		return 'U';
1203e12c5d1SDavid du Colombier 	case D_STATIC:		return 'b';
1213e12c5d1SDavid du Colombier 	case D_AUTO:		return 'a';
1223e12c5d1SDavid du Colombier 	case D_PARAM:		return 'p';
1233e12c5d1SDavid du Colombier 	default:		return UNKNOWN;
1243e12c5d1SDavid du Colombier 	}
1253e12c5d1SDavid du Colombier }
126bd389b36SDavid du Colombier 
127bd389b36SDavid du Colombier static void
128bd389b36SDavid du Colombier skip(Biobuf *bp, int n)
129bd389b36SDavid du Colombier {
130bd389b36SDavid du Colombier 	while (n-- > 0)
131bd389b36SDavid du Colombier 		Bgetc(bp);
132bd389b36SDavid du Colombier }
133