xref: /plan9-contrib/sys/src/libmach/6obj.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  * 6obj.c - identify and parse an I960 object file
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <bio.h>
7 #include "6c/6.out.h"
8 #include "obj.h"
9 
10 typedef struct Addr	Addr;
11 struct Addr
12 {
13 	char	sym;
14 	char	flags;
15 };
16 static	Addr	addr(Biobuf*);
17 static	char	type2char(int);
18 static	void	skip(Biobuf*, int);
19 
20 int
21 _is6(char *t)
22 {
23 	uchar *s = (uchar*)t;
24 
25 	return  s[0] == ANAME				/* aslo = ANAME */
26 		&& s[1] == D_FILE			/* type */
27 		&& s[2] == 1				/* sym */
28 		&& s[3] == '<';				/* name of file */
29 }
30 
31 int
32 _read6(Biobuf *bp, Prog* p)
33 {
34 	int as, n;
35 	Addr a;
36 
37 	as = Bgetc(bp);		/* as */
38 	if(as < 0)
39 		return 0;
40 	p->kind = aNone;
41 	if(as == ANAME){
42 		p->kind = aName;
43 		p->type = type2char(Bgetc(bp));	/* type */
44 		p->sym = Bgetc(bp);			/* sym */
45 		n = 0;
46 		for(;;) {
47 			as = Bgetc(bp);
48 			if(as < 0)
49 				return 0;
50 			n++;
51 			if(as == 0)
52 				break;
53 		}
54 		p->id = malloc(n);
55 		if(p->id == 0)
56 			return 0;
57 		Bseek(bp, -n, 1);
58 		if(Bread(bp, p->id, n) != n)
59 			return 0;
60 		return 1;
61 	}
62 	if(as == ATEXT)
63 		p->kind = aText;
64 	if(as == AGLOBL)
65 		p->kind = aData;
66 	skip(bp, 5);		/* lineno(4 bytes), reg(1 byte)*/
67 	a = addr(bp);
68 	addr(bp);
69 	if(!(a.flags & T_SYM))
70 		p->kind = aNone;
71 	p->sym = a.sym;
72 	return 1;
73 }
74 
75 static Addr
76 addr(Biobuf *bp)
77 {
78 	Addr a;
79 	int t;
80 	long off;
81 
82 	off = 0;
83 	a.sym = -1;
84 	a.flags = Bgetc(bp);			/* flags */
85 	if(a.flags & T_INDEX)
86 		skip(bp, 2);
87 	if(a.flags & T_OFFSET){
88 		off = Bgetc(bp);
89 		off |= Bgetc(bp) << 8;
90 		off |= Bgetc(bp) << 16;
91 		off |= Bgetc(bp) << 24;
92 		if(off < 0)
93 			off = -off;
94 	}
95 	if(a.flags & T_SYM)
96 		a.sym = Bgetc(bp);
97 	if(a.flags & T_FCONST)
98 		skip(bp, 8);
99 	else
100 	if(a.flags & T_SCONST)
101 		skip(bp, NSNAME);
102 	if(a.flags & T_TYPE) {
103 		t = Bgetc(bp);
104 		if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
105 			_offset(a.sym, off);
106 	}
107 	return a;
108 }
109 
110 static char
111 type2char(int t)
112 {
113 	switch(t){
114 	case D_EXTERN:		return 'U';
115 	case D_STATIC:		return 'b';
116 	case D_AUTO:		return 'a';
117 	case D_PARAM:		return 'p';
118 	default:		return UNKNOWN;
119 	}
120 }
121 
122 static void
123 skip(Biobuf *bp, int n)
124 {
125 	while (n-- > 0)
126 		Bgetc(bp);
127 }
128