1 /*
2 * vobj.c - identify and parse a mips object file
3 */
4 #include <lib9.h>
5 #include <bio.h>
6 #include "mach.h"
7 #include "vc/v.out.h"
8 #include "obj.h"
9
10 typedef struct Addr Addr;
11 struct Addr
12 {
13 char type;
14 char sym;
15 char name;
16 };
17 static Addr addr(Biobuf*);
18 static char type2char(int);
19 static void skip(Biobuf*, int);
20
21 int
_isv(char * s)22 _isv(char *s)
23 {
24 return s[0] == ANAME /* ANAME */
25 && s[1] == D_FILE /* type */
26 && s[2] == 1 /* sym */
27 && s[3] == '<'; /* name of file */
28 }
29
30 int
_readv(Biobuf * bp,Prog * p)31 _readv(Biobuf *bp, Prog *p)
32 {
33 int as, n;
34 Addr a;
35
36 as = Bgetc(bp); /* as */
37 if(as < 0)
38 return 0;
39 p->kind = aNone;
40 p->sig = 0;
41 if(as == ANAME || as == ASIGNAME){
42 if(as == ASIGNAME){
43 Bread(bp, &p->sig, 4);
44 p->sig = leswal(p->sig);
45 }
46 p->kind = aName;
47 p->type = type2char(Bgetc(bp)); /* type */
48 p->sym = Bgetc(bp); /* sym */
49 n = 0;
50 for(;;) {
51 as = Bgetc(bp);
52 if(as < 0)
53 return 0;
54 n++;
55 if(as == 0)
56 break;
57 }
58 p->id = malloc(n);
59 if(p->id == 0)
60 return 0;
61 Bseek(bp, -n, 1);
62 if(Bread(bp, p->id, n) != n)
63 return 0;
64 return 1;
65 }
66 if(as == ATEXT)
67 p->kind = aText;
68 else if(as == AGLOBL)
69 p->kind = aData;
70 skip(bp, 5); /* reg(1), lineno(4) */
71 a = addr(bp);
72 addr(bp);
73 if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
74 p->kind = aNone;
75 p->sym = a.sym;
76 return 1;
77 }
78
79 static Addr
addr(Biobuf * bp)80 addr(Biobuf *bp)
81 {
82 Addr a;
83 long off;
84
85 a.type = Bgetc(bp); /* a.type */
86 skip(bp,1); /* reg */
87 a.sym = Bgetc(bp); /* sym index */
88 a.name = Bgetc(bp); /* sym type */
89 switch(a.type){
90 default:
91 case D_NONE: case D_REG: case D_FREG: case D_MREG:
92 case D_FCREG: case D_LO: case D_HI:
93 break;
94 case D_OREG:
95 case D_CONST:
96 case D_BRANCH:
97 off = Bgetc(bp);
98 off |= Bgetc(bp) << 8;
99 off |= Bgetc(bp) << 16;
100 off |= Bgetc(bp) << 24;
101 if(off < 0)
102 off = -off;
103 if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
104 _offset(a.sym, off);
105 break;
106 case D_SCONST:
107 skip(bp, NSNAME);
108 break;
109 case D_FCONST:
110 skip(bp, 8);
111 break;
112 }
113 return a;
114 }
115
116 static char
type2char(int t)117 type2char(int t)
118 {
119 switch(t){
120 case D_EXTERN: return 'U';
121 case D_STATIC: return 'b';
122 case D_AUTO: return 'a';
123 case D_PARAM: return 'p';
124 default: return UNKNOWN;
125 }
126 }
127
128 static void
skip(Biobuf * bp,int n)129 skip(Biobuf *bp, int n)
130 {
131 while (n-- > 0)
132 Bgetc(bp);
133 }
134