xref: /plan9/sys/src/libmach/8obj.c (revision 0c547597109109560d53d0e274a258f0150779c4)
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>
7*0c547597SDavid du Colombier #include <mach.h>
83e12c5d1SDavid du Colombier #include "8c/8.out.h"
93e12c5d1SDavid du Colombier #include "obj.h"
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier typedef struct Addr	Addr;
123e12c5d1SDavid du Colombier struct Addr
133e12c5d1SDavid du Colombier {
143e12c5d1SDavid du Colombier 	char	sym;
153e12c5d1SDavid du Colombier 	char	flags;
163e12c5d1SDavid du Colombier };
17bd389b36SDavid du Colombier static	Addr	addr(Biobuf*);
183e12c5d1SDavid du Colombier static	char	type2char(int);
19bd389b36SDavid du Colombier static	void	skip(Biobuf*, int);
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier int
_is8(char * t)223e12c5d1SDavid du Colombier _is8(char *t)
233e12c5d1SDavid du Colombier {
243e12c5d1SDavid du Colombier 	uchar *s = (uchar*)t;
253e12c5d1SDavid du Colombier 
263e12c5d1SDavid du Colombier 	return  s[0] == (ANAME&0xff)			/* aslo = ANAME */
273e12c5d1SDavid du Colombier 		&& s[1] == ((ANAME>>8)&0xff)
283e12c5d1SDavid du Colombier 		&& s[2] == D_FILE			/* type */
293e12c5d1SDavid du Colombier 		&& s[3] == 1				/* sym */
303e12c5d1SDavid du Colombier 		&& s[4] == '<';				/* name of file */
313e12c5d1SDavid du Colombier }
323e12c5d1SDavid du Colombier 
33bd389b36SDavid du Colombier int
_read8(Biobuf * bp,Prog * p)34bd389b36SDavid du Colombier _read8(Biobuf *bp, Prog* p)
353e12c5d1SDavid du Colombier {
36219b2ee8SDavid du Colombier 	int as, n, c;
373e12c5d1SDavid du Colombier 	Addr a;
383e12c5d1SDavid du Colombier 
39bd389b36SDavid du Colombier 	as = Bgetc(bp);		/* as(low) */
403e12c5d1SDavid du Colombier 	if(as < 0)
413e12c5d1SDavid du Colombier 		return 0;
42bd389b36SDavid du Colombier 	c = Bgetc(bp);		/* as(high) */
433e12c5d1SDavid du Colombier 	if(c < 0)
443e12c5d1SDavid du Colombier 		return 0;
453e12c5d1SDavid du Colombier 	as |= ((c & 0xff) << 8);
463e12c5d1SDavid du Colombier 	p->kind = aNone;
47*0c547597SDavid du Colombier 	p->sig = 0;
48061a3f44SDavid du Colombier 	if(as == ANAME || as == ASIGNAME){
49*0c547597SDavid du Colombier 		if(as == ASIGNAME){
50*0c547597SDavid du Colombier 			Bread(bp, &p->sig, 4);
51*0c547597SDavid du Colombier 			p->sig = leswal(p->sig);
52*0c547597SDavid du Colombier 		}
533e12c5d1SDavid du Colombier 		p->kind = aName;
54bd389b36SDavid du Colombier 		p->type = type2char(Bgetc(bp));		/* type */
55bd389b36SDavid du Colombier 		p->sym = Bgetc(bp);			/* sym */
56219b2ee8SDavid du Colombier 		n = 0;
57219b2ee8SDavid du Colombier 		for(;;) {
58219b2ee8SDavid du Colombier 			as = Bgetc(bp);
59219b2ee8SDavid du Colombier 			if(as < 0)
60219b2ee8SDavid du Colombier 				return 0;
61219b2ee8SDavid du Colombier 			n++;
62219b2ee8SDavid du Colombier 			if(as == 0)
63219b2ee8SDavid du Colombier 				break;
643e12c5d1SDavid du Colombier 		}
65219b2ee8SDavid du Colombier 		p->id = malloc(n);
66219b2ee8SDavid du Colombier 		if(p->id == 0)
67219b2ee8SDavid du Colombier 			return 0;
68219b2ee8SDavid du Colombier 		Bseek(bp, -n, 1);
69219b2ee8SDavid du Colombier 		if(Bread(bp, p->id, n) != n)
70219b2ee8SDavid du Colombier 			return 0;
71bd389b36SDavid du Colombier 		return 1;
723e12c5d1SDavid du Colombier 	}
733e12c5d1SDavid du Colombier 	if(as == ATEXT)
743e12c5d1SDavid du Colombier 		p->kind = aText;
753e12c5d1SDavid du Colombier 	if(as == AGLOBL)
763e12c5d1SDavid du Colombier 		p->kind = aData;
77bd389b36SDavid du Colombier 	skip(bp, 4);		/* lineno(4) */
78bd389b36SDavid du Colombier 	a = addr(bp);
79bd389b36SDavid du Colombier 	addr(bp);
803e12c5d1SDavid du Colombier 	if(!(a.flags & T_SYM))
813e12c5d1SDavid du Colombier 		p->kind = aNone;
823e12c5d1SDavid du Colombier 	p->sym = a.sym;
83bd389b36SDavid du Colombier 	return 1;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier static Addr
addr(Biobuf * bp)87bd389b36SDavid du Colombier addr(Biobuf *bp)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier 	Addr a;
90bd389b36SDavid du Colombier 	int t;
913e12c5d1SDavid du Colombier 	long off;
923e12c5d1SDavid du Colombier 
933e12c5d1SDavid du Colombier 	off = 0;
94bd389b36SDavid du Colombier 	a.sym = -1;
95bd389b36SDavid du Colombier 	a.flags = Bgetc(bp);			/* flags */
96bd389b36SDavid du Colombier 	if(a.flags & T_INDEX)
97bd389b36SDavid du Colombier 		skip(bp, 2);
983e12c5d1SDavid du Colombier 	if(a.flags & T_OFFSET){
99bd389b36SDavid du Colombier 		off = Bgetc(bp);
100bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 8;
101bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 16;
102bd389b36SDavid du Colombier 		off |= Bgetc(bp) << 24;
1033e12c5d1SDavid du Colombier 		if(off < 0)
1043e12c5d1SDavid du Colombier 			off = -off;
1053e12c5d1SDavid du Colombier 	}
1063e12c5d1SDavid du Colombier 	if(a.flags & T_SYM)
107bd389b36SDavid du Colombier 		a.sym = Bgetc(bp);
1083e12c5d1SDavid du Colombier 	if(a.flags & T_FCONST)
109bd389b36SDavid du Colombier 		skip(bp, 8);
1103e12c5d1SDavid du Colombier 	else
1113e12c5d1SDavid du Colombier 	if(a.flags & T_SCONST)
112bd389b36SDavid du Colombier 		skip(bp, NSNAME);
113bd389b36SDavid du Colombier 	if(a.flags & T_TYPE) {
114bd389b36SDavid du Colombier 		t = Bgetc(bp);
1153e12c5d1SDavid du Colombier 		if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
116bd389b36SDavid du Colombier 			_offset(a.sym, off);
117bd389b36SDavid du Colombier 	}
1183e12c5d1SDavid du Colombier 	return a;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier static char
type2char(int t)1223e12c5d1SDavid du Colombier type2char(int t)
1233e12c5d1SDavid du Colombier {
1243e12c5d1SDavid du Colombier 	switch(t){
1253e12c5d1SDavid du Colombier 	case D_EXTERN:		return 'U';
1263e12c5d1SDavid du Colombier 	case D_STATIC:		return 'b';
1273e12c5d1SDavid du Colombier 	case D_AUTO:		return 'a';
1283e12c5d1SDavid du Colombier 	case D_PARAM:		return 'p';
1293e12c5d1SDavid du Colombier 	default:		return UNKNOWN;
1303e12c5d1SDavid du Colombier 	}
1313e12c5d1SDavid du Colombier }
132bd389b36SDavid du Colombier 
133bd389b36SDavid du Colombier static void
skip(Biobuf * bp,int n)134bd389b36SDavid du Colombier skip(Biobuf *bp, int n)
135bd389b36SDavid du Colombier {
136bd389b36SDavid du Colombier 	while (n-- > 0)
137bd389b36SDavid du Colombier 		Bgetc(bp);
138bd389b36SDavid du Colombier }
139